Writing Arduino Libraries, An Expert View

The Arduino IDE has a bit of a split personality. On the one hand, it is a simple environment where you can just pick and choose a few libraries, write a few lines of code, and make lots of interesting things. On the other hand, it is also an ecosystem in which many different boards and libraries can be supported. Writing a great library that everyone can easily use takes a little forethought. There is an official style guide, but a recent post by [Nate] from Sparkfun points out lessons learned from writing more libraries than most people.

Of course, as you might expect, some of this is a matter of opinion, and [Nate] admits that. For example, they always use the serial port at 115,200 baud, but they do note that 9,600 baud is also popular. They also suggest making code as readable as possible, which is usually good advice. In the old days, writing terse code might lead to higher efficiency, but with modern compilers, you ought to get a tight final result even when doing things in a pretty verbose fashion.

However, a lot of the advice is very subtle but important. For example, the use of default parameters and the order of parameters. If you add their advice to the official style guide, you should be well on your way to creating really great Arduino libraries.

Of course, you also need a great idea for a library or an improved library that doesn’t already exist. That may be your most difficult task. Sometimes it makes sense to port something over instead of starting from scratch.

32 thoughts on “Writing Arduino Libraries, An Expert View

  1. Wanna see how it should be done? Look at all of the stuff that PJRC, et al, has done. Stoffregen has fixed much garbage and problems found in arduino ‘core’ libs and other 3d party stuff from A/F and S/F.

  2. Biggest problem is C programmers trying to write C++ code.

    void func(void); // makes it obvioius it’s a C guy writing C++

    Maybe they’ve gotten better at Sparkfun but some libraries for environment sensors were pretty bad a couple years ago. The big hassle was not being able to change I2C port. Adafruit was little better but also had problems.

  3. queue winge mode ;-)
    I have real issues with the current arduino library structure and how it’s changed from the past.

    It’s so difficult to hack them for your own circuits and it’s equally annoying if you just want write something quick and basic to get a job done.

    Typically I’ll want to write a library to support a part of my project because I know that I’ll want to reuse it for some other project in the future.
    Writing it to conform to the current Arduino structure makes the library a bigger task than the project itself. There’s a reason I still write the bulk of my atmega/attiny code in 0022…

    1. Compared to using “real” build tools (e.g. CMake, ugh), I find I can write an Arduino library quite quickly. All you have to do to modify an existing library is modify the code in your libraries directory. Pretty easy…

      I’ve recently started using PlatformIO, and the intercompatibility with that and Arduino is great – I can use the command line tools and easy dependency management, and others can use the Arduino IDE if that’s what they’re used to.

  4. The horrors of Arduino, a personal rant.

    “Arduino” has a lot going for it, no doubt about that. Please interpret the rant as room for improvement, not as a hate speach.

    1). The boards: A board for beginners that does not fit on a bredboard, and has some of the pins offset by 0.1″ makes it very inconvenient to make a quick addon board on Veroboard. I’ve thought long and hard about connectors for “universal” development boards. The best I can think of is a 2-row IDC connector for all signals. You can easily place them next to a breadboard, so the breadboard stays free for the rest of the project. “Dupont wires” work pretty well. And with custom IDC connectors you can connect it to about anything else you want. You can also place a break-out board with a mating connector directly on top of it. A (small) connector or screw hole on the opposite site is a plus. a wide board with connectors around the outer edges is a bad design. It makes it impossible to make smaller boards in a compatible format. Look at the M.2 standard. It’s a relatively small connector with different mounting hole locations for different size boards. It’s universal and flexible. Something like this for uC development boards would be great.

    2). The ATMEGA328. It does not have a decent 8-Bit port (without sacrificing the UART). For most projects it’s irrelevant, but for other projects it is very annoying.
    For example look at Adafruits “pinmmagic.h”, where they had to go through extreme horrors just to make TFT lcd’s work with different arduino variants.

    3). Choice of crystal: 16MHz is a bad crystal choice for uC’s if you want to use the UART for communicating with a PC. UART has an error budget of around 2% and the 16MHz crystal eats up more than half of that. It “usually works” but it is not robust. Many people have had problems with this. Even on vlachoudis/bCNC for example they state that you may have occasional communication problems with even official arduino boards. Unreliable communication with a CNC machine is not nice, to say the least…

    4). Voltage regulator. “arduino” works with power from an USB port, but why not throw in a simple SMPS circuit. The boards are certainly expensive enough for that. It would have made it possible to use the arduino boards with any DC voltage between a few volts and 30V or so. Now you see boards from beginners which attempt to make a battery powered circuit with multiple batteries in series to generate 8V or so just to make the wastefull linear voltage regulator happy. A connector to directly power it from a battery would have been great for projects like that.
    An SMPS also has the big advantage that it decouples spikes from the external power supply and wiring. uC boards can easily be upset by spikes from for example switching fluorisent ligths or halogen lights with old fashioned transformers. Mains voltage is not a clean environment. The original arduino’s also had thermal releafs on the heat pad of the voltage regulator, which makes it overheat and shut down much sooner than otherwise. It is the main reason for the pretty low maximum voltage for the barrel connector on the arduino boards.

    5). The “ide”. The soft green java contraption is not an IDE, and certainly not fit for beginners. Only people who do not know better are willing to put up with it. The absolute minimum requirement for 20+ years is decent syntax completion. The difference while learning new libraries, is typing the class name, and selecting a function from the list, or Reading multiple pages of a file just to get the name of a function right. Also other basic functions, such as double clicking on a function call and jumping to it’s definition are missing. It’s just plain horrible. The way support for multiple boards is hacked in is also Yuch. Platformio has done this a lot better with all settings in a simple configuration file, and project templates to start new projects. (Platform IO also lets you use any IDE, so you can use the same IDE you’re already familiar with, if you have previous programming experience). If you use the default IDE in PlatformIO, you also have a pretty decent development environment.

    6). “They” had not even tried to start with a decent produkt. From what I understand it was developed by a few (first year?) students somewhere in Italy, and later It “exploded” to the rest of the world. For those students it was a great project, but the whole arduino thing was very slow to mature after that. They just stuck with the old limitations for many years.

    7). digitalWrite() … Just Yuck! OK, it’s possible to toggle a relay with it. It seems to be the ONLY way to use “arduino” for general I/O. Then people start complaining on forums why their hand written SPI bus is so slow… I’m still in doubt what a good way of implementing general I/O is. For a project with the scope and breath I think templates are the way to go. They’re a bit of a horror to write and debug, but If they’re well written they are a dream to work with and generate very fast & compact code, upto single cycle instructions for (re) setting I/O bits. Little David on EevBlog has made a few vid’s on using templates for an I/O library, and it’s a pretty good introduction on how these templates are supposed to work.
    The absence of a good I/O library also very severely hinders the development and portability of libraries. using “digitalWrite() in library code is simply not an option any library writher should even consider.

    8). begin() & loop(). Sigh. For me this is an instant hair raiser. Control over what your program is doing disapears then (when?) some time later you may hope it comes back. It seems that some “arduino” variants do some buffer management or other stuff in the background.

    9). Pre-instantiated classes. You have no idea what classes are available in an “arduino” environment. This pre-instantiation also forces them to use very generic names such as “wire.write()” for I2C. If I want to use an I2C class to write to an external EEprom for example, I want to instantiate the I2C class with the name Eeprom, so I can use Eeprom.write().

    10). It’s a weird (and especially in the beginning badly written) mismash of C and C++. That is however also hidden from beginners. It may take beginners half a year or so before they realize that “arduino” is not a programming language.

    11). The way “arduino” is set up is not a decent teaching environment. They hide all the library code in un-findable places. And use bad tools (See 3). so you can’t even use their own tools to examine how the framework works. Reading that code, examining it and experimenting it could have been a great teaching environment. Studying well written code is a great way to learn programming, especially if you can also use and modify that code to use in projects of your own

    12). “Arduino” is not a good learning environment. The whole “wiring” thing was only ever intended to give “artists” with no real interst in learning programming a way to write some code to get simple projects going quick. (And in that it works). “Arduino” has (should be) much more than that. Almost anyone who is intersted in starting with programming uC’s is automatically pointed to the arduino stuff. Schools are teaching “arduino” to students. In the arduino world they learn simple tricks to blink a led. And then later, they have to un-learn bad habits if they ever want to become decent programmers.

    13). The debacle between the 2 arduino companies, I believe even fought out in court. Stuff like that only happens if lots of money is to be made. Please do not buy the official boards. Get some cheap clones from China to start with. Then if you like it donate some money to whomever made software and /or libraries you like.

    14). The arduino website is closed by a “cookie wall”. This is not because they “respect your privacy”, but because they find making money from advertisements more important than user experience.

    15). The bootloader. Boot loaders are not user friendly! I’ve never understood the use of them. Just give me a decent programmer that “just works”. With bootloaders you often have to press a reset button or other fiddling to get it to work. If you’ve made an error with the uart wiring the bootloader does not work at all. One of the first programmers I built myself for the AVR’s was based on AN910, a slow and now vastly obsolete programmer, but it was decent for the time. With that programmer came an application note which switched the SPI bus with an analog multiplexer between the programmer and the application. This was a very robust setup (25+ years ago!). It always worked. You tell your IDE it has to program the chip, and it does it. Such a programmer also leaves the UART completely free to do more, or something else than communicating with the attached PC. RS485 is a wonderfull way to have multiple uC’s talk to each other. The Nucleo boards come with (snap off) on board programers. already much better, but I still prefer a separate programmer, such as for example the ST-Link V2 clones from Ebay / Ali. If you have multiple boards you only need one programmer, which makes the overall costs lower. And what is the difference for a beginner between plugging in an USB cable or plugging in an Programmer cable?

    With all these limitations, why has arduino become such a hype? There is nothing remarkable about the whole thing compared to other. My best guess it that it’s just coincidence. Back then there were not many “easy” ways to start with uC. You had to choose an IDE, an uC, set up the compiler and more of that stuff. I know, I started with programming my first 16F84 with a breadboard and wires hanging of the LPT port. I found assembly abhorrent, especially on the pic16 architecture, and quicky witched to a few wires to a breadboard to program my first AVR with AN910. Then I could use GCC to write progams. Using Gcc with AVR’s was my introduction into Open Source software. Now I’m among the 2% who have stopped buying into the commercial OS’es. I use some Linux distro for my daily dose of PC stuff. GCC was (and still is) a very good compiler. I just skipped the time where you had to buy uC’s in ceramic packages (Those cost EUR30+ for a simple uC (Euro’s did not even exist back then, that’s another story). In those days if you wanted a “complete setup” with a development board, an IDE and a C compiler without the tinkering such as I did the only choise was to shove out several hundred’s of dollars for a box with all that stuff in it.

    It was a big rant. But don’t understand me wrong. I believe arduino has a lot of potential. It is just really slow in realising it. “arduino” is still pumping out the same old boards with the weird connector setup, but breadboard friendly versions are also available. I’ve heard rumours that there is some incentive to drop the java contraption and switch to a decent IDE by default. PlatformIO is also a good alternative. My rant is a big list, and a list with counter arguments can easily be just as big. But all of the arguments in my list are valid for people starting with he arduino world, even if they do not know it because of their lack of experience, and do not know what alternatives exist.

    1. Come on… it’s such a hype not because of coincidence.
      It’s the fastest and cheapest prototyping ecosystem to get something up and running in minutes. There are a lot of uc supported with different form factors, not just the atmega328 on the stupid arduino uno pin layout.
      Of course, I won’t trust it on industrial products, but to check if a component works, it’s way quicker than Microchip-Atmel ST, [insert chip manufacturer] overpriced development boards than you cannot get support from if you’re not a big company.
      I don’t think it’s a good ecosystem for beginners, because of the flaws you described, you have to understand the limitations and it needs experience to avoid the bad practices of the Arduino’s world. You cannot trust libraries, but at the end of the day, they are often less buggy than the ones you get from the chip manufacturers.
      Saying that, it makes me restart personal projects at home because it just works.

      1. An ST official board is cheaper than an official Arduino… they also throw in a free IDE and code composer, which for an ARM chip is great to get started. Clones from China are also cheaper, though by little, than an arduino clone.

        The real reason are the libraries. Not the board, not the IDE or even the arduino language. It’s the libraries that unlock all the potential for prototyping.

    2. >has some of the pins offset by 0.1″
      You meant 0.05″ (i.e. 1/2 pitch)? off by a full pitch would still line up with the grid.

      They messing around with /reset which prevented access to hardware debug, crippled environment (vs Atmel IDE) which allows for multiple files view, source code level debugger etc. All of that makes the hardware platform useless for any serious development.

      Single row headers wide apart, not enough power/ground pairs to minimize return path loop area. Overall bad EMI decisions. :P

      It has too many noob decisions and platform lock-in.

      1. Yes, designed by beginners for beginners and apparently they never got a pro to clean it up and do it right. And the “IDE”? Even the arrow icons make no sense. Arrow to the right to UPLOAD and arrow up to OPEN and down arrow to SAVE. What? How could someone’s first attempt at a simple GUI be permanently adopted? Maybe it matched their VCR remote? Or the buttons for setting their monitor? Ah! The controls for a microwave?

    3. “There is nothing remarkable about the whole thing compared to other.”

      You seem to have found plenty to remark about :)

      Arduino seems to be the No 1 ecosystem for haters and admirers alike. I use Arduino when it is appropriate and use something else when it is not. Complaining about the limitations of a hammer when you need a screwdriver really says more about the maker than the tool.

    4. Nice rant.

      I got started on arduino in a college class, after learning to program through classes in java (barf), c++, and c, and maybe also assembly and vhdl by that time. It wasn’t hard to figure out, but man I hated it. Honestly hard to imagine how it became the default ecosystem for beginners.

      However having said that, I am glad that something did. Because when programmers grow up and graduate to proper tools, they will hopefully un-learn their bad habits and gain a greater understanding. And when you think about it, a newbie is not going to write great code on his own no matter how good the tools.

      @donotdespisethesnake:

      To be fair, I think paulvdh was more complaining about the limitations of a cheap plastic hammer from a kids play set, which has inexplicably been used all over by beginning carpenters and house framers despite it being badly designed, over-priced, poor performing, and encouraging of bad habits.

      And I heartily agree that as an educational development board, arduino certainly doesn’t merit the popularity it has received.

      1. Compare the setup difficulty in getting an arduino programmed the first time with the setup difficulty for doing the same with an msp430, or an 8051. We were having this argument at work so we got two people who don’t do microcontrollers on similar laptops and had them download (respectively) the arduino ide and program blink, and code composer studio and program blink. The guy downloading arduino had his board running blink before CCS was even downloaded. The guy running CCS needed two people helping him just to find how to set up CCS for the MSP430 launchpad we had available. He never did get an led to blink before we all decided this argument had been decisively won.

        I don’t think the arduino ide is perfect, but I don’t think there is anything that was available 12 years ago that was anywhere near competitive with it as regards ease of use, and even now its productivity per unit time invested exceeds anything I know of. I’d love to see something else easier to use, but at work we all use arduino unos for piles of day to day uses, even though my company ships more microcontrollers than avr/microchip, because, again, if you’re in a hurry you can throw a logic signal sequencer together in the arduino ide and have it running on a chip before CCS or Atmel Studio or Eclipse even opens.

        1. Seconded – I got the TI Watch development setup. It was cheap and I got the CCS installed and immediately ran into the problem that TI didn’t put the watch example code front and center. I spent a day looking for it; never created any thing with it. The only problem I ran into with creating a servo driver with an Arduino was the USB polyfuse cutting out from supplying power to the microservo. Got an external supply and away it went, working as expected.
          Success>>failure.

        1. I would contend that the 328 is fine. It is solid and accessible. It doesn’t have convenience features, like FIFO, but it isn’t difficult to use. The real problem is the way that the Arduino library accesses the peripherals. Pin reads and writes are wasteful. Almost every operation is a blocking operation. You can do a ton of stuff with a 16MHz microcontroller, just not with polling loops.

    5. I think you’re slightly missing the point. Arduino isn’t really meant for someone like you.

      Someone with your expertise should already have a decent idea of what microcontroller is going to be appropriate for a given application. You then slap your chosen MC onto a breadboard and begin developing your new widget. Arduino decided long ago that consistency was going to be paramount. I think that is great especially as newbie who has tried to make heads or tails out of an Orange Pi PC2!

      If you’re not familiar Orange Pi is a Chinese company that puts out sbc’s which in theory are incredibly feature rich at less than half the cost of a Raspberry Pi. The problem is that as far as I can tell there is no one on God’s green Earth that knows how to interact with the peripherals in any meaningful way. I to this day do my best to avoid anything with an AllWinner chip in it because of that experience.

      Yes a lot of Arduino consists of things obviously cobbled together with multiple layers of workarounds and creative solutions on top of one another. I’m a novice and that much is clear as day to me. On the other hand a great deal can be discerned digging through the patchwork and seeing exactly how this Rupe Goldberg is Frankensteined together. Needing a 125mhz PWM for a project has taught me more about timers and clocks and how they can or cannot be altered to achieve a desired effect. I also appreciate the chaos that can come about for everything else attached to the board if you are not careful of which, where, when, and how you manipulate those clocks.

      So really where you see inefficiency and bad habits (both true). The real value is the knowledge gained from being forced to deal with these issues and understanding what the limitations are. You’re talking beginners here, worrying about inefficient and bad habits at this stage is like worrying about your 3 year olds poor stance and lack of a follow through when driving from the tee.

    6. I used to program PICs in assembly. Compared to that, Arduinos are a gift from heaven, for most tasks. Your points might stand, but they matter to 5% of people, if that.

      I hate Java bloatware, though :)

    7. Arduino is not breadboardable – who cares? There are shields. Arduino + shield = quick and easy way to make the hardware part of a project for a beginner. There are breadboard-friendly versions too.

      I agree, 328 is not for communicating with PC. It just setup for project failure. Fortunately, there is 32U4.

      The concept of “loop” is not too bad considering 2kb of RAM. Poor man’s RTOS for noobs :)

      Arduino IDE is not an industrial grade SW. It is immediately obvious once you start using exotic (non-Arduino) boards. Good luck with troubleshooting errors by looking at IDE Java exceptions! If it communicated with board bootloader yesterday, but throwing exceptions today – you are out of luck.

      But libraries are great! That is where the most value of Arduino is! There are libraries for pretty much any type of hardware you can think of! It shortens project time by an order of magnitude.

      1. > But libraries are great! That is where the most value of Arduino is!

        Exactly! If you want to try something quickly, there’s usually a library and some examples to get going with.

        If a particular project grows in size, then I let the programmer in me loose and I try to break the project into a series of modules and libraries with proper header files etc… and if I do a good enough job, the libraries will work in other compilers as well,

        So this article is very much appreciated.

  5. ive written a few myself, though only put one up on git hub. hell its almost necessary if you want to organize a large project. like if you want to write a class, you usually have to do it in another file, and if its something you can use on more than one project, might as well just make it a library proper.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.