Pages: [1]   Go Down
Author Topic: XBee 2.5 API Packet Parsing Problem  (Read 1074 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,

I was wondering if anyone could give me some advice, I am having real problems doing what I think is a simple operation:

I am trying to parse API I/O sample packets from a XBee 2.5 (with Router/End Device Firmware 1347) with an accelerometer attached. The packets are being sent every 100ms to an Arduino FIO, with another XBee 2.5(also with with Router/End Device Firmware 1347). At the moment the code should just take the 6 bytes of sensor data and then send them to the Coordinator in a new packet. But I have tried using Andrew Rapp's XBee library to parse the data and it would not work properly: it parses the first two sensor readings but not the third, and intermittently throws up errors with no error code. So I have had somewhat more success using the example from Nootropic Design (http://nootropicdesign.com/projectlab/2009/11/01/wireless-temperature-sensor/) but this does parse the end of the packet properly (example below).

I am debugging using NewSoftSerial to see what the Arduino is parsing. To ensure accuracy, I have also parsed the data in Supercollider, with exactly the same logic, (as well as double checking in XCTU) so I know that the packets should look like this:

7E 00 16 92 00 13 A2 00 40 61 30 E0 3B 07 01 01 00 00 0D 02 57 01 F8 01 F2 71

But what I am getting printed in the NewSoftSerial port is this:

7E 00 16 92 00 13 A2 00 40 61 30 E0 3B 07 01 01 00 00 0D 02 57 01 FF FF FF FF

I have tried it with
Code:
if(Serial.available > 0)
as well, which seemed to incorrectly read the start of the packets.

Additionally, the packets are not transmitted smoothly from the Arduino FIO to the coordinator which also making me very confused!

If anyone has any feedback on why this is not working properly I would be very very grateful! I can't seem to find anything on the forums with a similar problem...

Please find the code below, your comments would be greatly appreciated!

Cheers

Dave

Code:
/**
 * Copyright (c) 2009 Andrew Rapp. All rights reserved.
 *
 * This file is part of XBee-Arduino.
 *
 * XBee-Arduino is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * XBee-Arduino is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with XBee-Arduino.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <XBee.h>
#include <NewSoftSerial.h>



// create the XBee object
XBee xbee = XBee();
uint8_t packet[30];
uint8_t payload[6];

// SH + SL Address of receiving XBee
XBeeAddress64 addr64 = XBeeAddress64(0x00000000, 0x00000000);
ZBTxRequest zbTx = ZBTxRequest(addr64, payload, sizeof(payload));
ZBTxStatusResponse txStatus = ZBTxStatusResponse();

int pin5 = 0;

int statusLed = 13;
int errorLed = 13;

long previousMillis = 0;
long interval = 50;
NewSoftSerial nss(3, 4);


void setup() {
  pinMode(statusLed, OUTPUT);
  pinMode(errorLed, OUTPUT);
 
  xbee.begin(9600);
  nss.begin(9600);
}



void loop()
{   
   
    unsigned long currentMillis = millis();
  //if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;   
    readPacket();
    xbee.send(zbTx);
 //}
   

  for(int i = 0; i < 30; i++){
    nss.print(packet[i],HEX);
    nss.print(" ");
   }
   nss.println();
   
}


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

      for(int i=1;i<=dataLength;i++) {
        packet[2+i] = Serial.read();
      }
      int apiID = packet[3];
     
     
      packet[3+dataLength] = Serial.read();//checksum
     
     if (apiID == 0x92) {
     
          for(int i = 0; i < 6; i++) {
            payload[i] = packet[i+19];
          }
         
      }
    }
  }
}
Logged

France
Offline Offline
Sr. Member
****
Karma: 2
Posts: 380
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I would not proceed like you do...

Because in that code :

  while (Serial.available()){
    int b = Serial.read();
    if (b == 0x7E) {
      packet[0] = b;
      packet[1] = Serial.read();
      packet[2] = Serial.read();
      int dataLength = (packet[1] << smiley-cool | packet[2];

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

you try to realize Serial.read() when you get the 0x7E data. But are you shure that always datas are ready ?

I prefere to store in an array all the datas until I receive another 0x7E character, so from It s easy to decode the datas already stored.

Another trick, Serial.read() return a byte not an int...

Try in that way.



Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey Grag38,

Thanks very much for your response but I'm not sure I understand what you mean...

The data is being stored in a uint8_t byte array as you can see from the code (called packet[30]), which is coming directly from Serial.read();

Perhaps you could elaborate slightly more on what you mean?

Many thanks

Dave
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 551
Posts: 46266
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In your code, you have this:
Code:
    while (Serial.available()){
    int b = Serial.read();
    if (b == 0x7E) {
      packet[0] = b;
      packet[1] = Serial.read();
      packet[2] = Serial.read();
      int dataLength = (packet[1] << 8) | packet[2];
Suppose that the Serial.available() call reports that there is one byte to read. The while() condition is true, so you read all three bytes, two of which haven't been received yet.

You know that the 0x7E represents the start of a packet, and that a packet contains so many bytes. So, once the start of packet marker has been received, it is not unreasonable to block waiting for the remaining n bytes.

Quote
Another trick, Serial.read() return a byte not an int...
Wrong. Serial.read() extracts a byte from the serial buffer, and returns it, but it does so in the least significant byte of an int. It does this so that it can return a "Hey, there was nothing to read" response when there was nothing to read. If Serial.read() returned a byte, every value in that byte would be valid, so there would be no way to return a "no data available" response. So, Serial.read() returns an int, which can contain every valid value and some non-valid values (the only one that is actually returned is -1 which means that there was nothing to read).
Logged

Pages: [1]   Go Up
Jump to: