Society of Robots - Robot Forum

Electronics => Electronics => Topic started by: webgeek on January 19, 2010, 07:14:23 PM

Title: Axon II and XBee Trouble
Post by: webgeek on January 19, 2010, 07:14:23 PM
Ok, so I've got a pair of series 1 XBees and I'm trying to get them working with the Axon II. It's been a rather irritating experience all around thus far. I'm running into a variety of problems and I don't know if they are Axon, XBee, or breakout board related. So, based on the problems I've heard from others using the SparkFun breakout board, I went ahead and am using the USB Explorer on the computer side and the SelmaWare AppBee SIP (http://www.selmaware.com/appbee/index.htm) board on the Axon side. I've got the Vin on the AppBee going to +5v regulated and the Vss(?) going to the ground pin on UART0. The Tx and Rx on the AppBee are tied to the appropriate T and R on the Axon.

The channel, baud and Pan ID are identical on both Xbees. The MY value on the computer-side XBee is "22" and it's DL (destination low) is "33". Likewise the Axon's XBee has a DL of 22 and a MY of 33. I'm using the following code on the Axon:

Code: [Select]
#include "sys/axon2.h"
#include "rprintf.h"

void appInitHardware(void) {
uartInit(UART1, (BAUD_RATE)115200);
uartInit(UART0, (BAUD_RATE)38400);

rprintfInit(&uart1SendByte);

rprintf("\nAxon II Initiated.\n");

}

TICK_COUNT appInitSoftware(TICK_COUNT loopStart){

return 0;
}


// This is the main loop
TICK_COUNT appControl(LOOP_COUNT loopCount, TICK_COUNT loopStart) {

while(!uartReceiveBufferIsEmpty(UART0)) {
int byte = uartGetByte(UART0);
rprintf("%d", byte);
uartSendByte(UART0, byte);
}

return 10;
}

and I go into the X-CTU application and tell it to run a "range test". It starts firing off "0123456789:;<=>?@ABCDEFGHIJKLMNO" messages once per second and never gets a response. The "transmit" LED on the breakout board comes on. The "receive" LED on the AppBee-SIP board blinks but I get nothing with the code I posted. I don't have an O-scope so I can't really monitor any of these voltages as they are firing away.

Next test, I go ahead and simply provide power to the AppBee-SIP board, taking the Axon II out of the picture entirely on the hope that the XBee echoes messages by default or some such. Oddly enough, it SOMETIMES works. Sometimes (one in a few hundred attempts) the X-CTU software will register a hit from the remote Xbee. Though I've not been able to get this to reproduce this for a while now. No clue what this tells me.

I'm sure it's something dumb but I'm not seeing it. Any help would be greatly appreciated!

Thanks!

Mike
Title: Re: Axon II and XBee Trouble
Post by: madsci1016 on January 19, 2010, 10:03:15 PM
I never liked the range test in the x-ctu program, i could never get it to work reliably.

You didn't mention that you checked to make sure the baud rates an each radio matched the computer and Axon. Did you check?
Title: Re: Axon II and XBee Trouble
Post by: KurtEck on January 19, 2010, 10:15:37 PM
Hi Mike,
This is attempt 2 as I accidental hit backspace and deleted my previous response.

Quick background: I started off with doing XBee stuff on Basic Atom Pros(BAP).  I have converted a DIY remote control from RC to be XBEE based.  There are lots of info about the DIY remote( http://www.lynxmotion.net/viewtopic.php?f=21&t=4399 (http://www.lynxmotion.net/viewtopic.php?f=21&t=4399))and my XBee conversion  (http://www.lynxmotion.net/viewtopic.php?f=21&t=5447 (http://www.lynxmotion.net/viewtopic.php?f=21&t=5447))up on Lynxmotion.

Notes: I developed my own packets of information that is sent from the Remote to the Robot.  This communications is bidirectional.  For example when you press a key on the remote, a packet is sent to the robot, and at times the robot may send back a test message to be displayed on the LCD on the remote...

Notes: I am using version 1 XBees, not version 2.5s.  My guess is you are as well as you talk about My and DL.

I have maybe 7-8 of these bouncing around.  I was having problems with one of them talking reliably with my remote and after awhile found it had a different version of the firmware.  

I have a config program on my test board (Basic Atom Pro based).  With this program I set some stuff like:
My (ATMY), Guard Time (ATGT 3), Node Identifier (ATNI), Baud (typically 38400 or 57600 or 62500).  Note the XBees don't have to run at the same baud rates to talk to each other, but your serial port must be at the same baud rate as your XBEE.  Obviously if you are sending lots of data at a high baud rate to another one running at a lower baud rate you can overflow buffers...

I think I have my XBEE on my Axon2 talking at 62500.  I have configured my USART port for this.  I also defined a READ and WRITE buffer for this port.
#define UART2_TX_BUFFER_SIZE 80
#define UART2_RX_BUFFER_SIZE 20

I am currently still running in Transparent mode, but may soon try converting to API mode as it will give me some more flexibility and I am currently replicating some of this stuff in my own packets (Size, Checksum...).

I don't know how you initialized your xbee.  For example mine normally come from Sparkfun with the default baud rate of 9600.

Note: I started off first simply trying to talk to my XBEE and enter/exit command mode.     Things like:
Code: [Select]
//==============================================================================
// [GetXBeeHVal] - Set the XBee DL or MY or??? Simply pass the two characters
// that were passed in to the XBEE
//==============================================================================
WORD GetXBeeHVal (char c1, char c2)
{
WORD wDL;
BYTE bTemp[10]; // temporary buffer
BYTE cbRead;
BYTE i;
pin_toggle(L3);

ClearXBeeInputBuffer(); // Clear our input buffer
rprintfInit(WIRELESS_ACTIVATE);
wDL = -1; // an error condition
clockWaitms(20); // wait 20ms for quard time to enter into command mode
rprintf("+++"); // Now output the string to enter command mode
WaitForXBeeTransmitComplete();
clockWaitms(20); // wait 20ms for quard time to enter into command mode

rprintf("AT%c%c\rATCN\r", c1, c2); // Ok I output the new DL as well as the ATCN to exit command mode

// Now lets try to read some stuff in
cbRead = ReadFromXBee(bTemp, sizeof(bTemp), 10000, 13); // This should be OK<cr>

cbRead = ReadFromXBee(bTemp, sizeof(bTemp), 10000, 13); // This shoould be our DL<cr>

if ((cbRead > 1) && (bTemp[cbRead-1] == 13))
{
// We need to convrt the number from a hex string to a number...
wDL = 0; // start off with 0
cbRead--; // subtract off the cr...
for (i = 0; i < cbRead; i++)
{
if ((bTemp[i] >= '0') && (bTemp[i] <= '9'))
wDL = (wDL<<4) + (bTemp[i]-'0');
else if ((bTemp[i] >= 'A') && (bTemp[i] <= 'F'))
wDL = (wDL<<4) + (bTemp[i]-'A' + 10);
else if ((bTemp[i] >= 'a') && (bTemp[i] <= 'f'))
wDL = (wDL<<4) + (bTemp[i]-'a' + 10);
}
}
cbRead = ReadFromXBee(bTemp, sizeof(bTemp), 10000, 13); // This should be OK<cr>
pin_toggle(L3);
#ifdef DEBUG
rprintfInit(USB_ACTIVATE);
rprintf("GetXBEEHVAL: %c%c=%x\n", c1, c2, wDL);
#endif //DEBUG

return wDL;
}

// Simple wrappers to get My and DL...
WORD GetXBeeMY(void)
{
return GetXBeeHVal ('M', 'Y');
}

WORD GetXBeeDL(void)
{
return GetXBeeHVal ('D', 'L');
}
//==============================================================================
// [ClearXBeeInputBuffer] - This simple helper function will clear out the input
// buffer from the XBEE
//==============================================================================
void ClearXBeeInputBuffer(void)
{
// pin_toggle(L4);
TICK_COUNT start = clockGetus(); // Get the start time
TICK_COUNT wait = 1000; // 1ms = 1000us

while(clockHasElapsed(start, wait)==FALSE)
{
if (!uartReceiveBufferIsEmpty(XBEE_UART))
{
uartFlushReceiveBuffer(XBEE_UART);
start = clockGetus(); // Update the start time
}
}
// pin_toggle(L4);
}

//==============================================================================
// [WaitForXBeeTransmitComplete] - This simple helper function will loop waiting
// for the uart to say it is done.
//==============================================================================
void WaitForXBeeTransmitComplete(void)
{
while(uartIsBusy(XBEE_UART))
;
}


I then had my main line simply try calling these functions and printing out the DL and the MY and the VR... Then I knew my program and XBEE were communicating properly.  Then I started adding in my own packet stuff.

The other thing that has made a lot of this stuff easier is having a logic analyzer.  I have simply one from www.saleae.com (http://www.saleae.com).  This was one of the best $150 I spent.  This really helps me verify that signals are getting back and forth.  Example: on some version of my code on the BAP I make use of the RTS line.  This is great if you don't have a hardware port available and are doing bit bang serial functions.  Well I found that when raise this level back up at the end of reading the data you want, the XBEE may send you two more characters...

Let ME know if this helps at all or if you wish to look at some of the code that I do have running.

Kurt
Title: Re: Axon II and XBee Trouble
Post by: webgeek on January 20, 2010, 12:02:50 AM
Thanks for the quick replies!
Quote
I never liked the range test in the x-ctu program, i could never get it to work reliably.
Ah, now that's interesting to know. I've tried using a Java API to control the XBee but it acts more than a little odd so I think something isn't quite right with it either.
Quote
You didn't mention that you checked to make sure the baud rates an each radio matched the computer and Axon. Did you check?
Both XBees are set to 38400 as is my program and when I connect to the XBee via Putty, I use that speed and it connects fine.
Quote
I don't know how you initialized your xbee.  For example mine normally come from Sparkfun with the default baud rate of 9600.
The first thing I did was use X-CTU to apply all the settings as defined here: http://forums.trossenrobotics.com/tutorials/how-to-diy-128/xbee-basics-3259/ (http://forums.trossenrobotics.com/tutorials/how-to-diy-128/xbee-basics-3259/) and I basically stopped there. Is there something else I need to do?

Thanks for the code posting, unfortunately, it's missing some things so it wont compile - specifically the "ReadFromXBee" function. It's also complaining about your use of WORD - what is that defined as so I can duplicate it? Thanks again for all the help!

Mike
Title: Re: Axon II and XBee Trouble
Post by: webgeek on January 20, 2010, 01:31:08 AM
GAH! The problem appears to be a bug in the WebBotLib. This fails:

Code: [Select]
while(!uartReceiveBufferIsEmpty(UART0)) {
            int byte = uartGetByte(UART0);
            rprintf("%c", byte);
        }
and this works:
Code: [Select]
int byte = uartGetByte(UART0);
if(byte != -1) {
    rprintf("%c", byte);
}

As soon as I stopped using uartReceivedBufferIsEmpty, everything started working as expected. Grrr!

Mike
Title: Re: Axon II and XBee Trouble
Post by: KurtEck on January 20, 2010, 08:39:06 AM
Glad you got it working.  But I am wondering as I am using the same function.  The beginning of my main function that receives stuff looks like:
Code: [Select]
void ReceiveXBeePacket(PDIYPACKET pdiyp)
{
BYTE cbRead;
BYTE bcsIn;
BYTE *pb;
int i;
XPACKETHEADER XBeePacketHeader; // A packet header to use
WORD wNewDL;
TICK_COUNT tcCurrentTime;
TICK_COUNT tcTimeDiffMS;
boolean _fPacketValidPrev = g_diystate.fPacketValid; // Save away the previous state as this is the state if no new data...
boolean _fNewPacketAvail = FALSE;

g_diystate.fPacketValid = FALSE;
g_diystate.fPacketTimeOut = FALSE;
g_diystate.fPacketForced = FALSE;

pin_toggle(L1);

// We will first see if we have a packet header waiting for us.
if (!uartReceiveBufferIsEmpty(XBEE_UART))
{
// The XBEE has sent us some data so try to get a packet header
cbRead = ReadFromXBee((void*)&XBeePacketHeader, sizeof(XPACKETHEADER), 10000, -1);

But again I defined that I was wanting to use a buffer, with:
#define UART2_TX_BUFFER_SIZE 80
#define UART2_RX_BUFFER_SIZE 20


Kurt
Title: Re: Axon II and XBee Trouble
Post by: webgeek on January 20, 2010, 09:29:59 AM
This program works:
Code: [Select]
#include "sys/axon2.h"

#include "iopin.h"
#include "rprintf.h"

#define UART0_TX_BUFFER_SIZE 80
#define UART0_RX_BUFFER_SIZE 20

void appInitHardware(void) {
uartInit(UART1, (BAUD_RATE)115200);
uartInit(UART0, (BAUD_RATE)38400);

rprintfInit(&uart1SendByte);

rprintf("\nAxon II Initiated.\n");

}


TICK_COUNT appInitSoftware(TICK_COUNT loopStart){
return 0;
}


// This is the main loop
TICK_COUNT appControl(LOOP_COUNT loopCount, TICK_COUNT loopStart) {

//while(!uartReceiveBufferIsEmpty(UART0)) {
int byte = uartGetByte(UART0);
        if(byte != -1) {
            rprintf("%c", byte);
        }
    //}

return 10;
}

Uncomment the while loop and it stops working. What version of WebBotLib are you using? I'm on 1.13 IIRC.

Mike
Title: Re: Axon II and XBee Trouble
Post by: KurtEck on January 20, 2010, 10:11:41 AM
I am using some version of 1.13...

I wonder if it is the order you have it defined and includes.
Mine looks like:
Code: [Select]
//allows for printing with features, but uses more memory
#include <stdlib.h>

//WebbotLib Includes
#define UART2_TX_BUFFER_SIZE 80
#define UART2_RX_BUFFER_SIZE 20
#include "buffer.h"
#include "sys/axon2.h"//declare microcontroller
#include "servos.h" //use for servos
#include "a2d.h" //use for ADC
#include "rprintf.h" //use for UART
#include "i2c_master.h" //use for I2C
#include "errors.h" //helpful for debugging mistakes
#include "string.h"
Title: Re: Axon II and XBee Trouble
Post by: Admin on January 21, 2010, 05:38:07 AM
change this:
Code: [Select]
while(!uartReceiveBufferIsEmpty(UART0)) {
int byte = uartGetByte(UART0);
        if(byte != -1) {
            rprintf("%c", byte);
        }

to this:
Code: [Select]
if(!uartReceiveBufferIsEmpty(UART0)) {
int byte = uartGetByte(UART0);
rprintf("%c", byte);
        }
Title: Re: Axon II and XBee Trouble
Post by: Soeren on January 21, 2010, 08:45:46 AM
Hi,

Shouldn't this be moved to the programming board?
Title: Re: Axon II and XBee Trouble
Post by: KurtEck on January 21, 2010, 09:03:40 AM
Hi Admin,

Just wondering about your proposed changes.  I personally would also remove the if for the -1 as it is redundent to the previous check for not being empty, but did not comment as I did not think it would matter. 

The main logic change I see is that this would only read and print 1 character per call of appControl, where his was initially set up to read in all of the characters that were currently in the buffer...

As I mentioned, I believe I have read a few times in the webbotlib documents that the buffers must be defined before you include the system files.  In the uart.h section it states:
Quote
Alternatively you can supply transmit and receive buffers by specifying UART_RX_BUFFER_SIZE and/or UART_TX_BUFFER_SIZE at the top of your program file (before you include the system file).

Kurt