Go Down

Topic: Xbee-Xbee communication stops (Read 776 times) previous topic - next topic

ksp1717

Hi all

I am trying to run a bunch of autonomous robots together. Each robot takes in the information of the preceding robot and follows it. I have 3 arduinos mega 2560 and 3 SF xbee shield and series 1 xbee. So I put the arduino, motor controller and xbee stack on each robot and try to coordinate them. Here is where the problem is

My program runs something like this..... the robots are named 1,2,3 and this is how im running them.

The comm loop runs every 75ms and communication is initiated by the 1st robot. Robot1 --> Robot2 --> Robot3 --> Robot1 --> Robot2 --> Robot3 and so on.  Robot 2 transmits only after it receives info from robot1.

The problem is for reasons unknown to me the communication just stops I mean, after robot 1 transmits, robot 2 does not receive and so it does not transmit stopping the comm loop. I dont know why this is happening. Sometimes when I run it, the loop works for a few seconds and then stops. I tried doing this with only 2 robots and it works for about 30-40 secs and it stops after that.

I have attached my program outline. Any help into figuring out this problem will be greatly appreciated.

Code: [Select]

#include "Arduino.h"
#include "QuadratureEncoder.h"
#include "TimerOne.h"

//Declare encoder interrupts and initialize pwm

//Define gains and other constants.

       //Initialize Velocity and Time


   //For Communication routine
float vData[4];
char inData[50];
byte index;
bool started=false;
bool ended=false;



void setup()
{
 Serial2.begin(9600);

//Other startup stuff
// Initialize timer interrupt for control routine.
 vData[0]=0;
 vData[1]=0;
 vData[2]=0;
 senddata();
} //setup

void loop()
{
       // motor Velocity controller
 vel_ctrl();
         
       //Run communication loop every 75ms

 if ((millis()-t) > 75){
 comm();
 t=millis();
 }
 delay(5);
} //loop



The comm() function where the communication received is parsed and information is transmitted is as follows.

Code: [Select]

void comm()
{
 char *Data=NULL;
 int count=0;
   //Read the Serial2 data from the buffer
 while(Serial2.available()>0)
   {
     char inChar = Serial2.read();
     if(inChar == '<')
     {
       index=0;
       inData[index]='\0';
       started=true;
       ended=false;
     }
     else if(inChar == '>')
     {
       ended=true;
       break;
     }
     else
     {
       if(index < 49)
       {
         inData[index]=inChar;
         index++;
         inData[index]='\0';
       }
     }
   } //while(Serial2.available()>0)
   
   //Process data received
 if(started && ended)
   {
     Data =strtok(inData,",");
     //Convert received data into floats and assign them to variables
     if(atof(Data)==3){
     while(Data != NULL){
         vData[count]=atof(Data);
         Data=strtok(NULL,",");
         count++;
       }
     
   //Transmit data if information received is from the robot 3

       senddata();
     }
     vData[0]=0;
     //Reset booleans
     started = false;
     ended= false;
     index=0;
     inData[index]='\0';
   } //if(started && ended)
} //comm



When senddata() is called the information is transmitted.

Code: [Select]

void senddata()
{
 Serial2.print('<');
 Serial2.print(1);Serial2.print(',');
 Serial2.print(PosX);Serial2.print(',');
 Serial2.print(PosY);Serial2.print(',');
 Serial2.print(Veld);
 Serial2.print('>');
 Serial2.print(millis());Serial2.print("\n");
} //senddata



PaulS

How are the XBees configured? List the PAN ID, MY and DL values for each one.

ksp1717

All of them have been set to this

ATID - 7115
ATMY - 0
ATDL - 0

I modified the program a little and it seems to work now ...... but i am not sure if what i did is correct way to do it.

I basically added a condition to check how long it has been since last communication is received. If the gap is greater than 200ms (> 65+65+65 ms) then the robot transmits.

But I found that the response of my system is not smooth (the robots acceleration is not smooth but jerky). I used 500ms initially and it was even worse.

Here is the communication function.

Code: [Select]

void comm()
{
  char *Data=NULL;
  int count=0;

             // if comm is lost in the middle then
            // this will prevent the communication loop from stopping
  if (millis()-commtime > 200) senddata();
   
           //Read the Serial2 data from the buffer
  while(Serial2.available()>0)
    {
      char inChar = Serial2.read();
      if(inChar == '<')
      {
        index=0;
        inData[index]='\0';
        started=true;
        ended=false;
      }
      else if(inChar == '>')
      {
        ended=true;
        break;
      }
      else
      {
        if(index < 49)
        {
          inData[index]=inChar;
          index++;
          inData[index]='\0';
        }
      }
    } //while(Serial2.available()>0)
   
    //Process data received
  if(started && ended)
    {
      Data =strtok(inData,",");
      //Convert received data into floats and assign them to variables
      if(atof(Data)==3){
      while(Data != NULL){
          vData[count]=atof(Data);
          Data=strtok(NULL,",");
          count++;
        }
        senddata();
        commtime=millis();
      }
      vData[0]=0;
      //Reset booleans
      started = false;
      ended= false;
      index=0;
      inData[index]='\0';
    } //if(started && ended)
} //comm

PaulS

You have all the radios having the same address. When one radio broadcasts, any other radio with the DL value that the radio is talking to, will hear that message (including itself) and need to acknowledge the receipt of that packet.

What you are trying to do is use point to point radios to create a mesh network. That really won't work. There is a lot of processing that the XBee manages to handle packet forwarding etc, that you are having to deal with on the Arduino (less than successfully).

ksp1717

Paul thanks for your reply. But I am confused.

How does the radio listen to itself. I mean shouldn't it be either transmitting or listening? Can it do both at the same time ?

I read about the mesh network using xbee. From what I understand in a mesh information can reach the destination in various routes and information flows both ways, meaning A --> B, B --> A.

What I want to do here the radio MAY receive transmissions from all the other radios but should use the data from only one specific radio. And it should transmit only when it receives from that radio. For example I have three robots, Robot 1 as I understand will receive information from radios of both 2 and 3. But it should only the data received from 3 and should only transmit after it receives data from 3.

So in my communication sketch, I read all the data in the buffers but parse only the ones which are received from robot 3 and transmit after that. I have put that in the program like this.


Code: [Select]
    //Process data received
  if(started && ended)
    {
      Data =strtok(inData,",");

      //Convert received data into floats and assign them to variables
     // if data received is from robot 3.

      if(atof(Data)==3){
      while(Data != NULL){
          vData[count]=atof(Data);
          Data=strtok(NULL,",");
          count++;
        }
        senddata();
        commtime=millis();
      }
      vData[0]=0;
      //Reset booleans
      started = false;
      ended= false;
      index=0;
      inData[index]='\0';
    } //if(started && ended)


If what I did is incorrect can you please suggest me how I should be doing it.

Thankyou



PaulS

Quote
Can it do both at the same time ?

Of course it can, and does.

Quote
I read about the mesh network using xbee. From what I understand in a mesh information can reach the destination in various routes and information flows both ways, meaning A --> B, B --> A.

Yes, that is true. But, if the packet you are sending from A is addressed to B, and it gets there by way of C, D, E, F, and G, does that matter? Only B will do anything with the packet, other than forward it.

When B replies, it should reply to A. The message might go directly from B to A, or it might go from B to H, I, J, C, D, Z, and R to A. Again, does it matter? Only A will do anything with the packet, other than forward it.

With series 2 XBees, the Arduino wouldn't even know that its XBee had received and forward dozens of packets that were not addressed to it.

As it is, your XBee has to pass every message to the Arduino, which is what has to decide whether or not to parse and respond to the message.

You need to have different code on each Arduino. Running a separate sketch to put an ID in EEPROM that the posted sketch reads at run time would enable you to run the posted sketch on each Arduino. The sketch would read the to and from values from EEPROM (which would be different on each Arduino) and decide, then, whether the message was from the correct sender. If it was, it could reply with the correct recipient ID in the packet.

Of course, all that you are trying to do is made much simpler by using Andrew Rapp's XBee library. That library would allow you to address packets to any specific destination, and to easily ignore any packets not intended for itself.

ksp1717

Quote

Yes, that is true. But, if the packet you are sending from A is addressed to B, and it gets there by way of C, D, E, F, and G, does that matter? Only B will do anything with the packet, other than forward it.

When B replies, it should reply to A. The message might go directly from B to A, or it might go from B to H, I, J, C, D, Z, and R to A. Again, does it matter? Only A will do anything with the packet, other than forward it.

Yes to these two. It does not matter as long as the message is used only by the intended robots.
Quote

With series 2 XBees, the Arduino wouldn't even know that its XBee had received and forward dozens of packets that were not addressed to it.

But I have series 1 xbee.

Quote

You need to have different code on each Arduino. Running a separate sketch to put an ID in EEPROM that the posted sketch reads at run time would enable you to run the posted sketch on each Arduino. The sketch would read the to and from values from EEPROM (which would be different on each Arduino) and decide, then, whether the message was from the correct sender. If it was, it could reply with the correct recipient ID in the packet.

I am kind of lost in this paragraph. So I should have another sketch on the eeprom which has the to and from ids ?

I am going through the library you have suggested.



Go Up