Trouble parsing serial input from XBee

Hi -

I have a slave Xbee sending data to a master Xbee. The master is connected to an arduino. The arduino is being run through the Arduino IDE.

I can see the exact same test data I am sending over when I look at the XCTU (xbee programming interface) however when I connect the DOUT pint from the XBee to my serial input (RX) pin for the arduino, I see numbers that do not make any sense.

My Arduino’s code is this:

// Num of bytes we are going to read each time (two bytes for each axis)
#define TO_READ (6)

// 6 bytes buffer for saving data read from the device
byte buff[TO_READ];

// String buffer to transform data before sending it to the serial port
char str[512];

// Initialize coordinate variables
int x, y, z;

// Serial pins
int serialRx = 4;
int serialTx = 5;
SoftwareSerial serialComm(serialRx, serialTx);

// Debug
#define DEBUG 0

void setup() {  
  // Open Serial port connection
  Serial.begin(9600);
  
  // Enable interrupt from accelerometer
  attachInterrupt(1, singletap_int, RISING);
 
  // Start serialComm at 9600
  serialComm.begin(9600);
  Serial.println("Setup complete.");
}

// Main loop
void loop() {

  for(int j=0; j<6; j++) {
    // Receive a byte 
    buff[j] = serialComm.read();
  }
    
  // Parse buffer and store coordinate values
  x = (((int)buff[1]) << 8) | buff[0];   
  y = (((int)buff[3]) << 8) | buff[2];
  z = (((int)buff[5]) << 8) | buff[4];
  sprintf(str, "%d %d %d\n", x, y, z);                                 
  Serial.println(str);

  // Set refresh rate
  delay(1000);
}

I am sending a string such as: 26 150 75 from the slave XBee, and I see that exact string in the XCTU terminal, so that tells me the data is getting to the Master Xbee/Arduino. I am simply not parsing it correctly (at least that is my working hypothesis).

Any advice is greatly appreciated so I don’t pull my last few hairs out.

Hi.

You forgot to tell what exactly you are receiving and if that can be repeated. Two things come to mind reading what you described: You might be connecting with an incorrect baudrate (unlikely if you are able to connect in another way), or your signals are inverted. I have read on this forum that it would be possible to communicate using inverted data, but you'd have to dig for that.

Signals can be inverted by using a transistor per channel.

  for(int j=0; j<6; j++) {
    // Receive a byte 
    buff[j] = serialComm.read();
  }

This code is reading the serial port without any idea whether there is data available. It will cycle through the FOR far faster than data can arrive.

One solution might be to preface it with if (serialComm.available >= 6) {

A better solution would probably be to read the bytes one at a time rather than in a FOR loop. The Arduino code in this demo will give the idea.

…R

Hi I am also getting started with arduino but have extensive experience with microcontrollers (8051s, STM32s, LPC2xxx,...) Robin2 is right. This is not a very good way to read data. Just to confirm, the data that you are sending is composed of ASCII characters (for the digits of the numbers) and are separated by spaces? Also, the number of digits varies from message to message? If yes, then: 1. you should not need to convert what you are getting to numbers and then back to ASCII string (also, the way you are merging bytes, you will end up with weird characters). As a test, just send every byte that you receive on the other serial port without any changes.

yapatel: I am sending a string such as: 26 150 75 from the slave XBee, and I see that exact string in the XCTU terminal, so that tells me the data is getting to the Master Xbee/Arduino. I am simply not parsing it correctly (at least that is my working hypothesis).

If I assume that the numbers in your example string (26, 150, 75 ) originate from 16 bit variables (you are trying to merge two bytes into one number), then while the original data had 2 bytes per number, the string has 2 bytes for the first and third number but 3 bytes for the second number. If this is the case: a. the data being sent has variable length and I would recommend that you either: use a byte count to let the receiver know how many bytes are in a message (e.g. "10 26 150 75") OR use special characters to indicate the start and end of the message (e.g. "$26,150,75;") b. convert them back to number properly... (look at http://arduino.cc/en/Tutorial/StringToIntExample for some ideas)

Hope this helps