Posts

Playing Xbee. Part 3 – Measure and send.

Xbee on a protoboard

Xbee on a protoboard


First of all – breadboards are evil. Sure, they are handy. But when you spend a whole day chasing glitches which drive your logic analyzer crazy, it’s not fun. I moved my Xbee setup on a protoboard; picture on the right shows the result. The capacitor on Xbee VDD pin is essential – the module generates pretty strong spikes every time it starts transmitting and without the capacitor one should expect to see glitches every 250ms or so. The manual recommends bypassing VDD using 1uF and 8.2pF caps in parallel; I’m using 0.1uF here and it works well also.

In the previous article, I talked about switching in and out of command mode on an Xbee module running AT firmware. You can do exciting things with AT commands; however, when you interact with the module via RF link, how are you supposed to see the output of an AT command? In command mode, all output goes back to the PIC USART, so we need a method to capture it and send back to us.

The following function is called from CLI. It queries every AT command, stores the result, and sends it back after going back online. The usual way of doing that is to switch to command mode, issue all the commands capturing output to a buffer, then switch back online and send the buffer contents back. PIC18 doesn’t have enough RAM to hold such a big buffer, that’s why this function queries one command at a time. Because of that, the function is quite slow – the guard time before sending “+++” is one second plus it needs to wait for RF transmission of previous result to complete before switching to command mode for the next query. It takes approximately 3 seconds per query and querying about 60 commands takes 3 minutes.

In order to be able to send commands in a loop, I defined a structure called XBEE_RD_CMD, which consists of command description and command itself. The command is used in the query, the description gets sent back along with command result. All command/description pairs are stored in array of structures called cmd_query. Last element of this array is zero; this way I can feel when I hit the bottom. The data structures are located in cli_constants.h header file.

Let’s take a look at the function. The main ‘while’ loop starting at line 6 executes until it gets to the last element of cmd_query[] array. The function enters command mode at line 7. Then it sends the command and then waits for the response in another ‘while’ loop starting at line 14. The exit from this loop is either when maximum length string or CR character is read. The RESP_MAXLEN symbol defines maximum length of AT command response and is currently set to 21. After exiting this loop, function switches back online, sends the buffer contents, and waits for transmit interrupt flag to clear at line 34. After all this, function continues from the beginning of the main loop.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
BOOL Xbee_regdump( void )
{
 char buf[ RESP_MAXLEN ];
 BYTE i,j,tmpdata;
    i = 0;
    while( cmd_query[ i ].name ) {
        if( Xbee_cmdmode_enter() == FALSE ) {   //enter command mode
            return( FALSE );
        }
        send_string( AT_pref );                         //send_prefix
        send_string( cmd_query[ i ].at_command );       //send command
        sendchar('\r');                                 //send CR
        j = 0;
        while( j < RESP_MAXLEN ) {                      //get response
            if( CharInQueue() ) {
                tmpdata = recvchar();
                if( tmpdata != '\r' ) {
                    buf[ j ] = tmpdata;
                    j++;
                }
                else {
                    buf[ j ] = 0;           //end of response
                    j = RESP_MAXLEN;
                }
            }
        }
        if( Xbee_cmdmode_exit() == FALSE ) {
            return( FALSE );
        }
        send_string( crlf );
        send_string( cmd_query[ i ].name );
        send_ram_string( buf );
        i++;
        while( PIE1bits.TXIE );             //wait for end of transmission
    }// while( cmd_query[ i ].name
    return( TRUE );
}

Another function I want to talk about demonstrates sensor main routine and uses ADC functions, that were also described in previous article. Every 10 seconds, it measures VDD and sends the result back. The function sits in an endless loop checking if anything gets received form the other side. Any key pressed in terminal program terminates the function. The function measures VDD first, then it wakes up the Xbee using sleep control pin, transmits the result and puts Xbee back to sleep.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/* Enters monitor mode. Sensors are probed, results sent, system goes to sleep */
/* Exit by pressing any key */
void Cycle_monitor( void )
{
 DWORD delay;
 WORD wakeup_counter = 0;
 WORD tmp;
    send_string("\rMonitoring sensors. Press any key to stop.");
    while( CharInQueue() == FALSE ) {
        tmp = VDD_measure();
        SL_RQ = 0;                  //wake-up
        delay = uptime + 10000;
        while( uptime < delay );
        sendchar('\r');
        send_decword( wakeup_counter );
        sendchar(' ');
        tmp = VDD_measure();
        send_decword( tmp );
        sendchar(' ');
        send_decword( 12280000/tmp );
        SL_RQ = 1;                  //sleep
        delay = uptime + 10000;
        while( uptime < delay );
        wakeup_counter++;
    }
 
}

Both functions run from CLI. As always, the source code is in project files. Give it a try and let me know if you have difficulties running the code.

Oleg.

15 comments to Playing Xbee. Part 3 – Measure and send.

  • Sergei

    Hi Oleg,

    In the last code snip, why the first “tmp = VDD_measure();” before the first “while(uptime) < delay"? VDD will be measured again into "tmp" before the actual sending of "tmp"…

    Thanks for excellent articles!

    Regards,
    Sergei

  • Ralph Anthony C. Planteras

    To the publisher;

    hello, i’m working on a project now with my team and we are using for the very first time xbee series 2 rf modules. the team has no idea on how to use the xbee rf module interfaced on a pic16f877a. im hoping if you can help us with this, can you let us see your code for references for our project? we are 5th year graduating students from the University of San Carlos here in the Philippines

  • manuel

    Hi Oleg,

    I’m using the xbee modules to sample an analog input (4Hz sinewave) at 200Hz and send the data in packages of 40 samples each. I think there may be something wrong with the ADC because when the voltage is greater than a certain value some data is lost. Instead of sending 40 samples it sends less randomly. The amplitude of the analog singal is always smaller than the Vref of the ADC. I’m thinking on using a couple of PICs to sample the signal and use the Xbee modules in transparent mode to communicate between them. Do you have any idea of what could be the source of the problem?

  • Manuel

    Hello again Oleg,

    Playing a bit more with the modules I’ve noticed that this error I told you about happens when the input voltage reaches values equal to n times Vref/4. At Vref I have 2.8V and the error occurs at 0.7V, 1,4V and 2,1V. Any help will be appreciated.

  • Eric S

    My Remote Xbee does not respond when I do the following:

    int OutputPacketLength = 9; // SB 9?

    XBee_Data[0] = 0x7E; // Start Delimiter
    XBee_Data[1] = 0x00; // Length Msb
    XBee_Data[2] = 0x05; // Length Lsb
    XBee_Data[3] = 0x08; // API Frame Type
    XBee_Data[4] = 0x4D; // Frame ID, any non-zero Value
    XBee_Data[5] = 0x44; // First Byte “D” AT Command (D0) Digital Output Zero?
    XBee_Data[6] = 0x30; // Second Byte “0” AT Command (D0)
    XBee_Data[7] = 0x05; // Pin High Output
    XBee_Data[8] = 0x31; // Checksum
    XBee_Data[9] = 0x00; // String Terminator (According to TS). Not really necessary since TS was echoing typed (non-zero) input from terminal

    ZBTxRequest zbTx = ZBTxRequest(XBee_Addr64, NetworkAddress, ZB_BROADCAST_RADIUS_MAX_HOPS, ZB_TX_UNICAST, (uint8_t*) XBee_Data, OutputPacketLength, xbee.getNextFrameId());
    xbee.send(zbTx);

    Please advise as to what I am doing wrong. The XBee_Addr_64 and NetworkAddress were obtained from an input packet received after a button push on the remote.

  • Robert

    Hi, I just have one little remark about something you said in this post. You said that “The manual recommends bypassing VDD using 1uF and 8.2pF caps in parallel; I’m using 0.1uF here and it works well also.” I calculated that you are using aprrox. 5 times less capacitance than what the manual recommends, and that, I thought was just astonishing to find out.

  • voland

    Hi, Oleg! Thanks for supporting such interesting site! I have question about XBee.
    There is AVR controller connected via SPI to Xbee. It performs SPI-master for XBee and uses API-mode operation to send some packets. Packets use commands of type 0x90 which could send data to remote modules. All’s working fine untill XBee works in Router mode. When I tried to switch it in the End-device mode (when it periodically sleeps) but such system doesn’t work at all :(. Module doesn’t send packets to remote, as it was in Router mode. What could advise in such situation?
    PS: now i’m triyng to connect AVR to XBee with USART. It was one probe to do so (I connected it to Cortex M3), but module still not worked :(.

    • Check the doc to see if these commands are indeed supported in end-device mode.

      • voland

        Hi, Oleg!
        These commands are supported every time, there’s no any info in datasheet which points to some contitions. I tried to communicate via USART and XBee in End Device mode started to work normally :). I saw that SPI interface connected to both modules – RF and controller inside XBee with the same CS signal. So, it’s possible that these parts use SPI to communicate while I try to send packets to them :/. But there is no any information about this in datasheet :(.
        Thanks for your answer šŸ˜‰

  • Kenji

    Hi Oleg,

    Have you ever experienced lags during the transmission of data?

    Sometimes my XBee works just fine and most of the times there are lags while sending the data to PC from my end device.