Sending an unsigned long via Xbee API

I am trying to send an unsigned long from one arduino to another via xbee using the API. And now I get weird results. I chop the unsigned long into 4 8-bit pieces and send them via Tx16Request(); If I send a number less than 445565, it works. If I send a number 445565 or greater, it doesn't even send the packet. Here is my code:

Transmitter code:
payload[0] is just an 8 bit unsigned int for another purpose. payload is declared as uint8_t[7], and the transmission is

Tx16Request tx = Tx16Request(0xFFFF, payload, sizeof(payload));
unsigned long outtime = 445565;
      payload[0] = onoff;
      payload[1] = (outtime >> 24) & 0x000000ff;
      payload[2] = (outtime >> 16) & 0x000000ff;
      payload[3] = (outtime >>  8) & 0x000000ff;
      payload[4] = (outtime      ) & 0x000000ff;
      
      xbee.send(tx);

Receiver code:

xbee.getResponse().getRx16Response(rx16);
      onoff = rx16.getData(0);
      big[1] = rx16.getData(1);
      big[2] = rx16.getData(2);
      big[3] = rx16.getData(3);
      big[4] = rx16.getData(4);
      time = big[4] + (big[3]<<8) + (big[2]<<16) + (big[1]<<24);

where big[] is an unsigned long big[7]. Again, if the number is below 445565, it will successfully send and receive the packet, but it will not even receive the packet if the number is 445565 or greater.

I have no clue why this is happening and would greatly appreciate the help.

      payload[1] = (outtime >> 24) & 0x000000ff;

How does 0x000000ff differ from 0xFF? Are all those 0s adding value somehow?

Perhaps you could get help at http://snippets-r-us.com with your snippets. Or, you could post ALL of your code (attach it if it is too big to post).

Here is my entire code:

Transmitter:

#include <XBee.h>

XBee xbee = XBee();

unsigned long start = millis();

uint8_t payload[] = { 0, 0, 0, 0, 0, 0, 0 };
uint8_t onoff = 0;
// with Series 1 you can use either 16-bit or 64-bit addressing

// 16-bit addressing: Enter address of remote XBee, typically the coordinator
Tx16Request tx = Tx16Request(0xFFFF, payload, sizeof(payload));

TxStatusResponse txStatus = TxStatusResponse();

int statusLed = 6;
int errorLed = 13;

unsigned long time = 0;
unsigned long currenttime = 0;
unsigned long outtime = 0;

int toggle = 7;
const int red = 13; // the pin that the LED is attached to
int incomingByte;      // a variable to read incoming serial data into
float test;

void flashLed(int pin, int times, int wait) {
    
    for (int i = 0; i < times; i++) {
      digitalWrite(pin, HIGH);
      delay(wait);
      digitalWrite(pin, LOW);
      
      if (i + 1 < times) {
        delay(wait);
      }
    }
}

void setup() {
  pinMode(statusLed, OUTPUT);
  pinMode(errorLed, OUTPUT);
  pinMode(toggle, INPUT);
  Serial.begin(9600);
  xbee.setSerial(Serial);
}

void loop() {
   
   // start transmitting after a startup delay.  Note: this will rollover to 0 eventually so not best way to handle
    if (millis() - start > 15000) {
      // break down 10-bit reading into two bytes and place in payload
      
      onoff = digitalRead(toggle);
      time = millis();
      outtime = 445565;
      payload[0] = onoff;
      payload[1] = (outtime >> 24) & 0x000000ff;
      payload[2] = (outtime >> 16) & 0x000000ff;
      payload[3] = (outtime >>  8) & 0x000000ff;
      payload[4] = (outtime      ) & 0x000000ff;
      payload[5] = 0;
      payload[6] = 0;
      
      xbee.send(tx);

      // flash TX indicator
      flashLed(statusLed, 1, 100);
    }
  
    // after sending a tx request, we expect a status response
    // wait up to 5 seconds for the status response
    if (xbee.readPacket(5000)) {
        // got a response!

        // should be a znet tx status            	
    	if (xbee.getResponse().getApiId() == TX_STATUS_RESPONSE) {
    	   xbee.getResponse().getZBTxStatusResponse(txStatus);
    		
    	   // get the delivery status, the fifth byte
           if (txStatus.getStatus() == SUCCESS) {
            	// success.  time to celebrate
             	flashLed(statusLed, 10, 50);
           } else {
            	// the remote XBee did not receive our packet. is it powered on?
             	flashLed(errorLed, 3, 500);
           }
        }      
    } else if (xbee.getResponse().isError()) {
      //nss.print("Error reading packet.  Error code: ");  
      //nss.println(xbee.getResponse().getErrorCode());
      // or flash error led
    } else {
      // local XBee did not provide a timely TX Status Response.  Radio is not configured properly or connected
      flashLed(errorLed, 2, 50);
      delay(500);
      flashLed(errorLed, 2, 50);
    }
    
    delay(1000);
}

Receiver code:

/*
This code is for the HUB box. It simply takes a switch input to determine 
if it should send an "ON" signal or an "OFF" signal

OFF:
int onoff=0
float time=0.0

ON:
int onoff=1
float time=millis()/1000.;
*/

#include <SD.h>
#include <XBee.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(12,11,10,9,8,7);

XBee xbee = XBee();
XBeeResponse response = XBeeResponse();

Rx16Response rx16 = Rx16Response();

//uint8_t data[6];

const int chipSelect = 4;

uint8_t onoff = 0;
unsigned long time = 0;
unsigned long big[7];

int toggle = 7;
const int red = 13; // the pin that the LED is attached to
const int yellow = 6;
int incomingByte;      // a variable to read incoming serial data into
float test;

void setup() {
  // initialize serial communication:
  Serial.begin(9600);
  xbee.setSerial(Serial);
  // initialize the LED pin as an output:
  pinMode(red, OUTPUT);
  pinMode(yellow, OUTPUT);
  pinMode(toggle, INPUT);
  
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  if (dataFile) {
    dataFile.println("Time    Voltage Current Power   Xaccel  Yaccel  Zaccel  Exceed?");
    dataFile.close();
  }
  
  lcd.begin(16, 2);
  lcd.print("Wireless test");
  delay(1000);
  lcd.clear();
  
}

void loop() {
  
  xbee.readPacket(5000);// waits for a packet for up to 5000 ms
  
  if (xbee.getResponse().isAvailable()) {
    // got something
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Got Something");
    delay(500);
    
    if (xbee.getResponse().getApiId() == RX_16_RESPONSE) {
      xbee.getResponse().getRx16Response(rx16);
      onoff = rx16.getData(0);
      big[1] = rx16.getData(1);
      big[2] = rx16.getData(2);
      big[3] = rx16.getData(3);
      big[4] = rx16.getData(4);
      time = big[4] + (big[3]<<8) + (big[2]<<16) + (big[1]<<24);
      flashLed(yellow, 1, 50);
      flashLed(red, 1, 50);
      flashLed(yellow, 1, 50);
      flashLed(red, 1, 50);
    } else if (xbee.getResponse().isError()){
      flashLed(yellow, 2, 100);
    }
  } else {
    flashLed(red, 2, 100);
  }    
  lcd.clear();
  delay(500);
  lcd.print(onoff);
  delay(500);
  lcd.clear();
  delay(500);
  lcd.print(rx16.getData(1));
  delay(500);
  lcd.clear();
  delay(500);
  lcd.print(rx16.getData(2));
  delay(500);
  lcd.clear();
  delay(500);
  lcd.print(rx16.getData(3));
  delay(500);
  lcd.clear();
  delay(500);
  lcd.print(rx16.getData(4));
  delay(500);
  lcd.clear();
  delay(500);
  lcd.print(time);
  delay(500);
    
  //Write data to SD card
  File dataFile = SD.open("datalog.txt", FILE_WRITE);
  if (dataFile) {
    dataFile.print(onoff, 1);
    dataFile.print("\t");
    dataFile.print(time, 6);
    dataFile.println("\t");
    dataFile.close();
  }    
  delay(3000);
   
}


void flashLed(int pin, int times, int wait) {
    
    for (int i = 0; i < times; i++) {
      digitalWrite(pin, HIGH);
      delay(wait);
      digitalWrite(pin, LOW);
      
      if (i + 1 < times) {
        delay(wait);
      }
    }
}

How are the XBees connected to the Arduino? You are using Serial to talk to them. If you have a choice, you should move the XBee off the hardware serial port, so that you can use that for debugging.

If not, test the code on the transmitter, without the XBee attached. Print out what is in payload, before sending. I suspect that there is some array out-of-bounds writing happening, though I don't see it.

      big[1] = rx16.getData(1);
      big[2] = rx16.getData(2);
      big[3] = rx16.getData(3);
      big[4] = rx16.getData(4);

Doesn't getData() return a byte? Storing that in an unsigned long seems a waste of space.

The output from the transmitter is:

payload[1] = 0
payload[2] = 6
payload[3] = 204
payload[4] = 125

So it is going into the xbee.send function correctly

Transmitter code:

#include <XBee.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(12,11,10,9,8,7);

XBee xbee = XBee();

unsigned long start = millis();

uint8_t payload[] = { 0, 0, 0, 0, 0, 0, 0 };
uint8_t onoff = 0;
// with Series 1 you can use either 16-bit or 64-bit addressing

// 16-bit addressing: Enter address of remote XBee, typically the coordinator
Tx16Request tx = Tx16Request(0xFFFF, payload, sizeof(payload));

TxStatusResponse txStatus = TxStatusResponse();

int statusLed = 6;
int errorLed = 13;

unsigned long time = 0;
unsigned long currenttime = 0;
unsigned long outtime = 0;

int toggle = 7;
const int red = 13; // the pin that the LED is attached to
int incomingByte;      // a variable to read incoming serial data into
float test;

void flashLed(int pin, int times, int wait) {
    
    for (int i = 0; i < times; i++) {
      digitalWrite(pin, HIGH);
      delay(wait);
      digitalWrite(pin, LOW);
      
      if (i + 1 < times) {
        delay(wait);
      }
    }
}

void setup() {
  pinMode(statusLed, OUTPUT);
  pinMode(errorLed, OUTPUT);
  pinMode(toggle, INPUT);
  Serial.begin(9600);
  xbee.setSerial(Serial);
  lcd.begin(16, 2);
  lcd.print("Wireless test");
  delay(300);
  lcd.clear();
}

void loop() {
   
   // start transmitting after a startup delay.  Note: this will rollover to 0 eventually so not best way to handle
    if (millis() - start > 15000) {
      // break down 10-bit reading into two bytes and place in payload
      
      onoff = digitalRead(toggle);
      time = millis();
      outtime = 445565;
      payload[0] = onoff;
      payload[1] = (outtime >> 24) & 0x000000ff;
      payload[2] = (outtime >> 16) & 0x000000ff;
      payload[3] = (outtime >>  8) & 0x000000ff;
      payload[4] = (outtime      ) & 0x000000ff;
      payload[5] = 0;
      payload[6] = 0;
      
      for (int i=0; i<=5; i++){
        lcd.print(payload[i]);
        delay(500);
        lcd.clear();
      }
      
      
      xbee.send(tx);

      // flash TX indicator
      flashLed(statusLed, 1, 100);
    }
  
    // after sending a tx request, we expect a status response
    // wait up to 5 seconds for the status response
    if (xbee.readPacket(5000)) {
        // got a response!

        // should be a znet tx status            	
    	if (xbee.getResponse().getApiId() == TX_STATUS_RESPONSE) {
    	   xbee.getResponse().getZBTxStatusResponse(txStatus);
    		
    	   // get the delivery status, the fifth byte
           if (txStatus.getStatus() == SUCCESS) {
            	// success.  time to celebrate
             	flashLed(statusLed, 10, 50);
           } else {
            	// the remote XBee did not receive our packet. is it powered on?
             	flashLed(errorLed, 3, 500);
           }
        }      
    } else if (xbee.getResponse().isError()) {
      //nss.print("Error reading packet.  Error code: ");  
      //nss.println(xbee.getResponse().getErrorCode());
      // or flash error led
    } else {
      // local XBee did not provide a timely TX Status Response.  Radio is not configured properly or connected
      flashLed(errorLed, 2, 50);
      delay(500);
      flashLed(errorLed, 2, 50);
    }
    
    delay(1000);
}

So apparently, it is only the last byte the matters. 7200000 works, 7200124 works, 7200125 DOES NOT work.
Last byte: smiles work, xxxxx doesn't work.

0 :slight_smile:
50 :slight_smile:
100 :slight_smile:
120 :slight_smile:
121 :slight_smile:
121 :slight_smile:
123 :slight_smile:
124 :slight_smile:
125XXXXX
126XXXXX
127 :slight_smile:
128 :slight_smile:
129 :slight_smile:
130 :slight_smile:
140 :slight_smile:
150 :slight_smile:
200 :slight_smile:
As to why 125 and 126 do not work, I have no idea.