xbee, arduino Mega, Data

Hello! After hours of looking, I am hoping someone can help me. Ultimately I want to drive a tank robot wirelessly with 2 xbee’s but I am starting simple and will settle on just reading potentiometer data from a sending xbee to the receiving xbee into an arduino mega serial port and reading it on the serial monitor. Then I hope to figure out how to use the data but first:

Problem: When I read from the XCTU terminal monitor directly from the receiving xbee which is pluged into to a sparkfun USB explorer board, I get good (I think) HEX data from the sending xbee.

7E 00 0A 83 12 34 25 00 01 02 00 01 9B 72 This repeats very very fast, so fast I need to disconnect the xbee.

However when I read the data from the Arduino Mega Serial Monitor from the program below I get this HEX data from the same setup:

7E 0A 83 12 34 01 1 9b 73 Note the single “1” and not a two number byte.

Why is the data different? It should be the same?

Material:

2 Xbee series 1

Transparent mode for both

1 Arduino Mega 2560 r3

1 logic level converter.

Sender: One pot center wire connected directly to the Xbee pin 20 or AD0, the other two pot wires one to ground the other to3.3 volts.

Reveiver: Receiving Xbee conected to the logic level converter (5 volts to 3…3 to 5) then to the Arduino Mega Serial1 port Pins 18tx, 19rx. The Mega main Serial/Power conected to my computer. The Serial1 Ports on the Mega are connected to the to the Xbee Din and DOUT accordingly.

I have a simple program

int data;

void setup()
{
Serial.begin(9600);
//Serial1.begin(9600);
}
void loop()
{
  if(Serial1.available() >0);  // make sure at least a byte is in the buffer
  
  data = Serial1.read();// read one byte from Serial1 port
  
  Serial.println(data); // print that one byte from Serial1 to the Arduino Serial 
                        // monitor screen on the computer to see the data.
  delay(20);            // delay 20 ms just because
}

Those codes look like API frames. I suggest you use the datasheet/manual to decipher the code and see if it makes sense. Either someone else is in the vicinity using Xbees aswel, interfering with your project. Or one of them is infact in API mode.

It’s definitely an api frame.

http://rubenlaguna.com/wp/2009/03/12/ex … pi-frames/

But the second string might have some byte loss. What happens when you remove the delay(20) line? I’m not that familiar with Arduino code, but 20 msec might cause it to skip a few characters. Also shouldn’t Serial1 be initialised when using it to read? So maybe remove the comment slashes to be sure?

Hello and thank you for responding:

I checked and the xbee’s are not in API mode. Really :slight_smile: I changed the delay to 5 miliseconds and took out the // in front of Serial1.begin and still with the same results. The xctu terminal window shows what appears to be a complete frame in hex bytes, yet the arduino mega does not duplicate this when I do a Serial.print to the arduino terminal window. It would appear simple but boy I just cant seem to grasp, how to get xbee data into the arduino so I can understand it and eventually use a joystick and drive my tank robot. Any ideas?

Thank you so much,

Scott

Frames that begin with 0x7E are API frames.

What is your design intent? To use API mode? To use transparent serial port mode? To use virtual wire mode?

sounds like you haven’t read the user manual, a.k.a. OEM guide. Or any of the hobby XBee tutorials.

Hi Stevech,

Thanks for you input. My design intent is to read a joystick (x and y values), send this data through the sending xbee, and the receiving xbee will then send this to the arduino mega. I hoped to then take the x and y values in the mega and with the use of a motor controller, drive a tank bot (brutusbot from solarbotics). I have read most of the Hands-on-Xbee lab manuel by Jon Titus (the last 3 chapters were way above my head). I think the xbee, even in transparent mode, sends api packets as that seems to be the data coming from the xctu terminal emulator. Or the xctu converts the binary data coming from the xbee into api so it can be parsed out. Thats my guess. In fact I’ve got the book open now trying to understand it. If I can figure out how to read the data I will be farther along in writing my program for my first robot.

Thank you

:slight_smile:

Scott

I’ve found it easiest to just map the joystick x/y to a logical array. The best array size varies from joystick to joystick and how precise you need the control to be. The pots never seem to match between x and y and they aren’t smooth from 0 to 1023 and 500 is not always center either.

To map the array I just figure out how many zones I want across the left/right extremes and up/down extremes and map my x and y values to that. Then, offset one set of values by 1 significant digit (multiple by 10) and add a leading 1 before all values (because a leading 0 for the x or y axis will get dropped. This results in a 3 digit int for all the possible values of the joystick. Send this value and use a switch statement on the other side to decode into motor commands.

Here’s an example of what I used for a 2-wheel vehicle:

  x_AxisSensorValue = analogRead(x_AxisSensorPin);
  y_AxisSensorValue = analogRead(y_AxisSensorPin);
  x_AxisSensorValue = map(x_AxisSensorValue, 0, 1000, 0, 4);// map x and y values to a 5x4 logical array of possible values.
  y_AxisSensorValue = map(y_AxisSensorValue, 0, 1000, 0, 3);
  
  // Used with switch statement. Brings x-axis value to the tens place and y-axis to ones place
  joystickPosition = (x_AxisSensorValue * 10) + y_AxisSensorValue + 100;

Using the above example, putting the joystick at the bottom left would send 100 and top right would be 143. Drawing out the array on paper and seeing what cells you want doing what helps with developing the switch statement. This would work with up to a 10 x 10 logical array using the same 3 digit int to send commands.

Here’s the receiving side switch statement:

...
if(newData){
    switch(motorCommand){
      case 111:
      case 112:
      case 121:  // ALL STOP A=0 B=0
      case 122:
      case 131:
      case 132:
        motorController(0,0,0,0);
        break;
      case 123:  // FORWARD A+ B+
        motorController(1,255,1,255);
        break;
      case 120:  // REVERSE A- B-
        motorController(0,255,0,255); 
        break;
      case 101:  // LEFT A+ B-
      case 102:
        motorController(1,255,0,255);
        break;
      case 103:  // FORWARD AND LEFT A+ B/+
      case 113:
        motorController(1,255,1,127);
        break;
...

jedihonor1:
Hi Stevech,

Thanks for you input. My design intent is to read a joystick (x and y values), send this data through the sending xbee, and the receiving xbee will then send this to the arduino mega. I hoped to then take the x and y values in the mega and with the use of a motor controller, drive a tank bot (brutusbot from solarbotics). I have read most of the Hands-on-Xbee lab manuel by Jon Titus (the last 3 chapters were way above my head). I think the xbee, even in transparent mode, sends api packets as that seems to be the data coming from the xctu terminal emulator. Or the xctu converts the binary data coming from the xbee into api so it can be parsed out. Thats my guess. In fact I’ve got the book open now trying to understand it. If I can figure out how to read the data I will be farther along in writing my program for my first robot.

Thank you

:slight_smile:

Scott

Is your plan to connect the Joystick's analog X and Y voltages to the XBee A/D input pins, then have the XBee sample these pins every x amount of time then send them to a mating XBee?

If so, you want to use the virtual wire configuation of the Xbee. You have to config the XBee to setup the I/O pins, the A/D samping rate, and so on.

This presumes the XBee connects to the Joystick and there is no need for a microprocessor at that end of the link.

jedihonor1:
Hello and thank you for responding:

I checked and the xbee’s are not in API mode. Really :slight_smile: I changed the delay to 5 miliseconds and took out the // in front of Serial1.begin and still with the same results.

I digged into the Arduino documentation on http://arduino.cc/en/Reference/Serial some more. I suspect you don’t need the delay statement at all. With your code, the first byte in the buffer is read and sent on de Serial line. But at 9600 baud one character takes about 1 milisecond. If you wait 5 or 20 miliseconds for no reason, sooner or later the receive buffer of Serial 1 is going to fill up because it is only read once in 5 or 20. And you’ll start to loose data, especially if the receiver XBee outputs a continuous stream of those frames.

Also I think in your loop you are not making appropriate use of curly brackets { } to contain the code that needs to be executed when there is a byte available in the Serial1 receive buffer. Compare your code to the Mega section in this link:

http://arduino.cc/en/Serial/Available

Your code ```
if(Serial1.available() >0); // make sure at least a byte is in the buffer

All it does here is check if there are bytes left in the buffer. But after the check it hits that semi-colon and does nothing further with that knowledge. After this you just blindly read a character, and send it into the Serial line, and wait for nothing (imho) and loop. The "then *{something}* or else *{something else}*" is missing.

<QUOTE>

> The xctu terminal window shows what appears to be a complete frame in hex bytes, yet the arduino mega does not duplicate this when I do a Serial.print to the arduino terminal window.

</QUOTE>This would suggest there is something wrong in that serialmonitoring-code. And not necessarily in the hardware. 

But XCTU doesn't automatically generate API frames in the terminal based on an incoming data-stream from the Xbee. One of the Xbees must be sending API fames. Please use Read button on the Configuration tab of XCTU to collect the XBee registers. Then with the Profile Save function save your register settings of both Xbees. And post the contents seperately in [ code ] [/ code] tags, please.

Hi Valen,

Thank you for responding. I changed the code as you suggested and removed the semicolon and put in brackets see code:

int data;

void setup()
{
Serial.begin(9600);
Serial1.begin(9600);
}
void loop()
{
  if(Serial1.available() >0)  // make sure at least a byte is in the buffer
  {
    data = Serial1.read();// read one byte from Serial1 port
  
    Serial.println(data,HEX); // print that one byte from Serial1 to the Arduino Serial 
                        // monitor screen on the computer to see the data.
    delay(2);     // delay 2 ms just because
}
}

I also made a profile of both xbees. One connected to the Mega, the other connected to the computer. However I cannot open this profile on my computer as it says not compatible and I cannot select and copy from XCTU modum config. I have Windows Vista 64 bit. XCTU struggles with this setup sometimes. So I will write the basic configuration and I have changed nothing else: Do you know of another way to copy the configuration profile?

Receiver:

DL: 1234

MY: 5678

NI: RCVR

IT: 1

IR: 0

P0: 1

AP: 0 API Enable

I/O line passing IA: FFFF

Transmitter:

DL: 5678

MY: 1234

NI: XMTR

D0: 2 ADC

IR: 14

IT: 1

P0: 1

AP: 0 API Enable

I/O line passing IA: FFFF

Both are in Transparent mode, yet on the XCTU terminal, when I choose show HEX, I get the API packet. I am thinking there has gotta be a way to have the arduino on the receiving side, and only the xbee and pot on the send side. I just cant figure a way to get at the data. I am sure the xbees are working fine together.

Thank you so much for your help.

Scott

The profile-files can be opened with any simple text editor, like Notepad. In the File/Open-menu you just have to tell it to show all files when opening something, and not filter only .txt files.

When double clicking on the profile file, and Vista says it cannot do anything with it, it should also provide an option to choose a program to open it with. There choose Notepad.

What is the IU register set to on both XBees? Because that determines if an API packet is sent out of UART when I/O data is received. And it doesn’t care about transparent mode/AP register

Please clarify again. Is your problem that you are getting the mysterious API frames?. Or that there is a difference in them between the direct connection and through the Atmega monitoring program.

Save the XBee profile as Valen instructed. You would then be able to open this file in an editor to copy/paste.

Setting a longer sample period (on the TX XBee) may be helpful. Current is 0x14 = 20ms (50Hz) which is the Minimum recommended period. For some thing like a joy stick between 10 & 30Hz would work. This will help on the Mega receive side.

As to to send out an API frame, this seems weird. Are you sure you have XBee Series 1 modules?

Read out the Firmware version and post it here to verify which module and protocol you are running.

Just read this in the Doc:

I/O data is sent out the UART using an API frame. All other data can be sent and received using

Transparent Operation [refer to p11] or API framing if API mode is enabled (AP > 0).

API Operations support two RX (Receive) frame identifiers for I/O data (set 16-bit address to

0xFFFE and the module will do 64-bit addressing):

• 0x82 for RX (Receive) Packet: 64-bit address I/O

• 0x83 for RX (Receive) Packet: 16-bit address I/O

So for sending IO and ADC data from one XBee to another this data is output from the receiving XBee’s UART as an API Frame. Frame type 0x83 is a Received Data frame with 16bit address.

Edited an error per Valen’s suggestion.

Thanks Valen

waltr:

Current is 0x14 = 20ms (50Hz) which is the Minimum recommended period.

Correct that for you. :wink:

Hi Valen,

I have made these changes. Increased the sample rate IR from 20ms to 50ms which brings the sample rate down from 50HZ to 20HZ.

Excellent catch in that the IU register is set to 1 on both xbees so even if the AP (API = 0) it still sends out API packets if I read it correctly. But that still does not explain why there is a difference in readings when there is a direction connection between the receiving xbee and and XCTU terminal (Xbee not connected to the Mega), and when the xbee is connected to the Mega and the data is printed in the Mega’s serial monitor? It should be the same?

Please clarify again. Is your problem that you are getting the mysterious API frames?. Or that there is a difference in them between the direct connection and through the Atmega monitoring program.

Yes, there is a difference in API bytes between a direct connection (monitoring the sending xbee directly with the recieving xbee and XCTU terminal, and when the receiving xbee is connected to the Mega and the data is read on the Mega's terminal monitor.

Thank you for showing me how to print out the xbee profile:

Receiving XBEE RCVR:

xb24_15_4_10ec.mxi
FE
0
231
10EC
0
[A]CH=C
[A]ID=3332
[A]DH=0
[A]DL=1234
[A]MY=5678
[A]MM=0
[A]RR=0
[A]RN=0
[A]NT=19
[A]NO=0
[A]CE=0
[A]SC=1FFE
[A]SD=4
[A]A1=0
[A]A2=0
[A]EE=0
[A]NI=RCVR
[A]PL=4
[A]CA=2C
[A]SM=0
[A]ST=1388
[A]SP=0
[A]DP=3E8
[A]SO=0
[A]BD=3
[A]NB=0
[A]RO=3
[A]AP=0
[A]D8=0
[A]D7=1
[A]D6=0
[A]D5=1
[A]D4=0
[A]D3=0
[A]D2=0
[A]D1=0
[A]D0=0
[A]PR=FF
[A]IU=1
[A]IT=1
[A]IC=0
[A]IR=0
[A]P0=1
[A]P1=0
[A]PT=FF
[A]RP=28
[A]IA=FFFF
[A]T0=FF
[A]T1=FF
[A]T2=FF
[A]T3=FF
[A]T4=FF
[A]T5=FF
[A]T6=FF
[A]T7=FF
[A]DD=10000
[A]CT=64
[A]GT=3E8
[A]CC=2B

Transmitting Xbee XMTR

xb24_15_4_10ed.mxi
FE
0
231
10ED
0
[A]CH=C
[A]ID=3332
[A]DH=0
[A]DL=5678
[A]MY=1234
[A]MM=0
[A]RR=0
[A]RN=0
[A]NT=19
[A]NO=0
[A]CE=0
[A]SC=1FFE
[A]SD=4
[A]A1=0
[A]A2=0
[A]EE=0
[A]NI=XMTR
[A]PL=4
[A]CA=2C
[A]SM=0
[A]ST=1388
[A]SP=0
[A]DP=3E8
[A]SO=0
[A]BD=3
[A]NB=0
[A]RO=3
[A]AP=0
[A]D8=0
[A]D7=1
[A]D6=0
[A]D5=1
[A]D4=0
[A]D3=0
[A]D2=0
[A]D1=0
[A]D0=2
[A]PR=FF
[A]IU=1
[A]IT=1
[A]IC=0
[A]IR=32
[A]P0=1
[A]P1=0
[A]PT=FF
[A]RP=28
[A]IA=FFFF
[A]T0=FF
[A]T1=FF
[A]T2=FF
[A]T3=FF
[A]T4=FF
[A]T5=FF
[A]T6=FF
[A]T7=FF
[A]DD=10000
[A]CT=64
[A]GT=3E8
[A]CC=2B

and my Arduino Mega code. Receiving xbee data on Serial1 and printing it to Serial so I can see the data.

int data;

void setup()
{
Serial.begin(9600);
Serial1.begin(9600);
}
void loop()
{
  if(Serial1.available() >0)  // make sure at least a byte is in the buffer
  {
    data = Serial1.read();// read one byte from Serial1 port
  
    Serial.println(data,HEX); // print that one byte from Serial1 to the Arduino Serial 
                        // monitor screen on the computer to see the data.
    delay(2);     // delay 2 ms just because
}
}

Again thank you for all your help. I am learning a lot!

Scott

After some tinkering I just discovered that when reading the Mega Serial monitor for xbee recieve and comparing this with the direct xbee recieve on the xctu monitor, the Mega Serial Monitor leaves off the leading zero of the API packet. I also changed the arduino code from Serial.available > 0 to Serial.available > 10 just to be sure there are bytes in the buffer. Any idea why the Mega’s terminal leaves off the leading 0?

Mega Serial monitor xbee xctu monitor

7E 7E

0 00

A 0A

83 83

12 12

34 34

2F 2D close enough

0 00

1 01

2 02

0 00

2 02

99 9A close enough

69 6A close enough

Thank you

Scott

I figured it out I think. Why there is a difference. On page 171 of Jon Titus’ book The Hands-On Xbee Lab Manual he states:

“The Arduino Uno module does not include a command that formats hex values with leading zeros. So an if statement (in his program) checks for hex values from 0x00 to 0x0F and gives then a 0 prefix in the Arduino Serial Monitor window. Thus you will see results such as AB 00 12 A2 00 rather than AB 0 13 A2 0.”

Excellent book!!! Whew took two days and many hours and help from you to get my head around this.

thank you,

Scott

Instead of using Serial.println you might consider using Serial.write, as that sends the byte to the other Serial port without changing the representation/modifying it. Then in XCTU you will probably receive funny looking characters instead of hex values. But that should be normal. You can make XCTU show the hex value of the received byte. (and take care of the leading zero correctly) Currently with Serial.Println your monitoring program is sending 4 bytes for 1 received (2 for the hex value, and 2 for carriage return and linefeed), and leaving out the leading zero. Also causing something of a bottleneck, aside from the delay routine.

Ok, looks like you are making good progress in understanding this.

Keep us posted.