Arduino Serial protocol design patterns

[I posted this to the Arduino developer's mailing list, but figured others might find it useful too]

When I first started with Arduino, I thought Serial.available() was a very loose wrapping of the RXC bit in the USCRA register, i.e. if I didn’t get data out of there fast, it’d be gone. That led to convoluted code like:

 if( Serial.available() ) {
   val1 = Serial.read();
   while( !Serial.available() );
   val2 = Serial.read();
   // and so on
 }

Yuck. So you end up designing protocols that are too terse. Or maybe you think you need to buffer so you don’t lose it:

 while( Serial.available() ) {
   commandbuffer[i++] = Serial.read();
 }

Then parsing becomes a two step process: read serial, parse buffer. Confusing to newbies perhaps, but at least it allows for a better protocol down the line. (And descend into madness as you gaze into the maw of strtok())

Because Serial contains these big comfy buffers, we often don’t need a second buffer to let us easily implement good protocols. My current favorite is to do something like this:

 // protocol is "CCaaaa", two bytes of command, four bytes of args
 if( Serial.available() >= 6 ) {  // command length is 6 bytes
   cmd0 = Serial.read();
   cmd1 = Serial.read();
   arg0 = Serial.read();
   arg1 = Serial.read();
  // ...etc...
 }

I don’t think I’ve seen any Serial examples that check for a specific number of bytes available. It’s really handy.

Implementing a human-friendly protocol like “command arg0 arg1 arg2″, where command and args are space-separated strings like “servo 12 0xff”, is currently hard with Serial. I do this right now with a 2nd buffer and lots of C hackery:

 char* cmdbuf; char c; int i;
 while( Serial.available() && c!= '\n' ) {  // buffer up a line
   c = Serial.read();
   cmdbuf[i++] = c;
 }

 int i = 0;
 while( cmdbuf[++i] != ' ' ) ; // find first space
 cmdbuf[i] = 0;          // null terminate command
 char* cmd = cmdbuf;     //
 int cmdlen = i;         // length of cmd

 int args[5], a;         // five args max, 'a' is arg counter
 char* s; char* argbuf = cmdbuf+cmdlen+1;
 while( (s = strtok(argbuf, " ")) != NULL && a < 5 ) {
   argbuf = NULL;
   args[a++] = (byte)strtol(s,NULL,0); // parse hex or decimal arg
 }
 int argcnt = a;         // number of args read

This sort of functionality would be great in a library I think. Maybe not in Serial, but a core class.

Any other protocols people like to use and the Arduino code they use to do it?

Quickie Laser-cut iPhone/iPod Dock

I recently got a case for my iPhone and it’s the kind that precludes the use of the dock. I kind of like the dock concept, but instead of taking a Dremel to the existing dock, I spent a few minutes drawing up a replacement that could be cut from acrylic scraps on the laser cutter. Here’s the result: (click for higher-res)

iphone-dock-1iphone-dock-1iphone-dock-1

iphone-dock-0

It is made of four slices of 1/4″ acrylic (actual width 0.22″). The top two slices have an oval opening just snug enough to fit the ipod connector and keep it in place with friction. The third slice has a channel for the cable to escape out the back, and the bottom slice keeps the cable from falling out and provides some pushback when the iphone is inserted. It’s held together by four 1″ 2-56 machine screws with nuts. I was a little concerned with the nuts scratching the table, so I’ve since added little hot glue feet to the bottom of each nut.

I didn’t add an additional layer at the top to provide lateral support of the iphone because I didn’t have long enough screws. And besides, it doesn’t seem to need it. If I get longer screws, I might make one that has the extra layer, which would also make the dock bigger, to encompass the bottom of the iPhone. And that would be good because it adds more mass to the dock, making it more stable.

If you want to try making one yourself, here are the files:

- iphone-dock.eps
- iphone-dock.svg
- iphone-dock.cdr

Also available on the wonderful Thingiverse