Embed With Elliot: There Is No Arduino “Language”

This installment of Embed with Elliot begins with a crazy rant. If you want to read the next couple of paragraphs out loud to yourself with something like an American-accented Dave-Jones-of-EEVBlog whine, it probably won’t hurt. Because, for all the good Arduino has done for the Hackaday audience, there’s two aspects that really get our goat.

(Rant-mode on!)

First off is the “sketch” thing. Listen up, Arduino people, you’re not writing “sketches”! It’s code. You’re not sketching, you’re coding, even if you’re an artist. If you continue to call C++ code a “sketch”, we get to refer to our next watercolor sloppings as “writing buggy COBOL”.

And you’re not writing “in Arduino”. You’re writing in C/C++, using a library of functions with a fairly consistent API. There is no “Arduino language” and your “.ino” files are three lines away from being standard C++. And this obfuscation hurts you as an Arduino user and artificially blocks your progress into a “real” programmer.

(End of rant.)

Let’s take that second rant a little bit seriously and dig into the Arduino libraries to see if it’s Arduinos all the way down, or if there’s terra firma just beneath. If you started out with Arduino and you’re looking for the next steps to take to push your programming chops forward, this is a gentle way to break out of the Arduino confines. Or maybe just to peek inside the black box.

Arduino is C/C++

Click on the “What is Arduino” box on the front page of arduino.cc, and you’ll see the following sentence:

“ARDUINO SOFTWARE: You can tell your Arduino what to do by writing code in the Arduino programming language…”

Navigate to the FAQ, and you’ll see

“the Arduino language is merely a set of C/C++ functions that can be called from your code”.

Where we come from, a bunch of functions written in a programming language is called a library. So which is it, Arduino?

(The Language Reference page is a total mess, combining parts of standard C with functions defined in the Arduino core library.)

Maybe that’s not as sexy or revolutionary as claiming to have come up with a new programming language, but the difference matters and it’s a damn good thing that it’s just a set of libraries. Because the beauty about the Arduino libraries is that you don’t have to use them, and that you can pick and choose among them. And since the libraries are written in real programming languages (C/C++), they’re a totally useful document if you understand those languages.

C and Assembly language, on the other hand, are different languages. If you’re writing assembler, you can easily specify exactly which of the chip’s native instructions to use for any particular operation — not so in C. Storing data in particular registers in the CPU is normal in assembler, but heroic in C. So if you start out writing your code in C, and then find out that you need some of the features of assembler, you’re hosed. You stop writing in C and port all your code over to assembler. You have to switch languages. You don’t get to pick and choose.

(Yes, there is inline assembler in GCC.  That’s cheating.)

This is not at all the case with Arduino: it’s not a programming language at all, and that’s a darned good thing. You’re writing in C/C++ with some extra convenience libraries on top, so where the libraries suck, or they’re just plain inconvenient, you don’t have to use them. It’s that simple.

A prime example is digitalWrite() in the Arduino’s core library, found in the “wiring_digital.c” file. It’s madness to use the ridiculously slow digitalWrite() functions when speed or timing matters. Compared to flipping bits in the output registers directly, digitalWrite() is 20-40x slower.

scopes_blinkingThe scope shots here are from simply removing the delay statements from the Blink.ino example code that comes with Arduino — essentially toggling the LED pin at full speed. Upper left is using digitalWrite() to flip the pin state. Upper right is using direct bit manipulation in C: PORTB ^= (1 << LED_BIT); Because Arduino’s digitalWrite() command has a bunch of if...then statements in it that aren’t optimized away by the compiler, it runs 28 times slower.

(And worse, as you can see in the lower left, the Arduino code runs with occasional timing glitches, because an interrupt service routine gets periodically called to update the millisecond timer. That’s not a problem with digitalWrite() per se, but it’s a warning when attempting tight timing using the Arduino defaults.)

OK, so digitalWrite() is no good for timing-critical coding. If Arduino were a real language, and you were stuck with digitalWrite(), you wouldn’t be able to use the language for anything particularly sophisticated. But it’s just a convenience function. So you can feel free to use digitalWrite() in the setup() portion of your code where it’s not likely to be time critical. That doesn’t mean that you have to use it in the loop() portion when timing does matter.

And what this also means is that you’re no longer allowed to say “Arduino sucks”. Arduino is C/C++, and at least C doesn’t suck. (Zing! Take that, C++ lovers. De gustibus non disputandem est.) If you think that some of the Arduino libraries suck, you’re really going to have to specify which libraries in particular you mean, or we’ll call you out on it, because nobody’s forcing you to use them wholesale. Indeed, if you’re coding on an AVR-based Arduino, you’ve got the entire avr-libc project baked in. And it doesn’t suck.

The “.ino” is a Lie

So if Arduino is just C/C++, what’s up with the “.ino” filetype? Why is it not “.c” or “.cpp” like you’d expect? According to the Arduino build process documentation,

“The Arduino environment performs a few transformations to your main sketch file (the concatenation of all the tabs in the sketch without extensions) before passing it to the avr-gcc compiler.”

True C/C++ style requires you to declare (prototype) all functions that you’re going to use before you define them, and this is usually done in a separate header “.h” file. When C compiles your code, it simply takes each function and turns it into machine code. In a philosophically (and often practically) distinct step, references to a function are linked up with the compiled machine code representing them. The linker, then, only needs to know the names of each function and what types of variables it needs and returns — exactly the data in the function declaration.

Long story short: functions need prior declaration in C, and your “.ino” code defines setup() and loop() but never declares them. So that’s one thing that the Arduino IDE does for you. It adds two (or more, if you define more functions in your “.inos”) function prototypes for you.

The other thing the IDE’s preprocessor does is to add #include "Arduino.h" to the top of your code, which pulls in the core Arduino libraries.

blink_loop

(And then, for some mysterious reason, it also deletes all comments from your code, making it harder to debug later on. Does anyone out there know why the Arduino IDE does this?)

So that’s it. Three lines (or maybe a few more) of very simple boilerplate separate a “sketch” from valid C/C++ code. This was presumably done in the interest of streamlining the coding experience for newbies, but given that almost every newb is going to start off with the template project anyway, it’s not clear that this buys much.

On the other hand, the harm done to the microcontroller newbie is reasonably large. The newb doesn’t know that it’s actually C/C++ underneath the covers and doesn’t learn anything about one of the most introductory, although mindless, requirements of the language(s): function declarations.

When the newb eventually does want to include outside code, the newb will need to learn about #include statements anyway, so hiding #include "Arduino.h" is inconsistent and sets up future confusion. In short, the newb is blinded from a couple of helpful learning opportunities, just to avoid some boilerplate that’s templated out anyway.

Write C++ Directly in the Arduino IDE

And if you don’t believe that Arduino is C/C++, try the following experiment:

  1. Save a copy of the example Blink project.
  2. Go into the “sketch’s” directory and copy Blink.ino to Blink.cpp.
  3. Re-open the project in Arduino and delete everything from Blink.ino
  4. Add the required boilerplate to Blink.cpp. (One include and two function declarations.)
  5. Verify, flash, and whatever else you want.

You’ve just learned to write C/C++ directly from within the Arduino IDE.

(Note: for some reason, the Arduino IDE requires a Blink.ino file to be present, even if it’s entirely empty. Don’t ask us.)

main.cpp

So if Blink.ino turns into Blink.cpp, what’s up with the setup() and loop() functions? When do they ever get called? And wait a minute, don’t all C and C++ programs need a main() function to start off? You are on the path to enlightenment.

Have a look at the main.cpp file in hardware/arduino/avr/cores/arduino.

maincpp3

There’s your main() function! And although we’ve streamlined the file a little bit for presentation, it’s just about this straightforward.

The init() function is called before any of your code runs. It is defined in “wiring.c” and sets up some of the microcontroller’s hardware peripherals. Included among these tasks on the AVR platform is configuring the hardware timers for the milliseconds tick and PWM (analogOut()) functions, and initializing the ADC section. Read through the init() function and the corresponding sections of the AVR datasheet if you’ve never done any low-level initializations of an AVR chip; that’s how it’s done without Arduino.

And then we get to the meat. The setup() function is called, and in an endless for loop, the loop() function is continually called. That’s it, and it’s the same code you’d write in C/C++ for any other microcontroller on the planet. That’s the magic Arduino setup() and loop(). The emperor has no clothes, and the Wizard of Oz is just a pathetic little man behind a curtain.

If you want to dig around more into the internals of the Arduino core library, search for “Arduino.h” on your local install, or hit up the core library on Github.

The Arduino Compile Phase

So we’ve got C/C++ code. Compiling it into an Arduino project is surprisingly straightforward, and it’s well-documented in the Arduino docs wiki. But if you just want to see for yourself, go into Preferences and enable verbose logging during compilation. Now the entire build process will flash by you in that little window when you click “Verify”.

It’s a lot to take in, but it’s almost all repetitive. The compiler isn’t doing anything strange or unique at all. It’s compiling all of the functions in the Arduino core files, and putting the resulting functions into a big (static) library file. Then it’s taking your code and this library and linking them all together. That’s all you’d do if you were writing your own C/C++ code. It’s just that you don’t know it’s happening because you’re pressing something that looks like a play button on an old Walkman. But it’s not rocket science.

There is one more detail here. If you include a library file through the menu, and it’s not part of the core Arduino libraries, the IDE locates its source code and compiles and links it in to the core library for you. It also types the #include line into your “.ino” file. That’s nice, but hardly a deal-breaker.

If you’d like to see this build process in the form of a Makefile, here’s (our) primitive version that’s more aimed at understanding, and this version is more appropriate for production use.

Next Steps

If the Arduino is the embedded electronics world’s gateway drug, what are the next steps that the Arduino programmer should take to become a “real” embedded programmer slash oil-burning heroin junkie? That depends on you.

Are you already good at coding in a lower-level language like C/C++? Then you need to focus on the microcontroller-specific side of things. You’re in great shape to just dive into the Arduino codebase. Try to take a few of the example pieces, or even some of your own “sketches” and look through the included Arduino library’s source code. Re-write some simple code outside the IDE and make sure that you can link to the Arduino core code. Then replace bits of the core with your own code and make sure it still works. You’ll spend half of your time looking into the relevant micro’s datasheet, but that’s good for you.

Are you comfy with electronics but bewildered by coding? You might spend a bit of time learning something like C. Learn C the Hard Way is phenomenal, and although it’s aimed at folks working on bigger computers, it’s got a lot of the background that you’ll need to progress through and beyond the Arduino codebase. You’re going to need to learn about the (relatively trivial) language conventions and boilerplatey stuff to get comfortable in straight C/C++, and then you can dig in to the Arduino source.

Wherever you are, remember that Arduino isn’t a language: it’s a set of libraries written in C/C++, some of them really quite good, and some of them (we’re looking at you EEPROM) simply C++ wrappers on the existant avr-libc EEPROM library. And that means that for every Arduino project you’ve written, you’ve got the equivalent source code sitting around in C/C++, ready for you to dig into. Thank goodness they didn’t invent their own programming language!

157 thoughts on “Embed With Elliot: There Is No Arduino “Language”

  1. I don’t think it’s any more unreasonable to call something “sketching” as it is to call it “scripting”. Yes, inventing a new term for an activity is a bit silly, but hardly worthy of condemnation.

    It’s a bit unfair to say that the Arduino reference docs are a mess because they include standard library and Arduino library functions on the same page, too, because it’s missing the point: the reference exists to serve as a one-stop-shop for people writing Arduino code, without having to go to multiple places, and understand where to look for particular functionality. Doing otherwise poses a significant barrier to entry, as anyone who’s tried to work with “enterprise” Java, or write a CMSIS based firmware for ARM would probably agree with.

    Finally, this is just plain wrong:
    “True C/C++ style requires you to declare (prototype) all functions that you’re going to use before you define them, and this is usually done in a separate header “.h” file.”

    You only need to provide function prototypes if your function is called before it’s declared, or declared in a different file. Arduino does its rewriting to remove that limitation for users – though personally I think it’s by far the ugliest and worst implemented part of the whole Arduino setup.

  2. In their defence, and preprocessor simplicity aside it wasn’t entirely Ardunio’s fault that saved source code gets referred to as “Sketches” in the IDE. That bit of genius was already there when they targeted Processing’s IDE for their own ends.

  3. This sort of stuff is what turned me off to Arduino at the beginning: Calling programs “sketches” and daughterboards “shields.” Now everyone else has followed suit with the cutesy names, e.g. “launchpads”, “capes”, “HAT”, even “Kippa” for the Jewish newbies.

  4. The Arduino IDE has single handedly enabled the average person a solid foot in the door to programming. The is MUCH to be said for simplicity and being held within “safe constructs” even as a seasoned programmer. Plus, the Arduino people are more about creating a good learning environment, which has it’s own reasons for keeping things as simple as possible. It is certainly a lot more work than meets the eye. They have done well in these regards.

    Of coarse, all good things can be improved upon. My main concern is the executable size. You quickly exhaust all the resources of the MCU if not careful. This renders Arduino code as pretty much “hobbyist” level unfortunately. But hey, that is what they offer, a nice learning setup.

    If you had an awesome compiler backing the Arduino with all it’s minimalist benefits you would have something really nice:

    …you would have OBERON http://www.projectoberon.com

    Oberon is the successor to Pascal and Modula. It is truly an astonishing compiler. ProjectOberon is the first full-blown “computer on a chip” based on an FPGA. Fits in under 2mb including RISC5 OS, compiler, graphics, wireless networking, mouse and keyboard. The Oberon language is truly a mavel of engineering itself. Take a look at the single web page. It has ALL the code for the whole system on this page. And it is no toy either. It is a complete development system.

    There is also Astrobe Oberon (Astrobe.com) which is the Arduino equivalent for the LPCxx line of MCU’s. It is much simpler than the Arduino and is simply download a 5mb installer. Amazing compiler. The blink.Mod is a mere 136 bytes vs Arduino at @1200 bytes. It is a commercial product but it is a great value. And here is what is scary: Astrobe Oberon HAS NO BUGS. There is no “bug tracker” anymore. They found them all, apparently.

    Coming soon is a “Oberon RISC soft processor” which is a FPGA implemented “microcontroller” which acts like a standard microcontroller but is “re-flashed” at startup. This opens up lot’s of opportunities.

  5. On a more serious note, do you think you could interview Hernando Barragán about his thoughts on Arduino in general? On the one hand, he’s frequently labeled as not getting the credit he deserves for “inventing” the Wiring libraries. On the other hand, I also get the sense that he wasn’t particularly INTERESTED in participating in the growth of Arduino (though by now he may be kicking himself for financial reasons.) This is not uncommon for things that start out as school (or research) projects; I can think of quite a few people/projects where someone preferred to remain on a particular path they had chosen, rather than divert to a risky (but possibly lucrative) business…

  6. Reading this article was like having a doctor finally tell you WHY you’ve been having migraines for the last 6 months.

    I’ve taken several programming classes, and tried some on my own(beginner level in PHP, JAVA, c/c++,…).
    I recently took some classes at the local community college, you know, to get an actual degree. One of the required classes for the program I was working on was Intro to Computers and Robotics. it introduced the Arduino. I looked at the sample sketches “oh, this is basically c, right?” Instructor “no, it’s Arduino!” “but, it’s kind of based on c, right?” “no, it’s different”
    I had just taken a couple of quarters of Java and PHP, using Eclipse and Komodo. Going from that to the Arduino IDE and being told “no, it’s not c, it’s Ardunio” was like going from full 2 stick RC cars to the one button “forward, reverse with right turn” controls. I was wondering what my options were for alternates to Arduino, or at least WHY it was so limiting.

    Now I have a much better idea of how to get the boards I have to do the things I want.

  7. Awesome. It is good to show people, what is reality. and it is specially for those who thinks they know everything with touch with aduino. No doubt, it is easy to learn, but go beyond that. Raw c coding is only way to take all controls of micro-controller.

  8. hehe this rings true, I remember years ago asking my programmer friend if he had heard of the arduino language. He immediately wanted to see it I opened the reference page and he looked so disturbed repeating ‘this is just C/C++…. i had a visual arts degree but now i’m close to having a mechatronics degree. I’m not sure if i would have made the leap had it not been for arduino. It takes a bit of study to really understand compilers, C, assembly, libraries. It’s good to lower the bar of entry by showing some cool results. But i agree arduino should make it more clear that it’s C/C++, people shouldn’t have to wait for articles like this to find out what they are really doing. Maybe they could include some examples aimed at people who are ready to progress to assembly.

    processing also uses the term ‘sketches’. I wonder who started it?

  9. Programmers are funny, arguing endlessly over minutia, or could they just as well be called religious about their programming. Any way reading comments on coding are entertaining ( for a while ).

    1. of course programmers argue about minutia, programming is all ABOUT minutia. You get very used to words meaning an exact thing. “close enough” and “you know what i mean” become terrifying in a programming context. So, yes, it DOES matter if you’re writing in Arduino, or if it’s really c with a light wrapper on it. If you know you are stuck with Arduino, you are limited. If you figure out it’s really c, then you realize that you have many more options.

  10. Well, I’m late to the party, but none the less, props to Elliot for at least taking “some” time to actually reveal comparisons between C/Arduino. We who have never really worked with either at all do appreciate it. It helps. I know it was really, REALLY hard not to flame the noobs. It’s so much FUN to do. “I know something yooou dooon’t!” Considering that I hadn’t done any programming since QBASIC was new, C/Arduino is a bit too cryptic, and since its now fairly old and archaic you’re lucky to find any useful intro explanations of it. “What? YOU don’t know C? Who doesn’t know C?” It at least gave me some info to use when looking for a more thorough guide to what does what and why, So, thanks for that.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

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