Shopping Cart

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.

Related posts:

  1. Xbee microcontroller board.
  2. Playing Xbee. Part 4 – API.
  3. Playing Xbee. Part 2 – Command mode.
  4. Playing Xbee. Part 1 – First impression.

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">