Arduino - Arduino via Xbee Multiple bytes

Hi

My problem is as follows, I have a bunch of Arduino boards which I am using to control some robots. There is one Xbee which is connected to the computer to monitor everything. Each Arduino board transmits a set of values which are all floats and all the others receive these values and use those to generate control signals. So each Arduino should transmit the values then sit there and keep reading the values from all the other arduinos until its turn comes up and the cycle repeats. My first problem is I do not know how to send read multiple values from the serial communication. So far I have used communication between an arduino and a computer via Xbee.. and I have just used Serial.print () to send all the values I want. If for eg the values are 20.25,10.4 and 0.9, how to send them and how to read them into three variables on the receiving end ? Should I just use Serial.print(value1)Serial.print(\t);Serial.print(value2) and so on ? If this is right, how do the read at the receiving arduino ?

Thanks in advance for your suggestion

ksp

My first problem is I do not know how to send read multiple values from the serial communication.

Which is it? You don’t know how to send multiple values, or you don’t know how to receive multiple bytes?

So far I have used communication between an arduino and a computer via Xbee… and I have just used Serial.print () to send all the values I want.

Where? I don’t see any code.

If for eg the values are 20.25,10.4 and 0.9, how to send them and how to read them into three variables on the receiving end ?
Should I just use Serial.print(value1)Serial.print(\t);Serial.print(value2) and so on ?

Something like that, yes.

If this is right, how do the read at the receiving arduino ?

Depends on what you actually send. If you send a string like “20.25,10.4, 0.9”, how does the receiver know when the complete packet has arrived? If you send a string like “<20.25,10.4, 0.9>”, it’s a lot more obvious where the packet starts and ends. You can then use code like this to read the string:

#define SOP '<'
#define EOP '>'

bool started = false;
bool ended = false;

char inData[80];
byte index;

void setup()
{
   Serial.begin(57600);
   // Other stuff...
}

void loop()
{
  // Read all serial data available, as fast as possible
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}

Where it says “Process the packet”, use strtok() to parse the string (“20.25,10.4, 0.9”). Then, convert each token back to a float.

That last step will be the hardest, since the support for floats on the Arduino is so limited.

What exactly is each Arduino supposed to do with “20.25,10.4, 0.9”?

Hi

My problem is I do not know how to receive multiple values at the receiving end. With the computer and arduino all I did was use the serial.print(variable names) and I checked my output on the serial monitor in arduino sdk. I want to send three values as mentioned before. If I use the serial.print and send the three separately i.e,

 var1 = 20.2; var2 = 10.4; var3 = 0.9;
Serial.begin(9600);
Serial.print(var1);Serial.print("\t");
Serial.print(var1);Serial.print("\t");
Serial.print(var1);

My idea was to send data like this (since I only need a max of 5 values). I had no idea how to receive all these values. But from the example code that you have kindly posted, I got an idea how to proceed. Each arduino takes these values which are actually the position coordinates of the robot and compares it with the position of its own and generates some control signals.

Thanks ksp

Serial.print("<");
Serial.print(var1);Serial.print("\t");
Serial.print(var2);Serial.print("\t");
Serial.print(var3);
Serial.print(">");

Then, the code I posted can be used. The strtok() and atof() functions can be used on the receiver to separate the tokens and convert them to values.

Thanks I will try that and get back here with the results.

ksp

Hi

I have tried the following code and I got the following output.
On the sender,

float v1=24.5,v2=10.8,v3=0.9;

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

void loop(){
  Serial.write("<");
  Serial.print(v1);Serial.print(",");
  Serial.print(v2);Serial.print(",");
  Serial.print(v3);Serial.print(">");
  Serial.print("\n");
  delay(5000);
}

On the receiver,

  if(started && ended)
  {
    int count=0;
    Serial.print(inData);
    Serial.print("\n");
    char *p = inData;
    char *str;
    while (str=strtok_r(p,",",&p))
    {
      Data[count]=*str;
      Serial.print(str);Serial.print("\n");
      p = NULL;
      count++;
    }
    
    //Reset
    started = false;
    ended= false;
    index = 0;
    inData[index]='\0';
  }

My output is

Receiving
<24.5,10.8,0.9>
24.5,10.8,0.9
24.5

and it continues the same for every 5 seconds.

Can you help me figure out why I keep getting only the first values ?

Thanks

ksp

Can you help me figure out why I keep getting only the first values ?

I think that it is pretty obvious.

    while (str=strtok_r(p,",",&p))
    {
      Data[count]=*str;
      Serial.print(str);Serial.print("\n");
      p = NULL;
      count++;
    }

Get a value from the string pointed to by p, then set p to NULL. Then, try to get another value from the string pointed to by p.

No wonder it doesn't work.

Where it says "Process the packet", use strtok() to parse the string ("20.25,10.4, 0.9").

strtok_r() != strtok()!!!!!

Hi Paul

Thanks for pointing out the problem.

I have used this and I am successful in parsing.

char *Data=NULL;
 if(started && ended)
  {
    Serial.print(inData);
    Serial.print("\n");
    Data =strtok(inData,",");
    while(Data != NULL)
    {
      Serial.print(Data);Serial.print("\n");
      Data=strtok(NULL,",");
    }
    
    //Reset
    started = false;
    ended= false;
    index = 0;
    inData[index]='\0';
  }

My output is as follows,

Receiving
<24.5,10.8,0.9>
24.5,10.8,0.9
24.5
10.8
0.9

Although I am not sure of some things here.

  1. When I just use char Data; and try to verify the code it throws me an error saying illegal char to char conversion. Why should I declare it as a pointer and point it to NULL ?
  2. In the while loop I have put Data=strtok(NULL,","); again why am I using null here ?

I would greatly appreciate it if you can answer these doubts I have.

I will also try the atof and convert them back to numbers and get back here.

Thanks
ksp

When I just use char Data; and try to verify the code it throws me an error saying illegal char to char conversion. Why should I declare it as a pointer and point it to NULL ?

Because the strtok function returns a pointer. You need to declare a variable to hold the returned value that matches the returned type. It is not necessary to initialized it to NULL; it's merely a good idea. A really good idea.

In the while loop I have put Data=strtok(NULL,","); again why am I using null here ?

That is how the strtok() function knows whether to get the first token again, or the next token.

I have tried the atof function and I was able to successfully convert the characters back into numbers.

Thank you Paul for your help.

ksp

KSP1717, can you post your complete final code to I learn about this kind of transmission? =(

Im getting a lot of problems sending and receiving multiple data by xbee.

Sory my english Cuco

Hi again, I did the code successfully, but I can't put the individual values in individual variables!

Do you have any idea to help me, please?

Thanks Daniel

Do you have any idea to help me, please?

I have a great idea. Post your code. Explain what is working and what is not working.