Use coordinator to tell xbee end devices when to send data

Hi

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 <SoftwareSerial.h>
#include <XBee.h>

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 <XBee.h>
#include <SoftwareSerial.h>

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);
   }
    
  
    
      
}

If you have MAC ACKs enabled in the XBee config, then the sending node will retry up to n times to transmit then get a MAC ACK confirmation. If the MAC ACK fails, there is a status sent back on the serial interface saying that the transmission failed due to MAC ACK timeouts or CCA faults. So the application may elect to try later.r

If node A and B are sending to node C, assuming you haven’t disabled CCA (a.k.a. CSMA/CA, or listen-before-transmitting), then no two nodes will transmit at the same time. If A cannot hear B’s transmissions due to RF conditions, by C can hear A and B, there may be collisions. However, C will get an errored frame and not send a MAC ACK. The sending node will retransmit to correct.

These are basics of IEEE 802.15.4. Indeed, 802.11 (WiFi) works the same way.