2

I have very weird problem with a library I am creating. The library will be used to communicate between Arduino modules using XBee Series 1 modules. Library is very simple wrapper library around Arduino XBee library.

I have one function that reads received packet and sends it back. At the moment it is implemented as a simple "echo" service - the function just displays the data received and sends it back to per-defined address.

At the moment I have three versions of this function, out of which one is not working.

  1. A function taking no arguments: void processPacket()
  2. A function taking structure as a value as an argument: void processPacket(valuesStruct valuesStructData) - THIS VERSION OF THE FUNCTION IS NOT WORKING!
  3. A function taking pointer to the structure as an argument: void processPacket(valuesStruct* valuesStructData)

At this moment I noticed strange behavior in the 2nd version of the function. I do nothing with the passed argument - the content of all three functions is the same. In 2nd case the function reads wrong values from received XBee packet. In the 1st and 3rd case the function performs correctly.

Code:

ExampleLib.h

#ifndef ExampleLib_h
#define ExampleLib_h

#include "Arduino.h"
#include <XBee.h>

#define ADDRESS_BROADCAST 0xffff
#define ADDRESS_PC 0x3333

typedef struct
  {
    int valA;
    int valB;
    int valC;
  } valuesStruct;

class ExampleLib
{
public:
    ExampleLib();
    void setSerial(Stream &serial);
    boolean tryReceivePacket();
    void processPacket();
    // THIS FUNCTION IS NOT WORKING!
    void processPacket(valuesStruct valuesStructData);
    void processPacket(valuesStruct* valuesStructData);
private:
    XBee xbee;
    Rx16Response rx16;
};

#endif

ExampleLib.cpp

The value read in line byte* packetData = rx16.getData(); is wrong when we trigger processPacket(valuesStruct valuesStructData) function. In other cases the behavior is correct.

#include "Arduino.h"
#include <XBee.h>
#include "ExampleLib.h"

ExampleLib::ExampleLib()
{
    xbee = XBee();
    rx16 = Rx16Response();
}

void ExampleLib::setSerial(Stream &serial)
{
    xbee.setSerial(serial);
}

boolean ExampleLib::tryReceivePacket()
{
    xbee.readPacket();

  if (xbee.getResponse().isAvailable()) {
    // got something

    if (xbee.getResponse().getApiId() == RX_16_RESPONSE) {
      // got a rx packet

      xbee.getResponse().getRx16Response(rx16);
      return true;
    } 
    else {
      return false;
    }
  } 
  else if (xbee.getResponse().isError()) {
    //nss.print("Error reading packet.  Error code: ");  
    //nss.println(xbee.getResponse().getErrorCode());
    // or flash error led
    return false;
  } 

  return false;
}
void ExampleLib::processPacket()
{
  byte* packetData = rx16.getData();
  byte dataLength = rx16.getDataLength();
  Serial.print("START L:");
  Serial.println(dataLength);
  for (int i = 0; i < dataLength; i++) { 
    Serial.print(packetData[i]);
    Serial.print(" - "); 
  }
  Serial.println("END");

  //16-bit addressing: Enter address of remote XBee, typically the coordinator
  Tx16Request tx = Tx16Request(ADDRESS_PC, packetData, sizeof(packetData));
  xbee.send(tx);
}

void ExampleLib::processPacket(valuesStruct valuesStructData)
{
  processPacket();
}

void ExampleLib::processPacket(valuesStruct* valuesStructData)
{
  processPacket();
}

Arduino sketch

#include <XBee.h>
#include <ExampleLib.h>

ExampleLib exampleLibObj = ExampleLib();

void setup()
{
  Serial.begin(9600);
  exampleLibObj.setSerial(Serial);
}

void loop()
{

  boolean isPacketReceived = exampleLibObj.tryReceivePacket();

  if (isPacketReceived) {
    // leave only one section, the rest should be commented

    //Section 1: working
    exampleLibObj.processPacket();

    //Section 2: not working
//    valuesStruct test;
//    test.valA = 0;
//    test.valB = 0;
//    test.valC = 0;
//    exampleLibObj.processPacket(test);

    //Section 3: working
//  valuesStruct* test;
//  test->valA = 0;
//  test->valB = 0;
//  test->valC = 0;
//  exampleLibObj.processPacket(test);
  }
}

I am really puzzled why in this one case function is performing differently. Looking forward to any suggestions to that issue.

Thanks!

2
  • This does seem to be very puzzling.
    – m3z
    Commented Apr 29, 2014 at 19:44
  • I've read through your code 3 times now and all I've managed to glean is that your question (and your code's behaviour) seems to be beyond me
    – m3z
    Commented Apr 29, 2014 at 19:56

1 Answer 1

2

If the second isn't working, it may be best to use the other 2. Especially on the Arduino with limited RAM, you will not have enough if you pass a full struct to a function. Passing a pointer is less memory-intensive, and if it works, use it!

2
  • Thanks! I have actually made some tests using MemoryFree library and in that case memory is not an issue at all. What actually happens is, for some reason, copied version of the object, that we use in a function is written in the area of a memory, where XBee packet resides. In later tests the same happened to me with option 3 and passing a pointer - a copy of a pointer would corrupt the packet structure. Further investigation led me to the way of initializing XBee object to be the possible culprit.
    – MichalG
    Commented May 8, 2014 at 14:36
  • Following those instructions - link - I managed to fix the problem in both cases, but I still don't know why the problem occurred in the first place.
    – MichalG
    Commented May 8, 2014 at 14:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.