Xbee+arduino problem: one hour restarting

Hello,
I am working on Xbee wireless sensor network. I have two separate Xbee modules (series 2), which each has temperature sensor (TMP36) on pin 19. I evaluate everything on the arduino+xbee shield. I'm basing my code on Wireless Temperature Sensor | Project Lab and simplify them. Displaying temperature via a serial port on PC.
Everything works well, I am getting a right value of temperature from sensors. But an error appears about every hour. Maybe restart of arduino. Look at the list of serial port, see below the code.

#define NUM_ANALOG_SAMPLES 4
int packet[32];
int analogSamples[NUM_ANALOG_SAMPLES];
float c;
 
//=================== SETUP =================================
void setup() {
  Serial.begin(9600);
  delay(1000);
  Serial.print("Starting.........."); 
  Serial.println(); 
}

//==================== LOOP =================================
void loop() {
  readPacket();
}

//==================== podprogramy XBEE ======================
void readPacket() {
  if (Serial.available() > 0) {
    int b = Serial.read();
    if (b == 0x7E) {
	packet[0] = b;
	packet[1] = readByte();
	packet[2] = readByte();
	int dataLength = (packet[1] << 8) | packet[2];

	for(int i=1;i<=dataLength;i++) {
	  packet[2+i] = readByte();
	}
	int apiID = packet[3];
	packet[3+dataLength] = readByte(); // checksum

 	if (apiID == 0x92) {
	  int analogSampleIndex = 19;
	  int analogChannelMask = packet[18];
	  for(int i=0;i<4;i++) {
	    if ((analogChannelMask >> i) & 1) {
		analogSamples[i] = (packet[analogSampleIndex] << 8) | packet[analogSampleIndex+1];
		analogSampleIndex += 2;
	    } 
            else {
		analogSamples[i] = -1;
	    }
	  }
	}
    }

    int reading = analogSamples[1];  // pin 19 [0] is pin 20
    // convert reading to millivolts
    float v = ((float)reading /(float)0x3FF) * 1200.0;
        
    // convert to Celcius.  10mv per Celcius degree with 500mV offset at 0 celcius
    float c = (v - 500.0) / 10.0;
    
    Serial.println();   
    Serial.print("Temp: ");
    Serial.print(c);
    Serial.println();
   }
}

int readByte() {
    while (true) {
	if (Serial.available() > 0) {
	return Serial.read();
    }
  }
}

Listing of the serial port:
Starting..........
Temp: 26.41
Temp: 23.01
Temp: 27.11
Temp: 21.95
Temp: 27.11
Temp: 23.01
Temp: 26.99
Temp: 23.01
Temp: 26.99
Temp: 23.01
...
after about an hour I get
Starting..........
Starting..........
Starting..........
Starting..........
Temp: 27.11
Temp: 22.19
Temp: 26.99
...

I dont know what is it. 4 times restart of arduino? Overflow of some value?...but it not cause four times restart. I tried almost everything. I tried simple code with printing through serial port and it works well, no restarting. So my arduino has not hardware defect.

Please, if anyone know what's wrong, help me.
Thanks for reply, George.

If you get any corruption in transmission of the two bytes that make up the datalength, the resulting datalength has the possibility of being huge, producing a huge overflow, writing all over the SRAM the arduino has. Try defending against this & see if things improve

I agree with the reply about corruption. If datalength is corrupt and is a large value, the read loop will stomp all over memory past the packet pointer. Ensure that the loop

for(int i=1;i<=dataLength;i++) {
	  packet[2+i] = readByte();
	}

doesn't go bast the allocated length of the packet array (32 bytes).

In theory this shouldn't be happening though, since XBee is supposed to be dealing with all the integrity of the packets. That's why you pay over $20 per radio.

Agree that corruption should not happen, but a few more suggestions, (1) Check the checksum, (2) On the sending node, check the ZigBee Transmit Status packet that the module returns after the TX Request, (3) On the receiving node, check the Packet Acknowledged bit which indicates the receiving node let the transmitting node know that the transmission was successful, (4) Use API mode with escape characters (AP=2). The following values need to be escaped: 0x7E, 0x7D, 0x11, 0x13. If these occur in the data, and they are not escaped, I'd expect issues. Actually, I'm not sure why they even have AP=1. I guess it assumes you know those values will not occur in your data. Not an assumption I'd normally be willing to make.

I use Andrew Rapp's XBee library, GitHub - andrewrapp/xbee-api: Java library for communicating with XBee radios, it works great, and takes care of a lot of stuff for you.

FYI, the ZB Series 2 modules can be had direct from Digi for $17.

Good luck, let us know what you find!

Thx for fast reply.
I tried your adrvices. I make my code even simpler. Read to serial buffer only 21 bytes, then proceed and evaluate them. And at the end buffer is flushed. The result is again right temperatures, but with four times restarting(overflow) arduino approximately every hour.

So I dont know, where I am making mistake.

int analogValue;
float c;
 
//=================== SETUP =================================
void setup() {
  Serial.begin(9600);
  delay(1000);
  Serial.print("Starting.........."); 
  Serial.println(); 
}

//==================== LOOP =================================
void loop() {
  readPacket();
}

//==================== podprogramy XBEE ======================
void readPacket() {
  if (Serial.available() == 21) {
    if (Serial.read() == 0x7E) {
	for(int i=0;i<18;i++){
          byte discard = Serial.read();
        }
                
        int analogHigh = Serial.read();
        int analogLow = Serial.read();
        analogValue = analogLow + (analogHigh * 256);
    }

    int reading = analogValue;  // pin 19 [0] is pin 20
    // convert reading to millivolts
    float v = ((float)reading /(float)0x3FF) * 1200.0;
        
    // convert to Celcius.  10mv per Celcius degree with 500mV offset at 0 celcius
    float c = (v - 500.0) / 10.0;
    
    Serial.print("Temp: ");
    Serial.print(c);

    Serial.flush();
   }
}
  if (Serial.available() == 21) {

If, for some reason, there become more that 21 bytes available, your code will never read any of them.

  if (Serial.available() >= 21) {

would work much better.

I can't see anything else wrong with your code, unless the issue PaulS identified means that the serial buffer is filling up, but even then, I can't make the leap from the UART dropping bytes to four restarts. Could it be an issue with your power? For example, if it's powered from the wall, is there anything else on the same circuit in the building that draws a lot of current & kicks in ~hourly? Heating? If it's battery powered, are you running anything else from the same source that has periodic needs?

Thanks all for replies.
I think, it can not be interference from power supply, because simple code only with Serial_printing works well hours without disturb.

  1. I tried my code only with one xbee periodic sleeping sensor - approximately one hour four times restart of base station (arduino+xbee).
    Received data:
    7E 00 12 92 00 13 A2 00 40 62 0A 68 A7 45 41 01 00 00 02 02 8A E8
    7E 00 12 92 00 13 A2 00 40 62 0A 68 3C EE 41 01 00 00 02 02 8A AA
    7E 00 12 92 00 13 A2 00 40 62 0A 68 89 3D 41 01 00 00 02 02 8A 0E
    7E 00 12 92 00 13 A2 00 40 62 0A 68 03 85 41 01 00 00 02 02 84 52

  2. Second test - only one xbee non sleeping sensor - no restarting of base station!!!
    Received data:
    7E 00 12 92 00 13 A2 00 40 62 0A 68 A6 C7 01 01 00 00 02 02 0C 5F
    7E 00 12 92 00 13 A2 00 40 62 0A 68 A6 C7 01 01 00 00 02 02 0C 5F
    7E 00 12 92 00 13 A2 00 40 62 0A 68 A6 C7 01 01 00 00 02 02 0C 5F

What is confusing is that "receive option" byte is 0x41. But xbee datasheet tells that possible for "ZIGBEE RECEIVE PACKET 0x92" is only 0x01 - packet acknowledged and 0x02 - packet was i broadcast packet. So what is my 0x41???

I can think that it might be bad setting of sleeping mode of xbee sensor.
My settings:
SM 4 - sleep mode (4=enabled cyclic sleeping)
ST 3C - time before sleep => 60ms
SP 7D0 - sleep period ( 2000 x 10 ms) => 20seconds
SN 3 - number of sleep periods => 3x
IR 32 - IO sample rate 50ms

Maybe low ST "time before sleep".

0x41 is "packet was acknowledged, from an end device"; they don't always show all the bits in a response.

The last code listing didn't show anything that could cause the code to run off uncontrolled. You're not using any buffers that could be overrun and you're simply throwing away the bytes that are not sensor data. However, your packet listings didn't come from the code you posted (there aren't any prints in the posted code) so you must have gotten them from some other device during the period you were testing.

I recommend you put in Serial.print(incoming_byte) for every character you are receiving on the arduino that is restarting and try it again. There's something that is happening that you can't see. Perhaps you could display and discard all characters until you get a 0x7e and start from there to decode the packet?

The sleep period of an end device won't cause problems on the coordinator. They might affect the end device, but restarting the coordinator's arduino shouldn't be possible. You don't have the XBee's reset pin tied to the arduino do you? Possibly without a pull up resistor? (I made that mistake once).