Arduino X2 serial communication problems

I am trying to get two arduinos to communicate together using Xbee’s but for right now I just have two arduino’s that are connected together with wires to eliminate the xbee’s as being an issue with my programming. What I am doing is sending the value of some pots from one arduino to the other then comparing the values and outputting to an LED that says the sending pot is either higher or lower. Right now nothing is happening, the Tx and Rx pins are not flashing or doing anything, i press reset, nothing happens. I’m very new and have little experience with programming so here is my code.

Sending Arduino:

// SENDER
int grabValue, wristValue, elbowValue, shoulderValue, twistValue, val1, val2, val3, val4, val5;

void setup()
{
// start serial port at 19200 bps
Serial.begin(19200);
}

void loop()
{
// reads analog input for each sensor on the controling arm
grabValue = analogRead(0);
wristValue = analogRead(1);
elbowValue = analogRead(2);
shoulderValue = analogRead(3);
twistValue = analogRead(4);

// remap values
// 251 through 255 for SYNC
val1 = map(grabValue, 0, 1023, 250, 0); 
val2 = map(wristValue, 0, 1023, 250, 0); 
val3 = map(elbowValue, 0, 1023, 250, 0);
val4 = map(shoulderValue, 0, 1023, 250, 0); 
val5 = map(twistValue, 0, 1023, 250, 0);

Serial.print(251, BYTE); //SYNC char
Serial.print(val1, BYTE);

Serial.print(252, BYTE); //SYNC char
Serial.print(val2, BYTE);

Serial.print(253, BYTE); //SYNC char
Serial.print(val3, BYTE);

Serial.print(254, BYTE); //SYNC char
Serial.print(val4, BYTE);

Serial.print(255, BYTE); //SYNC char
Serial.print(val5, BYTE);

delay(150);
}

Receiving arduino:

// RECIEVER
byte incomingByte, grabValue, wristValue, elbowValue, shoulderValue, twistValue;
byte grabPos, wristPos, elbowPos, shoulderPos, twistPos;

void setup() {

// start serial port at 19200 bps
Serial.begin(19200);

// pins for relay control
pinMode (2, OUTPUT);
pinMode (3, OUTPUT);
pinMode (4, OUTPUT);
pinMode (5, OUTPUT);
pinMode (6, OUTPUT);
pinMode (7, OUTPUT);
pinMode (8, OUTPUT);
pinMode (9, OUTPUT);
pinMode (10, OUTPUT);
pinMode (11, OUTPUT);

delay(1000);

}

void loop() {
if (Serial.available()) {   // are there any bytes available on the serial port ???

// reads in arm position
grabPos = analogRead(0);
wristPos = analogRead(1);
elbowPos = analogRead(2);
shoulderPos = analogRead(3);
twistPos = analogRead(4);

// assign bytes to the var ‘incomingByte’
incomingByte = Serial.read();

Serial.print(int(incomingByte));

// from now on is pretty clear I guess   :)

if ((int(incomingByte) == 251)) {
grabValue = Serial.read();
Serial.print(int(grabValue)); 
}

if ((int(incomingByte) == 252)) {
wristValue = Serial.read();
Serial.print(int(wristValue));
}

if ((int(incomingByte) == 253)) {
elbowValue = Serial.read();
Serial.print(int(elbowValue));
}

if ((int(incomingByte) == 254)) {
shoulderValue = Serial.read();
Serial.print(int(shoulderValue));
}

if ((int(incomingByte) == 255)) {
twistValue = Serial.read();
Serial.print(int(twistValue));
}

// adjusting motors position
if (grabValue > grabPos) {
  digitalWrite(2, HIGH);
  digitalWrite(3, LOW);
} else { // grabValue <= grabPos
  digitalWrite(2, LOW);
  digitalWrite(3, HIGH);
}

if (wristValue > wristPos) {
  digitalWrite(4, HIGH);
  digitalWrite(5, LOW);
} else { // wristValue <= wristPos
  digitalWrite(4, LOW);
  digitalWrite(5, HIGH);
}


if (elbowValue > elbowPos) {
  digitalWrite(6, HIGH);
  digitalWrite(7, LOW);
} else { // elbowValue <= elbowPos
  digitalWrite(6, LOW);
  digitalWrite(7, HIGH);
}

if (shoulderValue > shoulderPos) {
  digitalWrite(8, HIGH);
  digitalWrite(9, LOW);
} else { // shoulderValue <= shoulderPos
  digitalWrite(8, LOW);
  digitalWrite(9, HIGH);
}

if (twistValue > twistPos) {
  digitalWrite(10, HIGH);
  digitalWrite(11, LOW);
} else { // twistValue <= twistPos
  digitalWrite(10, LOW);
  digitalWrite(11, HIGH);
}
  
  
}
}

Explain ALL connections you are making between the two Arduinos. You should have TX on one connected to RX on the other, for two wires, and you should have ground on one connected to ground on the other, for a total of three wires.

If you are going to cast incomingByte to an int everywhere, it makes more sense to declare it as an int, especially since Serial.read() returns an int.

Also, you test for one byte of data to be available, then proceed to read several values. Find a club and whack yourself a few times.

This program can get into a condition where Serial.available() might return 1, yet you try to read 2 bytes. You must make sure that you have bytes available before you start reading.

I hate to be a stinker and point to my own library, but using UComms on the Arduino playground will make this code much easier to read/maintain. You won't have to worry about the sync bytes, and you won't have to worry about checking whether any data is available because the library uses a callback.

Paul, yes I have those wires connected correctly, one question, when I'm using the xbee's the two arduinos will be far apart, how should i go about making the grounds neutral then?

I said in my original post, I have no idea what I am doing with programming, most of this code I got from a bunch of examples. What you're saying about the incoming byte is to declare it as "int incoming byte = serial.read()" and then how should I code it where I can check for a variable and then check for another? Put serial.available after every if statement?

John, What do you mean your own library, I am very new to programming and don't know what you mean? Sounds interesting though.

Your “receiving Arduino” sketch only checks for 1 byte:

if (Serial.available()) {   // are there any bytes available on the serial port ???

Serial.available() returns the number of bytes that are available.

First you read incomingByte, then later on if incomingByte is one of your sync bytes, you read another byte. But you’ve only checked to make sure that one byte is available. If you Serial.read() when no data is available, you’ll get -1 instead of what you expected.

What you can do is to either do another check on Serial.available(), or you can change your first if() to check that Serial.available >= 2.


By my own library, I meant one that I wrote for a personal project and open sourced on the Arduino Playground. It comes with an example :slight_smile: oh and I’ll be updating it later this week. Right now it requires you to packetize your own data, but it should do that for you. That’s in the next revision.

Thanks for all of the help. I rewrote the program for receiving so let me know if this looks right.

// RECIEVER
byte incomingByte, grabValue, wristValue, elbowValue, shoulderValue, twistValue;
byte grabPos, wristPos, elbowPos, shoulderPos, twistPos;

void setup() {

// start serial port at 19200 bps
Serial.begin(19200);

// pins for relay control
pinMode (2, OUTPUT);
pinMode (3, OUTPUT);
pinMode (4, OUTPUT);
pinMode (5, OUTPUT);
pinMode (6, OUTPUT);
pinMode (7, OUTPUT);
pinMode (8, OUTPUT);
pinMode (9, OUTPUT);
pinMode (10, OUTPUT);
pinMode (11, OUTPUT);

delay(1000);

}

void loop() {

// reads in arm position
grabPos = analogRead(0);
wristPos = analogRead(1);
elbowPos = analogRead(2);
shoulderPos = analogRead(3);
twistPos = analogRead(4);

if (Serial.available()) {   // are there any bytes available on the serial port ???

// assign bytes to the var ‘incomingByte’
int incomingByte = Serial.read();

if (incomingByte == 251) 
{
if (Serial.available()){
grabValue = Serial.read();
}
}

if (incomingByte == 252) 
{
if (Serial.available()){
wristValue = Serial.read();
}
}

if (incomingByte == 253) 
{
if (Serial.available()){
elbowValue = Serial.read();
}
}

if (incomingByte == 254) 
{
if (Serial.available()){
shoulderValue = Serial.read();
}
}

if (incomingByte == 255) 
{
if (Serial.available()){
twistValue = Serial.read();
}
}

// adjusting motors position
if (grabValue > grabPos) {
  digitalWrite(2, HIGH);
  digitalWrite(3, LOW);
} else { // grabValue <= grabPos
  digitalWrite(2, LOW);
  digitalWrite(3, HIGH);
}

if (wristValue > wristPos) {
  digitalWrite(4, HIGH);
  digitalWrite(5, LOW);
} else { // wristValue <= wristPos
  digitalWrite(4, LOW);
  digitalWrite(5, HIGH);
}


if (elbowValue > elbowPos) {
  digitalWrite(6, HIGH);
  digitalWrite(7, LOW);
} else { // elbowValue <= elbowPos
  digitalWrite(6, LOW);
  digitalWrite(7, HIGH);
}

if (shoulderValue > shoulderPos) {
  digitalWrite(8, HIGH);
  digitalWrite(9, LOW);
} else { // shoulderValue <= shoulderPos
  digitalWrite(8, LOW);
  digitalWrite(9, HIGH);
}

if (twistValue > twistPos) {
  digitalWrite(10, HIGH);
  digitalWrite(11, LOW);
} else { // twistValue <= twistPos
  digitalWrite(10, LOW);
  digitalWrite(11, HIGH);
}
  
  
}
}

I’m new to serial and never even touched library’s. I used them in Java so I assume they are similar where as I can call a method used in your library but I think it’s a lot more in depth than I would like to go.

Something you'll get better at with practice is writing non-redundant code.

  if(Serial.available()) {
    
    switch(incomingByte) {
      
      case 251:
        grabValue = Serial.read();
        break;
      case 252:
        wristValue = Serial.read();
        break;
      case 253:
        elbowValue = Serial.read();
        break;
      case 254:
        shoulderValue = Serial.read();
        break;
      case 255:
        twistValue = Serial.read();
        break;
      default:
        //What do you do if it's NOT one of these??
        //you should handle this case somehow
    }
  }

Also, especially when getting help, run Tools -> Auto Format on your code to make it easier to read.

Also, you're using C# style. C code is traditionally written in K&R style or the "1TBS". You can read about these on Wikipedia.

I learned Java in college when I was computer science major, but have since changed to computer engineering and am now electrical engineering just because I wanted to get away from programming. I didn't know there was an option to have it clean up my code! Thanks for your help so much! How would your recommend handling the exception? Have it turn on an LED to let me know its having an error?

No, I would recommend packetization of data so that you never have that problem in the first place.

That’s why I recommended UComms. :stuck_out_tongue:

Hell, you could send all 5 of your values in one packet! That would make this muuuch easier

If you wouldn't mind explaining how to do this or giving me a sample code to help me understand it then I would love to try it! I basically just search for what I want to do, then take everyone's code and modify it to make it work for my jobs. I tried to hook up the two arduinos today and somehow something got messed up and cooked one of my arduinos, i couldn't figure out what was going on and then i touched one of the controllers and burned my finger, then ripped all of the wires out trying to save it.

johnmchilton: By my own library, I meant one that I wrote for a personal project and open sourced on the Arduino Playground. It comes with an example :)

Edit: I just updated the library to 0.2

Now the packetization scheme is invisible to the user! This is good. The example is updated, too.

John, sorry I missed that little bit about having an example.

From what I understand in the example, it reads in serial from a computer and when it reads the letter H coming in it makes a pin go high. I am VERY NEW to programing, so 90% of the program is incomprehensible to me. It sounds interesting and I want to be able to understand how it works if you wouldn't mind explaining it or how I would make it work between two Arduino Uno's using xbee's. It seems like it's just using H as a trigger where in my program I am using a number.

Look at the example I have for reading a packet with three values. You want to convert that to a callback function that handles 5 different messages, each with two parameters ...maybe, for example. But let's run with that for a minute.

Your first parameter can indicate which value you are changing (grab, wrist, elbow, shoulder, twist), and the second parameter will be the new value.

Using this protocol, to change all 5 values to 200, you could send from your other device: (G,200)(W,200)(E,200)(S,200)(T,200)

...But you don't have to do it that way. You could also do something like: (C,200,200,200,200,200) to change all values at the same time. This option will require less code, but will be harder to add to when you want to add more parameters. It's really up to you how to define your packets.

Remember to use int() to change the input character arrays to integers before using the values!

Come back if you need me to write the code for you, but I think you can do it based on the examples and the sample protocols above.

John, I admire your faith in me, but I am still clueless. The only thing in your code that I can read and makes sense is your comments and I am actually trying. I think I am going to try to stick with my code because I understand it and can somewhat debug it on my own.