Advanced Arduino – Including Multiple Libraries In Your Project

Arduino IDE

The Arduino IDE is a great environment for getting started programming microprocessors. It radically lowers the cost of entry, and greatly simplifies the learning curve. The importance of these properties should not be underestimated. Most of us are capable of advanced microprocessor programming given time, desire and opportunity even without the Arduino environment. The biggest obstacle, however, is getting started. When that first hurdle is at last overcome, we can then soar to greater heights. That is where the Arduino is an incredible blessing. It is so simple that it removes most of the barriers to entry. From scratch, we can get started in microprocessors and build our confidence and knowledge at an easy pace. Once that is done, then we can advance to more complex projects and techniques.

That easy means of entry, however, can also become a limitation. Because the Arduino IDE makes the cost of getting started very low, that same simplicity can also prevent us from advancing to more complex projects. A good example is when you want to create new libraries that make use of existing libraries. When you try to do so in the usual fashion of including libraries, you are confronted with compiler errors. This article will examine the problem in combining various libraries within the IDE and how to work around them. It will also address some more advanced C++ practices that help when dealing with multiple libraries and larger projects.

Including Libraries within Another Library

The Arduino IDE has an easy way to include libraries in your sketch. Just use the Import Library command, and an include directive appears in your sketch. From there, not only is the header file (ending in .h) included in your sketch, but the code file (ending .cpp) is also compiled behind the scenes.

Now, say we are developing a more complex project that will use a library of our own. That library will itself build on other libraries. When we try to include one of those existing libraries in our new custom library, this automatic mechanism fails. In fact, it doesn’t even exist.  To see what I mean, let’s look at an example:

MyLibrary.h:
class Bounce;
 
class MyLibrary {
protected:
  Bounce* btn;
 
public:
  MyLibrary(int btnPin);
};
 
MyLibrary.cpp:
#include "Bounce.h"
 
MyLibrary::MyLibrary(int btnPin) {
btn = new Bounce(btnPin, 5);
}
MyLibrary.h:
class Bounce;

class MyLibrary {
protected:
  Bounce* btn;

public:
  MyLibrary(int btnPin);
};

MyLibrary.cpp:
#include "Bounce.h"

MyLibrary::MyLibrary(int btnPin) {
btn = new Bounce(btnPin, 5);
}

In this example, in my header file, I’ll provide a forward declaration to the class Bounce, and then in my code file, I’ll include the Bounce library. If I did this include in a sketch file, I would have no problem. When I try it in a library file, it fails.

Getting Your Library to Compile while including a Library

When you try to compile this code, the first error you get indicates that the Bounce.h file can not be found. The reason is the Arduino IDE searches for library includes, so the user is not hassled with specifying their exact location. It is setup to search the library directory from sketches only, not from within the library directory itself. When including files from within the library, if the include file is not in the same directory as the file doing the including, it won’t be found.

The remedy is simple – provide a directory specification to the file to include. In this example, to include the “Bounce.h” file, we specify the relative file path this way:

#include "../Bounce/Bounce.h"
#include "../Bounce/Bounce.h"

That is the relative path in Linux. In Windows, you may need to use backslashes (‘\’) instead. The ‘../’ indicates the parent directory of the current one which is “MyLibrary”. If we followed the path specifier, we go up one directory, which puts us in the library directory, and then down into the Bounce directory. Lastly, we then specify the filename to include.

Now when you try to compile, the compiler will find the Bounce header code and compile with no problem. That was simple wasn’t it? Not so fast. We now run into our next problem. As part of keeping things simple for the new user, the Arduino IDE makes no distinction between compiling and linking. These are two distinct operations and the linking operation comes after the compile operation. What is linking you may be asking? Read on.

Linking versus Compiling

What the compile operation does is check the source files for syntax errors, and then if all is well, it converts them to machine code. Next comes the linking part. In this step, the linker scours all the source files (generally ending in .cpp) given it and connects or “links” the functions being called with their actual code, with result being one large file (called a hex file), which is then uploaded to your Arduino. If a needed file is not given to the linker, the link step will fail. Most development environments separate the two processes, so it is easy to track down the cause of the error. In the Arduino IDE, this separation is not made. That being the case, one way to detect a link error from a compile error is to simply to watch the compile error window. Compile errors show up quickly. If you have to wait a while before you get errors, the errors are likely coming from the linker.

Getting Your Library to Link to another Library

When you try to compile and link our changed example, you will now get errors complaining that various functions being called in the Bounce library cannot be found:

<code>MyLibrary/MyLibrary.cpp.o: In function `MyLibrary::MyLibrary(...)': /home/scott/Arduino Sketches/libraries/MyLibrary/MyLibrary.cpp:28: undefined reference to `Bounce::read()'</code>

That is because the Bounce library is not being sent to the linker. The Arduino IDE magic has again failed. The fix is unfortunately somewhat of a hack. Being a hack, it must be applied every time it is needed, and it isn’t real pretty. Having said all that, it is relatively easy.

The Arduino IDE sends any files included in the sketch to the linker, so the fix is to simply include the missing files in the sketch itself. In our example, in our sketch we put:

#include "Bounce.h"
#include "Bounce.h"

You should understand that the linker really is looking for the source code file “Bounce.cpp”. Since we have no way in the IDE to specify which source files to include in the linking process, the only way to specify to the Arduino IDE to link to this file is to include the header file in the sketch itself. That signals the IDE to send the corresponding .cpp file to the linker. You will need to repeat this step for every library used in your project. In the end, your sketch file will have one include for every library used in the entire project.

With this simple include statement in our sketch, the example will not only compile, it will also link. Problem solved.

Good Include Practices

While we are on the arcane subject of file includes, I thought it would be useful provide some good programming practices and clear up some confusion that may exist on the subject.

Forward Class Declaration vs Includes

In my simple example’s header file, you may have noticed that I did not try to include the Bounce.h file, but instead simply wrote what is known as a forward declaration to it:
class Bounce;
I did so because it is good programming practice. You should only include header files when necessary, especially within header files, since they in turn are included in other files. It speeds compile time and prevents possible trouble down the road. When you need to make use of another class within your header file, instead of including that class’s header file, you only need to provide a forward declaration to it. Then in your source code file, you actually include the class header so you can use the class. If you are confused, just look at my example header and source code file again.

Using Brackets vs Quotation Marks for Includes

You may have noticed when looking at other people’s code, that sometimes files are included using brackets (<>), and sometimes using quotes (“”). What is the reason for these two ways and which one should be used? I haven’t found documentation for any particular rules in the Arduino IDE. From my experience, it appears both can be used interchangeably. Normally though, C++ does make a distinction. The brackets should be used for built-in language library files, and quotes for your own files as well as third party libraries. In the Arduino’s case, if including a file in the Arduino IDE directory, you should use brackets. For example:

#include <WConstants.h>
#include <WConstants.h>

For anything in your sketch directory, including libraries, use quotes:
#include "Bounce.h"
Like I said, the Arduino IDE doesn’t enforce this distinction, but other IDEs may. It is good practice to make your code conform to the rules of C++. Good practices in the beginning will avoid countless headaches down the road.

Conclusion

Because of the inherent limitations in the Arduino IDE, many people migrate to more powerful development tools such as Eclipse as they begin to tackle larger projects. Interestingly, the Arduino website has a tutorial on converting over to Eclipse. Unfortunately, Eclipse has a bit of learning curve itself. If you are not ready to make that plunge, the technique provided in this tutorial will serve you until you take that next step.

In summary, we have examined some of the limitations of the Arduino IDE in regards to including files and provided a workaround. We examined good coding practices that may save trouble later on. At some point you may outgrow the IDE and migrate to Eclipse or some other IDE. Until that day, this article will make you better equipped to work within its limitations.

In researching solutions to this library include problem, as well as correct include syntax, I couldn’t find any relevant documentation on the subject. Therefore, the recommendations given are drawn from my own experience. As such, these techniques and practices may be flawed or there may be better ones available.  If you have any advice to the contrary, please post them in the comments section. Anything valid and pertinent will be added to this article.

Happy Arduino-ing!

This entry was posted in Tech and tagged . Section: . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

11 Comments

  1. Posted August 12, 2011 at 8:58 am | Permalink

    Nice article! I has to figure this all out for myself when writing my DayCounter library that uses my ShiftRegister library. My experience was entirely consistent with this article, well done.

  2. Eugen
    Posted August 12, 2011 at 10:52 am | Permalink

    I think it would be helpful to write or link to a tutorial that shows how to just built the toolchain, compile, link and upload your hex from scratch. I know I would follow that just to know I would get all the insights of what happens behind the scene of the IDE even if I would still use it.

  3. NotLogical
    Posted August 12, 2011 at 1:25 pm | Permalink

    Another technique which I use all the time to prevent multiple includes, is to format your .h files in the following manner:

    #ifndef _BOUNCE_H
    #define _BOUNCE_H

    class Bounce;

    class MyLibrary {
    protected:
    Bounce* btn;

    public:
    MyLibrary(int btnPin);
    };

    #endif

  4. Coda
    Posted August 18, 2011 at 1:24 am | Permalink

    Nice article, I found it while searching for experiences using AVR Studio with an Arduino (with bootloader) as I could really use its debugger.
    By the way, you are correct about the library inclusion standard, in fact it goes way back. Brackets are used to include standard libraries that are provided by the language or by the compiler package you are using ( for example) and quotes are used to include header files that you had written yourself or were specific to the current project. It’s good IMHO to stick to this practice even though I don’t think it’s a defined standard per se.

  5. Dan Maney
    Posted May 25, 2012 at 3:39 am | Permalink

    I think I proved that (for #include) just putting quotes around a filename, does not look in the sketch folder, but rather defaults to looking in the Arduino IDE folder. To get it to look for the file somewhere besides the IDE folder, the full filepath must be used.
    I tested this by renaming the .h files in the sketch folder to something unique that should not be found. With the #include “filename.h” method, no “file not found” error resulted, meaning I think, that it used the IDE folder. So if this is correct, then you must use the filepath unless you want to access files in the IDE folder.

  6. Markus
    Posted August 4, 2012 at 2:54 pm | Permalink

    Thank you so much for the advice on how to work around this – thought I had to pull out references to other libraries in my library which would have been a big mess. Now it is working beautifully! Really helpful – you saved my day! :-)

  7. Posted November 23, 2012 at 12:08 am | Permalink

    Thanks for this helpful article. I was getting undefined reference errors, and I couldn’t figure out why the linker was unhappy! I suspected that Arduino was naming command line options in an odd order, and you confirmed it for me. Including the .cpp files in my sketch worked great.

  8. Posted February 8, 2013 at 2:27 am | Permalink

    Thank you so much for this article. I spent hours earlier today trying to figure out why my libraries weren’t loading. Banging my head against the wall because it didn’t make any sense, and I was unable to find any information about this issue until I found this blog post. Thanks!

  9. mark C
    Posted August 10, 2013 at 10:48 pm | Permalink

    I would like some help with Statistics libraries ?
    Statistics.cpp , Statistics.h, Statistics.ino

    if u could email one that works that B cool

    thank U

  10. Tim Coddington
    Posted January 22, 2014 at 12:57 pm | Permalink

    I’m work with Teensy 3.1 which as an extension to the Arduino IDE called Teensyduino. So, I’m back to having to use it since it’s the only readily available IDE w/ built in download, etc.

    I have an Arduino IDE question I was hoping you could help answer:

    When I’m looking at an example, or any code, that include libraries and use their functions, how can one navigate to the header file contents of an included file without going out to a file browser and looking for the file itself. And similarly, how can I navigate to the spec of a function used in the code to see what it’s argument signature? I know keywords can be “referenced” with a hotkey but I thought I had seen these other types of “navigation” features in Arduino before.

    Thanks

3 Trackbacks

  • By Arduino Link Libraries - Hack a Day on August 12, 2011 at 8:05 am

    [...] covers how to make your own custom libraries while building off of preexisting ones. That’s something Arduino’s automatic magic wont touch.He covers getting your library [...]

  • By Arduino Link Libraries | You've been blogged! on August 12, 2011 at 8:25 am

    [...] covers how to make your own custom libraries while building off of preexisting ones. That’s something Arduino’s automatic magic wont touch.He covers getting your library [...]

  • By hackaholicballa - Arduino Link Libraries on August 15, 2011 at 12:08 am

    [...] covers how to make your own custom libraries while building off of preexisting ones. That’s something Arduino’s automatic magic wont touch.He covers getting your library [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code lang=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" extra="">

*