<?xml version="1.0" encoding="utf-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Arduino Serial protocol design patterns</title>
	<atom:link href="http://todbot.com/blog/2009/07/30/arduino-serial-protocol-design-patterns/feed/" rel="self" type="application/rss+xml" />
	<link>http://todbot.com/blog/2009/07/30/arduino-serial-protocol-design-patterns/</link>
	<description>Random experiments, circuits, code, rapid prototyping, sometimes things to buy, and the odd tune by Tod E. Kurt.</description>
	<lastBuildDate>Fri, 30 Jul 2010 00:10:54 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
	<item>
		<title>By: todbot</title>
		<link>http://todbot.com/blog/2009/07/30/arduino-serial-protocol-design-patterns/comment-page-2/#comment-72557</link>
		<dc:creator>todbot</dc:creator>
		<pubDate>Tue, 27 Jul 2010 18:18:03 +0000</pubDate>
		<guid isPermaLink="false">http://todbot.com/blog/?p=601#comment-72557</guid>
		<description>Yes, it&#039;s easy to run into many traps when using malloc().  Since the memory space of the chip in Arduino is so small and the tasks being performed are usually fairly simple, I much prefer to use statically-allocated buffers.  You never run the risk of memory leaks then and you can know at compile-time exactly how much RAM you have left.  (Arduino doesn&#039;t yet expose this however, but the &quot;avr-size&quot; command can give you static RAM usage)</description>
		<content:encoded><![CDATA[<p>Yes, it&#8217;s easy to run into many traps when using malloc().  Since the memory space of the chip in Arduino is so small and the tasks being performed are usually fairly simple, I much prefer to use statically-allocated buffers.  You never run the risk of memory leaks then and you can know at compile-time exactly how much RAM you have left.  (Arduino doesn&#8217;t yet expose this however, but the &#8220;avr-size&#8221; command can give you static RAM usage)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Matt Jarvis</title>
		<link>http://todbot.com/blog/2009/07/30/arduino-serial-protocol-design-patterns/comment-page-2/#comment-72556</link>
		<dc:creator>Matt Jarvis</dc:creator>
		<pubDate>Tue, 27 Jul 2010 18:04:35 +0000</pubDate>
		<guid isPermaLink="false">http://todbot.com/blog/?p=601#comment-72556</guid>
		<description>Hi todbot &amp; Rob -

*Loved* the code for serial communication- many many thanks... 

In using it I noticed it was getting so far and it was freezing.. going through the code (Rob re-wrote) I noticed that the malloc was been run and using up all the memory.. so put

     free(cmdbuf);

somewhere when you are clearing variables and you shouldn&#039;t have the same problem :D</description>
		<content:encoded><![CDATA[<p>Hi todbot &amp; Rob -</p>
<p>*Loved* the code for serial communication- many many thanks&#8230; </p>
<p>In using it I noticed it was getting so far and it was freezing.. going through the code (Rob re-wrote) I noticed that the malloc was been run and using up all the memory.. so put</p>
<p>     free(cmdbuf);</p>
<p>somewhere when you are clearing variables and you shouldn&#8217;t have the same problem :D</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: My Arduino workings &#124; Prodical's Blog</title>
		<link>http://todbot.com/blog/2009/07/30/arduino-serial-protocol-design-patterns/comment-page-1/#comment-72548</link>
		<dc:creator>My Arduino workings &#124; Prodical's Blog</dc:creator>
		<pubDate>Wed, 21 Jul 2010 09:50:31 +0000</pubDate>
		<guid isPermaLink="false">http://todbot.com/blog/?p=601#comment-72548</guid>
		<description>[...] Todbot’s blog has a post Arduino Serial protocol design patterns which discusses solutions and has example code for this very issue&#8230; so after a bit of [...]</description>
		<content:encoded><![CDATA[<p>[...] Todbot’s blog has a post Arduino Serial protocol design patterns which discusses solutions and has example code for this very issue&#8230; so after a bit of [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Smoker code repository and something more interesting with ProtoThreads &#171; The Arduino Collective</title>
		<link>http://todbot.com/blog/2009/07/30/arduino-serial-protocol-design-patterns/comment-page-1/#comment-58691</link>
		<dc:creator>Smoker code repository and something more interesting with ProtoThreads &#171; The Arduino Collective</dc:creator>
		<pubDate>Tue, 15 Dec 2009 06:37:06 +0000</pubDate>
		<guid isPermaLink="false">http://todbot.com/blog/?p=601#comment-58691</guid>
		<description>[...] The initial Arduino sketch implements a simple LED blinker that can be controlled over the serial connection.  It starts off blinking the led every second and you can set the delay by sending a setDelay command (like &#8220;setDelay 4&#8243;).  It also reports the current delay every ten seconds.  It&#8217;s not much, but it does demonstrate using ProtoThreads to handle more than one process at a time.  It also implements serial command parsing, with heavy inspiration (and code) from this todbot post. [...]</description>
		<content:encoded><![CDATA[<p>[...] The initial Arduino sketch implements a simple LED blinker that can be controlled over the serial connection.  It starts off blinking the led every second and you can set the delay by sending a setDelay command (like &#8220;setDelay 4&#8243;).  It also reports the current delay every ten seconds.  It&#8217;s not much, but it does demonstrate using ProtoThreads to handle more than one process at a time.  It also implements serial command parsing, with heavy inspiration (and code) from this todbot post. [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: todbot</title>
		<link>http://todbot.com/blog/2009/07/30/arduino-serial-protocol-design-patterns/comment-page-1/#comment-56608</link>
		<dc:creator>todbot</dc:creator>
		<pubDate>Wed, 07 Oct 2009 17:55:24 +0000</pubDate>
		<guid isPermaLink="false">http://todbot.com/blog/?p=601#comment-56608</guid>
		<description>Posted for Kasper, since there&#039;s some weirdness with him posting this.  He says:

I tried the method above and I got it working partly. It works almost perfect when I send a message with a keypress action in Processing. However when I trigger the sending code from the draw() function it fails. I tried several framerates ( 1 loop every second ) but that didn&#039;t work out. 

By the way, with lower framerates (&lt;10) the keyPress function seems more unstable as well. 

It could be Osx Snow Leopard in combination with Processing. Since they fixed serial communication with &quot;duct-tape&quot; for the 1.0.7 release. 

Another thing could have been that I send DMX ( and use sei() and cli() to disable interrupts during that time ), however even turning the DMX sending of ( and let Arduino response with the received message ) didn&#039;t help. 

Maybe you see any flaws ? Code below is working good when I write the array from the keyPressed function. 

Arduino code :
&lt;pre&gt;
int intensity_Array[72];
int arraylength=72;

byte ledNum; 
byte redVal; 
byte grnVal; 
byte bluVal;  

int arrayStartPos;

void setup() 
{ pinMode(11, OUTPUT);
  digitalWrite(13, HIGH);  
  Serial.begin(57600); 
}

void loop()
{ if( Serial.available() == 4 ) {
    ledNum = Serial.read();
    redVal = Serial.read();
    grnVal = Serial.read();
    bluVal = Serial.read();
    
    arrayStartPos = ledNum*3;
    
    intensity_Array[arrayStartPos]   = redVal;
    intensity_Array[arrayStartPos+1] = grnVal;
    intensity_Array[arrayStartPos+2] = bluVal;
  }
  
  if(ledNum==22) 
  { ledNum=0; // set the ledNum to the beginning
    
    for(int i=0; i&lt;arraylength ; i++)
    { Serial.print(intensity_Array[i]);
      Serial.print(&quot;,&quot;);  
    }  
    Serial.println(13);

    /* send frame to led data */
    //cli();    
    //sendFrame(); 
    //sei();
  }
   
}
&lt;/pre&gt;
Processing code :
&lt;pre&gt;
import processing.serial.*;

Serial port;                        
String message = null;              

int counter = 0;

void setup() 
{ //frameRate(10);  
  println(&quot;Opening: &quot;+Serial.list()[0]);
  port = new Serial(this, Serial.list()[0], 57600);     
} 

void draw() 
{  // running writeArray from here doesn&#039;t work
   //writeArray();
  
   // print the reply from Arduino
   message = port.readStringUntil(13); 
   if (message != null) println(message);  
}
    
void keyPressed()
{ writeArray();
}
   
void writeArray()
{ for( int i=0; i&lt; 23; i++ ) 
  { writeLed( i, 200, counter*20, 0 );      
  }
  counter++;
  if(counter&gt;12) counter=0;
}    

void writeLed( int ledNum, int r, int g, int b ) 
{ port.write( (byte) ledNum );
  port.write( (byte) r );
  port.write( (byte) g );
  port.write( (byte) b );
}
&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>Posted for Kasper, since there&#8217;s some weirdness with him posting this.  He says:</p>
<p>I tried the method above and I got it working partly. It works almost perfect when I send a message with a keypress action in Processing. However when I trigger the sending code from the draw() function it fails. I tried several framerates ( 1 loop every second ) but that didn&#8217;t work out. </p>
<p>By the way, with lower framerates (&lt;10) the keyPress function seems more unstable as well. </p>
<p>It could be Osx Snow Leopard in combination with Processing. Since they fixed serial communication with &#8220;duct-tape&#8221; for the 1.0.7 release. </p>
<p>Another thing could have been that I send DMX ( and use sei() and cli() to disable interrupts during that time ), however even turning the DMX sending of ( and let Arduino response with the received message ) didn&#8217;t help. </p>
<p>Maybe you see any flaws ? Code below is working good when I write the array from the keyPressed function. </p>
<p>Arduino code :</p>
<pre>
int intensity_Array[72];
int arraylength=72;

byte ledNum;
byte redVal;
byte grnVal;
byte bluVal;  

int arrayStartPos;

void setup()
{ pinMode(11, OUTPUT);
  digitalWrite(13, HIGH);
  Serial.begin(57600);
}

void loop()
{ if( Serial.available() == 4 ) {
    ledNum = Serial.read();
    redVal = Serial.read();
    grnVal = Serial.read();
    bluVal = Serial.read();

    arrayStartPos = ledNum*3;

    intensity_Array[arrayStartPos]   = redVal;
    intensity_Array[arrayStartPos+1] = grnVal;
    intensity_Array[arrayStartPos+2] = bluVal;
  }

  if(ledNum==22)
  { ledNum=0; // set the ledNum to the beginning

    for(int i=0; i&lt;arraylength ; i++)
    { Serial.print(intensity_Array[i]);
      Serial.print(",");
    }
    Serial.println(13);

    /* send frame to led data */
    //cli();
    //sendFrame();
    //sei();
  }

}
</pre>
<p>Processing code :</p>
<pre>
import processing.serial.*;

Serial port;
String message = null;              

int counter = 0;

void setup()
{ //frameRate(10);
  println("Opening: "+Serial.list()[0]);
  port = new Serial(this, Serial.list()[0], 57600);
} 

void draw()
{  // running writeArray from here doesn't work
   //writeArray();

   // print the reply from Arduino
   message = port.readStringUntil(13);
   if (message != null) println(message);
}

void keyPressed()
{ writeArray();
}

void writeArray()
{ for( int i=0; i&lt; 23; i++ )
  { writeLed( i, 200, counter*20, 0 );
  }
  counter++;
  if(counter&gt;12) counter=0;
}    

void writeLed( int ledNum, int r, int g, int b )
{ port.write( (byte) ledNum );
  port.write( (byte) r );
  port.write( (byte) g );
  port.write( (byte) b );
}
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: todbot</title>
		<link>http://todbot.com/blog/2009/07/30/arduino-serial-protocol-design-patterns/comment-page-1/#comment-56570</link>
		<dc:creator>todbot</dc:creator>
		<pubDate>Mon, 05 Oct 2009 22:15:31 +0000</pubDate>
		<guid isPermaLink="false">http://todbot.com/blog/?p=601#comment-56570</guid>
		<description>Hi Kasper,
I&#039;ve had good luck with the &quot;if(Serial.available() == len)&quot; before.  I&#039;m not sure why it doesn&#039;t work for you, your example is light on details.  Having the protocol consist of 4 bytes, one for the led number, and 3 bytes for the color, is a sound one.  If I were to do this, it would look something like:
&lt;pre&gt;
void loop() {
  if( Serial.available() == 4 ) {
    ledNum = Serial.read();
    redVal = Serial.read();
    grnVal = Serial.read();
    bluVal = Serial.read();
    set_led( ledNu, redVal, grnVal, bluVal );
  }
}
&lt;/pre&gt;
(where &quot;set_led()&quot; is some function you have in your Arduino sketch that does the actual LED handling).

In Processing, the code to set a particular LED to a particular color would look something like:
&lt;pre&gt;
void setLEDColor( int ledNum, color c ) {
  myPort.write( (byte) ledNum );
  myPort.write( red(c) );
  myPort.write( green(c) );
  myPort.write( blue(c) );
}
void draw() {
  for( int i=0; i&lt; 22; i++ ) { // 22 == number of LEDs
    color c = color( random(), random(), random() );
    setLedColor( i, c );
  }
}
&lt;/pre&gt;

Because this very simple 4-byte protocol has no stop/start byte, it&#039;s possible for the Processing sketch and the Arduino sketch to get out of sync.  In practice, this rarely happens.&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>Hi Kasper,<br />
I&#8217;ve had good luck with the &#8220;if(Serial.available() == len)&#8221; before.  I&#8217;m not sure why it doesn&#8217;t work for you, your example is light on details.  Having the protocol consist of 4 bytes, one for the led number, and 3 bytes for the color, is a sound one.  If I were to do this, it would look something like:</p>
<pre>
void loop() {
  if( Serial.available() == 4 ) {
    ledNum = Serial.read();
    redVal = Serial.read();
    grnVal = Serial.read();
    bluVal = Serial.read();
    set_led( ledNu, redVal, grnVal, bluVal );
  }
}
</pre>
<p>(where &#8220;set_led()&#8221; is some function you have in your Arduino sketch that does the actual LED handling).</p>
<p>In Processing, the code to set a particular LED to a particular color would look something like:</p>
<pre>
void setLEDColor( int ledNum, color c ) {
  myPort.write( (byte) ledNum );
  myPort.write( red(c) );
  myPort.write( green(c) );
  myPort.write( blue(c) );
}
void draw() {
  for( int i=0; i< 22; i++ ) { // 22 == number of LEDs
    color c = color( random(), random(), random() );
    setLedColor( i, c );
  }
}
</pre>
<p>Because this very simple 4-byte protocol has no stop/start byte, it's possible for the Processing sketch and the Arduino sketch to get out of sync.  In practice, this rarely happens.</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Kasper Kamperman</title>
		<link>http://todbot.com/blog/2009/07/30/arduino-serial-protocol-design-patterns/comment-page-1/#comment-56562</link>
		<dc:creator>Kasper Kamperman</dc:creator>
		<pubDate>Mon, 05 Oct 2009 18:46:24 +0000</pubDate>
		<guid isPermaLink="false">http://todbot.com/blog/?p=601#comment-56562</guid>
		<description>I came across this post, because I&#039;m trying to work a serial message out. 

I want to update a string of 22 RGB led lights controlled by Arduino from processing. 

I like to update the colors ( 3bytes ) from processing. 

I tried several things. Like sending a really long string and using the messenger library ( http://www.arduino.cc/playground/Code/Messenger ) to put everything in an array when the carriage return is received. 

That doesn&#039;t really work. 

I was thinking to make a small command. 
1 address byte for the light
2 r byte
3 g byte
4 b byte

However the method above doesn&#039;t seem to work
&lt;pre&gt;
if( Serial.available() &gt;= 6 ) {  // command length is 6 bytes
   cmd0 = Serial.read();
   cmd1 = Serial.read();
   arg0 = Serial.read();
   arg1 = Serial.read();
  // ...etc...
 }
&lt;/pre&gt;
This works for one light, but not for all. Do I need to use the while loop. And how do I make sure that I&#039;ve received everything. 

Or might the best solution by a call-response system with processing. 

So arduino request light A value and processing reply&#039;s with that value. 

Fast updates are not really important, but of course I like to update as fast as possible :)

My main problem is the length of data. I worked out some things with shorter strings before. 

Hope you can give me some hints, or code examples ( maybe there is already something out there on the net that I overlooked ). 

Thanks in advance.</description>
		<content:encoded><![CDATA[<p>I came across this post, because I&#8217;m trying to work a serial message out. </p>
<p>I want to update a string of 22 RGB led lights controlled by Arduino from processing. </p>
<p>I like to update the colors ( 3bytes ) from processing. </p>
<p>I tried several things. Like sending a really long string and using the messenger library ( <a href="http://www.arduino.cc/playground/Code/Messenger" rel="nofollow">http://www.arduino.cc/playground/Code/Messenger</a> ) to put everything in an array when the carriage return is received. </p>
<p>That doesn&#8217;t really work. </p>
<p>I was thinking to make a small command.<br />
1 address byte for the light<br />
2 r byte<br />
3 g byte<br />
4 b byte</p>
<p>However the method above doesn&#8217;t seem to work</p>
<pre>
if( Serial.available() &gt;= 6 ) {  // command length is 6 bytes
   cmd0 = Serial.read();
   cmd1 = Serial.read();
   arg0 = Serial.read();
   arg1 = Serial.read();
  // ...etc...
 }
</pre>
<p>This works for one light, but not for all. Do I need to use the while loop. And how do I make sure that I&#8217;ve received everything. </p>
<p>Or might the best solution by a call-response system with processing. </p>
<p>So arduino request light A value and processing reply&#8217;s with that value. </p>
<p>Fast updates are not really important, but of course I like to update as fast as possible :)</p>
<p>My main problem is the length of data. I worked out some things with shorter strings before. </p>
<p>Hope you can give me some hints, or code examples ( maybe there is already something out there on the net that I overlooked ). </p>
<p>Thanks in advance.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: todbot</title>
		<link>http://todbot.com/blog/2009/07/30/arduino-serial-protocol-design-patterns/comment-page-1/#comment-56533</link>
		<dc:creator>todbot</dc:creator>
		<pubDate>Mon, 05 Oct 2009 04:24:09 +0000</pubDate>
		<guid isPermaLink="false">http://todbot.com/blog/?p=601#comment-56533</guid>
		<description>Hi ubi!
Yeah I often use a 2-3 byte protocol for most of my stuff too (which is usually computers talking to other computers).  But sometimes I have to write code that talks to humans. :)
Things are well!  I hope to make it back out to Amsterdam soon, later this year.</description>
		<content:encoded><![CDATA[<p>Hi ubi!<br />
Yeah I often use a 2-3 byte protocol for most of my stuff too (which is usually computers talking to other computers).  But sometimes I have to write code that talks to humans. :)<br />
Things are well!  I hope to make it back out to Amsterdam soon, later this year.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: ubi de feo</title>
		<link>http://todbot.com/blog/2009/07/30/arduino-serial-protocol-design-patterns/comment-page-1/#comment-56499</link>
		<dc:creator>ubi de feo</dc:creator>
		<pubDate>Sun, 04 Oct 2009 13:01:30 +0000</pubDate>
		<guid isPermaLink="false">http://todbot.com/blog/?p=601#comment-56499</guid>
		<description>hey tod!
remember we met in amsterdam for lunch with Ben Cerveny.
how are things?
I was reading this article and I&#039;m happy because I do the same when I have to write my protocols.
to be honest most of the times I write byte based protocols where in 2-3 bytes I can have all I need and use start/stop bytes to wrap my message.
this way I can have a flexible amount of bytes as a command to parse.
then depending on the number of bytes I decide where to route the action.
I do a lot of bit shifting/masking too :)

hope to see you again in amsterdam some day.

ciao.ubi</description>
		<content:encoded><![CDATA[<p>hey tod!<br />
remember we met in amsterdam for lunch with Ben Cerveny.<br />
how are things?<br />
I was reading this article and I&#8217;m happy because I do the same when I have to write my protocols.<br />
to be honest most of the times I write byte based protocols where in 2-3 bytes I can have all I need and use start/stop bytes to wrap my message.<br />
this way I can have a flexible amount of bytes as a command to parse.<br />
then depending on the number of bytes I decide where to route the action.<br />
I do a lot of bit shifting/masking too :)</p>
<p>hope to see you again in amsterdam some day.</p>
<p>ciao.ubi</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: todbot</title>
		<link>http://todbot.com/blog/2009/07/30/arduino-serial-protocol-design-patterns/comment-page-1/#comment-54279</link>
		<dc:creator>todbot</dc:creator>
		<pubDate>Wed, 19 Aug 2009 21:20:07 +0000</pubDate>
		<guid isPermaLink="false">http://todbot.com/blog/?p=601#comment-54279</guid>
		<description>No worries about the formatting, I fixed it by wrapping in pre tags.

And yeah my code snippets were totally partial and didn&#039;t include all the setup. Unfortunately, I&#039;m an old-school C programmer so when I see &quot;char* cmdbuf&quot; I read that as &quot;cmdbuf is a string defined elsewhere&quot;.  I should&#039;ve just made it be &quot;char cmdbuf[80]&quot; or something.

In Arduino, people generally don&#039;t use malloc().  This is mostly because malloc() can be confusing and you usually don&#039;t need to dynamically allocate arrays.

As for the delay, I think that&#039;s because there&#039;s an error in the while() logic in what I originally wrote.  I need to spend more a bit more time thinking about it, but a delay() will solve the problem as you&#039;ve discovered.</description>
		<content:encoded><![CDATA[<p>No worries about the formatting, I fixed it by wrapping in pre tags.</p>
<p>And yeah my code snippets were totally partial and didn&#8217;t include all the setup. Unfortunately, I&#8217;m an old-school C programmer so when I see &#8220;char* cmdbuf&#8221; I read that as &#8220;cmdbuf is a string defined elsewhere&#8221;.  I should&#8217;ve just made it be &#8220;char cmdbuf[80]&#8221; or something.</p>
<p>In Arduino, people generally don&#8217;t use malloc().  This is mostly because malloc() can be confusing and you usually don&#8217;t need to dynamically allocate arrays.</p>
<p>As for the delay, I think that&#8217;s because there&#8217;s an error in the while() logic in what I originally wrote.  I need to spend more a bit more time thinking about it, but a delay() will solve the problem as you&#8217;ve discovered.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Rob</title>
		<link>http://todbot.com/blog/2009/07/30/arduino-serial-protocol-design-patterns/comment-page-1/#comment-54277</link>
		<dc:creator>Rob</dc:creator>
		<pubDate>Wed, 19 Aug 2009 21:09:43 +0000</pubDate>
		<guid isPermaLink="false">http://todbot.com/blog/?p=601#comment-54277</guid>
		<description>Man, sorry about the poor formatting.</description>
		<content:encoded><![CDATA[<p>Man, sorry about the poor formatting.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Rob</title>
		<link>http://todbot.com/blog/2009/07/30/arduino-serial-protocol-design-patterns/comment-page-1/#comment-54276</link>
		<dc:creator>Rob</dc:creator>
		<pubDate>Wed, 19 Aug 2009 21:08:57 +0000</pubDate>
		<guid isPermaLink="false">http://todbot.com/blog/?p=601#comment-54276</guid>
		<description>Hi there, 

I tried your &quot;human readable&quot; code and I could only get it working with a few modifications. Mainly I had to allocate memory for the char pointers, and a delay was necessary (I&#039;m not sure why this is). Also, it seems that char* will only hold a few bytes, so commands longer than about a dozen characters are truncated. Here&#039;s the code:

(I&#039;m using Arduino 15 and a Duemilanova with a 168 chip. Also I&#039;m using the terminal app that&#039;s built into Arduino).

------

&lt;pre&gt;
#define STRING_SIZE 16
#define MAX_ARGS 5

void setup()
{
 Serial.begin(9600);
 Serial.flush();
}

void loop()
{
 if( Serial.available() &gt; 0 ) {  // command length is 6 bytes
   delay(10);
   char* cmdbuf = (char*)malloc(sizeof(char) * STRING_SIZE);
   char c;
   int i = 0;
   while( Serial.available() &amp;&amp; c != &#039;\n&#039; ) {  // buffer up a line
     c = Serial.read();
     cmdbuf[i++] = c;
   }

   i = 0;
   while( cmdbuf[++i] != &#039; &#039; ) ; // find first space
   cmdbuf[i] = 0;          // null terminate command
   char* cmd = cmdbuf;     
   int cmdlen = i;         // length of cmd
   int args[5] = {0}, a;         // five args max, &#039;a&#039; is arg counter
   char* s;
   char* argbuf = cmdbuf+cmdlen+1;

   while( (s = strtok(argbuf, &quot; &quot;)) != NULL &amp;&amp; a &lt;= MAX_ARGS ) {
     argbuf = NULL;
     args[a++] = (byte)strtol(s, NULL, 0); // parse hex or decimal arg
   }

   int argcnt = a;         // number of args read
   Serial.flush();
 }
}
&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>Hi there, </p>
<p>I tried your &#8220;human readable&#8221; code and I could only get it working with a few modifications. Mainly I had to allocate memory for the char pointers, and a delay was necessary (I&#8217;m not sure why this is). Also, it seems that char* will only hold a few bytes, so commands longer than about a dozen characters are truncated. Here&#8217;s the code:</p>
<p>(I&#8217;m using Arduino 15 and a Duemilanova with a 168 chip. Also I&#8217;m using the terminal app that&#8217;s built into Arduino).</p>
<p>&#8212;&#8212;</p>
<pre>
#define STRING_SIZE 16
#define MAX_ARGS 5

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

void loop()
{
 if( Serial.available() &gt; 0 ) {  // command length is 6 bytes
   delay(10);
   char* cmdbuf = (char*)malloc(sizeof(char) * STRING_SIZE);
   char c;
   int i = 0;
   while( Serial.available() &amp;&amp; c != '\n' ) {  // buffer up a line
     c = Serial.read();
     cmdbuf[i++] = c;
   }

   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] = {0}, a;         // five args max, 'a' is arg counter
   char* s;
   char* argbuf = cmdbuf+cmdlen+1;

   while( (s = strtok(argbuf, " ")) != NULL &amp;&amp; a &lt;= MAX_ARGS ) {
     argbuf = NULL;
     args[a++] = (byte)strtol(s, NULL, 0); // parse hex or decimal arg
   }

   int argcnt = a;         // number of args read
   Serial.flush();
 }
}
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Johan Adler</title>
		<link>http://todbot.com/blog/2009/07/30/arduino-serial-protocol-design-patterns/comment-page-1/#comment-54135</link>
		<dc:creator>Johan Adler</dc:creator>
		<pubDate>Sat, 15 Aug 2009 18:19:38 +0000</pubDate>
		<guid isPermaLink="false">http://todbot.com/blog/?p=601#comment-54135</guid>
		<description>I finally rewrote the whole GPS reading code and used a switch statement, and now it works just the way I want it to. I wish I could implement it in a more compact way, but on the other hand this way works. My next task is to interpret and use the SiRF Binary data, and I think I am about halfway there. Pasting extensive code below (using a serial LCD adapter from Modern Devices):
&lt;pre&gt;
#define gps Serial3
#define gpsBps 57600

byte gpsRxStage = 0;
byte gpsRxPayload[1024];
int gpsRxPayloadLength = 0;
int gpsRxPayloadChecksum = 0;

byte gpsMsgStart[2] = {0xa0, 0xa2};
byte gpsMsgEnd[2] = {0xb0, 0xb3};

boolean gpsValidPackage = false;
boolean gpsFix = false;

void gpsRead() {
  int c, temp;
  byte bc;

  if(gps.available()) {
    c = gps.read();
    if(c != 0xffff) {
      bc = byte(c);
      switch (gpsRxStage) {
      case 0:
        if(bc == gpsMsgStart[0]) {
          gpsRxStage = 1;
          gpsValidPackage = false;
        }
        break;
      case 1:
        if(bc == gpsMsgStart[1]) {
          gpsRxStage = 2;
        }
        break;
      case 2:
        gpsRxPayloadLength = (bc &amp;&amp; 0x7f) &lt;= gpsRxPayloadLength) {
          gpsRxPayload[i] = 0;
          gpsRxStage = 5;
        }
        break;
      case 5:
        gpsRxPayloadChecksum = bc &lt;&lt; 8;
        gpsRxStage = 6;
        break;
      case 6:
        gpsRxPayloadChecksum += bc;
        temp = checksumCalc(gpsRxPayload, gpsRxPayloadLength);
        if(gpsRxPayloadChecksum == temp) {
          gpsRxStage = 7;
        } 
        else {
          gpsRxStage = 0;
        }
        break;
      case 7:
        if(bc == gpsMsgEnd[0]) {
          gpsRxStage = 8;
        }
        else {
          gpsRxStage = 0;
        }
        break;
      case 8:
        gpsRxStage = 0;
        if(bc == gpsMsgEnd[1]) {
          gpsValidPackage = true;
        }
        break;
      default:
        lcd.print(&quot;?fUnknown error in switch statement, gpsRead&quot;);
        for(;;);
      }
    }
  }
}
&lt;/pre&gt;
</description>
		<content:encoded><![CDATA[<p>I finally rewrote the whole GPS reading code and used a switch statement, and now it works just the way I want it to. I wish I could implement it in a more compact way, but on the other hand this way works. My next task is to interpret and use the SiRF Binary data, and I think I am about halfway there. Pasting extensive code below (using a serial LCD adapter from Modern Devices):</p>
<pre>
#define gps Serial3
#define gpsBps 57600

byte gpsRxStage = 0;
byte gpsRxPayload[1024];
int gpsRxPayloadLength = 0;
int gpsRxPayloadChecksum = 0;

byte gpsMsgStart[2] = {0xa0, 0xa2};
byte gpsMsgEnd[2] = {0xb0, 0xb3};

boolean gpsValidPackage = false;
boolean gpsFix = false;

void gpsRead() {
  int c, temp;
  byte bc;

  if(gps.available()) {
    c = gps.read();
    if(c != 0xffff) {
      bc = byte(c);
      switch (gpsRxStage) {
      case 0:
        if(bc == gpsMsgStart[0]) {
          gpsRxStage = 1;
          gpsValidPackage = false;
        }
        break;
      case 1:
        if(bc == gpsMsgStart[1]) {
          gpsRxStage = 2;
        }
        break;
      case 2:
        gpsRxPayloadLength = (bc &amp;&amp; 0x7f) &lt;= gpsRxPayloadLength) {
          gpsRxPayload[i] = 0;
          gpsRxStage = 5;
        }
        break;
      case 5:
        gpsRxPayloadChecksum = bc &lt;&lt; 8;
        gpsRxStage = 6;
        break;
      case 6:
        gpsRxPayloadChecksum += bc;
        temp = checksumCalc(gpsRxPayload, gpsRxPayloadLength);
        if(gpsRxPayloadChecksum == temp) {
          gpsRxStage = 7;
        }
        else {
          gpsRxStage = 0;
        }
        break;
      case 7:
        if(bc == gpsMsgEnd[0]) {
          gpsRxStage = 8;
        }
        else {
          gpsRxStage = 0;
        }
        break;
      case 8:
        gpsRxStage = 0;
        if(bc == gpsMsgEnd[1]) {
          gpsValidPackage = true;
        }
        break;
      default:
        lcd.print("?fUnknown error in switch statement, gpsRead");
        for(;;);
      }
    }
  }
}
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: todbot</title>
		<link>http://todbot.com/blog/2009/07/30/arduino-serial-protocol-design-patterns/comment-page-1/#comment-54015</link>
		<dc:creator>todbot</dc:creator>
		<pubDate>Wed, 12 Aug 2009 17:47:49 +0000</pubDate>
		<guid isPermaLink="false">http://todbot.com/blog/?p=601#comment-54015</guid>
		<description>Hi Johan,
If you can get the device to output a fixed-length Sirf Binary datastream, that would be the easiest.  You could use the third example I give above.

Otherwise, you&#039;d probably be better reading the Payload length value right after the 0xa2,0xa0, and then just looping on that.  Something like this:
&lt;pre&gt;
byte buf[MAXSIZE];  // shouldn&#039;t be more than 512 probably
if( Serial.available() == 4 ) { // we got start bytes + len
  int s0   = Serial.read();
  int s1   = Serial.read();
  int lenH = Serial.read();
  int lenL = Serial.read();
  if( s0 == 0xa0 &amp;&amp; s1 == 0xa2 ) { 
    int len = lenH &lt;&lt; 8 + lenL;  // make into 16-bit value
  for( int i = 0; i &lt; len ; i++ ) {
    while( !Serial.available() ) { }  // wait for it
    buf[i] = Serial.read();
  }
}
&lt;/pre&gt;

The above has several issues if you want a fault-tolerant system, but it should work to test things out.  The main problems with the above are:
- Initial Serial.read()s don&#039;t take into account coming mid-way into the data stream.
- The &quot;len&quot; isn&#039;t checked to see if it&#039;s smaller than MAXSIZE, or if it&#039;s the expected size for the payload you requested
- The &quot;while(!Serial.avaialable())&quot; can block indefinitely.

There are pretty easy solutions to all those however.</description>
		<content:encoded><![CDATA[<p>Hi Johan,<br />
If you can get the device to output a fixed-length Sirf Binary datastream, that would be the easiest.  You could use the third example I give above.</p>
<p>Otherwise, you&#8217;d probably be better reading the Payload length value right after the 0xa2,0xa0, and then just looping on that.  Something like this:</p>
<pre>
byte buf[MAXSIZE];  // shouldn't be more than 512 probably
if( Serial.available() == 4 ) { // we got start bytes + len
  int s0   = Serial.read();
  int s1   = Serial.read();
  int lenH = Serial.read();
  int lenL = Serial.read();
  if( s0 == 0xa0 &#038;&#038; s1 == 0xa2 ) {
    int len = lenH &lt;&lt; 8 + lenL;  // make into 16-bit value
  for( int i = 0; i &lt; len ; i++ ) {
    while( !Serial.available() ) { }  // wait for it
    buf[i] = Serial.read();
  }
}
</pre>
<p>The above has several issues if you want a fault-tolerant system, but it should work to test things out.  The main problems with the above are:<br />
- Initial Serial.read()s don&#8217;t take into account coming mid-way into the data stream.<br />
- The &#8220;len&#8221; isn&#8217;t checked to see if it&#8217;s smaller than MAXSIZE, or if it&#8217;s the expected size for the payload you requested<br />
- The &#8220;while(!Serial.avaialable())&#8221; can block indefinitely.</p>
<p>There are pretty easy solutions to all those however.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Johan Adler</title>
		<link>http://todbot.com/blog/2009/07/30/arduino-serial-protocol-design-patterns/comment-page-1/#comment-54012</link>
		<dc:creator>Johan Adler</dc:creator>
		<pubDate>Wed, 12 Aug 2009 16:53:27 +0000</pubDate>
		<guid isPermaLink="false">http://todbot.com/blog/?p=601#comment-54012</guid>
		<description>Nice tricks!

Right now I am thinking about how to implement a Sirf Binary GPS parser, reading serial strings from the GPS. The strings/containers have a two byte start sequence and another two byte stop sequence (and no &quot;\n&quot; etc). I would love to find a way to read this whole string without having to use multiple nested if statements.

Since you have worked with the serial communication more than I have, do you have any suggestions on how to do this?

The code should check for 0xa0 0xa2 and then read everything up to 0xb0 0xb3. Everything between these two two byte sequences is the useful and information carrying part of the message (payload length, payload and checksum).

On second thought my specific application might just use if statements or whatever is needed. Once the program is &quot;in sync&quot; with the GPS the stop sequence will always be followed by a new start sequence (though it can be up to one second later). As long as the program keeps up with the GPS transmissions the should be in sync.</description>
		<content:encoded><![CDATA[<p>Nice tricks!</p>
<p>Right now I am thinking about how to implement a Sirf Binary GPS parser, reading serial strings from the GPS. The strings/containers have a two byte start sequence and another two byte stop sequence (and no &#8220;\n&#8221; etc). I would love to find a way to read this whole string without having to use multiple nested if statements.</p>
<p>Since you have worked with the serial communication more than I have, do you have any suggestions on how to do this?</p>
<p>The code should check for 0xa0 0xa2 and then read everything up to 0xb0 0xb3. Everything between these two two byte sequences is the useful and information carrying part of the message (payload length, payload and checksum).</p>
<p>On second thought my specific application might just use if statements or whatever is needed. Once the program is &#8220;in sync&#8221; with the GPS the stop sequence will always be followed by a new start sequence (though it can be up to one second later). As long as the program keeps up with the GPS transmissions the should be in sync.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
