API for communicating with XBee devices.

Dependencies:   CircularBuffer FixedLengthList

Dependents:   XBeeApiTest XBeeApiSimpleATCmdsExample XBeeApiBroadcastExample XBeeApiBroadcastExampleRTOS ... more

Overview

XBeeApi is intended to be a library for providing a high-level API interface to the XBee - for example getChannel() and setChannel(2) methods rather than needing to send( "ATCH" ) and send( "ATCH 2" ) - and then de-code the responses.

See the notebook page here for a description of how the API works & some details on the various classes.

Features:

  • Support for transmission & reception of data packets
  • Support for reading & changing settings
  • Support for "Remote AT" interface to access settings & I/O channels on remote XBees
  • XBeeApi should work if you're using mbed-rtos, though it is not currently threadsafe. Take a look at the XBeeApiBroadcastExampleRTOS example if you're including mbed-rtos.

Example Programs

There are also example programs available:

Transmit

Import programXBeeApiSimpleBroadcastExample

Simple example of how to use XBeeApi - set up the XBee, configure P2P networking then transmit a frame.

Import programXBeeApiBroadcastExample

Example for XBeeAPI; a little more involved than XBeeApiSimpleBroadcastExample with report on failure to set up the XBee and on the transmit status of the message.

Import programXBeeApiBroadcastExampleRTOS

Example of using the XBeeApi library to broadcast a message, based on XBeeApiBroadcastExample. This example shows how to use the library when using mbed-rtos. Before compiling you must open "XbeeApi\Config\XBeeApiCfg.hpp" and change the '#if 0' to '#if 1' on the line above the comment reading "Use RTOS features to make XBeeApi threadsafe"

Settings/Status

Import programXBeeApiSimpleATCmdsExample

Simple example of using XBeeApi to send AT-style commands to the XBee

Import programXBeeApiRemoteATCmdsExample

Example of using the XBeeApi library to send AT commands to remote XBee devices in order to read/write settings

Receive

Import programXBeeApiSimpleReceiveExample

Simple example of using XBeeApi to receive data packets via wireless

Import programXBeeApiReceiveCallbackExample

Example of using the XBeeApi library to receive a message via a callback method

Import programXBeeApiReceiveCallbackExampleRTOS

Example of using the XBeeApi library to receive a message via a callback method. This example shows how to use the library when using mbed-rtos. See the comment at the top of main.cpp

Remote I/O

Import programXBeeApiRemoteIOExample

Example of using the XBeeApi library to read inputs on a remote XBee

If you have 2 mbed connected XBees available then you can use XBeeApiSimpleReceiveExample and XBeeApiSimpleBroadcastExample as a pair.

Note that this is still a work in progress! XBeeApiTodoList tracks some of the functionality still to be added.

Committer:
johnb
Date:
Fri Jan 31 01:16:56 2014 +0000
Revision:
8:1b48b619d7f6
Child:
11:bfcf1356027b
Work-in-progress commit.  Add blocking version of XBeeApiCmdAt

Who changed what in which revision?

UserRevisionLine numberNew contents of line
johnb 8:1b48b619d7f6 1 /**
johnb 8:1b48b619d7f6 2
johnb 8:1b48b619d7f6 3 Copyright 2014 John Bailey
johnb 8:1b48b619d7f6 4
johnb 8:1b48b619d7f6 5 Licensed under the Apache License, Version 2.0 (the "License");
johnb 8:1b48b619d7f6 6 you may not use this file except in compliance with the License.
johnb 8:1b48b619d7f6 7 You may obtain a copy of the License at
johnb 8:1b48b619d7f6 8
johnb 8:1b48b619d7f6 9 http://www.apache.org/licenses/LICENSE-2.0
johnb 8:1b48b619d7f6 10
johnb 8:1b48b619d7f6 11 Unless required by applicable law or agreed to in writing, software
johnb 8:1b48b619d7f6 12 distributed under the License is distributed on an "AS IS" BASIS,
johnb 8:1b48b619d7f6 13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
johnb 8:1b48b619d7f6 14 See the License for the specific language governing permissions and
johnb 8:1b48b619d7f6 15 limitations under the License.
johnb 8:1b48b619d7f6 16
johnb 8:1b48b619d7f6 17 */
johnb 8:1b48b619d7f6 18
johnb 8:1b48b619d7f6 19 #include "XBeeApiCmdAt.hpp"
johnb 8:1b48b619d7f6 20
johnb 8:1b48b619d7f6 21 /* Set of Frame ID codes for the various commands (see XBEE_CMD_POSN_FRAME_ID) */
johnb 8:1b48b619d7f6 22
johnb 8:1b48b619d7f6 23 #define CMD_RESPONSE_GET_VR '1'
johnb 8:1b48b619d7f6 24 #define CMD_RESPONSE_GET_HV '2'
johnb 8:1b48b619d7f6 25 #define CMD_RESPONSE_GET_CH '3'
johnb 8:1b48b619d7f6 26 #define CMD_RESPONSE_SET_CH '4'
johnb 8:1b48b619d7f6 27
johnb 8:1b48b619d7f6 28 /* Content for the various commands - value of 0 indicates a value to be populated (i.e. variable) */
johnb 8:1b48b619d7f6 29
johnb 8:1b48b619d7f6 30 const uint8_t cmd_vr[] = { CMD_RESPONSE_GET_VR, 'V', 'R' };
johnb 8:1b48b619d7f6 31 const uint8_t cmd_hv[] = { CMD_RESPONSE_GET_HV, 'H', 'V' };
johnb 8:1b48b619d7f6 32 const uint8_t cmd_ch[] = { CMD_RESPONSE_GET_CH, 'C', 'H' };
johnb 8:1b48b619d7f6 33 const uint8_t cmd_set_ch[] = { CMD_RESPONSE_SET_CH, 'C', 'H', 0 };
johnb 8:1b48b619d7f6 34
johnb 8:1b48b619d7f6 35 #define XBEE_CMD_POSN_FRAME_ID (4U)
johnb 8:1b48b619d7f6 36 #define XBEE_CMD_POSN_PARAM_START (8U)
johnb 8:1b48b619d7f6 37
johnb 8:1b48b619d7f6 38 XBeeApiCmdAt::XBeeApiCmdAt() : XBeeApiFrameDecoder( ) , m_haveHwVer( false ),
johnb 8:1b48b619d7f6 39 m_haveFwVer( false ),
johnb 8:1b48b619d7f6 40 m_haveChan( false )
johnb 8:1b48b619d7f6 41 {
johnb 8:1b48b619d7f6 42 }
johnb 8:1b48b619d7f6 43
johnb 8:1b48b619d7f6 44 bool XBeeApiCmdAt::decodeCallback( const uint8_t* const p_data, size_t p_len )
johnb 8:1b48b619d7f6 45 {
johnb 8:1b48b619d7f6 46 bool ret_val = false;
johnb 8:1b48b619d7f6 47
johnb 8:1b48b619d7f6 48 if( XBEE_CMD_AT_RESPONSE == p_data[ XBEE_CMD_POSN_API_ID ] )
johnb 8:1b48b619d7f6 49 {
johnb 8:1b48b619d7f6 50
johnb 8:1b48b619d7f6 51 switch( p_data[ XBEE_CMD_POSN_FRAME_ID ] )
johnb 8:1b48b619d7f6 52 {
johnb 8:1b48b619d7f6 53 case CMD_RESPONSE_GET_HV:
johnb 8:1b48b619d7f6 54 m_haveHwVer = true;
johnb 8:1b48b619d7f6 55 // TODO: Is this right?
johnb 8:1b48b619d7f6 56 m_hwVer = ((uint16_t)p_data[ XBEE_CMD_POSN_PARAM_START ] << 8) + p_data[ XBEE_CMD_POSN_PARAM_START + 1 ];
johnb 8:1b48b619d7f6 57 ret_val = true;
johnb 8:1b48b619d7f6 58 break;
johnb 8:1b48b619d7f6 59
johnb 8:1b48b619d7f6 60 case CMD_RESPONSE_GET_VR:
johnb 8:1b48b619d7f6 61 m_haveFwVer = true;
johnb 8:1b48b619d7f6 62 // TODO: Is this right?
johnb 8:1b48b619d7f6 63 m_fwVer = ((uint16_t)p_data[ XBEE_CMD_POSN_PARAM_START ] << 8) + p_data[ XBEE_CMD_POSN_PARAM_START + 1 ];
johnb 8:1b48b619d7f6 64 ret_val = true;
johnb 8:1b48b619d7f6 65 break;
johnb 8:1b48b619d7f6 66
johnb 8:1b48b619d7f6 67 case CMD_RESPONSE_GET_CH:
johnb 8:1b48b619d7f6 68 m_haveChan = true;
johnb 8:1b48b619d7f6 69 m_chan = p_data[ XBEE_CMD_POSN_PARAM_START ];
johnb 8:1b48b619d7f6 70 ret_val = true;
johnb 8:1b48b619d7f6 71 break;
johnb 8:1b48b619d7f6 72
johnb 8:1b48b619d7f6 73 case CMD_RESPONSE_SET_CH:
johnb 8:1b48b619d7f6 74 m_chan = m_chanPend;
johnb 8:1b48b619d7f6 75 m_haveChan = true;
johnb 8:1b48b619d7f6 76 ret_val = true;
johnb 8:1b48b619d7f6 77 break;
johnb 8:1b48b619d7f6 78 }
johnb 8:1b48b619d7f6 79 }
johnb 8:1b48b619d7f6 80 return ret_val;
johnb 8:1b48b619d7f6 81 }
johnb 8:1b48b619d7f6 82
johnb 8:1b48b619d7f6 83 bool XBeeApiCmdAt::setChannel( uint8_t const p_chan )
johnb 8:1b48b619d7f6 84 {
johnb 8:1b48b619d7f6 85 XBeeApiCmdAt::XBeeApiCmdAtChannelSet req( p_chan );
johnb 8:1b48b619d7f6 86 m_chanPend = p_chan;
johnb 8:1b48b619d7f6 87 m_device->SendFrame( &req );
johnb 8:1b48b619d7f6 88
johnb 8:1b48b619d7f6 89 return true;
johnb 8:1b48b619d7f6 90 }
johnb 8:1b48b619d7f6 91
johnb 8:1b48b619d7f6 92 bool XBeeApiCmdAt::requestHardwareVersion( void )
johnb 8:1b48b619d7f6 93 {
johnb 8:1b48b619d7f6 94 XBeeApiCmdAt::XBeeApiCmdAtHardwareVersionRequest req;
johnb 8:1b48b619d7f6 95 m_haveHwVer = false;
johnb 8:1b48b619d7f6 96 m_device->SendFrame( &req );
johnb 8:1b48b619d7f6 97 return true;
johnb 8:1b48b619d7f6 98 }
johnb 8:1b48b619d7f6 99
johnb 8:1b48b619d7f6 100 bool XBeeApiCmdAt::requestFirmwareVersion( void )
johnb 8:1b48b619d7f6 101 {
johnb 8:1b48b619d7f6 102 XBeeApiCmdAt::XBeeApiCmdAtFirmwareVersionRequest req;
johnb 8:1b48b619d7f6 103 m_haveFwVer = false;
johnb 8:1b48b619d7f6 104 m_device->SendFrame( &req );
johnb 8:1b48b619d7f6 105 return true;
johnb 8:1b48b619d7f6 106 }
johnb 8:1b48b619d7f6 107
johnb 8:1b48b619d7f6 108 bool XBeeApiCmdAt::requestChannel( void )
johnb 8:1b48b619d7f6 109 {
johnb 8:1b48b619d7f6 110 XBeeApiCmdAt::XBeeApiCmdAtChannelRequest req;
johnb 8:1b48b619d7f6 111 m_haveChan = false;
johnb 8:1b48b619d7f6 112 m_device->SendFrame( &req );
johnb 8:1b48b619d7f6 113 return true;
johnb 8:1b48b619d7f6 114 }
johnb 8:1b48b619d7f6 115
johnb 8:1b48b619d7f6 116 bool XBeeApiCmdAt::getFirmwareVersion( uint16_t* const p_ver )
johnb 8:1b48b619d7f6 117 {
johnb 8:1b48b619d7f6 118 if( m_haveFwVer )
johnb 8:1b48b619d7f6 119 {
johnb 8:1b48b619d7f6 120 *p_ver = m_fwVer;
johnb 8:1b48b619d7f6 121 }
johnb 8:1b48b619d7f6 122 return m_haveFwVer;
johnb 8:1b48b619d7f6 123
johnb 8:1b48b619d7f6 124 }
johnb 8:1b48b619d7f6 125
johnb 8:1b48b619d7f6 126 bool XBeeApiCmdAt::getHardwareVersion( uint16_t* const p_ver )
johnb 8:1b48b619d7f6 127 {
johnb 8:1b48b619d7f6 128 if( m_haveHwVer )
johnb 8:1b48b619d7f6 129 {
johnb 8:1b48b619d7f6 130 *p_ver = m_hwVer;
johnb 8:1b48b619d7f6 131 }
johnb 8:1b48b619d7f6 132 return m_haveHwVer;
johnb 8:1b48b619d7f6 133 }
johnb 8:1b48b619d7f6 134
johnb 8:1b48b619d7f6 135 bool XBeeApiCmdAt::getChannel( uint8_t* const p_chan )
johnb 8:1b48b619d7f6 136 {
johnb 8:1b48b619d7f6 137 if( m_haveChan )
johnb 8:1b48b619d7f6 138 {
johnb 8:1b48b619d7f6 139 *p_chan = m_chan;
johnb 8:1b48b619d7f6 140 }
johnb 8:1b48b619d7f6 141 return m_haveChan;
johnb 8:1b48b619d7f6 142 }
johnb 8:1b48b619d7f6 143
johnb 8:1b48b619d7f6 144 XBeeApiCmdAtBlocking::XBeeApiCmdAtBlocking( const uint16_t p_timeout, const uint16_t p_slice ) :
johnb 8:1b48b619d7f6 145 XBeeApiCmdAt( ),
johnb 8:1b48b619d7f6 146 m_timeout( p_timeout ),
johnb 8:1b48b619d7f6 147 m_slice( p_slice )
johnb 8:1b48b619d7f6 148 {
johnb 8:1b48b619d7f6 149 }
johnb 8:1b48b619d7f6 150
johnb 8:1b48b619d7f6 151 extern Serial pc;
johnb 8:1b48b619d7f6 152
johnb 8:1b48b619d7f6 153
johnb 8:1b48b619d7f6 154 template<typename par>
johnb 8:1b48b619d7f6 155 bool blockingGet( XBeeApiCmdAtBlocking* p_t,
johnb 8:1b48b619d7f6 156 bool (XBeeApiCmdAtBlocking::*p_req)( void ),
johnb 8:1b48b619d7f6 157 bool (XBeeApiCmdAtBlocking::*p_get)( par* const ),
johnb 8:1b48b619d7f6 158 par* const p_par,
johnb 8:1b48b619d7f6 159 uint16_t p_timeout,
johnb 8:1b48b619d7f6 160 uint16_t p_slice )
johnb 8:1b48b619d7f6 161 {
johnb 8:1b48b619d7f6 162 bool ret_val = false;
johnb 8:1b48b619d7f6 163 uint16_t counter = p_timeout;
johnb 8:1b48b619d7f6 164
johnb 8:1b48b619d7f6 165 if( (p_t->*p_get)( p_par ) )
johnb 8:1b48b619d7f6 166 {
johnb 8:1b48b619d7f6 167 ret_val = true;
johnb 8:1b48b619d7f6 168 }
johnb 8:1b48b619d7f6 169 else if( (p_t->*p_req)() )
johnb 8:1b48b619d7f6 170 {
johnb 8:1b48b619d7f6 171 bool cont = false;
johnb 8:1b48b619d7f6 172
johnb 8:1b48b619d7f6 173 do{
johnb 8:1b48b619d7f6 174 wait_ms( p_slice );
johnb 8:1b48b619d7f6 175 if( (p_t->*p_get)( p_par ) )
johnb 8:1b48b619d7f6 176 {
johnb 8:1b48b619d7f6 177 ret_val = true;
johnb 8:1b48b619d7f6 178 }
johnb 8:1b48b619d7f6 179 else if( counter > p_slice ) {
johnb 8:1b48b619d7f6 180 counter -= p_slice;
johnb 8:1b48b619d7f6 181 cont = true;
johnb 8:1b48b619d7f6 182 }
johnb 8:1b48b619d7f6 183 } while( cont );
johnb 8:1b48b619d7f6 184 }
johnb 8:1b48b619d7f6 185
johnb 8:1b48b619d7f6 186 return( ret_val );
johnb 8:1b48b619d7f6 187 }
johnb 8:1b48b619d7f6 188
johnb 8:1b48b619d7f6 189 bool XBeeApiCmdAtBlocking::getHardwareVersionS( uint16_t* const p_ver )
johnb 8:1b48b619d7f6 190 {
johnb 8:1b48b619d7f6 191 return XBeeApiCmdAt::getHardwareVersion( p_ver );
johnb 8:1b48b619d7f6 192 }
johnb 8:1b48b619d7f6 193
johnb 8:1b48b619d7f6 194 bool XBeeApiCmdAtBlocking::getFirmwareVersionS( uint16_t* const p_ver )
johnb 8:1b48b619d7f6 195 {
johnb 8:1b48b619d7f6 196 return XBeeApiCmdAt::getFirmwareVersion( p_ver );
johnb 8:1b48b619d7f6 197 }
johnb 8:1b48b619d7f6 198
johnb 8:1b48b619d7f6 199 bool XBeeApiCmdAtBlocking::getChannelS( uint8_t* const p_chan )
johnb 8:1b48b619d7f6 200 {
johnb 8:1b48b619d7f6 201 return XBeeApiCmdAt::getChannel( p_chan );
johnb 8:1b48b619d7f6 202 }
johnb 8:1b48b619d7f6 203
johnb 8:1b48b619d7f6 204 bool XBeeApiCmdAtBlocking::getHardwareVersion( uint16_t* const p_ver )
johnb 8:1b48b619d7f6 205 {
johnb 8:1b48b619d7f6 206 return blockingGet( this,
johnb 8:1b48b619d7f6 207 &XBeeApiCmdAtBlocking::requestHardwareVersion,
johnb 8:1b48b619d7f6 208 &XBeeApiCmdAtBlocking::getHardwareVersionS,
johnb 8:1b48b619d7f6 209 p_ver,
johnb 8:1b48b619d7f6 210 m_timeout, m_slice );
johnb 8:1b48b619d7f6 211 }
johnb 8:1b48b619d7f6 212
johnb 8:1b48b619d7f6 213 bool XBeeApiCmdAtBlocking::getFirmwareVersion( uint16_t* const p_ver )
johnb 8:1b48b619d7f6 214 {
johnb 8:1b48b619d7f6 215 return blockingGet( this,
johnb 8:1b48b619d7f6 216 &XBeeApiCmdAtBlocking::requestFirmwareVersion,
johnb 8:1b48b619d7f6 217 &XBeeApiCmdAtBlocking::getFirmwareVersionS,
johnb 8:1b48b619d7f6 218 p_ver,
johnb 8:1b48b619d7f6 219 m_timeout, m_slice );
johnb 8:1b48b619d7f6 220 }
johnb 8:1b48b619d7f6 221
johnb 8:1b48b619d7f6 222 bool XBeeApiCmdAtBlocking::getChannel( uint8_t* const p_chan )
johnb 8:1b48b619d7f6 223 {
johnb 8:1b48b619d7f6 224 return blockingGet( this,
johnb 8:1b48b619d7f6 225 &XBeeApiCmdAtBlocking::requestChannel,
johnb 8:1b48b619d7f6 226 &XBeeApiCmdAtBlocking::getChannelS,
johnb 8:1b48b619d7f6 227 p_chan,
johnb 8:1b48b619d7f6 228 m_timeout, m_slice );
johnb 8:1b48b619d7f6 229 }
johnb 8:1b48b619d7f6 230
johnb 8:1b48b619d7f6 231 bool XBeeApiCmdAtBlocking::setChannel( uint8_t const p_chan )
johnb 8:1b48b619d7f6 232 {
johnb 8:1b48b619d7f6 233 }
johnb 8:1b48b619d7f6 234
johnb 8:1b48b619d7f6 235
johnb 8:1b48b619d7f6 236 XBeeApiCmdAt::XBeeApiCmdAtFirmwareVersionRequest::XBeeApiCmdAtFirmwareVersionRequest( void ) : XBeeApiFrame( )
johnb 8:1b48b619d7f6 237 {
johnb 8:1b48b619d7f6 238 m_apiId = XBEE_CMD_AT_CMD;
johnb 8:1b48b619d7f6 239 m_data = cmd_vr;
johnb 8:1b48b619d7f6 240 m_dataLen = sizeof( cmd_vr );
johnb 8:1b48b619d7f6 241 }
johnb 8:1b48b619d7f6 242
johnb 8:1b48b619d7f6 243 XBeeApiCmdAt::XBeeApiCmdAtHardwareVersionRequest::XBeeApiCmdAtHardwareVersionRequest( void ) : XBeeApiFrame( )
johnb 8:1b48b619d7f6 244 {
johnb 8:1b48b619d7f6 245 m_apiId = XBEE_CMD_AT_CMD;
johnb 8:1b48b619d7f6 246 m_data = cmd_hv;
johnb 8:1b48b619d7f6 247 m_dataLen = sizeof( cmd_hv );
johnb 8:1b48b619d7f6 248 }
johnb 8:1b48b619d7f6 249
johnb 8:1b48b619d7f6 250 XBeeApiCmdAt::XBeeApiCmdAtChannelRequest::XBeeApiCmdAtChannelRequest( void ) : XBeeApiFrame( )
johnb 8:1b48b619d7f6 251 {
johnb 8:1b48b619d7f6 252 m_apiId = XBEE_CMD_AT_CMD;
johnb 8:1b48b619d7f6 253 m_data = cmd_ch;
johnb 8:1b48b619d7f6 254 m_dataLen = sizeof( cmd_ch );
johnb 8:1b48b619d7f6 255 }
johnb 8:1b48b619d7f6 256
johnb 8:1b48b619d7f6 257 XBeeApiCmdAt::XBeeApiCmdAtChannelSet::XBeeApiCmdAtChannelSet( const uint8_t p_chan ) : XBeeApiFrame( )
johnb 8:1b48b619d7f6 258 {
johnb 8:1b48b619d7f6 259 m_apiId = XBEE_CMD_AT_CMD;
johnb 8:1b48b619d7f6 260 m_buffer[0] = cmd_set_ch[0];
johnb 8:1b48b619d7f6 261 m_buffer[1] = cmd_set_ch[1];
johnb 8:1b48b619d7f6 262 m_buffer[2] = cmd_set_ch[2];
johnb 8:1b48b619d7f6 263 m_buffer[3] = p_chan;
johnb 8:1b48b619d7f6 264 m_data = m_buffer;
johnb 8:1b48b619d7f6 265 m_dataLen = sizeof( cmd_set_ch );
johnb 8:1b48b619d7f6 266 }