Monday, February 27, 2012

Hidden Variables: Arduino and AVR Microcontrollers

(Update 2013-01-23: this article is about the Arduino Uno and similar boards that use the eight-bit Atmel AVR ATmega microcontrollers. If you're looking for the Arduino Due that uses the thirty-two-bit ARM Cortex-M3 microcontroller, see Hidden Variables: Arduino Due and the Cortex-M3.)

In Hidden Variables I showed what command line options you could use to see what preprocessor symbols your GNU C and C++ compilers define by default. There are a lot of them. If you write code intended to run on different AVR microcontrollers, as I am doing for my Amigo project, this is worth knowing. For example, the Ardunino Uno board uses an Atmel ATmega328P microcontroller, while the Ardunino Mega 2560 board uses an Atmel ATmega2560 microcontroller. There are significant differences, some of which the compiler knows about.

Here are all the preprocessor symbols for the ATmega328P that are generated by the command

avr-g++ -dM -E -mmcu=atmega328p - < /dev/null

when using the GCC 4.3.2 AVR tool chain that comes with the Arduino 1.0 software development kit. It's a long list.

#define __DBL_MIN_EXP__ (-125)
#define __FLT_MIN__ 1.17549435e-38F
#define __DEC64_DEN__ 0.000000000000001E-383DD
#define __CHAR_BIT__ 8
#define __WCHAR_MAX__ 32767
#define __DBL_DENORM_MIN__ 1.40129846e-45
#define __FLT_EVAL_METHOD__ 0
#define __DBL_MIN_10_EXP__ (-37)
#define __FINITE_MATH_ONLY__ 0
#define __GNUC_PATCHLEVEL__ 2
#define __AVR_MEGA__ 1
#define __DEC64_MAX_EXP__ 384
#define __SHRT_MAX__ 32767
#define __LDBL_MAX__ 3.40282347e+38L
#define __UINTMAX_TYPE__ long long unsigned int
#define __DEC32_EPSILON__ 1E-6DF
#define __LDBL_MAX_EXP__ 128
#define __SCHAR_MAX__ 127
#define __DBL_DIG__ 6
#define __SIZEOF_INT__ 2
#define __SIZEOF_POINTER__ 2
#define __USER_LABEL_PREFIX__
#define __STDC_HOSTED__ 1
#define __LDBL_HAS_INFINITY__ 1
#define __FLT_EPSILON__ 1.19209290e-7F
#define __LDBL_MIN__ 1.17549435e-38L
#define __DEC32_MAX__ 9.999999E96DF
#define __SIZEOF_LONG__ 4
#define __DECIMAL_DIG__ 9
#define __AVR_2_BYTE_PC__ 1
#define __LDBL_HAS_QUIET_NAN__ 1
#define __GNUC__ 4
#define __FLT_HAS_DENORM__ 1
#define __SIZEOF_LONG_DOUBLE__ 4
#define __DBL_MAX__ 3.40282347e+38
#define __DBL_HAS_INFINITY__ 1
#define __DEC32_MIN_EXP__ (-95)
#define __LDBL_HAS_DENORM__ 1
#define __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL
#define __USING_SJLJ_EXCEPTIONS__ 1
#define __DEC32_MIN__ 1E-95DF
#define __DBL_MAX_EXP__ 128
#define __DEC128_EPSILON__ 1E-33DL
#define __AVR_ENHANCED__ 1
#define __LONG_LONG_MAX__ 9223372036854775807LL
#define __SIZEOF_SIZE_T__ 2
#define __SIZEOF_WINT_T__ 2
#define __GXX_ABI_VERSION 1002
#define __FLT_MIN_EXP__ (-125)
#define __DBL_MIN__ 1.17549435e-38
#define __DEC128_MIN__ 1E-6143DL
#define __REGISTER_PREFIX__
#define __DBL_HAS_DENORM__ 1
#define __AVR_ARCH__ 5
#define __NO_INLINE__ 1
#define __FLT_MANT_DIG__ 24
#define __VERSION__ "4.3.2"
#define __AVR_HAVE_MUL__ 1
#define __DEC64_EPSILON__ 1E-15DD
#define __DEC128_MIN_EXP__ (-6143)
#define __SIZE_TYPE__ unsigned int
#define __DEC32_DEN__ 0.000001E-95DF
#define __FLT_RADIX__ 2
#define __LDBL_EPSILON__ 1.19209290e-7L
#define __SIZEOF_PTRDIFF_T__ 2
#define __AVR 1
#define __FLT_HAS_QUIET_NAN__ 1
#define __FLT_MAX_10_EXP__ 38
#define __LONG_MAX__ 2147483647L
#define __FLT_HAS_INFINITY__ 1
#define __DEC64_MAX__ 9.999999999999999E384DD
#define __AVR_HAVE_LPMX__ 1
#define __DEC64_MANT_DIG__ 16
#define __DEC32_MAX_EXP__ 96
#define __DEC128_DEN__ 0.000000000000000000000000000000001E-6143DL
#define __LDBL_MANT_DIG__ 24
#define __DBL_HAS_QUIET_NAN__ 1
#define AVR 1
#define __WCHAR_TYPE__ int
#define __SIZEOF_FLOAT__ 4
#define __AVR__ 1
#define __AVR_HAVE_JMP_CALL__ 1
#define __DEC64_MIN_EXP__ (-383)
#define __FLT_DIG__ 6
#define __INT_MAX__ 32767
#define __FLT_MAX_EXP__ 128
#define __DBL_MANT_DIG__ 24
#define __AVR_HAVE_MOVW__ 1
#define __DEC64_MIN__ 1E-383DD
#define __WINT_TYPE__ unsigned int
#define __SIZEOF_SHORT__ 2
#define __LDBL_MIN_EXP__ (-125)
#define __LDBL_MAX_10_EXP__ 38
#define __DBL_EPSILON__ 1.19209290e-7
#define __SIZEOF_WCHAR_T__ 2
#define __DEC_EVAL_METHOD__ 2
#define __INTMAX_MAX__ 9223372036854775807LL
#define __FLT_DENORM_MIN__ 1.40129846e-45F
#define __FLT_MAX__ 3.40282347e+38F
#define __AVR_ATmega328P__ 1
#define __SIZEOF_DOUBLE__ 4
#define __FLT_MIN_10_EXP__ (-37)
#define __INTMAX_TYPE__ long long int
#define __DEC128_MAX_EXP__ 6144
#define __GNUC_MINOR__ 3
#define __DEC32_MANT_DIG__ 7
#define __DBL_MAX_10_EXP__ 38
#define __LDBL_DENORM_MIN__ 1.40129846e-45L
#define __STDC__ 1
#define __PTRDIFF_TYPE__ int
#define __DEC128_MANT_DIG__ 34
#define __LDBL_MIN_10_EXP__ (-37)
#define __SIZEOF_LONG_LONG__ 8
#define __LDBL_DIG__ 6
#define __GNUC_GNU_INLINE__ 1

Here are just the symbols containing the string "AVR" sorted alphabetically. Significantly (to me anyway) there are symbols that identify the size of the Program Counter (PC) register as being two bytes, and the underlying architecture as AVR5, which tells you what machine instructions are available.

#define AVR 1
#define __AVR 1
#define __AVR_2_BYTE_PC__ 1
#define __AVR_ARCH__ 5
#define __AVR_ATmega328P__ 1
#define __AVR_ENHANCED__ 1
#define __AVR_HAVE_JMP_CALL__ 1
#define __AVR_HAVE_LPMX__ 1
#define __AVR_HAVE_MOVW__ 1
#define __AVR_HAVE_MUL__ 1
#define __AVR_MEGA__ 1
#define __AVR__ 1

Here are the preprocessor symbols for the ATmega2560 that are generated by the command

avr-g++ -dM -E -mmcu=atmega2560 - < /dev/null

that differ from the complete list above when using the same tool chain. The PC is now three bytes in length, because the ATmega2560 has more program memory than can be addressed in two, and the instruction set conforms to the AVR6 architecture, so that additional machine instructions are available.

3,5c3,5
< #define __AVR_2_BYTE_PC__ 1
< #define __AVR_ARCH__ 5
< #define __AVR_ATmega328P__ 1
---
> #define __AVR_3_BYTE_PC__ 1
> #define __AVR_ARCH__ 6
> #define __AVR_ATmega2560__ 1
6a7,9
> #define __AVR_HAVE_EIJMP_EICALL__ 1
> #define __AVR_HAVE_ELPMX__ 1
> #define __AVR_HAVE_ELPM__ 1
10a14
> #define __AVR_HAVE_RAMPZ__ 1

When you are developing close to bare metal it pays to know these things.

Wednesday, February 22, 2012

Advanced Embedded C++ Development with Arduino II

One of the techniques for managing growing code bases that I haven't been able to make work with the Arduino IDE in my Amigo project is hierarchical header file directories. Once you start combining code bases from a variety of sources, eventually you will run into two bases that use a header file by the same name, for example Display.h. In the case of Arduino, the conflict isn't in the file system -- the source code for each Arduino library is already separated into its own subdirectory -- but in how the #include statement is coded by the developer: the statement

#include <Display.h>

will be ambiguous as to which library you mean.

In Up the Source Code Organization I illustrated a way to handle this: by imposing the same convention I use for C++ namespaces and C preprocessor symbols, where I incorporate Digital Aggregates' domain name, for header file path names. This results in #include statements that look something like (as a completely fictional example)

#include <com/diag/amigo/Display.h>
#include <cc/arduino/Display.h>

such that my LC100 library would keep its header files in a com/diag/amigo subdirectory in its library directory, while arduino.cc would keep its header files in a cc/arduino subdirectory in its own library directory. This has the added advantage that all of the header file directory trees could be merged into a common /usr/include-like directory tree if that proved advantageous in the future. A similar convention is already being used to manage the growing /usr/include directory tree in various Linux/GNU distributions.

Currently the Import Library function in the Arduino IDE doesn't grok this kind of directory structure so that it uses the appropriate -Idirectory option, which tells the GNU C++ compiler where in the file system to start looking for header files, when the IDE generates the commands to build an Arduino application. How could it do so? I'm not really qualified to have an opinion on this, but maybe something as simple as the Import Library function doing a deeper search in the library directory and generating #include statements that include the relative paths of all the header files it finds. This wouldn't change how it is used today with existing libraries, and in fact would generate the same -I option for the compiler as it does now regardless of the header file organization. But it would permit a more complex organization in the future.

It is tempting to say that Arduino is too small to need this kind of organization, but I can see that this is already not the case in my own development. And when you start contemplating applications for the Arduino Mega-class boards, which have serious resources available to support quite complex applications, this is going to become even more of a problem.

Monday, February 20, 2012

Advanced Embedded C++ Development with Arduino

My first experience with using C++ for embedded development was circa 1988. I was teaching a university course for seniors and graduate students in real-time software design. We did everything in assembler, and very occasionally experimentally in C. I wanted to see if I could write embedded code in C++, which I was just learning at the time. I used cfront, Bell Labs' early preprocessor which input C++ source code and emitted C source code. No one could have been more surprised than I was when it worked.

C++ has evolved a lot since then, and so have I. Coincidentally, I ended up working for Bell Labs starting in 1996. The Labs had by then experience using C++ for embedded development, and thanks to some very patient mentors (Tam, Doug, and Randy: you know who you are), I ended up exploiting many of the advanced features of C++ to do development in code bases of hundreds of thousands or even millions of lines of C++ that was shared across entire product lines.

That experience has informed my professional career in the years hence, so it was only natural to see if I could use some of these same C++ features when writing code for Arduino. Ever since my days teaching CEG431 at Wright State University I've been looking for a modern and cost effective hardware and software platform on which to duplicate that pedagogical environment. I've written about this quest in this blog: Diminuto and Arroyo (AT91RM9100-EK board using an Atmel ARM9 microprocessor with Linux/GNU), Cascada and Contraption (BeagleBoard using a TI Cortex-A8 microprocessor with Linux/GNU and Android), and finally Amigo (Arduino Uno and Mega boards using Atmel AVR microcontrollers with Arduino).

It would be easy for one to assume that a 16MHz eight-bit microcontroller with only 2KB of SRAM would be too resource constrained to really pull the stops out on C++. One would be wrong. Not only can the C++ features that are routinely used in large embedded code bases be also used effectively in Arduino, there are lots of good reasons to do so, and they are all the same reasons, like code reuse and easier integration of disparate code bases.

A good example of my efforts so far is LC100, an Arduino software library that implements the most-used VT100 display and keyboard escape sequences on a small liquid crystal display (LCD), and TinyTerminal, an application that uses LC100 to implement a minuscule VT100-compatible wireless remote terminal.

Here's a side view of the TinyTerminal hardware stack. It includes an Arduino Uno at the bottom, a SparkFun XBee shield with a Digi Series 1 XBee radio in the middle, and on top a DFRobot two-line by sixteen-column LCD shield with joystick buttons to indicate up, down, left, right, and select. It's being powered by a 9-Volt transister radio battery.

Arduino Uno, XBee Shield, LCD Shield

Here's a top view of the TinyTerminal stack talking to my desktop Mac Mini via a USB-connected SparkFun XBee Explorer. The characters on the LCD display that you see below were generated by me using the Mac screen utility, pointing it to the USB serial port provided by the XBee Explorer, telling it to set the serial rate to 9600, and using the arrow keys on my Mac keyboard to position the cursor on the LCD display as I typed. In turn, I can move the cursor of the screen utility on my Mac around by pressing the joystick buttons on the LCD shield.

TinyTerminal using LC100

The TinyTerminal application uses an object of the LC100 class, which derives from the LC100Base class where most of the implementation is located. The interface to the LCD shield is abstracted out into a pure interface class called Display. This makes it easy to adapt LC100 to other LCD hardware with no source code changes through the use of dependency injection. TinyTerminal implements Display for both the DFRobot shield as well as for a simple mock object so that you can debug applications without any actual LCD hardware.

The source code to do all this, which is definitely a work in progress, is a little lengthy to cut and paste into this article. But you can download the tarball containing all the source code for both the LC100 library and the TinyTerminal example application from a link on the Amigo web page.

Here's a list of some of the C++ features I used in this project that in my experience are commonly used in much larger embedded projects.

Namespaces. When you start integrating software from a variety of other projects, you start running into name collisions. C++ gets around this by allow you to partition the global C++ namespace into hierarchically nested subspaces.


namespace com {

namespace diag {

namespace amigo {


...


}

}

}



This is a lot easier than it sounds. Basically it just makes your C++ names longer. All of the LC100 symbols are in the com::diag::amigo namespace, following a standard I've used on other C++ projects of incorporating my company's unique domain name as part of the namespace name.

Unique Preprocessor Symbols. You need to worry about name collisions even more with C preprocessor symbols because they are in a global namespace about which C++ knows nothing. That's one of the reasons I minimize the use of preprocessor symbols in TinyTerminal and LC100. But when they are necessary, such as in header file guards, I also include my domain name as part of the preprocessor symbol name, as shown in the example below.

#ifndef _COM_DIAG_AMIGO_LC100_H_

#define _COM_DIAG_AMIGO_LC100_H_

...

#endif /* _COM_DIAG_AMIGO_LC100_H_ */


Static Constants. Typically in C we are used to defining manifest constants, like the dimensions of the LCD display, as preprocessor symbols. That gets more and more problematic the more preprocessor symbols there are, for just the reasons cited above. But when you declare an primitive variable in C++ to be both static and const and provide its value in its declaration, for example

static const byte COLS = 16;


most C++ compilers won't even assign storage to the variable unless you force them to do so by taking the address of it in your code. Instead they use the variable just like a preprocessor symbol and textually replace each use with its corresponding numeric value. Unlike preprocessor symbols, static constants still have all the type safety and namespace capabilities of normal C++ variables.

Abstract Classes and Dependency Injection. LC100 is not tied to any specific LCD hardware. It expects the LCD that it uses to implement a dirt simple interface that is defined as an abstract or pure class, that is, a class without any implementation.

struct Display

{

...

virtual void setCursor(byte col, byte row) = 0;

...

};


All LCD interfaces, like the one that TinyTerminal implements for the DFRobot LCD shield, derive from class Display. TinyTerminal provides LC100 with an object of this subclass. This makes it easy to write generic software that works with lots of different hardware.

Printable Enumerations. This is a trick long known to C programmers, too, but I see it used all too seldom. States and actions used by LC100 are defined in enumations. But the actual enumeration values are explicitly defined to be printable ASCII characters.

enum State {

DATA = 'D',

ESCAPE = 'E',

DECIMAL = 'N',

BRACKET = 'B',

FIRST = 'F',

SECOND = 'S',

QUESTION = 'Q'

};


This allows them to be printed directly in debug output without requiring any mapping at run-time. This is only useful in smallish to middle-sized enumerations, but it can really simplify debugging.

Templates and Variable Length Objects. LC100 is a templatized class, which is to say it's exact definition is parameterized and determined at compile-time. LC100 uses its template parameters _COLS_ and _ROWS_ to specify the dimensions of the LCD display, than uses these values to size arrays that are part of the object.

template <byte _COLS_, byte _ROWS_> class LC100

: public LC100Base

{

...

byte lineLength[_ROWS_];

...

};


This eliminates any need for a heap and dynamic memory allocation. Templates perform code generation at compile-time, which is a very powerful form of code reuse. Because they generate code, they must be used with discipline. But the LC100 template generates no executable code other than its constructor and destructor; its implementation is in the LC100Base super class that is common to all uses of LC100.

Grammars, Finite State Machines, and Push Down Automata. The large set of VT100 escape sequences can be abstractly described as a formal grammar. If you have ever seen a programming language described in terms of Bauckus-Naur Form (BNF) then you already have some familiarity with a formal grammar. But it turns out that all sorts of things can be described in terms of a formal grammar. This is very good indeed, because even though a grammar can seem complicated, if it is in the right form then a parser for it can be routinely, even mechanically, generated, and implemented trivially as a finite state machine (FSM). A push down automata (PDA) is merely a finite state machine with a stack so that a production or rule of the grammar can be called like a subroutine; this allows a much broader class of grammars to be parsed. LC100 uses a PDA to parse incoming escape sequences a character at a time. This eliminates any need for buffering of incoming data, and can be implemented extremely efficiently in C++ using switch statements. Once you become accustomed to using grammars and implementing FSMs and PDAs, you will start to see all sorts of problems as parsing problems.

Mock Objects. TinyTerminal has a compile time option to build a Display interface object not for the DFRobot LCD shield but for a dirt simple mock object that merely traces its calls to the serial monitor.

class Mock

: public com::diag::amigo::Display

{

...

};


The LC100 software has no idea this is happening, thanks to the abstract interface and dependency injection. This makes it easy to test on Arduino but without actual LCD hardware, and to determine whether a fault lies with the LCD hardware, the Arduino LiquidCrystal library, the Arduino-side application, or even a host-side application, when wackiness ensues.

Embedded Unit Tests. TinyTerminal has embedded in it functions that perform a variety of unit tests. These include things like scrolling, erasing, and cursor placement.

#if 0

/**

* Cursor control unit test.

*/

static char TEST[] = {

lc100.ESC, '[', 'H',

'0',

lc100.ESC, '[', '1', ';', '1', '6', 'H',

'1',

lc100.ESC, '[', '2', ';', '1', '6', 'H',

'2',

lc100.ESC, '[', '2', ';', '1', 'H',

'3'

};

static void test() {

for (byte ii = 0; ii < (sizeof(TEST)/sizeof(TEST[0])); ++ii) {

lc100.write(TEST[ii]);

}

}

#endif


These unit tests can be selectively enabled at compile-time, and can be run on either the actual LCD hardware or the mock object. Since they are normally not included as part of the normal build, they incur zero overhead if they are not used. And like all unit tests, they are a form of documentation about how I expect LC100 to be used. I confess I had the passing notion of porting the entire Google Test platform to Arduino. But this simpler approach, which I've used in several production embedded systems, is a huge win all by itself.

Doxygen. Doxygen is a powerful open source tool that scans your source code for comments of a very particular format and then generates documentation based on those comments.

/**

* Place the cursor at the specified position. The column and row

* coordinates are taken modulo of the actual display dimensions.

* @param col is the zero-based column number.

* @param row is the zero-based row number.

*/

void setCursor(byte col, byte row);


Doxygen output can be web pages, PDF manuals, etc. Files, classes, functions, macros, can all be documented using Doxygen. I've used Doxygen obsessively for years. But even if I never installed the Doxygen software, I'd still use Doxygen-format comments. They encourage a specific discipline for documenting source code that has value all by itself. Both LC100 and TinyTerminal are commented using Doxygen-style comments.

I predict that you are now asking yourself how expensive is it to use all of these fancy features of C++ in your Arduino code. So here it is: the entire TinyTerminal application, including the LC100 library, the LiquidCrystal library that controls the DFRobot LCD display, and all of the other Arduino and C++ run-time, takes 8764 bytes of flash and 128 bytes of SRAM for the BSS segment. Almost all of the overhead in using these features is at compile-time. And they all can make your life much much easier.

Monday, February 13, 2012

Power over Ethernet with Arduino

If you have a Ethernet-attached Voice over Internet Protocol (VoIP) telephone on your desk, as so many of us do, than you already may be using Power over Ethernet (PoE). PoE is a standard (IEEE 802.3af) way to power Ethernet-connected devices over the CAT5 Ethernet cable itself. I routinely encountered PoE VoIP phones back in my telephony days, but it's also found in all sorts of devices, like wireless access points and security cameras, anywhere it's a hassle to run an Ethernet cable and a power cable.

(Important safety tip: PoE provides serious voltage, 48 volts DC, compatible with a lot of legacy telephone equipment. It's enough to make you sit up and take notice if you get careless with it.)

So since I'm on a roll regarding alternative methods to power Arduino microcontroller boards, it probably comes as no surprise that I wanted to see if I could power one just with an Ethernet cable for my Amigo project. Arduino is so popular that an entire ecosystem has sprung up making Arduino-compatible parts and accessories, and also Arduino-clone microcontroller boards. One of these is the Freetronics EtherTen, which combines a Arduino Uno-clone with an Ethernet Shield-compatible Ethernet port, all on one board. When my EtherTen arrived in an envelope covered in international shipping labels from this Australia-based company, the very first thing I did was hook it up and download my little web server application. It worked the first time with absolutely no changes. The EtherTen just looks like a standard Arduino Uno with a standard Ethernet shield. The only difference was the board uses a mini-B USB connector instead of the Uno's relatively gigantic B connector; the EtherTen comes with the appropriate USB cable just so this detail doesn't slow you down. For you doubters, here's a screen snapshot taken from my application running on the EtherTen (without any actual sensors, so the readings are bogus).

Screen shot 2012-02-13 at 9.56.00 AM

But the integrated Ethernet isn't the only thing that attracted me to the EtherTen. Freetronics offers an optional PoE module that can be attached to the EtherTen to draw power for the board from any PoE-compatible Ethernet connection. Some assembly is required, but recent experience has made this software guy pretty fearless with a soldering iron. Here's a photo of the EtherTen with the PoE module on top. Yes, those are LEDs you see lit, and that is only a CAT5 Ethernet cable attached to the board. The screen snapshot above was actually taken from this configuration.

Freetronics EtherTen with PoE

For large sites that have lots of PoE devices, like a VoIP phone on every desk, the wired network infrastructure will have been built out with Ethernet switches that natively provide PoE, what are known as Power Sourcing Equipment (PSE). For my tiny little lab, I just purchased a TRENDnet PoE injector. A PoE injector takes a regular CAT5 Ethernet cable and mains (wall) power as input and outputs PoE over a second CAT5 cable. (There are also PoE splitters which take a PoE CAT5 as input and output a CAT5 without power and a separate power cable.) Here's a photo of the EtherTen hooked up to the injector. You can see the unpowered CAT5 and power cord coming into the injector on the right and the powered CAT5 exiting on the left connected to the EtherTen.

IMG_1380

So why Power over Ethernet for Arduino? Because doing so allows a network-attached microcontroller, perhaps with a Zigbee radio or other useful shield, to be deployed to remote locations using just a CAT5 Ethernet cable. If the radio has a Zigbee Coordinator (ZC) or Zigbee Router (ZR) personality, than the remote yet effectively mains-powered microcontroller can provide management and routing for the mesh network and provide bridging between battery-powered Zigbee End Devices (ZEDs) and applications running elsewhere on the network.

This is all ridiculously inexpensive to play with. We're in an era of ubiquitous computing and network connectivity. Why not be a part of it?

Friday, February 10, 2012

Thinking Small With Arduino

When's the last time you had a computer you could program in a higher level language like C++ that you could run on a 9 volt transistor radio battery? Here's one doing just that.

Arduino Uno running on 9 Volt battery

The Arduino Uno microcontroller prototyping board can run off power ranging from about 7 to 12 volts, converting it all to 5 volts and 3.3 volts for the components on the board. When you connect an Arduino via USB to your desktop system to download software, it can run off the 12 volts provided over the USB cable, just like a keyboard or mouse. But you can also run it off the ubiquitous wall wart in the right voltage range with a 2.1 millimeter center-positive power plug.

Or you can go by Radio Shack, spend a couple of bucks on parts and a few minutes with a soldering iron and heat gun, and make a mobile 9 volt power supply.

9 Volt power delivery system for Arduino

Add to this one of the tiny Zigbee radios I've been writing about as part of my Amigo project and you have a self-contained wireless computing platform. Zigbee was designed from the ground up to be a personal area network (PAN) technology with short range (a few hundred feet) and low power (about a milliwatt). Zigbee radios come in three personalities: coordinator (a.k.a. ZC), router (ZR), and end device (ZED). The first two have to be powered up at all times in order to manage and route messages for the mesh network. But end devices can spend most of their time powered off; the other personalities will store and forward any packets destined for an end device when it periodically wakes up and connects to the network.

It pays to think small.

Update (2012-03-15)

I haven't measured yet how long a 9 volt battery will last, but it's not that long. Here's another approach that provides 12 volts for longer duration than the 9 volt solution: eight 1.5 volt AA batteries in series in a battery pack. The pack from Radio Shack has a 9 volt battery connector on it, so it's trivial to switch from the 9 volt battery to the 12 volt battery pack. Here's the pack powering an Arduino Uno with an XBee radio shield transmitting to my desktop system.

Eight AA Batteries In Series (12V)

Wednesday, February 08, 2012

Arduino to Android on BeagleBoard via Zigbee

It eventually became clear that it was time to combine two projects, Contraption, in which I run Android overlaid with GNU on the BeagleBoard, and Amigo, my latest effort in which I build a wireless sensor platform using Arduino and Zigbee radios. Now I have Amigo reporting sensor readings to Contraption via a wireless serial connection using XBee Series 1 radios from Digi.

Here's an aerial view. Up at the top you can see the LCD monitor for the BeagleBoard running Android FroYo. Below is my tiny Mac Mini desktop system and it's huge Cinema display. To the right is the explosion of boards and cables.

Aerial View: Android on BeagleBoard, Arduino Sensor Platform

Here's a closeup of the boards. To the left is the BeagleBoard xM Revision C inside its clear plastic case festooned with cables. To its right is the Arduino with two shields stacked on top of it, an Ethernet shield and a Xbee shield. In front of them is the tiny Xbee Explorer board connected via USB to the BeagleBoard.

BeagleBoard running Android, Arduino Sensor Platform

I had budgeted a couple of days to getting this working. It took a couple of hours. I had to rebuild the Linux 2.6.32 kernel used by FroYo to include the ftdi_sio driver (kernel option CONFIG_SERIAL_FTDI_SIO). This supports the FTDI USB-to-serial chip used on the Explorer board, and whose driver has been part of the mainline Linux kernel distribution since 2.6.31. Once Android was booted up on the BeagleBoard, I plugged in the Explorer and was greeted by a new serial device /dev/ttyUSB0. I set the serial baud rate via

stty -F /dev/ttyUSB0 9600

using BusyBox running on the GNU layer in Contraption. Then I just did a

cat /dev/ttyUSB0

on the BeagleBoard serial console and saw the CSV output of the Amigo sensor platform wirelessly over Zigbee.

Android Serial Console

Amigo implements a tiny web server through which its sensors can be interrogated across its Ethernet connection. It seemed like a moral imperative to try this from the Android browser.

Android Web Browser Interrogating Arduino Web Server

I'm eventually going to migrate to XBee Series 2 radios, which are capable of much more complicated topologies than the wireless serial link provided by Series 1. I'm playing with Series 2 radios right now. But this was a useful first step.

Thursday, February 02, 2012

Embedded Software Development Economics 1

A Java developer of my acquaintance once remarked, probably to his eventual regret, "I don't want to know how it works under the hood." I've made a lot of filthy lucre off this attitude in others, so I have a strong economic incentive to encourage it. But in fact, I believe that to control costs in development projects you have to have developers work at as high a level of abstraction as possible. This is why we all don't still work in assembler except when it's really necessary.

This is also why I really like Linux/GNU as an embedded platform when it's possible because it opens the possibility of doing a lot of development for prototyping or even production in scripting languages in which the think-type-compile-debug cycle can be very very short. I've leveraged the hell out of the bash shell, or even the more limited BusyBox ash shell, on embedded products. Scripting may
also allow you to use less expensive developers who have no idea what the sizes are of variables in memory, but don't need to know for the kind work that they do.

(Update 2012-02-04: I've also made excellent use of the command line shell available in the VxWorks RTOS that allows you to invoke any function with C-linkage and pass it integer arguments. I have implemented a similar capability using Ficl, a full blown Forth interpreter, embedded in a C++ application. The latter is fully doable in a non-Linux/GNU or even non-POSIX system, including those systems which run from flash or are completely memory resident.)

Java falls into this category. If you can support it on your system, and its footprint meets your resource requirements, then you would be remiss not doing as much work in it as you can, with faster development iterations and less expensive developers. Java is increasingly becoming the language of choice in which to teach software development, so more and more college graduates are being produced with Java as their core programming language competency. I'm fully aware of the irony of this since some of my buddies tell me that Java is on the wane as an application language. But I think it has a lot of merit as a high level embedded language. Case in point: Android, on its way to becoming the most popular software platform for mobile devices, which has a Java application layer sitting on top of a C/C++ run-time and Linux kernel.

Over the years I have personally helped develop and ship two Java-based products. One was a typical server-side application than ran on powerful multi-core Pentium boxes. But the other was a small embedded system that was based on a PowerPC microprocessor running a real-time OS and for which I developed device drivers in C and the application, some of which had hard real-time constraints, in Java. The Java development went a lot faster, in part because we could develop and test a lot of the application on our desktop in simulation using VisualAge, the IDE which eventually evolved into Eclipse, along with all its editing, refactoring, and debugging capabilities.

Those organizations who insist on doing everything in C or even C++ when more cost effective alternatives are available are quickly going to go the way of organizations who want to do everything in assembler on gigahertz ARM processors. Which is to say: they won't exist.

Wednesday, February 01, 2012

Arduino Data Types

(Update 2013-01-23: this article is about the Arduino Uno and similar boards that use the eight-bit Atmel AVR ATmega microcontrollers. If you're looking for the Arduino Due that uses the thirty-two-bit ARM Cortex-M3 microcontroller, see Arduino Due Data Types.)

I think for every system I've ever worked on that had a C compiler, going all the way back to my PDP-11 days, I eventually wrote this program or its equivalent. I have had some surprises. Here it is for Arduino, as part of my Amigo project.


#include <stdint.h>
#include <avr/pgmspace.h>

void setup() {
Serial.begin(9600);
}

void loop() {
Serial.print("sizeof(byte)="); Serial.println(sizeof(byte));
Serial.print("sizeof(char)="); Serial.println(sizeof(char));
Serial.print("sizeof(short)="); Serial.println(sizeof(short));
Serial.print("sizeof(int)="); Serial.println(sizeof(int));
Serial.print("sizeof(long)="); Serial.println(sizeof(long));
Serial.print("sizeof(long long)="); Serial.println(sizeof(long long));
Serial.print("sizeof(bool)="); Serial.println(sizeof(bool));
Serial.print("sizeof(boolean)="); Serial.println(sizeof(boolean));
Serial.print("sizeof(float)="); Serial.println(sizeof(float));
Serial.print("sizeof(double)="); Serial.println(sizeof(double));
Serial.print("sizeof(int8_t)="); Serial.println(sizeof(int8_t));
Serial.print("sizeof(int16_t)="); Serial.println(sizeof(int16_t));
Serial.print("sizeof(int32_t)="); Serial.println(sizeof(int32_t));
Serial.print("sizeof(int64_t)="); Serial.println(sizeof(int64_t));
Serial.print("sizeof(uint8_t)="); Serial.println(sizeof(uint8_t));
Serial.print("sizeof(uint16_t)="); Serial.println(sizeof(uint16_t));
Serial.print("sizeof(uint32_t)="); Serial.println(sizeof(uint32_t));
Serial.print("sizeof(uint64_t)="); Serial.println(sizeof(uint64_t));
Serial.print("sizeof(char*)="); Serial.println(sizeof(char*));
Serial.print("sizeof(int*)="); Serial.println(sizeof(int*));
Serial.print("sizeof(long*)="); Serial.println(sizeof(long*));
Serial.print("sizeof(float*)="); Serial.println(sizeof(float*));
Serial.print("sizeof(double*)="); Serial.println(sizeof(double*));
Serial.print("sizeof(void*)="); Serial.println(sizeof(void*));
Serial.print("sizeof(prog_char)="); Serial.println(sizeof(prog_char));
Serial.print("sizeof(prog_char*)="); Serial.println(sizeof(prog_char*));
Serial.println();
delay(5000);
}

And here's it's output for one of my Arduino Uno boards with the ATmega328p microcontroller.


sizeof(byte)=1
sizeof(char)=1
sizeof(short)=2
sizeof(int)=2
sizeof(long)=4
sizeof(long long)=8
sizeof(bool)=1
sizeof(boolean)=1
sizeof(float)=4
sizeof(double)=4
sizeof(int8_t)=1
sizeof(int16_t)=2
sizeof(int32_t)=4
sizeof(int64_t)=8
sizeof(uint8_t)=1
sizeof(uint16_t)=2
sizeof(uint32_t)=4
sizeof(uint64_t)=8
sizeof(char*)=2
sizeof(int*)=2
sizeof(long*)=2
sizeof(float*)=2
sizeof(double*)=2
sizeof(void*)=2
sizeof(prog_char)=1
sizeof(prog_char*)=2

Pointers are sixteen bits. Just like, in fact, on my beloved PDP-11s. Sixteen bits can address at most sixty-four kilobytes of memory, addresses 0x0000 through 0xffff. This now seems outrageously large compared to the two kilobytes of SRAM available on the AVR microcontroller on my Arduino Uno board.

Sometimes I miss Java.

Update 2012-02-06

The GCC tool chain for the AVR family has a command line switch -mint8 that can make the int data type eight bits wide; Arduino doesn't use it, but you might encounter it elsewhere in other AVR-based projects.

I strongly recommend using the types defined in stdint.h that have their widths explicitly defined, e.g. int8_t, uint32_t, etc., when such things matter (as they so often do in the embedded realm).

Update 2012-02-20

Here's the same for an Arduino Mega ADK board that uses the ATmega2560 microcontroller. Short answer: it's the same as the Uno.

sizeof(byte)=1
sizeof(char)=1
sizeof(short)=2
sizeof(int)=2
sizeof(long)=4
sizeof(long long)=8
sizeof(bool)=1
sizeof(boolean)=1
sizeof(float)=4
sizeof(double)=4
sizeof(int8_t)=1
sizeof(int16_t)=2
sizeof(int32_t)=4
sizeof(int64_t)=8
sizeof(uint8_t)=1
sizeof(uint16_t)=2
sizeof(uint32_t)=4
sizeof(uint64_t)=8
sizeof(char*)=2
sizeof(int*)=2
sizeof(long*)=2
sizeof(float*)=2
sizeof(double*)=2
sizeof(void*)=2
sizeof(prog_char)=1
sizeof(prog_char*)=2

The ATmega2560 has more input and output pins and more on-board flash (256 kilobytes instead of 32) and more SRAM (8 kilobytes instead of 2) than the ATmega328 used on the Uno. The flash and SRAM increases make the Mega a particularly interesting target for a multitasking real-time operating system (RTOS) where each task needs its own stack and context. Because of its larger program memory, the ATmega2560 requires three bytes instead of two for its program counter (PC), the hardware register that keeps track of the current instruction address.