Go Down

Topic: why initialize XBee object before setup(), not inside? (Read 1 time) previous topic - next topic

michalg

Hello.

I am writing an Arduino library, that uses XBee library. I am using XBee Series 1 modules in API mode with Arduino Uno and Wireless Shields. In the process of library development I found out one interesting thing about initialization of XBee. All the examples I could find initialize XBee object before setup() function.

Code: [Select]

XBee xbee = XBee();
Rx16Response rx16 = Rx16Response();

void setup() {
  //code
}


If I want to initialize XBee object in setup, it turns out the whole program does not work and start to behave weirdly (either packet is not received, although from another XBee I am getting Transmit Success notification, or data received is wrong - all those weird behaviors differ, depending on what the code exactly does).

Code: [Select]

XBee xbee;
Rx16Response rx16 = Rx16Response();

void setup() {
  xbee = XBee();
  //code
}


According to my way of thinking - it should work, at least in all the other situations it did not matter if I initialized a given variable before or in setup() function.

To sum up - XBee seems not to be working correctly (sometimes does not receive packets, sometimes receives wrong data) when initialized in setup() function instead of before it. Does anyone have any suggestions why initialization of this object inside setup loop is not correct?

Below I post a code that just displays payload of the packet to Serial port and also sends it back to XBee that send the packet. You can just copy/paste it to try it out for yourselves, or try to modify Series1_Rx example from the library.

correct sketch:
Code: [Select]

#include <XBee.h>

XBee xbee = XBee();
Rx16Response rx16;

void setup() {
  // initialization of XBee object in setup creates wrong behavior
  //xbee = XBee();
  rx16 = Rx16Response();
  Serial.begin(9600);
  xbee.setSerial(Serial);

}

boolean isPacketReceived = false;
// continuously reads packets, looking for RX16 or RX64
void loop() {
  xbee.readPacket();
  if (xbee.getResponse().isAvailable()) {
    // got something
    Serial.println("Got sth!");
    Serial.print("Api id: ");
    Serial.println(xbee.getResponse().getApiId());
    if (xbee.getResponse().getApiId() == RX_16_RESPONSE) {
      // got a rx packet
      Serial.println("RX 16 response");
      xbee.getResponse().getRx16Response(rx16);

      // Display received data
      byte* packetData = rx16.getData();
      byte dataLength = rx16.getDataLength();
      Serial.println();
      Serial.print("START Length:");
      Serial.println(dataLength);
      for (int i = 0; i < dataLength; i++) {
        Serial.print(packetData[i], HEX);
        Serial.print(" - ");
      }
      Serial.println("END");

      Tx16Request tx = Tx16Request(rx16.getRemoteAddress16(), packetData, dataLength);
      xbee.send(tx);
    }
  }
}



incorrect sketch:
Code: [Select]

#include <XBee.h>

XBee xbee;
Rx16Response rx16;

void setup() {
  // initialization of XBee object in setup creates wrong behavior
  xbee = XBee();
  rx16 = Rx16Response();
  Serial.begin(9600);
  xbee.setSerial(Serial);

}

boolean isPacketReceived = false;
// continuously reads packets, looking for RX16 or RX64
void loop() {
  xbee.readPacket();
  if (xbee.getResponse().isAvailable()) {
    // got something
    Serial.println("Got sth!");
    Serial.print("Api id: ");
    Serial.println(xbee.getResponse().getApiId());
    if (xbee.getResponse().getApiId() == RX_16_RESPONSE) {
      // got a rx packet
      Serial.println("RX 16 response");
      xbee.getResponse().getRx16Response(rx16);

      // Display received data
      byte* packetData = rx16.getData();
      byte dataLength = rx16.getDataLength();
      Serial.println();
      Serial.print("START Length:");
      Serial.println(dataLength);
      for (int i = 0; i < dataLength; i++) {
        Serial.print(packetData[i], HEX);
        Serial.print(" - ");
      }
      Serial.println("END");

      Tx16Request tx = Tx16Request(rx16.getRemoteAddress16(), packetData, dataLength);
      xbee.send(tx);
    }
  }
}


PaulS

First, you are creating your xbee object incorrectly.

Code: [Select]
XBee xbee = XBee();
invokes the constructor directly, which you should never do.

Code: [Select]
XBee *pXbee = new XBee();
indirectly invokes the constructor, and new returns a pointer to the created instance. You could use this approach, to separate the declaration and initialization:
Code: [Select]
XBee *pXbee;

void setup()
{
   pXbee = new XBee();
}


Code: [Select]
XBee xbee;
also invokes the constructor, indirectly, which is the correct way to create an object.

Clearly, you can't separate this declaration and initialization into separate parts.
The art of getting good answers lies in asking good questions.

Go Up