Thursday, 4 December 2008

Passing large values between the Arduino to the TouchShield

(I've gotten a couple of questions about this, especially since I posted the Processing on a TouchShield post, so here's a little tutorial on how to pass large values, like integers between the Arduino and TouchShield ... it's a slightly modified version of what I posted on the forum.)

Communicating from the Arduino to the TouchShield is a bit of a manual process, largely because there are so many different ways someone might want to communicate that it's tough to plan for all of them ahead of time. It's easy to pass unsigned chars one at a time, because the function grabs one char at a time, which is one byte. The catch is that integers (ints) are 2 bytes long, so if you try to just use serial.print() and, it only sends one byte, or 8 bits, and then you lose the other part of your number!

So in order to send a full int from the arduino, you have to send each byte of the 2-byte integer separately, and then reconstruct it back into the full two-byte value. Chris figured out how to get this working in the Pin Visualizer project, and I've adapted it for the Processing graphics library code too.

On the TouchShield, I use this code:

int getValue =;
getValue = (getValue < < 8) +;

This first calls to get the high bit. The " < < 8" means bit shift the byte up (to the left) 8 bits. Then, it calls again to get the low byte. And finally it adds both together. It kind of looks like this:

First get byte 1, the high byte:
Shift it left 8 bits
Then get byte 2, the low byte:
Add that to the left-shifted byte:

And on the Arduino, I'll use this code:

unsigned char lowByte, highByte;
unsigned int val;
//set val to something
lowByte = (unsigned char)val;
highByte = (unsigned char)(val > > 8);

That kind of does the inverse behavior. First it take val, and sets lowByte to only the lower or rightmost 8 bits. Then, it sets highByte to the upper or leftmost 8 bits (by bitshifting it down 8 bits first). Then, it prints the high byte, followed by the low byte. I throw a delay(1) in between just to give the Arduino and TouchShield time to separate the two sends from each other.

So if val looks like:
It sets lowByte to:
It then shifts val to the right by 8 bits to get:
Which it then grabs only the lower 8 bits of:
Which get stored as highByte

Because I send highByte first, and the send lowByte, that means the TouchShield has to know that the first thing it gets will be the highByte. So that's why the first byte the TouchShield gets is shifted left by 8 bits... the "circle of life" is now complete :-)

Phew. That was really long... On the plus side, this also happens to be a convenient way to pass large values between two Arduinos over a two-wire Rx/Tx serial connection, or between the Arduino and a custom program on the PC. I know they tend not to be used in too many apps or sketches, but bit shifts really do come in handy sometimes. And if you still want some more help, just send me some code to look at, and I'll try my best!


Post a Comment