How To Create Custom Arduino Libraries for More Efficient Projects
2022-08-03 | By Maker.io Staff
Many Arduino projects rely on reusable code parts to perform standard tasks, such as sending characters to common LCDs. Instead of writing the communication code from scratch in every program, you can package such standard code in libraries that other programmers can import and utilize in their projects. Building and using libraries is a valuable tool in every programmer’s toolbox, and the technique is not only helpful when writing Arduino code. Read on to learn the basics of creating custom Arduino libraries and how to package and publish your code to share with other programmers.
A Basic Non-Library Example
This article uses the following short Arduino code example to explain the process of moving reusable code to an external library. Consider the following code:
#define DELAY_TIME 100 #define OUT_PIN 13 unsigned long lastMillis = 0; boolean state = false; void setup() { pinMode(OUT_PIN, OUTPUT); } void loop() { unsigned long currentMillis = millis(); if(currentMillis - lastMillis > DELAY_TIME) { state = !state; digitalWrite(OUT_PIN, state); } }
This simple program toggles the output state of one of the Arduino’s digital I/O pins without using the blocking delay() function. This code is a simple example of a standard method you’d often use throughout many projects.
Unfortunately, you’d need to duplicate most of the code if you wanted to toggle multiple pins using different delay times. Therefore, outsourcing this function to an external class can significantly reduce the complexity of future programs.
Identifying Reusable Parts of Your Code
Start by identifying which parts of your program you can reuse before moving any code to an external library. In the example from above, you could move the two variables and the code from within the setup() and delay() function to an external library. While you can move the variables to a new file without any modifications, you’ll have to introduce new functions for the contents of the old setup and loop method in the library class. Usually, you’d call the replacement for the setup function something like init(), start(), or begin(). However, you can also create a constructor, as shown below.
Creating Library Classes
Once you have identified the parts you can move to an external library, it’s time to create some classes. In C++, classes consist of two files: A header file (with the extension .h) and a source code file that bears the .cpp extension. The header defines all methods and variables present in the class without defining their exact behavior or values. In contrast, the source file contains the concrete implementation of the methods.
To create a custom library, navigate to the Arduino library folder. Then, create a folder called NonBlockingToggle, or whichever name you want to give your library. Then, create two files within that new folder and call them “NonBlockingToggle.h” and “NonBlockingToggle.cpp”. You’ll have to use an external text editor, such as Notepad++, to change the contents of these files, as the Arduino IDE doesn’t allow you to edit files located outside of the sketchbook.
Create a new folder within the libraries folder, and then add two new files that will hold the source code of your custom Arduino library.
Write the Header File
As mentioned, the header file serves as a list of variables and methods that the compiler can expect to find in your custom source code file. In this example, the header file looks as follows:
#ifndef NonBlockingToggle_h #define NonBlockingToggle_h #include "Arduino.h" class NonBlockingToggle { public: NonBlockingToggle(unsigned pin, unsigned long delay_time); void update(); private: unsigned long lastMillis = 0; boolean state = false; unsigned OUT_PIN; unsigned long DELAY_TIME; }; #endif
As you can see, I created a simple constructor for the new class that takes two arguments: the pin number to toggle and the delay time. The constructor is a special method you call when creating new objects. This special function always bears the same name as the class. Next, the header file defines a public update method that the main code can call from within its loop function. Finally, the header contains definitions for the four variables previously found in the main source code.
Note the #ifndef, #define, and #endif preprocessor statements. These ensure that users can’t accidentally include your library more than once, which could easily happen if users include other libraries that reference your code. Finally, include the Arduino header in your custom header files. Doing so allows you to use standard Arduino functions within your library. Note that the Arduino IDE automatically includes this header in your Arduino programs, but that doesn’t apply to custom libraries and external files.
Write the CPP Source File
Finally, you can move the contents from the original Arduino program to the new functions in your custom library’s CPP file:
#include "NonBlockingToggle.h" unsigned long lastMillis = 0; boolean state = false; unsigned OUT_PIN; unsigned long DELAY_TIME; NonBlockingToggle::NonBlockingToggle(unsigned pin, unsigned long delay_time) { OUT_PIN = pin; DELAY_TIME = delay_time; pinMode(OUT_PIN, OUTPUT); } void NonBlockingToggle::update() { unsigned long currentMillis = millis(); if(currentMillis - lastMillis > DELAY_TIME) { state = !state; digitalWrite(OUT_PIN, state); } }
Make sure to include the header file you created earlier. Then, create the functions defined in the header. Note that you have to write the class name before every function name and connect the two names using double colons. Besides that, the CPP file now contains the code from the main Arduino program introduced at the beginning of this article. However, you still have to update the original file so that it utilizes your custom library.
Importing and Using Your Custom Library
Head back to the Arduino IDE and update the file from the beginning of the article:
#include <NonBlockingToggle.h> #define DELAY_TIME 100 #define OUT_PIN 13 NonBlockingToggle toggle(OUT_PIN, DELAY_TIME); void setup() { } void loop() { toggle.update(); }
As you can see, the code is now significantly shorter than before, and you can import and use the functionality across as many programs as you like without rewriting any code. You can import your custom library just as you would with any external Arduino library.
Adding Examples to Your Library
Typically, there will be usage examples in most Arduino libraries that you download and install. These short examples illustrate how users can utilize your library in their projects. Enhancing your custom libraries with code examples is as simple as creating folders and moving source code files.
To get started, create an examples folder within your custom library’s folder. Then, you can move Arduino sketches that showcase how to include and employ your library to that folder:
Add all sketches you want to include as examples with your library to a folder called “examples.” Users can access these example sketches using the Arduino IDE’s main menu bar.
Summary
Software libraries are a fantastic way to package code into reusable units that you can include in any project that needs it. This way, you can avoid repeatedly rewriting the same piece of software and share your custom libraries with other developers.
Creating custom libraries for Arduino projects is as easy as moving the code you want to outsource to external class and header files located in a separate folder within the Arduino IDE’s standard libraries folder. Here, you can add as many files as your library needs. For the sake of simplicity, this tutorial illustrated the process using only a single class.
Finally, you can add examples to your custom Arduino libraries by adding an examples folder and copying some sketches from the sketchbook to that folder. Other developers can then access these example sketches from the main menu bar of the Arduino IDE. You can distribute your library using platforms such as GitHub or create a ZIP archive that contains the library and distribute it, for example, by uploading it to your personal blog or website. You can even submit your library for inclusion in the Arduino IDE Library Manager by following the submission process here: https://github.com/arduino/library-registry.
Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.
Visit TechForum