Use coordinator to tell xbee(series1) end devices when to send data, Arduino

Hi

Not sure if this is the right place, but I try anyway.
If this is easier with a series 2 xbee, I can switch.

I’m trying to get 3 end devices and 1 coordinator to talk together.

My setup is series 1 and AP2 mode.
When the end devices just send with a delay (1000ms) the coordinator might not receive data from all three end devices. So one end device might get trough with its data more than the others.

What I have tried is to hook up pin 20 on end devices to a digital pin on Arduino to read if its high or low.

Coordinator sends an AT request to set pin 20 high on end device #1.
When end device #1 is high it sends data back to coordinator.

This works sort of, the end device sends but it like the coordinators not in sync and doesn’t always receive the data.
With the counter I have in end device code it can jump as much as 100 at a time. I would like it to count 1 at a time.

Have also tried to get the end devices to set there own pin20 to low at end of code, but when I do this it won’t send any data.
Any suggestions. Used google, read other forums post, pdf documents, but none the wiser.

End device code below

#include 
#include 

SoftwareSerial softserial(2, 3); // RX, TX


XBee xbee = XBee();
uint8_t package[] = { 0, 0, 0  };
Tx16Request tx1 = Tx16Request(0x1234, package, sizeof(package));


// Set DIO0 (pin 20)
uint8_t d0Cmd[]={'D','0'};
uint8_t valueHigh[]={5};
uint8_t valueLow[]={4};

int xbeePin20 = 6;                 // LED connected to digital pin 13
int times;

void setup()
{
  Serial.begin(115200);
  pinMode(xbeePin20, INPUT);   
  
    softserial.begin(9600);
  xbee.setSerial(softserial);
  xbee.begin(softserial);
  
  delay(5000);
}

void loop()
{

  
  while  (digitalRead(xbeePin20) == 0){
    
    
   Serial.println("pin 0 is LOW");  
 
  }   

     times = times + 1; //adds 1 to see if all the data is received.
     package[1] = times >> 8 & 0xff;
     package[2] = times & 0xff; 
     
       xbee.send(tx1);      
     
    Serial.print("pin 0 is HIGH");
    Serial.println(digitalRead(xbeePin20));
   
    
    } 

Coordinator code. I have removed the code for the other Xbees as I first need coordinator to receive from just 1 end device all the time.


#include 
#include 

SoftwareSerial softserial(2, 3); // RX, TX
XBee xbee = XBee();


XBeeResponse response = XBeeResponse();
Rx16Response rx16 = Rx16Response();

int value1;
int value2;
int value3;

int count1;
int count2;
int count3;



// allocate two bytes for to hold a 10-bit analog reading
uint8_t payload1[] = { 0, 0, 0 };
uint8_t payload2[] = { 0, 0, 0 };
uint8_t payload3[] = { 0, 0, 0 };

// Set DIO0 (pin 20)
uint8_t d0Cmd[]={'D','0'};
uint8_t valueHigh[]={5};
uint8_t valueLow[]={4};

// SH + SL of your remote radio
XBeeAddress64 remoteAddress1 = XBeeAddress64(0x0013a200, 0x407C917C);
XBeeAddress64 remoteAddress2 = XBeeAddress64(0x0013a200, 0x4002392E);
XBeeAddress64 remoteAddress3 = XBeeAddress64(0x0013a200, 0x400239EE);

// Create a remote AT request with the IR command
RemoteAtCommandRequest remoteHigh1 = RemoteAtCommandRequest(remoteAddress1, d0Cmd, valueHigh, sizeof(valueHigh));
RemoteAtCommandRequest remoteHigh2 = RemoteAtCommandRequest(remoteAddress2, d0Cmd, valueHigh, sizeof(valueHigh));
RemoteAtCommandRequest remoteHigh3 = RemoteAtCommandRequest(remoteAddress3, d0Cmd, valueHigh, sizeof(valueHigh));

//set low
RemoteAtCommandRequest remoteLow1 = RemoteAtCommandRequest(remoteAddress1, d0Cmd, valueLow, sizeof(valueLow));
RemoteAtCommandRequest remoteLow2 = RemoteAtCommandRequest(remoteAddress2, d0Cmd, valueLow, sizeof(valueLow));
RemoteAtCommandRequest remoteLow3 = RemoteAtCommandRequest(remoteAddress3, d0Cmd, valueLow, sizeof(valueLow));


void setup() {
  
  Serial.begin(115200);
  
  softserial.begin(9600);
  xbee.setSerial(softserial);
  xbee.begin(softserial);
  
  delay(5000);
  
}

void loop() {
    



xbee.send(remoteHigh1);   


 xbee.readPacket();   
 

  
    if (xbee.getResponse().isAvailable()) {
      // got something
      
      if (xbee.getResponse().getApiId() == RX_16_RESPONSE) {
        // got a rx packet
        
        if (xbee.getResponse().getApiId() == RX_16_RESPONSE) {
                xbee.getResponse().getRx16Response(rx16);
        	for (int i = 0; i < rx16.getDataLength(); i++) 
          payload1[i] = rx16.getData(i);
          
       } 
          
    }
   
 
   uint8_t analogHigh1 = payload1[1];
   uint8_t analogLow1 = payload1[2];
   value1 = analogLow1 + (analogHigh1 * 256); 
  
 
  count1 = count1 + 1;
   
   Serial.print("value1  ");
   Serial.print(value1);
     Serial.print("    ");
   Serial.println(count1);
   xbee.send(remoteLow1);  
   
   delay (500);
   }
    
  
    
      
}



   

With only 3 devices, each talking once per second, you will be better to just have them send without your hand-shaking. The Xbee automatically handle Rf collision, so if 2 try to talk at once they will take turns.

Such manual polling is only required with high numbers (more than 30 maybe?).

Why don’t you create a simple protocol? So send a serial messsage to the Ardino instead of the pin 20 thing, which you’ll need to do twice since you need to send it twice.

Long-term this ‘serial poll’ is a more powerful solution since you could do many things, such as ask for different data and so on.