Writing my own (very basic) communication protocol

I'm working on several different projects that use serial communication. So I created a little side project that incorporates all the elements and functions I want to use in my other projects as a way to learn and test all of my code/hardware. I have been using a section of "Arduino and Kinect Projects" by Enrique Ramos Melgar and Ciriaco Castro Diaz, titled "Writing your own communication protocol" (pg 67-69). Again, this project is for learning and testing purposes so it doesn't really do much.

Setup:
I have an Arduino UNO connected to three potentiometers (A0, A2, A4), it reads the values and divides by 4 to get a range between 0-255, then transmits the values via the TX pin to an Arduino Nano RX pin. The Nano reads the values, then passes them on via the Nano TX pin to an HC-06 Bluetooth module, the Bluetooth module then sends it to my computer where I have a simple Processing program that receives the values and displays them on my screen.
The UNO and Nano have been tested and are working.
The 3 pots have been tested and are sending values to the UNO.
The HC-06 has been tested with the Nano before and worked, but I am still pretty new to this little piece of hardware so maybe I'm missing something.

Please forgive the illustration, I know it's pretty rough.

Arduino UNO code

const int XIn = 0;
const int YIn = 2;
const int ZIn = 4;
int XVal, YVal, ZVal;

void setup(){
Serial.begin(9600);
pinMode(XIn, INPUT);
pinMode(YIn, INPUT);
pinMode(ZIn, INPUT);
}

void loop(){
XVal = int(analogRead(XIn)/4); //read pot value and divide by 4 to get a range between 0-255
YVal = int(analogRead(YIn)/4);
ZVal = int(analogRead(ZIn)/4);
Serial.write('A'); //send trigger character
Serial.write(XVal); //send first value
Serial.write(YVal); //send second value
Serial.write(ZVal); //send third value
}

Arduino Nano code

int StartVal, XVal, YVal, ZVal;
void setup(){
Serial.begin(9600);
}
void loop(){
if(Serial.available()<3){ //check if info available
StartVal = Serial.read();
if(StartVal=='A'){ // check for trigger character
XVal=Serial.read(); //read first value
YVal=Serial.read(); //read first value
ZVal=Serial.read(); //read first value
}
}
Serial.write('A'); //send trigger character
Serial.write(XVal); //send first value
Serial.write(YVal); //send second value
Serial.write(ZVal); //send third value
}

Processing code
import processing.serial.*;
Serial XYZ;
int StartVal, XVal, YVal, ZVal;

void setup(){
size(200,200);
XYZ = new Serial(this,"COM9",9600);
}
void draw(){
if(XYZ.available()>3){
StartVal=XYZ.read();
if(StartVal=='A'){ //check trigger character
XVal = XYZ.read(); //read first value
YVal = XYZ.read(); //read second value
ZVal = XYZ.read(); //read thrid value
}
}
print(XVal); //display values
print(" ");
print(YVal);
print(" ");
println(ZVal);
}

The Goal
Read three different pots, send the values from one Arduino to another, and on to a computer via Bluetooth.

Results
In the processing serial window it continuously displays "0 0 0". I used the serial monitor to check the UNO and it is reading the pot values correctly. So it seems the issue is with my "communication protocol". Maybe you can spot the problem. Specific answers and suggestions are great, resources that I can read or study are good too.

Thanks
-J

Imagine for an instant, if you will, that one of your "analogRead"s returned the value 260.

Please use code tags when posting code.

Like this if(Serial.available()<3){ //check if info available :o

The first step is to write a Processing sketch to display every value received. That way you can make sure the PC is receiving the messages you think you are sending.

Why on earth is the Nano in the picture? I can't see what it does.

Just send a sequence of values through the bluetooth and display it in Processing. My guess is that you haven't got the bluetooth coms working correctly.

I got my HC06 working with this Instructables tutorial

My HC06 is a 3v device so I have a level-shifter to convert the Arduino 5v Tx down to 3v for the HC06 Rx. The output of the HC06 Tx is understood by the Arduino Rx without need for a level-shifter.

If you want to receive Bluetooth data on your Arduino you may find some useful stuff in Serial Input Basics

...R

AWOL,
If the pot returned a value of 260... yeah... I can see how that might cause issues. I spent the night thinking about it, but any ideas I came up with for a trigger character would encounter the same issue. Any suggestions, or do you have any favorite resources (books, websites, examples) for learning serial communication that teach different or more efficient communication protocols?

Thanks for your reply!

johnwasser,
That's good advice. I have changed the code, and it seems that the processing sketch is not receiving anything. But that might have to do with this next part below.

Thanks!

Robin2,
I did not know that the HC06 is a 3v device, that's pretty important and kind of a big oversight on my part, oops. I was looking at level-shifters like the ones sparkfun provides, are there specific advantages to using a level-shifter over a simple voltage divider (1kohm and 2kohm resistors)?
Thanks for the link to Serial page, that is really helpful!
Thanks for your reply!

-J

 if(Serial.available()<3){ //check if info available

That is silly. There might be no info available at all, or 1, or 2 chars.

Pete

el_supremo:

 if(Serial.available()<3){ //check if info available

That is silly. There might be no info available at all, or 1, or 2 chars.

Pete

Is it? I'm sending four values (trigger character plus three values) so if there aren't at least four values in the buffer there's no reason to check it, no? Can you elaborate or offer an example of something not silly?
Thanks for your reply!
-J

If you are moving signals from a 5 v. to a 3.3 v. device, you don't really need a level shifter, just a voltage divide.

Jrodenba:
so maybe I'm missing something.

Please forgive the illustration, I know it's pretty rough.

The illustration is fine. I suspect that the something you are missing is what a completely pointless exercise this is. For starters, why don't you connect the HC-06 directly to the Uno like everybody else does? You may then find you only need to

serial.print(Xval) folloowed y YVal and ZVal, and you can forget all that other stuff.

Note that while the HC-06 is indeed a 3.3v device, it runs on 5v using that breakout board and you only need to use a divider on the Arduino Tx line.

Jrodenba:
Robin2,
are there specific advantages to using a level-shifter over a simple voltage divider (1kohm and 2kohm resistors)?

A voltage divider makes a perfectly good level shifter.

...R

Jrodenba:
Is it? I'm sending four values (trigger character plus three values) so if there aren't at least four values in the buffer there's no reason to check it, no? Can you elaborate or offer an example of something not silly?

If that is what you want to do you would use > not <

Robin2:
A voltage divider makes a perfectly good level shifter

Providing the signal speed is to too high.

but any ideas I came up with for a trigger character would encounter the same issue. Any suggestions

Therefore you have to restrict the range of numbers that you send from your pots. One simple way to do this would be to send the numbers in ASCII and then have a start character that has a one in the most significant bit.
There are other ways like using a first byte and then if that number occurred in the data, adding an extra byte in the data like an escape character, this would require a bit of intelligence in both transmitted and receiving routines.

I'm sending four values (trigger character plus three values) so if there aren't at least four values in the buffer there's no reason to check it, no?

Exactly. Think about it. If there are less than 3 characters available then you read 1 or 4 of them.

Pete

If that is what you want to do you would use > not <

Exactly. Think about it. If there are less than 3 characters available then you read 1 or 4 of them.

Pete

Grunmpy_Milke and Pete,
I see my mistake now. Such a stupid little mistake, this is why I'm grateful we can come to the forums and have others proof our stuff. Thanks!!!

A voltage divider makes a perfectly good level shifter.

...R

Providing the signal speed is to too high.

Robin2 and Grumpy_Mike,
Thanks, a voltage divider using two resistors is a quick and easy fix. I'm using 9600 baud, at that signal speed it shouldn't be too much of a problem, no?

Therefore you have to restrict the range of numbers that you send from your pots. One simple way to do this would be to send the numbers in ASCII and then have a start character that has a one in the most significant bit.
There are other ways like using a first byte and then if that number occurred in the data, adding an extra byte in the data like an escape character, this would require a bit of intelligence in both transmitted and receiving routines.

Grumpy_Mike,
Thanks for the suggestions! I'll be spending the day playing around with those and seeing what I can come up with. Would an escape character be similar to the start and end characters that Robin2 uses in his Serial Input Basics

Thanks!
-J

Would an escape character be similar to the start and end characters that Robin2 uses

No totally different.

The image is an example of using an escape character in an OSC message ( Open Sound Control ), the start of the message is 0xC0, but what happens if this is in the data. Therefore if it does the pair of numbers 0xDB and 0xDC are substituted in place of the 0xC0. But then what happens if 0xDB is part of the data? Then it is followed by the dummy 0xDD to indicate that 0xDB was intended.

The code in this Python Arduino demo illustrates how to send any character using the concept that @Grumpy_Mike mentions.

Note that I usually refer people to the simpler version at Reply #4 in that Thread.

...R