by on
Arduino

Dumbest thing ever.

For the last year I have been working with a piece of software that was started two years ago by another programmer in Arduino using the Arduino mega2560. It has since grown into several thousand lines of code across a small pile of libraries maintained in a git repository. There are units of this which have been installed in offices around the country and to update the code we send around a pair of linux laptops with a script that backs up the dataloggers and the old firmware and uploads the current firmware.

To get the firmware out of the Arduino IDE my clients hardware engineer is required to download the new source code from the git repository, bring up the Arduino IDE build in verbose mode and then manually copy the hex file from its obscure location to the git repository commit and push the resulting code. Then he has pull the code to the repositories on the update machines. Testing code is roughly the same process except for finding the hex file.

It is pretty much the dumbest thing ever.

The Arduino Preprocessor

The history of the Arduino preprocessor is almost a decade long. The preprocessor’s job is pretty simple — hide as much confusing detail as possible from the novice user do a bunch of the users detail work and compile all of the dependencies. When Wiring was created this was done by pile of Java using regular expressions. 10 years later, it remains one. Here is its source code: https://github.com/arduino/Arduino/blob/master/app/src/processing/app/preproc/PdePreprocessor.java

If you are used to doing these things yourself and controlling the organization of your code then the Arduino preprocessor does some really arbitrary and annoying things. Try sharing a common file between your sketch and modules (libraries) which you may or not use depending on what sketch you are compiling. It will compile everything in the directory with the included file. You have no say in what gets compiled and in what context.

What’s that in the shadows?

Ok, so it simplifies the users experience. But does it really make things clearer? Lets look at a trivial example designed for the target (novice) audience.

/*
Blink -- This example code is in the public domain.
*/
void setup() {
pinMode(13, OUTPUT);
}

void loop() {
digitalWrite(13, HIGH); // set the LED on
delay(1000); // wait for a second
digitalWrite(13, LOW); // set the LED off
delay(1000); // wait for a second
}

If you hold the shift key down while compiling your code you will find that along with the arduino core there is a Blink.cpp file that is created by the preprocessor. Its buried in a temporary location in this case

/var/folders/pT/pTwTtnMcHL0MMWMWt3BuNU+++TQ/-Tmp-/build1406962201643661317.tmp/Blink.cpp

Must be pretty scary stuff. Lets take a look at what its done.

/*
Blink -- This example code is in the public domain.
*/
#include "Arduino.h"
void setup();
void loop();

void setup() {
pinMode(13, OUTPUT);
}

void loop() {
digitalWrite(13, HIGH); // set the LED on
delay(1000); // wait for a second
digitalWrite(13, LOW); // set the LED off
delay(1000); // wait for a second
}

The preprocessor added 3 lines of code. These lines are needed to tell the compiler to use the definitions needed to make things like pinMode, digitalWrite and Delay “just work”. It also tells the compiler about the functions the user defined. You still don’t get to see the main loop which calls setup and loop. Loop is a misnomer since if you could see it you would find a function that is called repeatedly, losing its context every time. So the novice is still relatively sheltered from the details in order to make things easy for them. They aren’t however sheltered from fact that they are actually just programming in the gnu/g++ language. This could have been accomplished in other ways, for instance it would not be extremely difficult for the editor to add those lines, if the user forgot them.

“Make”ing it a little better.

If you google for Arduino make file you should find at least two or three branches off of the makefile that  Nicholas Zambetti, David A. Mellis & Hernando Barragan wrote that used to be included in the Arduino. I took the one that fit the most closely to my target application and trimmed it down. https://github.com/mjoldfield/Arduino-Makefile I also added some (still a bit buggy) support for Windows. Then I put the makefiles include (Arduino.mk) in the same directory as the core for the stable branch of the arduino (I am conservative and found serious flaws in arduino 1.0’s serial handling so it is 0022 in this case).

I compile my code one last time in the IDE and put the resulting cpp file in a directory called csource/<Sketchname>/

Then I put my Makefile in the same directory.

MCU = mega2560
ARDUINO_LIBS =
USER_LIBS = Monitor Wire DS2482
include ../../arduino/Arduino.mk

Since I use xcode as my primary development IDE I set up my build settings to make install from that directory and I am done. It would not be incredibly difficult to add this to the Arduino IDE “clunky” though it is. More importantly updating the code from the repository becomes a matter of two command lines.

git pull
make install

Which is much less painful for me and my client. In fact the update machines can do it themselves.

You can find the result (minus my clients project code) at https://github.com/suspect-devices/arduino-core-0022

Warning: Experimental

This is a solution that I needed. It is not complete and it should be regarded as highly suspect. Also while I have been able to use it it build on windows finding the serial port without an external program is problematic at best. Nevermind the lack of a real shell outside of cygwin or powershell. You have been warned.

One Response to “Using the Arduino core as a library”

  1. ben

    I find the arduino environment to be very confusing.. although I’m pretty new to programming. I understand they’ve tried to make things easier by hiding the internal workings but then when things don’t work you’re totally lost!

    For example, just downloading the “core” library is confusing. Presumably this is the core code:
    https://github.com/arduino/Arduino/tree/master/hardware/arduino/cores/arduino
    You can see all the files present, yet if you want to download the project with all the files where’s that link? If you click the code symbol, it takes you to an entirely different set of code..
    https://github.com/arduino/Arduino
    and on that page you can download a zip of all the files, except it’s not the same files as the first link!

    I suppose it depends on forks, but is there a list of functions that are in libcore.a? For example, you can limit the number of cpp/h files in your project if you know that you don’t call the associated libcore functions, correct?

Leave a Reply

  • (will not be published)