What is this Arduino Thing?
Straight from the horse’s mouth …
Arduino is an open-source electronics prototyping platform based on flexible, easy-to-use hardware and software. It's intended for artists, designers, hobbyists, and anyone interested in creating interactive objects or environments.
Actually Arduino is a lot of things. Given a specific context, it may mean any of the following…
- Arduino – The hardware platform (“the board”)
- Arduino – The abstraction library over WinAVR. WinAVR is the GNU tool chain (Compiler + C Runtime library etc.) for the AVR microcontroller used in the Arduino boards (“the software”)
- Arduino – “The IDE” (We’re using Arduino 19)
Here is a picture of the specific variant of Arduino I am using (It’s called the Freeduino serial board):
Figure 1 Freeduino-serial board (with ATMega328)
Show Me Something Interesting
Here you go, but remember to come back!
- Makezine Arduino archive
- Electronics lab Arduino archive
My Hands Are All Itchy, Where Do I Start?
First of all, you need to familiarize yourself with the Arduino platform and play with the Arduino IDE which is freely downloadable from the Arduino website.
Being the expert programmer that you are, you’ll soon realize that your hands are itchier but the Arduino IDE is getting in your way of alleviating that itch. What you need is a more powerful set of tools. I recommend using the combination of WinAVR + Arduino Library + Eclipse and this is what we will explore in the rest of this article.
So What’s This Article About, Again?
This article is all about empowering you, the expert programmer (for almost any definition of expert ;)), with more powerful tools that let you unleash your creativity without being limited by the default IDE.
With Eclipse, you will have code completion, better code navigation, syntax highlighting and the whole shebang!
So from here onwards I am assuming that you have already familiarized yourself with regular Arduino development. If not, then go ahead and do it (should not take too long) then come back for a better deal or just stay the course if you don’t mind a little suspense.
Show Me the Way
Alright then, here are the steps to Arduino nirvana…
- Download Eclipse (about 90 MBs). Unzip it to C:\Misc\Eclipse
- Download the Arduino IDE. Unzip to C:\Misc\arduino-0019
- Download the latest version of WinAVR. Unzip to C:\Misc\WinAVR
- Download the AVR Eclipse plug-in and install it (follow the instructions on their website)
Starting Eclipse and Trying on a Sample Program for Size…
- Start Eclipse
- Dismiss the welcome page by clicking the cross on the tab to reveal the actual work environment…
- Start a new project by clicking on “File->New->C++ Project”. Choose the “AVR Cross Target Static Library” project type and set the project name to Arduino. We are now going to compile the Arduino source files into a static Library for later use. Finally click on finish.
- Use Windows Explorer to go to C:\Misc\arduino-0019\hardware\arduino\cores\arduino, select all the code files and drag them onto the Arduino project already open in Eclipse. Note only include files with the extensions .c, .cpp and .h …
- Next click ok on the following dialog (accept the default copy option)…
- Now build the project by right clicking on it and choosing “Build” from the context menu. Horror of horrors we have 10 build errors…
- But don’t worry, we’ll fix them in a moment. Right click on the project and choose “Properties” and go to the “C/C++ Build -> Settings->AVR Compiler” option. Click on the “+” icon (after selecting the “Directories” option).
- Click on the “Workspace…” button and add the project directory “${workspace_loc:/${ProjName}}” as an include directory once for the “AVR Compiler” and again for the “AVR C++ Compiler”
- Right click on the project and choose “Properties”, then go to “AVR->Target Hardware” and then set the MCU Type option to the Microprocessor being used on your Arduino board along with the frequency of the crystal supplied with it. For me, it’s ATmega328P and 16,000,000 respectively. Then click on ok.
- Now build your project again and the build should succeed this time. Though you might get a bunch of warnings (21 in my case), just ignore them for now.
Das blinkenlights
- It’s time now for the “Hello world” equivalent of the embedded systems world. Go to “File->New->C++ Project” as before but now choose “AVR Cross Target Application” as the project type and set the project name to “BlinkenLights”
- Right click on the BlinkenLights project and choose “New->File”, set the file name to Main.cpp and click on Finish.
- Now add the following C++ code to Main.cpp:
-
#include "WProgram.h" //Include arduino headers
const int ledPin = 13;
const int interval = 1000;
int main()
{
init();
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
Serial.println("Ready.");
while(true)
{
digitalWrite(ledPin, HIGH);
delay(interval/2);
digitalWrite(ledPin, LOW);
delay(interval/2);
}
return 0;
}
- Now compile the project. Whoa, a whole bunch of errors!
- Ok let’s fix them. Right click on the “BlinkenLights” project and choose “Properties” and go to the “C/C++ build->Settings->Avr Compiler->Directories” option and click on the “+” icon.
- Then click on the “workspace…” button on the subsequent dialog and then choose Arduino->Debug in the sub-subsequent dialog.
- Finally you should see the following. Click on ok after you have verified the path.
- Do the same for “C/C++ build->Settings->Avr C++ Compiler->Directories”
- The go to “C/C++ build->Settings->Avr C++ linker->Libraries” and set the following options.
- Now compile the BlinkenLights project again.
Ok that’s much better now but we still have one error to go. This is a linker error. The linker is complaining here that it could not find an implementation for the function called __cxa_pure_virtual
anywhere though it is being referred to/used in other parts of the code. Hmm I hear you say “It’s a lie the function name doesn’t even suit my taste, why would I use it?!” Well I hear you alright but the thing is you are barely getting started and you haven’t seen all the code being used behind the scenes yet.
Suffice it to say the function is required by the C++ runtime to decide what needs to be done when someone calls a pure virtual function directly. As you’ll remember from your dealings with C++, a pure virtual function cannot be called directly without providing an implementation in some derived class. Well for that matter, a class with a pure virtual function cannot be instantiated at all but the C++ runtime likes to be prepared for any and all eventuality.
Advanced compilers would have thrown an exception from this function to signal an illegal operation but since we do not have those on the WinAVR platform, all we can do is prevent further harm from being done by entering a never ending loop (assuming the program is running amok in the first place since it has done the impossible by calling a pure virtual function directly!)
Note: This needs to be done only for the debug build. This function is apparently not used in the release build of Arduino. The debug builds are rigged to fail fast so that the point of failure is as close as possible to the place where the real problem is.
So here’s how we get rid of the above error…
- Add a new .c file to the Arduino project (note it should be .c and not .cpp). Call it missing.c and paste the following code in it and build both projects again. The error should go away. Note you need to build Arduino before you can build BlinkenLights.
void __cxa_pure_virtual()
{
while(1);
}
- On switching to the “Console” pane, you can see the result of running the avr-size command on the generated .elf file…
But it is not a pretty sight to behold. A meager led blinking program occupies about 62% of the whole of available program memory. But don’t be alarmed, we are in the debug build and such bloat is par for the course. You will get better results when you switch to release builds.
Switching to the Release Build
- Right click on a project and select “Build configurations->Set Active->2 Release”. Do this for all projects. Also please let me know if you find a way of doing this for all projects at once.
Note: You need to re-specify all the settings for the release build like you did for the debug build in order to make it compile.
Hmm, much better, but still not good enough 18% for BlinkenLights is still too much.
Premature Optimization Not the Root of All Evils?
- Here’s how we go from better to impressive. The following will ensure that you only pay for those functions and data-sections which are actually being used in the program. Add the following additional flags to both the C and C++ compilers in all projects
-ffunction-sections -fdata-sections
Add the following flag to the linker options in all the projects.
-Wl,-gc-sections
- Rebuild them (in the correct order Arduino first, BlinkenLights second.)
What a relief!
Uploading your Program to the Arduino
The time has now come when you can upload your very first Arduino program built within the comfy confines of Eclipse.
- Right click on the BlinkenLights project and select “Properties”. Go to the AVRDude page and click on new.
- Fill the form as follows:
- Configuration name: Arduino
- Programmer Hardware: Arduino
- Override default port: \\.\COM3. Replace COM3 to whatever port the Arduino hardware is connected to.
- Override default baud rate: 19200. Replace 19200 to whatever baud rate was specified by your board manufacturer / the person who uploaded the Arduino boot loader onto your board.
- Select Arduino as the programmer in AVRDude settings and click OK.
- Click on the AVR toolbar button to upload your program to the board.
You should see something like the following in the console window…
Launching C:\misc\WinAVR\bin\avrdude -pm328p
carduino "-P\\.\COM3" -b19200 -Uflash:w:BlinkenLights.hex:a
Output:
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.02s
avrdude: Device signature = 0x1e950f
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "BlinkenLights.hex"
avrdude: input file BlinkenLights.hex auto detected as Intel Hex
avrdude: writing flash (2828 bytes):
Writing | ################################################## | 100% 2.16s
avrdude: 2828 bytes of flash written
avrdude: verifying flash memory against BlinkenLights.hex:
avrdude: load data flash data from input file BlinkenLights.hex:
avrdude: input file BlinkenLights.hex auto detected as Intel Hex
avrdude: input file BlinkenLights.hex contains 2828 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 2.14s
avrdude: verifying ...
avrdude: 2828 bytes of flash verified
avrdude done. Thank you.
- If everything went right, the on-board test LED (usually red in color) should now start blinking at about 1 blink/sec. Congratulations!
In Conclusion
We have finally seen how to use Eclipse for AVR development. But this is only the beginning. I have shown you how to catch fish and also given you a small fish for today, but tomorrow you must catch your own! Well actually what I mean is… there’s still a lot to explore but I have shown you the basics and you should now be fine on your own. The examples and libraries supplied with Arduino should be a good place to start for further exploration.
History
- 16th September, 2010: Initial version