Pages: [1]   Go Down
Author Topic: How to get variable length data from Xbee packet  (Read 1098 times)
0 Members and 1 Guest are viewing this topic.
Netherlands
Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi All,

I searched the (read only) forums, but did not find an answer, I hope someone can point me in the right direction.

For a project I have setup 2 Xbee modules in API mode, each on a different Arduino board. One sends sensor data to the other, which works fine. I am using the Xbee-Api library (found here: http://code.google.com/p/xbee-arduino/) from user Rappa (http://rapplogic.blogspot.com/)

However, I have trouble extracting the data (sensor values) from the received packet on the receiving Xbee. I only have a ugly method to get the data out, which is this (lines marked with -->):

Code:
    xbee.readPacket();
    
    if (xbee.getResponse().isAvailable()) {
      // got something
      //Serial.println("[Xbee] Received something on Xbee link");
      if (xbee.getResponse().getApiId() == ZB_RX_RESPONSE) {
        // got a zb rx packet
        //Serial.println("[Xbee] Got a zb rx packet");
        // now fill our zb rx class
        xbee.getResponse().getZBRxResponse(rx);
            
        if (rx.getOption() == ZB_PACKET_ACKNOWLEDGED) {
            // the sender got an ACK
            flashLed(RFLink, 3, 500);
        } else {
            // we got it (obviously) but sender didn't get an ACK
            flashLed(ERRLED, 2, 20);
        }

        uint8_t* rxData = rx.getData();

-->        Serial.println("Received: [" + packetMessage + "]");
-->        Serial.println("<START DATA>");
-->        String dataString = "";
-->        for (int i = 0; i < 35; i++) {

-->          dataString +=  rx.getData(i);
-->          Serial.print(rx.getData(i), BYTE);
-->        }

-->        Serial.println("<END DATA>");
        .
        .
        .
        

That does get me a string of 35 characters, however this seems to be the maximum I can send succesfully, but the messages are not always that long.

So, I tried this:
Code:
    xbee.readPacket();
    
    if (xbee.getResponse().isAvailable()) {
      // got something
      //Serial.println("[Xbee] Received something on Xbee link");
      if (xbee.getResponse().getApiId() == ZB_RX_RESPONSE) {
        // got a zb rx packet
        //Serial.println("[Xbee] Got a zb rx packet");
        // now fill our zb rx class
        xbee.getResponse().getZBRxResponse(rx);
            
        if (rx.getOption() == ZB_PACKET_ACKNOWLEDGED) {
            // the sender got an ACK
            flashLed(RFLink, 3, 500);
        } else {
            // we got it (obviously) but sender didn't get an ACK
            flashLed(ERRLED, 2, 20);
        }

        uint8_t* rxData = rx.getData();
-->        String packetMessage = dataToString(rx.getData(), rx.getDataOffset() + 1, rx.getDataLength() - 1);
        .
        .
        .
       

and added the dataToString function to the sketch:
Code:
String dataToString(uint8_t* msg, int offset, int length) {
 
  uint8_t i;
  String dataAsString = "";
  
  for (i = offset; i<offset + length; i++) {
    dataAsString +=  (byte)msg[i];
  }
}

It all compiles and runs, but leaves me with an empty string returned. When I Serial.print the two integers (rx.getDataOffset() + 1 and rx.getDataLength() - 1), the values are null. Nothing is shown, explicitly casting the values to (int) did not work either.

I took example code from the Droplet project from Rappa's website (here: http://rapplogic.blogspot.com/2009/08/droplet.html).

I must be missing something here, and I guess I am messing with the pointer or something, but I can't figure out what's wrong?

Does anybody see what I am missing maybe?
« Last Edit: March 11, 2011, 05:47:56 am by aetjansen » Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 548
Posts: 46004
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

When you declare a function that returns a value, you need to include a return statement to actually return a value.

Why are you adding one to the offset defined in the packet when calling your function to extract the data?

rxData is defined as a pointer to the data. Why do you need to create another function to make a copy of the data? Why can't you just access the data directly?
Logged

Netherlands
Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi PaulS,

Thanks for the reply. The reason for using that function was because I found it in example code from the original author and was trying to see how that would work.

In reality, the data I receive is of variable length, and I want to pass it onto a parser which determines the type of message that was received, from which node and based on that, chooses how to handle it further...

So, there is indeed no need to add it to the function like I did here, but I was hoping to get a clue why my train of thought was incorrect...
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 80
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You should always use rx.getDataLength() when iterating through the packet.  It will always return the size of the payload.  The offset + 1 is from the droplet code and is used to skip the status byte.  I routinely send packets of up to 80 bytes so shouldn't be a size issue.
Logged

Pages: [1]   Go Up
Jump to: