Disable printing XBee API packet to serial monitor

Hi All,

As the subject says, let me allow myself to explain my situation. I’m using an Arduino Uno with XBee Pro S1 module with ArduinoXBee v1.1 shield and a TEMT6000 ambient light sensor.

I simply want to read the sensor data from the light sensor and transmit that value to another XBee which works fine and has no problem. I want the serial monitor to show comma separated values of every sensor reading but every time the XBee sends this data, the API packet frame (starting with 7E or ‘~’ along with the rest of the data frame) is printing as well and shows up as garbage values along with the comma separated values.

Is there anyway to disable the printing of this API packet frame? I’m using andrewrapp/xbee-arduino library. Below is the sketch.

#include <XBee.h>

//create reusable object to handle excpetion
XBee xbee = XBee();

//allocate two bytes to hold a 10-bit analog reading
uint8_t payload[] = {0, 0};

//16-bit addressing, enter address of remote XBee (coordinator)
Tx16Request tx = Tx16Request(0x1234, payload, sizeof(payload));

//reusable object used to get status of transmission
TxStatusResponse txStatus = TxStatusResponse();

int sensorData = 0;
unsigned long start = millis();

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  xbee.setSerial(Serial);
}

void loop()
{

  // put your main code here, to run repeatedly:
  if (millis() - start > 5000)
  {
    //read ambient light sensor data
    sensorData = analogRead(5);
    float lux = sensorData * 0.9765625;
    Serial.print(lux);
    Serial.print(",");

    //populate payload, convert 10-bit analog data across two bytes
    payload[0] = sensorData >> 8 & 0xff;  //MSB
    payload[1] = sensorData & 0xff; //LSB

    //send packet
    xbee.send(tx);

    if (xbee.readPacket(5000))  //after TX request, wait 5 seconds check status response
    {
      //Serial.println("Got a response!");
      if (xbee.getResponse().getApiId() == TX_STATUS_RESPONSE)
      {
        xbee.getResponse().getTxStatusResponse(txStatus);
        //Serial.println("Getting transmission status");
        if (txStatus.getStatus() == SUCCESS)
        {
          //Serial.println("Packet successfully transmitted.");
        }
      }
    }
    else if (xbee.getResponse().isError())
    {
      //Serial.println("Error sending packet.");
      //Serial.println(xbee.getResponse().getErrorCode());
    }
  }
  delay(1000);
}

If i understand you well you have the XBee ans pin 0 and 1 (Serial object) from which you are sending and receiving stuff from the remote XBee and you are connected to your computer through USB and printing stuff to your computer?

As The USB is also connected to pin 0,1 you are in a wrong situation. Besides electric challenges at pins level being with 0 and 1 being connected to 2 different equipments, whatever you send to the remote XBee is also up for grabs by the USB and thus getting you garbage on screen

You need two serial ports and the uno has only one, so you need to use software serial. Lucky for you, the shield you have makes it easy and has jumpers you can set to connect DIN to D2/13, DOUT to D2/D13 by the jumpers and from the code. So decide which pins you want to use for software serial on the arduino, declare a software serial object with those pins (import the library of course) and set the jumpers to match those pins at the bottom of the shield (the big row of 3 pins labeled D0/D13 and Din Dout on the side - today you have probably the jumpers at D0 and D1)

Then you can use the Serial object to print just the lux value to the serial monitor and keep the discussion with your XBee on the other serial line.

Makes sense?

I'm quite new to software serial, would you care to explain it in this context with some example code. I'm quite lost.

Thanks in advance.

Well first start with the ArduinoXBee v1.1 documentation. That will show you what to do with the jumpers.

Then You need to read about SoftwareSerial

then (I’ve not tried, typing this from my iPhone while on the go) from a code perspective you would do something like this for the declaration of the Software Serial port

/* The circuit:
 * RX is digital pin 10 - connect to TX of ArduinoXBee - configure jumper appropriately 
 * TX is digital pin 11 - connect to RX of ArduinoXBee - configure jumper appropriately
*/
#include <SoftwareSerial.h>

SoftwareSerial xBeeSerial(10, 11); // RX, TX

then in the setup()

void setup() {
  Serial.begin(115200); // this is pin 0 and 1 that are connected to the USB of the computer. you can write there quickly so 115200 is fine.
  while (!Serial); // wait for serial port to connect. avoids weird characters on the line

  xBeeSerial.begin(9600); // this is to discuss with the module. we set baud rate to 9600, matching the XBee config
  xbee.setSerial(xBeeSerial); // we tell the library that this is the port we are using
}

Rest of your code would be as it is.

When you want to display something to your computer you use Serial and whenever you want to discuss with the XBee you use the xBeeSerial object

The last thing you need to change is the speed used in the Serial console to 115200 as this is what I set it to in the setup(), no reason to go slow there.

let me know if that works.

Hi,

After using software serial, I’m able to remove the garbage characters from the serial monitor but now for some reason upon transmitting, I’m unable to receive anything. I can transmit normally without using software serial and it works fine but I still cannot receive anything.

The receiver code looks fine, my guess is the transmitter side that’s causing this issue.

Transmitter Code

#include <SoftwareSerial.h>
#include <XBee.h>

//create reusable object to handle excpetion
XBee xbee = XBee();

//allocate two bytes to hold a 10-bit analog reading
uint8_t payload[] = {0, 0};

//16-bit addressing, enter address of remote XBee (coordinator)
Tx16Request tx = Tx16Request(0x1234, payload, sizeof(payload));

//reusable object used to get status of transmission
TxStatusResponse txStatus = TxStatusResponse();

int sensorData = 0;
unsigned long start = millis();

SoftwareSerial xBeeSerial(10, 11);    //(RX, TX)

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  while (!Serial);

  xBeeSerial.begin(9600);
  xbee.setSerial(xBeeSerial);   //communicates with software serial port {10,11} (RX,TX)
}

void loop()
{

  // put your main code here, to run repeatedly:
  if (millis() - start > 5000)
  {
    //read ambient light sensor data
    sensorData = analogRead(5);
    float lux = sensorData * 0.9765625;
    Serial.print(lux);
    delay(100);
    Serial.print(",");
    delay(100);

    if (Serial.available())   //checks if USB serial has data
    {
      xBeeSerial.write(Serial.read());  //read from USB serial port and writes to software serial port
    }

    if (xBeeSerial.available()) //checks if software serial port has any dat
    {
      Serial.write(xBeeSerial.read());    //read from software serial port and writes to USB serial port
    }


    //populate payload, convert 10-bit analog data across two bytes
    payload[0] = sensorData >> 8 & 0xff;  //MSB
    payload[1] = sensorData & 0xff; //LSB

    //send packet
    xbee.send(tx);

    if (xbee.readPacket(5000))  //after TX request, wait 5 seconds check status response
    {
      //Serial.print("Got a response!");
      if (xbee.getResponse().getApiId() == TX_STATUS_RESPONSE)
      {
        xbee.getResponse().getTxStatusResponse(txStatus);
        //Serial.print("Getting transmission status");
        if (txStatus.getStatus() == SUCCESS)
        {
          //Serial.print("Packet successfully transmitted.");
        }
      }
    }
    else if (xbee.getResponse().isError())
    {
      //Serial.print("Error sending packet.");
      //Serial.println(xbee.getResponse().getErrorCode());
    }
  }
  delay(1000);
}

Receiver Code

#include <XBee.h>

//Create resuable object to handle exception
XBee xbee = XBee();
XBeeResponse response = XBeeResponse();
Rx16Response rx16 = Rx16Response();
uint8_t data[2] = {0, 0};
int value;
double lux;
unsigned long start = millis();

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  xbee.setSerial(Serial);
}

void loop()
{
  // put your main code here, to run repeatedly:
  xbee.readPacket();
  Serial.println("Reading...");
  if (xbee.getResponse().isAvailable())
  {
    Serial.println("Got something!");
    if (xbee.getResponse().getApiId() == RX_16_RESPONSE || xbee.getResponse().getApiId() == RX_64_RESPONSE)
    {
      Serial.println("Received packet");
      xbee.getResponse().getRx16Response(rx16);
      data[0] = rx16.getData(0);
      data[1] = rx16.getData(1);
      value = data[1] + (data[0] * 256);  //recontruct data upon receiving
      Serial.print("Reconstructed payload data : ");
      Serial.print(value);
      Serial.println();
      lux = value * 0.9765625;
      Serial.print("Illuminance : ");
      Serial.print(lux);
      Serial.print(" lux");
      Serial.println();

    }
  }
  else if (xbee.getResponse().isError())
  {
    Serial.println("Error receiving packet...");
    Serial.println(xbee.getResponse().getErrorCode());
  }
  delay(1000);
}

Am I going wrong somewhere? Could you point me in the right direction?

Thanks in advance

    if (Serial.available())   //checks if USB serial has data
    {
      xBeeSerial.write(Serial.read());  //read from USB serial port and writes to software serial port
    }

Why? What are you typing on the Serial Monitor application that the other XBee needs to know about?

    if (xBeeSerial.available()) //checks if software serial port has any dat
    {
      Serial.write(xBeeSerial.read());    //read from software serial port and writes to USB serial port
    }

Why do you read only one byte every 5 seconds?

Reading data from the serial port or from the other XBee has NOTHING to do with whether or not it is time to send another reading.

  delay(1000);

Using millis() for timing and delay() in the same sketch illustrates a high level of clueless-ness. Get rid of the delay()!

Showing us your serial output, instead of waving your arms madly, would have been better. Showing us a schematic, instead of waving your arms madly, would have been better.

Here is the following output I get from transmitter and receiver side.

Transmitter:

9.77,9.77,9.77,9.77,9.77,8.79,9.77,8.79,9.77,8.79,8.79,8.79,8.79,8.79,9.77,7.81,7.81,8.79,7.81,7.81,3.91,5.86,6.84,5.86,6.84,6.84,5.86,7.81,7.81,6.84,6.84,6.84,6.84,7.81,7.81,6.84,4.88,6.84,7.81,7.81,

Receiver:

Reading... Reading... Reading... Reading... Reading... Reading... Reading...

I have removed the comments on Serial.print("Got a response!"); and Serial.print("Getting transmission status"); for debugging. Those do not appear on the serial monitor at all.

Nothing is being transmitted and received at all. I would like to know where I'm going wrong.

I would like to know where I'm going wrong.

Start with explaining why ALL the code on the transmitter end is inside the if(millis() - start > 5000) block.

Receiving data from the XBee should be independent from sending data. Receiving data from the PC should be independent from sending data.

That if statement is used for an initial startup delay for transmission. I took this from the example provided from Andrew Rapp XBee-Arduino library.

That if statement is used for an initial startup delay for transmission. I took this from the example provided from Andrew Rapp XBee-Arduino library.

And, you don't seem interested in understanding what that statement does, or what should be done on every pass through loop() vs. what should be done on only some passes.

All I can do do, then, is to wish you luck. So, good luck.

PaulS: And, you don't seem interested in understanding what that statement does, or what should be done on every pass through loop() vs. what should be done on only some passes.

All I can do do, then, is to wish you luck. So, good luck.

Paul - double check what he does. he never updates start so when you enter the loop the code actually does nothing for the first 5 seconds and then it broadcast all the time. the delay management is because they wait up to 5 sec for the answer and then there is a 1 sec delay

That being said - until you understand that connecting both the XBee and the Arduino IDE Serial monitor to the same pins and not using Software Serial I’m not sure we can do much for you.

When you send something from the arduino on the Serial line, you don’t know who consumes it.

for example in the receiver when you do

      Serial.print("Reconstructed payload data : ");
      Serial.print(value);
      Serial.println();
      lux = value * 0.9765625;
      Serial.print("Illuminance : ");
      Serial.print(lux);
      Serial.print(" lux");
      Serial.println();

you are sending all of this to your XBee and the PC?

→ REMOVE ALL THE Serial.print that are for debug, keep only the stuff that needs to talk to the XBee on that serial line or use Software Serial.


What did you set the MY on the receiving radio to?


sraj50:
That if statement is used for an initial startup delay for transmission.

Yes, but still, proper code would be to always listen for an answer.

if (millis() - start > 5000) {
      // break down 10-bit reading into two bytes and place in payload
      sensorData = analogRead(5);
      payload[0] = sensorData >> 8 & 0xff;
      payload[1] = sensorData & 0xff;  
      xbee.send(tx);
   } // CLOSE THE IF

    // NOW wait up to 5 seconds for the status response
     if (xbee.readPacket(5000)) {
        // got a response!

        // should be a znet tx status            	
    	if (xbee.getResponse().getApiId() == TX_STATUS_RESPONSE) {
    	   xbee.getResponse().getTxStatusResponse(txStatus);
    		
    	   // get the delivery status, the fifth byte
           if (txStatus.getStatus() == SUCCESS) {
            	// success. 
           } else {
            	// the remote XBee did not receive our packet. is it powered on?
           }
        }      
    } else if (xbee.getResponse().isError()) {
      // Error reading packet.  Error code --> xbee.getResponse().getErrorCode());
    } else {
      // local XBee did not provide a timely TX Status Response.  Radio is not configured properly or connected
    }

In the receiver

    if (xbee.getResponse().getApiId() == RX_16_RESPONSE || xbee.getResponse().getApiId() == RX_64_RESPONSE)
    {
      Serial.println("Received packet");
      xbee.getResponse().getRx16Response(rx16);

so you might have got a RX_64_RESPONSE but you always go read a RX_16_RESPONSE?

if you want to support a RX_64_RESPONSE then at the begining of the code you need to define a Rx64Response rx64 = Rx64Response(); global variable and then do something like

 if (xbee.getResponse().isAvailable()) {
      // got something
      
      if (xbee.getResponse().getApiId() == RX_16_RESPONSE || xbee.getResponse().getApiId() == RX_64_RESPONSE) {
        // got a rx packet
        
        if (xbee.getResponse().getApiId() == RX_16_RESPONSE) {
                xbee.getResponse().getRx16Response(rx16);
        	option = rx16.getOption();
                data[0] = rx16.getData(0);
                data[1] = rx16.getData(1);
                value = data[1] + (data[0] * 256);  //recontruct data upon receiving
        } else {
                xbee.getResponse().getRx64Response(rx64);
        	option = rx64.getOption();
                data[0] = rx64.getData(0);
                data[1] = rx64.getData(1);
                value = data[1] + (data[0] * 256);  //recontruct data upon receiving
        }