Labels

Saturday, August 3, 2013

Xbee Series 2 RSSI Bug

For those of you who didn't read the last post, be sure to look at it here before reading this one, because
otherwise it doesn't make any sense!
http://stupidembeddedblog.blogspot.com/2013/07/getting-rssi-from-xbee-series-2.html

I have been wrestling with this stupid "bug" for the past week, and just before losing my last bit of sanity I discovered my problem and I feel it is appropriate to post it here. Last entry we had looked at how to retrieve the RSSI value from an Xbee series 2 module and some code to obtain it with as well.

Source
In my sensor network, I have each node periodically broadcast a message to all nodes within 1 hop, and the receiving nodes then obtain the sender's 16 bit address and the RSSI of the packet, then sends that back to the coordinator along with it's own 16 bit address. The coordinator is connected to a PC running MATLAB which then uses the information to localize the nodes using triangulation.

The problem I was having was after a brief period of time, when using the code from the previous post to obtain the RSSI, the code would get stuck after the DB AT command was issued. I couldn't figure out what was going on because most of the time the code worked, but it would lock up after at least 3 other nodes were on the network, constantly bombarding each other with packets. At first I was suspicious an interrupt was causing the problem, but that was not the case.

The Xbees store a message queue, and despite issuing the AT command and expecting the appropriate response frame back immediately, instead I was getting the Zigbee receive frame from a previously received message. This caused the code to get stuck waiting for certain parts of an expected frame that it wasn't going to received.

Here's the updated code!

char getRSSI(void)
{
RxPacket pkt;
int temp;

do 
{
AT_Command(0x01, 'D', 'B', 0, 0); // Send DB AT Command
while ((UCSR0A & (1 << RXC0)) == 0){};
temp = UDR0;
receive_Msg(&pkt);
} while (pkt.api_identifier != 0x88);

printf("RSSI is %d\n", pkt.data[0]);
return pkt.data[0]; // Return RSSI value
}

In this code we use the receive message command to obtain the packet, then check to see if the frame received was an AT response. If not, then we simply request it again. This may not be perfect, but for now, it works! Also, the new packet function was removed from the receive_Msg() function and added to the USART ISR which now looks like this:

ISR(USART_RX_vect) 
{   
PORTD ^= 0x80; // TEST LED
if(UDR0 == 0x7E)
{
receive_Msg(&rx_pkt);
newPacketRX(&rx_pkt); // Call function for responding to new packet
}

PORTD ^= 0x80; // TEST LED
}

So this is it for now. Subscribe for future updates!