00001 /********************************************************************************* 00002 00003 Copyright 2006-2008 MakingThings 00004 00005 Licensed under the Apache License, 00006 Version 2.0 (the "License"); you may not use this file except in compliance 00007 with the License. You may obtain a copy of the License at 00008 00009 http://www.apache.org/licenses/LICENSE-2.0 00010 00011 Unless required by applicable law or agreed to in writing, software distributed 00012 under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 00013 CONDITIONS OF ANY KIND, either express or implied. See the License for 00014 the specific language governing permissions and limitations under the License. 00015 00016 *********************************************************************************/ 00017 #include "config.h" 00018 00019 #include "stdlib.h" 00020 #include <stdio.h> 00021 #include "string.h" 00022 #include "xbee.h" 00023 00024 static bool XBee_GetIOValues( XBeePacket* packet, int *inputs ); 00025 void XBeeTask( void* p ); 00026 #define XBEEPACKET_Q_SIZE 5 00027 #define XBEE_OSC_RX_TIMEOUT 500 00028 00029 typedef struct 00030 { 00031 XBeePacket* currentPkt; 00032 int packetIndex; 00033 #ifdef OSC 00034 bool autosend; 00035 #endif 00036 bool waitingForConfirm; 00037 } XBeeSubsystem; 00038 00039 XBeeSubsystem* XBee; 00040 00041 /** \defgroup XBee XBee 00042 Communicate with XBee (Zigbee) wireless modules via the Make Controller's serial port. 00043 00044 XBee modules from \b MaxStream are small, cheap ($19 each), wireless \b RF (radio frequency) modules that 00045 can easily be used with the Make Controller Kit to create projects that require wireless communication. Check 00046 http://www.maxstream.net/products/xbee/xbee-oem-rf-module-zigbee.php for more info. 00047 00048 \section Overview 00049 XBee modules are <b>ZigBee/IEEE 802.15.4</b> compliant and can operate in several modes: 00050 - Transparent serial port. Messages in one side magically end up at the other endpoint. Great for enabling wireless 00051 communication between 2 Make Controllers. 00052 - AT command mode. Send traditional AT commands to configure the module itself (as opposed to having 00053 the data go straight through via serial mode. 00054 - Packet (API) mode. Lower level communication that doesn't have to wait for the module to be in 00055 AT command mode. Check the \ref XBeePacketTypes for a description of how these packets are laid out. 00056 Be sure to call XBeeConfig_SetPacketApiMode before trying to do anything in this mode. 00057 00058 The general idea is that you have one XBee module connected directly to your Make Controller Kit, and then 00059 any number of other XBee modules that can communicate with it in order to get information to and from the 00060 Make Controller. Or, several Make Controllers can each have an XBee module connected in order to 00061 communicate wirelessly among themselves. 00062 00063 XBee modules also have some digital and analog I/O right on them, which means you can directly connect 00064 sensors to the XBee modules which will both read the values and send them wirelessly. Check the XBee doc 00065 for the appropriate commands to send in order to set this up. 00066 00067 \section API 00068 The Make Controller API for working with the XBee modules makes use of the XBee Packet API. If you simply want to make use 00069 of the transparent serial port functionality, you can use the following functions: 00070 XBee_SetActive( ) 00071 XBee_Write( ); 00072 XBee_Read( ); 00073 XBee_GetReadable( ); 00074 00075 Or if you want to handle setup etc. yourself, you don't need to deal with these - just hook up the module to your 00076 Make Controller and start reading and writing over the serial port. 00077 00078 Bytes sent in this way are broadcast to all XBee modules on the same chanel and with the same PAN ID. All similarly 00079 configured modules will receive all bytes sent. However, because these bytes are broadcast, there is no message 00080 reliability, so there's no guarantee that the messages will actually get there. 00081 00082 The XBee Packet API allows for much more flexible and powerful communication with the modules. With the Packet API 00083 you can send messages to a specific module, detect where messages came from, check signal strength, and most importantly 00084 packets are sent with a send / acknowledges / retry scheme which greatly increases message reliability. 00085 00086 Packet API uses commands to configure the XBee module itself, and then a handful of Zigbee specified packet types can be sent and received. 00087 See \ref XBeePacketTypes for details on these packet types. 00088 00089 The \b XBeeConfig_ functions are convenient wrappers around some of the most common AT commands you might want to send. For 00090 any of the other AT commands, check the XBee documentation and create them using XBee_CreateATCommandPacket( ). These will always 00091 be sent to the XBee module attached to the Make Controller. The \b XBee_ functions deal with sending and receiving 00092 messages to other XBee modules not connected to the Make Controller. 00093 00094 \ingroup Libraries 00095 @{ 00096 */ 00097 00098 /** 00099 Controls the active state of the \b XBee subsystem 00100 @param state Whether this subsystem is active or not 00101 @return Zero on success. 00102 */ 00103 int XBee_SetActive( int state ) 00104 { 00105 if( state ) 00106 { 00107 if( XBee == NULL ) 00108 { 00109 if( CONTROLLER_OK != Serial_SetActive( SERIAL_0, 1 ) ) 00110 return CONTROLLER_ERROR_SUBSYSTEM_INACTIVE; 00111 00112 // Configure the serial port 00113 Serial_SetBaud( SERIAL_0, 9600 ); 00114 Serial_SetBits( SERIAL_0, 8 ); 00115 Serial_SetParity( SERIAL_0, 0 ); 00116 Serial_SetStopBits( SERIAL_0, 1 ); 00117 00118 XBee = MallocWait( sizeof( XBeeSubsystem ), 100 ); 00119 XBee->packetIndex = 0; 00120 #ifdef OSC 00121 XBee->autosend = XBee_GetAutoSend( true ); 00122 #endif 00123 XBee->currentPkt = MallocWait( sizeof( XBeePacket ), 100 ); 00124 XBee_ResetPacket( XBee->currentPkt ); 00125 XBee->waitingForConfirm = false; 00126 } 00127 } 00128 else 00129 { 00130 Serial_SetActive( SERIAL_0, 0 ); 00131 00132 if( XBee ) 00133 { 00134 Free( XBee ); 00135 Free( XBee->currentPkt ); 00136 XBee = NULL; 00137 } 00138 } 00139 return CONTROLLER_OK; 00140 } 00141 00142 /** 00143 Read the active state of the \b XBee subsystem 00144 @return An integer specifying the active state - 1 (active) or 0 (inactive). 00145 */ 00146 int XBee_GetActive( ) 00147 { 00148 return Serial_GetActive( SERIAL_0 ); 00149 } 00150 00151 00152 /** 00153 Write the specified number of bytes into the XBee unit. It is 00154 assumed that the unit is in TRANSPARENT, not in PACKET API mode. To write to the 00155 unit using packets first set packet mode (using XBeeConfig_SetPacketApiMode) then use 00156 XBee_CreateXXXPacket() followed by XBee_SendPacket(). 00157 @param buffer The block of bytes to write 00158 @param count The number of bytes to write 00159 @param timeout The time in ms to linger waiting to succeed (0 for no wait) 00160 @return status 00161 */ 00162 int XBee_Write( uchar *buffer, int count, int timeout ) 00163 { 00164 return Serial_Write( SERIAL_0, buffer, count, timeout ); 00165 } 00166 00167 /** 00168 Read data from the Xbee unit waiting for the specified time. Use XBee_GetReadable() to 00169 determine how many bytes are waiting to avoid waiting. It is 00170 assumed that the unit is in TRANSPARENT, not in PACKET API mode. To write to the 00171 unit using packets first set packet mode (using XBeeConfig_SetPacketApiMode) then use 00172 XBee_CreateXXXPacket() followed by XBee_SendPacket(). 00173 @param buffer A pointer to the buffer to read into. 00174 @param count An integer specifying the maximum number of bytes to read. 00175 @param timeout Time in milliseconds to block waiting for the specified number of bytes. 0 means don't wait. 00176 @return number of bytes read (>=0) or error <0 . 00177 */ 00178 int XBee_Read( uchar* buffer, int count, int timeout ) 00179 { 00180 return Serial_Read( SERIAL_0, buffer, count, timeout ); 00181 } 00182 00183 /** 00184 Returns the number of bytes in the queue waiting to be read. 00185 @return bytes in the receive queue. 00186 */ 00187 int XBee_GetReadable( void ); 00188 00189 /** 00190 Receive an incoming XBee packet. 00191 A single call to this will continue to read from the serial port as long as there are characters 00192 to read or until it times out. If a packet has not been completely received, call it repeatedly 00193 with the same packet. 00194 00195 Clear out a packet before reading into it with a call to XBee_ResetPacket( ) 00196 @param packet The XBeePacket to receive into. 00197 @param timeout The number of milliseconds to wait for a packet to arrive. Set this to 0 to return as 00198 soon as there are no characters left to process. 00199 @return 1 if a complete packet has been received, 0 if not. 00200 @see XBeeConfig_SetPacketApiMode( ) 00201 @todo Probably need some way to reset the parser if there are no bytes for a while 00202 00203 \par Example 00204 \code 00205 // we're inside a task here... 00206 XBeePacket myPacket; 00207 XBee_ResetPacket( &myPacket ); 00208 while( 1 ) 00209 { 00210 if( XBee_GetPacket( &myPacket, 100 ) ) 00211 { 00212 // process the new packet 00213 XBee_ResetPacket( &myPacket ); // then clear it out before reading again 00214 } 00215 Sleep( 10 ); 00216 } 00217 \endcode 00218 */ 00219 int XBee_GetPacket( XBeePacket* packet, int timeout ) 00220 { 00221 if( CONTROLLER_OK != XBee_SetActive( 1 ) ) 00222 return CONTROLLER_ERROR_SUBSYSTEM_INACTIVE; 00223 00224 int time = TaskGetTickCount( ); 00225 00226 do 00227 { 00228 Serial_ClearErrors( SERIAL_0 ); 00229 while( Serial_GetReadable( SERIAL_0 ) ) 00230 { 00231 int newChar = Serial_GetChar( SERIAL_0 ); 00232 if( newChar == -1 ) 00233 break; 00234 00235 switch( packet->rxState ) 00236 { 00237 case XBEE_PACKET_RX_START: 00238 if( newChar == XBEE_PACKET_STARTBYTE ) 00239 packet->rxState = XBEE_PACKET_RX_LENGTH_1; 00240 break; 00241 case XBEE_PACKET_RX_LENGTH_1: 00242 packet->length = newChar; 00243 packet->length <<= 8; 00244 packet->rxState = XBEE_PACKET_RX_LENGTH_2; 00245 break; 00246 case XBEE_PACKET_RX_LENGTH_2: 00247 packet->length += newChar; 00248 if( packet->length > XBEE_MAX_PACKET_SIZE ) // in case we somehow get some garbage 00249 packet->rxState = XBEE_PACKET_RX_START; 00250 else 00251 packet->rxState = XBEE_PACKET_RX_PAYLOAD; 00252 packet->crc = 0; 00253 break; 00254 case XBEE_PACKET_RX_PAYLOAD: 00255 *packet->dataPtr++ = newChar; 00256 if( ++packet->index >= packet->length ) 00257 packet->rxState = XBEE_PACKET_RX_CRC; 00258 packet->crc += newChar; 00259 break; 00260 case XBEE_PACKET_RX_CRC: 00261 packet->crc += newChar; 00262 packet->rxState = XBEE_PACKET_RX_START; 00263 if( packet->crc == 0xFF ) 00264 return 1; 00265 else 00266 { 00267 XBee_ResetPacket( packet ); 00268 return 0; 00269 } 00270 } 00271 } 00272 if ( timeout > 0 ) 00273 Sleep( 1 ); 00274 } while( ( TaskGetTickCount( ) - time ) < timeout ); 00275 return 0; 00276 } 00277 00278 /** 00279 Send an XBee packet. 00280 Use the following functions to create packets to be sent: 00281 - XBee_CreateTX16Packet( ) - create a data packet to be sent out wirelessly with a 16-bit address 00282 - XBee_CreateTX64Packet( ) - create a data packet to be sent out wirelessly with a 64-bit address 00283 - XBee_CreateATCommandPacket( ) - create an AT command to configure an attached XBee module 00284 @param packet The XBeePacket to send. 00285 @param datalength The length of the actual data being sent (not including headers, options, etc.) 00286 @return Zero on success. 00287 @see XBeeConfig_SetPacketApiMode( ) 00288 00289 \par Example 00290 \code 00291 XBeePacket txPacket; 00292 uint8 data[] = "ABC"; // 3 bytes of data 00293 XBee_CreateTX16Packet( &txPacket, 0, 0, 0, data, 3 ); 00294 XBee_SendPacket( &txPacket, 3 ); 00295 \endcode 00296 */ 00297 int XBee_SendPacket( XBeePacket* packet, int datalength ) 00298 { 00299 if( CONTROLLER_OK != XBee_SetActive( 1 ) ) 00300 return CONTROLLER_ERROR_SUBSYSTEM_INACTIVE; 00301 00302 Serial_SetChar( SERIAL_0, XBEE_PACKET_STARTBYTE ); 00303 int size = datalength; 00304 switch( packet->apiId ) 00305 { 00306 case XBEE_TX64: //account for apiId, frameId, 8 bytes destination, and options 00307 size += 11; 00308 break; 00309 case XBEE_TX16: //account for apiId, frameId, 2 bytes destination, and options 00310 size += 5; 00311 break; 00312 case XBEE_ATCOMMAND: // length = API ID + Frame ID, + AT Command (+ Parameter Value) 00313 size = (datalength > 0) ? 8 : 4; // if we're writing, there are 4 bytes of data, otherwise, just the length above 00314 break; 00315 default: 00316 size = 0; 00317 break; 00318 } 00319 00320 Serial_SetChar( SERIAL_0, (size >> 8) & 0xFF ); // send the most significant bit 00321 Serial_SetChar( SERIAL_0, size & 0xFF ); // then the LSB 00322 packet->crc = 0; // just in case it hasn't been initialized. 00323 uint8* p = (uint8*)packet; 00324 while( size-- ) 00325 { 00326 Serial_SetChar( SERIAL_0, *p ); 00327 packet->crc += *p++; 00328 } 00329 //uint8 test = 0xFF - packet->crc; 00330 Serial_SetChar( SERIAL_0, 0xFF - packet->crc ); 00331 return CONTROLLER_OK; 00332 } 00333 00334 /** 00335 Initialize a packet before reading into it. 00336 @param packet The XBeePacket to initialize. 00337 @see XBee_GetPacket( ) 00338 */ 00339 void XBee_ResetPacket( XBeePacket* packet ) 00340 { 00341 packet->dataPtr = (uint8*)packet; 00342 packet->crc = 0; 00343 packet->rxState = XBEE_PACKET_RX_START; 00344 packet->length = 0; 00345 packet->index = 0; 00346 packet->apiId = 0; 00347 memset( packet->payload, 0, 100 ); 00348 } 00349 00350 /** 00351 Checks to see if a packet is receiving a message 00352 @param packet The XBeePacket to check 00353 @returns true if the packet is busy, false if it's free 00354 */ 00355 int XBee_IsBusyPacket( XBeePacket* packet ) 00356 { 00357 return ( packet->rxState != XBEE_PACKET_RX_START ); 00358 } 00359 00360 /** 00361 Set a module into packet API mode. 00362 XBee modules are in transparent serial port mode by default. This allows you to work with them 00363 via the packet API. 00364 00365 When setting this on, the XBee module needs to wait 1 second after sending the command sequence before it's 00366 ready to receive any AT commands - this function will block for that amount of time. Once you turn it off, 00367 you won't get any responses to packets you send the module until you turn packet mode on again. 00368 @param value 1 to turn packet mode on, 0 to turn it off. 00369 00370 \par Example 00371 \code 00372 MyTask( void * p ) 00373 { 00374 XBeeConfig_SetPacketApiMode( 1 ); // initialize the module to be in API mode 00375 while( 1 ) 00376 { 00377 // your task here. 00378 } 00379 } 00380 \endcode 00381 */ 00382 void XBeeConfig_SetPacketApiMode( int value ) 00383 { 00384 if( CONTROLLER_OK != XBee_SetActive( 1 ) ) 00385 return; 00386 00387 if( value ) 00388 { 00389 char buf[50]; 00390 sprintf( buf, "+++" ); // enter command mode 00391 Serial_Write( SERIAL_0, (uchar*)buf, strlen(buf), 0 ); 00392 Sleep( 1025 ); // have to wait one second after +++ to actually get set to receive in AT mode 00393 sprintf( buf, "ATAP1,CN\r" ); // turn API mode on, and leave command mode 00394 Serial_Write( SERIAL_0, (uchar*)buf, strlen(buf), 0 ); 00395 Sleep(50); 00396 Serial_Flush( SERIAL_0 ); // rip the OKs out of there 00397 } 00398 else 00399 { 00400 XBeePacket xbp; 00401 uint8 params[4]; 00402 memset( params, 0, 4 ); 00403 XBee_CreateATCommandPacket( &xbp, 0, "AP", params, 4 ); 00404 XBee_SendPacket( &xbp, 4 ); 00405 } 00406 } 00407 00408 /** 00409 Query whether the module is in API mode. 00410 This will block for up to a 1/2 second waiting for a response from the XBee module. 00411 @return 0 if off, 1 if enabled, 2 if enabled with escape characters. 00412 00413 \par Example 00414 \code 00415 int mode = XBeeConfig_RequestPacketApiMode( ); 00416 if( mode >= 0 ) 00417 { 00418 // then we have our mode 00419 } 00420 \endcode 00421 */ 00422 int XBeeConfig_RequestPacketApiMode( ) 00423 { 00424 XBeePacket xbp; 00425 XBee_CreateATCommandPacket( &xbp, 0x52, "AP", NULL, 0 ); 00426 XBee_SendPacket( &xbp, 0 ); 00427 return CONTROLLER_OK; 00428 } 00429 00430 /** 00431 A convenience function for creating an AT command packet. 00432 As per the XBee spec, AT Command packets that want to set/write a value must have 4 bytes of data. 00433 Packets that query the value of an AT parameter send 0 bytes of data. Note that multi-byte 00434 data must be sent \b big-endian (most significant byte first) - see XBee_IntToBigEndianArray( ). 00435 00436 Make sure you're in API mode before creating & sending packets - see XBeeConfig_SetPacketApiMode( ). 00437 See the XBee documentation for the official list of AT commands that the XBee modules understand. 00438 @param packet The XBeePacket to create. 00439 @param frameID The frame ID for this packet that subsequent response/status messages can refer to. 00440 @param cmd The 2-character AT command. 00441 @param params A pointer to the buffer containing the data to be sent. 00442 @param datalength The number of bytes to send from the params buffer. 00443 00444 \par Example - Writing 00445 \code 00446 XBeePacket txPacket; 00447 uint8 params[4]; 00448 XBee_IntToBigEndianArray( 1000, params ); // set our sampling rate to 1000 00449 XBee_CreateATCommandPacket( &txPacket, 0, "IR", ¶ms, 4 ); // set the sampling rate of the IO pins 00450 XBee_SendPacket( &txPacket, 4 ); 00451 \endcode 00452 00453 \par Example - Reading 00454 \code 00455 XBeePacket txPacket; 00456 XBee_CreateATCommandPacket( &txPacket, 0, "IR", NULL, 0 ); // query the sampling rate of the IO pins 00457 XBee_SendPacket( &txPacket, 0 ); 00458 // then we'll receive a response packet 00459 \endcode 00460 */ 00461 void XBee_CreateATCommandPacket( XBeePacket* packet, uint8 frameID, char* cmd, uint8* params, uint8 datalength ) 00462 { 00463 packet->apiId = XBEE_ATCOMMAND; 00464 packet->atCommand.frameID = frameID; 00465 uint8* p = packet->atCommand.command; 00466 *p++ = *cmd++; 00467 *p++ = *cmd; 00468 p = packet->atCommand.parameters; 00469 while( datalength-- ) 00470 *p++ = *params++; 00471 } 00472 00473 /** 00474 Query the address of the module. 00475 This will block for up to a 1/2 second waiting for a response from the XBee module. 00476 @return An integer corresponding to the address of the module, or negative number on failure. 00477 00478 \par Example 00479 \code 00480 int address = XBeeConfig_RequestAddress( ); 00481 if( address >= 0 ) 00482 { 00483 // then we have our address 00484 } 00485 \endcode 00486 */ 00487 int XBeeConfig_RequestATResponse( char* cmd ) 00488 { 00489 XBeePacket xbp; 00490 XBee_CreateATCommandPacket( &xbp, 0x52, cmd, NULL, 0 ); 00491 XBee_SendPacket( &xbp, 0 ); 00492 return CONTROLLER_OK; 00493 } 00494 00495 /** 00496 Configure the IO settings on an XBee module. 00497 IO pins can have one of 5 values: 00498 - \b XBEE_IO_DISABLED 00499 - \b XBEE_IO_ANALOGIN - Analog input (10-bit) 00500 - \b XBEE_IO_DIGITALIN - Digital input 00501 - \b XBEE_IO_DIGOUT_HIGH - Digital out high 00502 - \b XBEE_IO_DIGOUT_LOW - Digital out low 00503 @param pin An integer specifying which pin to configure. There are 9 IO pins (numbered 0-8) on the XBee modules. 00504 Only channels 0-7 can be analog inputs - channel 8 can only operate as a digital in or out. 00505 @param value An int specifying the behavior of this pin (options shown above). 00506 \par Example 00507 \code 00508 // set channel 0 to analog in 00509 XBeeConfig_SetIO( 0, XBEE_IO_ANALOGIN ); 00510 \endcode 00511 */ 00512 void XBeeConfig_SetIO( int pin, int value ) 00513 { 00514 XBeePacket packet; 00515 XBee_ResetPacket( &packet ); 00516 uint8 params[4]; 00517 char cmd[2]; 00518 sprintf( cmd, "D%d", pin ); 00519 XBee_IntToBigEndianArray( value, params ); 00520 XBee_CreateATCommandPacket( &packet, 0, cmd, params, 4 ); 00521 XBee_SendPacket( &packet, 4 ); 00522 } 00523 00524 /** 00525 Query the configuration of an IO pin. 00526 See XBeeConfig_SetIO( ) for the possible return values. 00527 This will block for up to a 1/2 second waiting for a response from the XBee module. 00528 @return An integer corresponding to the config of the requested pin, or negative number on failure. 00529 00530 \par Example 00531 \code 00532 int pin = XBeeConfig_RequestIO( 0 ); // request the configuration of pin 0 00533 if( pin >= 0 ) 00534 { 00535 // then we have our pin config 00536 } 00537 \endcode 00538 */ 00539 int XBeeConfig_RequestIO( int pin ) 00540 { 00541 XBeePacket xbp; 00542 char cmd[2]; 00543 sprintf( cmd, "D%d", pin ); 00544 XBee_CreateATCommandPacket( &xbp, 0x52, cmd, NULL, 0 ); 00545 XBee_SendPacket( &xbp, 0 ); 00546 return CONTROLLER_OK; 00547 } 00548 00549 /** 00550 Create a packet to be transmitted with a 16-bit address. 00551 If the \b frameID is 0, you won't receive a TX Status message in response. 00552 00553 @param xbp The XBeePacket to create. 00554 @param frameID The frame ID for this packet that subsequent response/status messages can refer to. Set to 0 for no response. 00555 @param destination The destination address for this packet. Broadcast Address: 0xFFFF. 00556 @param options The XBee options for this packet (0 if none). 00557 @param data A pointer to the data to be sent in this packet. Up to 100 bytes. 00558 @param datalength The number of bytes of data to be sent. Maximum 100 bytes. 00559 @return True on success, false on failure. 00560 00561 \par Example 00562 \code 00563 XBeePacket txPacket; 00564 uint8 data[] = "ABC"; 00565 XBee_CreateTX16Packet( &txPacket, 0x52, 0, 0, data, 3 ); 00566 XBee_SendPacket( &txPacket, 3 ); 00567 \endcode 00568 */ 00569 bool XBee_CreateTX16Packet( XBeePacket* xbp, uint8 frameID, uint16 destination, uint8 options, uint8* data, uint8 datalength ) 00570 { 00571 xbp->apiId = XBEE_TX16; 00572 xbp->tx16.frameID = frameID; 00573 xbp->tx16.destination[0] = destination >> 8; 00574 xbp->tx16.destination[1] = destination & 0xFF; 00575 xbp->tx16.options = options; 00576 xbp->length = datalength + 5; 00577 uint8* p = xbp->tx16.data; 00578 while( datalength-- ) 00579 *p++ = *data++; 00580 return true; 00581 } 00582 00583 /** 00584 Create a packet to be transmitted with a 64-bit address. 00585 00586 @param xbp The XBeePacket to create. 00587 @param frameID The frame ID for this packet that subsequent response/status messages can refer to. Set to 0 for no response. 00588 @param destination The destination address for this packet. Broadcast Address: 0xFFFF (same as 16b broadcast address) 00589 @param options The XBee options for this packet (0 if none). 00590 @param data A pointer to the data to be sent in this packet. Up to 100 bytes. 00591 @param datalength The number of bytes of data to be sent. Maximum 100 bytes. 00592 @return True on success, false on failure. 00593 00594 \par Example 00595 \code 00596 XBeePacket txPacket; 00597 uint8 data[] = "ABCDE"; 00598 XBee_CreateTX16Packet( &txPacket, 0, 0, 0, data, 5 ); 00599 XBee_SendPacket( &txPacket, 5 ); 00600 \endcode 00601 */ 00602 bool XBee_CreateTX64Packet( XBeePacket* xbp, uint8 frameID, uint64 destination, uint8 options, uint8* data, uint8 datalength ) 00603 { 00604 uint8* p; 00605 int i; 00606 xbp->apiId = XBEE_TX64; 00607 xbp->tx64.frameID = frameID; 00608 for( i = 0; i < 8; i++ ) 00609 xbp->tx64.destination[i] = (destination >> 8*i) & (0xFF * i); // ???????? 00610 xbp->tx64.options = options; 00611 xbp->length = datalength + 5; 00612 p = xbp->tx64.data; 00613 while( datalength-- ) 00614 *p++ = *data++; 00615 return true; 00616 } 00617 00618 /** 00619 Unpack the info from an incoming packet with a 16-bit address. 00620 Pass \b NULL into any of the parameters you don't care about. 00621 @param xbp The XBeePacket to read from. 00622 @param srcAddress The 16-bit address of this packet. 00623 @param sigstrength The signal strength of this packet. 00624 @param options The XBee options for this packet. 00625 @param data A pointer that will be set to the data of this packet. 00626 @param datalength The length of data in this packet. 00627 @return True on success, false on failure. 00628 00629 \par Example 00630 \code 00631 XBeePacket rxPacket; 00632 if( XBee_GetPacket( &rxPacket, 0 ) ) 00633 { 00634 uint16 src; 00635 uint8 sigstrength; 00636 uint8* data; 00637 uint8 datalength; 00638 if( XBee_ReadRX16Packet( &rxPacket, &src, &sigstrength, NULL, &data, &datalength ) ) 00639 { 00640 // then process the new packet here 00641 XBee_ResetPacket( &rxPacket ); // and clear it out before reading again 00642 } 00643 } 00644 \endcode 00645 */ 00646 bool XBee_ReadRX16Packet( XBeePacket* xbp, uint16* srcAddress, uint8* sigstrength, uint8* options, uint8** data, uint8* datalength ) 00647 { 00648 if( xbp->apiId != XBEE_RX16 ) 00649 return false; 00650 00651 if( srcAddress ) 00652 { 00653 *srcAddress = xbp->rx16.source[0]; 00654 *srcAddress <<= 8; 00655 *srcAddress += xbp->rx16.source[1]; 00656 } 00657 if( sigstrength ) 00658 *sigstrength = xbp->rx16.rssi; 00659 if( options ) 00660 *options = xbp->rx16.options; 00661 if( data ) 00662 *data = xbp->rx16.data; 00663 if( datalength ) 00664 *datalength = xbp->length - 5; 00665 return true; 00666 } 00667 00668 /** 00669 Unpack the info from an incoming packet with a 64-bit address. 00670 Pass \b NULL into any of the parameters you don't care about. 00671 @param xbp The XBeePacket to read from. 00672 @param srcAddress The 64-bit address of this packet. 00673 @param sigstrength The signal strength of this packet. 00674 @param options The XBee options for this packet. 00675 @param data A pointer that will be set to the data of this packet. 00676 @param datalength The length of data in this packet. 00677 @return True on success, false on failure. 00678 00679 \par Example 00680 \code 00681 XBeePacket rxPacket; 00682 if( XBee_GetPacket( &rxPacket, 0 ) ) 00683 { 00684 uint64 src; 00685 uint8 sigstrength; 00686 uint8* data; 00687 uint8 datalength; 00688 if( XBee_ReadRX64Packet( &rxPacket, &src, &sigstrength, NULL, &data, &datalength ) ) 00689 { 00690 // then process the new packet here 00691 XBee_ResetPacket( &rxPacket ); // and clear it out before reading again 00692 } 00693 } 00694 \endcode 00695 */ 00696 bool XBee_ReadRX64Packet( XBeePacket* xbp, uint64* srcAddress, uint8* sigstrength, uint8* options, uint8** data, uint8* datalength ) 00697 { 00698 if( xbp->apiId != XBEE_RX64 ) 00699 return false; 00700 00701 int i; 00702 if( srcAddress ) 00703 { 00704 for( i = 0; i < 8; i++ ) 00705 { 00706 *srcAddress <<= i*8; 00707 *srcAddress += xbp->rx64.source[i]; 00708 } 00709 } 00710 if( sigstrength ) 00711 *sigstrength = xbp->rx64.rssi; 00712 if( options ) 00713 *options = xbp->rx64.options; 00714 if( data ) 00715 *data = xbp->rx64.data; 00716 if( datalength ) 00717 *datalength = xbp->length - 11; 00718 return true; 00719 } 00720 00721 /** 00722 Unpack the info from an incoming IO packet with a 16-bit address. 00723 When an XBee module has been given a sample rate, it will sample its IO pins according to their current configuration 00724 and send an IO packet with the sample data. This function will extract the sample info into an array of ints for you. 00725 There are 9 IO pins on the XBee modules, so be sure that the array you pass in has room for 9 ints. 00726 00727 Pass \b NULL into any of the parameters you don't care about. 00728 @param xbp The XBeePacket to read from. 00729 @param srcAddress A pointer to a uint16 that will be filled up with the 16-bit address of this packet. 00730 @param sigstrength A pointer to a uint8 that will be filled up with the signal strength of this packet. 00731 @param options A pointer to a uint8 that will be filled up with the XBee options for this packet. 00732 @param samples A pointer to an array of ints that will be filled up with the sample values from this packet. 00733 @return True on success, false on failure. 00734 @see XBeeConfig_SetSampleRate( ), XBeeConfig_SetIOs( ) 00735 00736 \par Example 00737 \code 00738 XBeePacket rxPacket; 00739 if( XBee_GetPacket( &rxPacket, 0 ) ) 00740 { 00741 uint16 src; 00742 uint8 sigstrength; 00743 int samples[9]; 00744 if( XBee_ReadIO16Packet( &rxPacket, &src, &sigstrength, NULL, samples ) ) 00745 { 00746 // then process the new packet here 00747 XBee_ResetPacket( &rxPacket ); // and clear it out before reading again 00748 } 00749 } 00750 \endcode 00751 */ 00752 bool XBee_ReadIO16Packet( XBeePacket* xbp, uint16* srcAddress, uint8* sigstrength, uint8* options, int* samples ) 00753 { 00754 if( xbp->apiId != XBEE_IO16 ) 00755 return false; 00756 if( srcAddress ) 00757 { 00758 *srcAddress = xbp->io16.source[0]; 00759 *srcAddress <<= 8; 00760 *srcAddress += xbp->io16.source[1]; 00761 } 00762 if( sigstrength ) 00763 *sigstrength = xbp->io16.rssi; 00764 if( options ) 00765 *options = xbp->io16.options; 00766 if( samples ) 00767 { 00768 if( !XBee_GetIOValues( xbp, samples ) ) 00769 return false; 00770 } 00771 return true; 00772 } 00773 00774 /** 00775 Unpack the info from an incoming IO packet with a 64-bit address. 00776 When an XBee module has been given a sample rate, it will sample its IO pins according to their current configuration 00777 and send an IO packet with the sample data. This function will extract the sample info into an array of ints for you. 00778 There are 9 IO pins on the XBee modules, so be sure that the array you pass in has room for 9 ints. 00779 00780 Pass \b NULL into any of the parameters you don't care about. 00781 @param xbp The XBeePacket to read from. 00782 @param srcAddress A pointer to a uint64 that will be filled up with the 16-bit address of this packet. 00783 @param sigstrength A pointer to a uint8 that will be filled up with the signal strength of this packet. 00784 @param options A pointer to a uint8 that will be filled up with the XBee options for this packet. 00785 @param samples A pointer to an array of ints that will be filled up with the sample values from this packet. 00786 @return True on success, false on failure. 00787 @see XBeeConfig_SetSampleRate( ), XBeeConfig_SetIOs( ) 00788 00789 \par Example 00790 \code 00791 XBeePacket rxPacket; 00792 if( XBee_GetPacket( &rxPacket, 0 ) ) 00793 { 00794 uint64 src; 00795 uint8 sigstrength; 00796 int samples[9]; 00797 if( XBee_ReadIO16Packet( &rxPacket, &src, &sigstrength, NULL, samples ) ) 00798 { 00799 // then process the new packet here 00800 XBee_ResetPacket( &rxPacket ); // and clear it out before reading again 00801 } 00802 } 00803 \endcode 00804 */ 00805 bool XBee_ReadIO64Packet( XBeePacket* xbp, uint64* srcAddress, uint8* sigstrength, uint8* options, int* samples ) 00806 { 00807 if( xbp->apiId != XBEE_RX64 ) 00808 return false; 00809 if( srcAddress ) 00810 { 00811 int i; 00812 for( i = 0; i < 8; i++ ) 00813 { 00814 *srcAddress <<= i*8; 00815 *srcAddress += xbp->io64.source[i]; 00816 } 00817 } 00818 if( sigstrength ) 00819 *sigstrength = xbp->io64.rssi; 00820 if( options ) 00821 *options = xbp->io64.options; 00822 if( samples ) 00823 { 00824 if( !XBee_GetIOValues( xbp, samples ) ) 00825 return false; 00826 } 00827 return true; 00828 } 00829 00830 /** 00831 Unpack the info from an incoming AT Command Response packet. 00832 In response to a previous AT Command message, the module will send an AT Command Response message. 00833 00834 Pass \b NULL into any of the parameters you don't care about. 00835 @param xbp The XBeePacket to read from. 00836 @param frameID A pointer to a uint64 that will be filled up with the 16-bit address of this packet. 00837 @param command A pointer to a uint8 that will be filled up with the signal strength of this packet. 00838 @param status A pointer to a uint8 that will be filled up with the XBee options for this packet. 00839 @param datavalue The value of the requested command. 00840 @return True on success, false on failure. 00841 00842 \par Example 00843 \code 00844 XBeePacket rxPacket; 00845 if( XBee_GetPacket( &rxPacket, 0 ) ) 00846 { 00847 uint8 frameID; 00848 char* command; 00849 uint8 status; 00850 int value = -1; 00851 if( XBee_ReadAtResponsePacket( &rxPacket, &frameID, command, &status, &value ) ) 00852 { 00853 // then process the new packet here 00854 XBee_ResetPacket( &rxPacket ); // and clear it out before reading again 00855 } 00856 } 00857 \endcode 00858 */ 00859 bool XBee_ReadAtResponsePacket( XBeePacket* xbp, uint8* frameID, char** command, uint8* status, int* datavalue ) 00860 { 00861 if( xbp->apiId != XBEE_ATCOMMANDRESPONSE ) 00862 return false; 00863 if( frameID ) 00864 *frameID = xbp->atResponse.frameID; 00865 if( command ) 00866 *command = (char*)xbp->atResponse.command; 00867 if( status ) 00868 *status = xbp->atResponse.status; 00869 if( datavalue ) 00870 { 00871 uint8 *dataPtr = xbp->atResponse.value; 00872 int i; 00873 int datalength = xbp->length - 5; // data comes after apiID, frameID, 2-bytes of cmd, and 1-byte status 00874 *datavalue = 0; 00875 for( i = 0; i < datalength; i++ ) 00876 { 00877 *datavalue <<= 8; 00878 *datavalue += *dataPtr++; 00879 } 00880 } 00881 return true; 00882 } 00883 00884 /** 00885 Unpack the info from TX Status packet. 00886 When a TX is completed, the modules esnds a TX Status message. This indicates whether the packet was transmitted 00887 successfully or not. If the message you sent had a frameID of 0, a TX status message will not be generated. 00888 00889 Pass \b NULL into any of the parameters you don't care about. 00890 @param xbp The XBeePacket to read from. 00891 @param frameID A pointer to a uint8 that will be filled up with the frame ID of this packet. 00892 @param status A pointer to a uint8 that will be filled up with the status of this packet. 00893 @return True on success, false on failure. 00894 00895 \par Example 00896 \code 00897 XBeePacket rxPacket; 00898 if( XBee_GetPacket( &rxPacket, 0 ) ) 00899 { 00900 uint8 frameID; 00901 uint8 status; 00902 if( XBee_ReadTXStatusPacket( &rxPacket, &frameID, &status ) ) 00903 { 00904 // then process the new packet here 00905 XBee_ResetPacket( &rxPacket ); // and clear it out before reading again 00906 } 00907 } 00908 \endcode 00909 */ 00910 bool XBee_ReadTXStatusPacket( XBeePacket* xbp, uint8* frameID, uint8* status ) 00911 { 00912 if( xbp->apiId != XBEE_TXSTATUS ) 00913 return false; 00914 if( frameID ) 00915 *frameID = xbp->txStatus.frameID; 00916 if( status ) 00917 *status = xbp->txStatus.status; 00918 return true; 00919 } 00920 00921 /** 00922 Save the configuration changes you've made on the module to memory. 00923 When you make configuration changes - setting the module to API mode, or configuring the sample rate, for example - 00924 those changes will be lost when the module restarts. Call this function to save the current state to non-volatile memory. 00925 00926 As with the other \b XBeeConfig functions, make sure you're in API mode before trying to use this function. 00927 @return True on success, false on failure. 00928 @see XBeeConfig_SetPacketApiMode( ) 00929 00930 \par Example 00931 \code 00932 XBeeConfig_SetPacketApiMode( ); 00933 XBeeConfig_SetSampleRate( 100 ); 00934 XBeeConfig_WriteStateToMemory( ); 00935 \endcode 00936 */ 00937 void XBeeConfig_WriteStateToMemory( void ) 00938 { 00939 XBeePacket xbp; 00940 uint8 params[4]; 00941 memset( params, 0, 4 ); 00942 XBee_CreateATCommandPacket( &xbp, 0, "WR", params, 4 ); 00943 XBee_SendPacket( &xbp, 4 ); 00944 } 00945 00946 /** 00947 Set this module's address. 00948 00949 As with the other \b XBeeConfig functions, make sure you're in API mode before trying to use this function. 00950 @param address An integer specifying the module's address. 00951 @return True on success, false on failure. 00952 @see XBeeConfig_SetPacketApiMode( ) 00953 00954 \par Example 00955 \code 00956 XBeeConfig_SetPacketApiMode( ); 00957 XBeeConfig_SetAddress( 100 ); 00958 XBeeConfig_WriteStateToMemory( ); 00959 \endcode 00960 */ 00961 void XBeeConfig_SetAddress( uint16 address ) 00962 { 00963 XBeePacket xbp; 00964 uint8 params[4]; // big endian - most significant bit first 00965 XBee_IntToBigEndianArray( address, params ); 00966 XBee_CreateATCommandPacket( &xbp, 0, "MY", params, 4 ); 00967 XBee_SendPacket( &xbp, 4 ); 00968 } 00969 00970 /** 00971 Query the address of the module. 00972 This will block for up to a 1/2 second waiting for a response from the XBee module. 00973 @return An integer corresponding to the address of the module, or negative number on failure. 00974 00975 \par Example 00976 \code 00977 int address = XBeeConfig_RequestAddress( ); 00978 if( address >= 0 ) 00979 { 00980 // then we have our address 00981 } 00982 \endcode 00983 */ 00984 int XBeeConfig_RequestAddress( ) 00985 { 00986 XBeePacket xbp; 00987 XBee_CreateATCommandPacket( &xbp, 0x52, "MY", NULL, 0 ); 00988 XBee_SendPacket( &xbp, 0 ); 00989 return CONTROLLER_OK; 00990 } 00991 00992 /** 00993 Set this PAN (Personal Area Network) ID. 00994 Only modules with matching PAN IDs can communicate with each other. Unique PAN IDs enable control of which 00995 RF packets are received by a module. Default is \b 0x3332. 00996 00997 As with the other \b XBeeConfig functions, make sure you're in API mode before trying to use this function. 00998 @param id A uint16 specifying the PAN ID. 00999 @return True on success, false on failure. 01000 @see XBeeConfig_SetPacketApiMode( ) 01001 01002 \par Example 01003 \code 01004 XBeeConfig_SetPacketApiMode( ); 01005 XBeeConfig_SetPanID( 0x1234 ); 01006 \endcode 01007 */ 01008 void XBeeConfig_SetPanID( uint16 id ) 01009 { 01010 XBeePacket xbp; 01011 uint8 params[4]; // big endian - most significant bit first 01012 XBee_IntToBigEndianArray( id, params ); 01013 XBee_CreateATCommandPacket( &xbp, 0, "ID", params, 4 ); 01014 XBee_SendPacket( &xbp, 4 ); 01015 } 01016 01017 /** 01018 Query the PAN ID of the module. 01019 This will block for up to a 1/2 second waiting for a response from the XBee module. 01020 @return An integer corresponding to the PAN ID of the module, or negative number on failure. 01021 01022 \par Example 01023 \code 01024 int panid = XBeeConfig_RequestPanID( ); 01025 if( panid >= 0 ) 01026 { 01027 // then we have our pan id 01028 } 01029 \endcode 01030 */ 01031 int XBeeConfig_RequestPanID( ) 01032 { 01033 XBeePacket xbp; 01034 XBee_CreateATCommandPacket( &xbp, 0x52, "ID", NULL, 0 ); 01035 XBee_SendPacket( &xbp, 0 ); 01036 return CONTROLLER_OK; 01037 } 01038 01039 /** 01040 Set the module's channel. 01041 The channel is one of 3 addressing options available to the module - the others are the PAN ID and the 01042 destination address. In order for modules to communicate with each other, the modules must share the same 01043 channel number. Default is \b 0x0C. 01044 01045 This value can have the range \b 0x0B - \b 0x1A for XBee modules, and \b 0x0C - \b 0x17 for XBee-Pro modules. 01046 01047 As with the other \b XBeeConfig functions, make sure you're in API mode before trying to use this function. 01048 @param channel A uint8 specifying the channel. 01049 @return True on success, false on failure. 01050 @see XBeeConfig_SetPacketApiMode( ) 01051 01052 \par Example 01053 \code 01054 XBeeConfig_SetPacketApiMode( ); 01055 XBeeConfig_SetChannel( 0x0D ); 01056 \endcode 01057 */ 01058 void XBeeConfig_SetChannel( uint8 channel ) 01059 { 01060 XBeePacket xbp; 01061 uint8 params[4]; 01062 XBee_IntToBigEndianArray( channel, params ); 01063 XBee_CreateATCommandPacket( &xbp, 0, "CH", params, 4 ); 01064 XBee_SendPacket( &xbp, 4 ); 01065 } 01066 01067 /** 01068 Query the channel of the module. 01069 This will block for up to a 1/2 second waiting for a response from the XBee module. 01070 @return An integer corresponding to the channel of the module, or negative number on failure. 01071 01072 \par Example 01073 \code 01074 int chan = XBeeConfig_RequestChannel( ); 01075 if( chan >= 0 ) 01076 { 01077 // then we have our channel 01078 } 01079 \endcode 01080 */ 01081 int XBeeConfig_RequestChannel( ) 01082 { 01083 XBeePacket xbp; 01084 XBee_CreateATCommandPacket( &xbp, 0x52, "CH", NULL, 0 ); 01085 XBee_SendPacket( &xbp, 0 ); 01086 return CONTROLLER_OK; 01087 } 01088 01089 /** 01090 Set the rate at which the module will sample its IO pins. 01091 When the sample rate is set, the module will sample all its IO pins according to its current IO configuration and send 01092 a packet with the sample data. If this is set too low and the IO configuration is sampling too many channels, 01093 the RF module won't be able to keep up. You can also adjust how many samples are gathered before a packet is sent. 01094 01095 As with the other \b XBeeConfig functions, make sure you're in API mode before trying to use this function. 01096 @param rate A uint16 specifying the sample rate in milliseconds. 01097 @return True on success, false on failure. 01098 @see XBeeConfig_SetIOs( ), XBeeConfig_SetPacketApiMode( ) 01099 01100 \par Example 01101 \code 01102 XBeeConfig_SetPacketApiMode( ); 01103 XBeeConfig_SetSampleRate( 0x14 ); 01104 \endcode 01105 */ 01106 void XBeeConfig_SetSampleRate( uint16 rate ) 01107 { 01108 XBeePacket xbp; 01109 uint8 params[4]; // big endian - most significant bit first 01110 XBee_IntToBigEndianArray( rate, params ); 01111 XBee_CreateATCommandPacket( &xbp, 0, "IR", params, 4 ); 01112 XBee_SendPacket( &xbp, 4 ); 01113 } 01114 01115 /** 01116 Query the sample rate of the module. 01117 This will block for up to a 1/2 second waiting for a response from the XBee module. 01118 @return An integer corresponding to the sample rate of the module, or negative number on failure. 01119 01120 \par Example 01121 \code 01122 int rate = XBeeConfig_RequestSampleRate( ); 01123 if( rate >= 0 ) 01124 { 01125 // then we have our rate 01126 } 01127 \endcode 01128 */ 01129 int XBeeConfig_RequestSampleRate( ) 01130 { 01131 XBeePacket xbp; 01132 XBee_CreateATCommandPacket( &xbp, 0x52, "IR", NULL, 0 ); 01133 XBee_SendPacket( &xbp, 0 ); 01134 return CONTROLLER_OK; 01135 } 01136 01137 /** 01138 Convert a 32-bit integer into a big endian array of 4 unsigned 8-bit integers. 01139 This is mostly useful for sending AT Command packets. 01140 @param value The value to convert. 01141 @param array An array of 4 unsigned 8-bit integers (uint8). Be sure you have 4. 01142 \par Example 01143 see XBee_CreateATCommandPacket( ) for an example. 01144 */ 01145 void XBee_IntToBigEndianArray( int value, uint8* array ) 01146 { 01147 array[0] = (value >> 24) & 0xFF; 01148 array[1] = (value >> 16) & 0xFF; 01149 array[2] = (value >> 8) & 0xFF; 01150 array[3] = value & 0xFF; 01151 } 01152 01153 /** @} 01154 */ 01155 01156 /** 01157 Unpack IO values from an incoming packet. 01158 @param packet The XBeePacket to read from. 01159 @param inputs An array of at least 9 integers, which will be populated with the values of the 9 input lines on the XBee module. 01160 @return 1 if IO values were successfully retrieved, otherwise zero. 01161 01162 \par Example 01163 \code 01164 XBeePacket rxPacket; 01165 if( XBee_GetPacket( &rxPacket, 0 ) ) 01166 { 01167 int inputs[9]; 01168 if( XBee_GetIOValues( &rxPacket, inputs ) ) 01169 { 01170 // process new input values here 01171 } 01172 } 01173 \endcode 01174 */ 01175 static bool XBee_GetIOValues( XBeePacket* packet, int *inputs ) 01176 { 01177 if( packet->apiId == XBEE_IO16 || packet->apiId == XBEE_IO64 ) 01178 { 01179 int i; 01180 static bool enabled; 01181 int digitalins = 0; 01182 uint8* p; 01183 int channelIndicators; 01184 if( packet->apiId == XBEE_IO16 ) 01185 { 01186 p = packet->io16.data; 01187 channelIndicators = (packet->io16.channelIndicators[0] << 0x08) | packet->io16.channelIndicators[1]; 01188 } 01189 else // packet->apiId == XBEE_IO64 01190 { 01191 p = packet->io64.data; 01192 channelIndicators = (packet->io64.channelIndicators[0] << 0x08) | packet->io64.channelIndicators[1]; 01193 } 01194 01195 for( i = 0; i < XBEE_INPUTS; i++ ) 01196 { 01197 enabled = channelIndicators & 1; 01198 channelIndicators >>= 1; 01199 if( i < 9 ) // digital ins 01200 { 01201 inputs[i] = 0; // zero out the 9 inputs beforehand 01202 if( enabled ) 01203 { 01204 if( !digitalins ) 01205 { 01206 int dig0 = *p++ << 0x08; 01207 digitalins = dig0 | *p++; 01208 } 01209 inputs[i] = ((digitalins >> i) & 1) * 1023; 01210 } 01211 } 01212 else // analog ins 01213 { 01214 if( enabled ) 01215 { 01216 int ain_msb = *p++ << 0x08; 01217 inputs[i-9] = ain_msb | *p++; 01218 } 01219 } 01220 } 01221 return true; 01222 } 01223 else 01224 return false; 01225 } 01226 01227 #ifdef OSC 01228 #include "osc.h" 01229 01230 /** \defgroup XBeeOSC XBee - OSC 01231 Communicate with XBee modules with the Make Controller Kit via OSC. 01232 \ingroup OSC 01233 01234 \section devices Devices 01235 There can only be one XBee board connected to the Make Controller Kit's serial port at a time, 01236 so there is not a device index in XBee OSC messages. 01237 01238 \section properties Properties 01239 The XBee system has the following properties: 01240 - autosend 01241 - io16 01242 - io64 01243 - rx16 01244 - rx64 01245 - tx16 01246 - tx64 01247 - tx-status 01248 - active 01249 01250 \par Autosend 01251 The \b autosend property corresponds to whether the Make Controller will automatically send out 01252 messages it receives from a connected XBee module. By default, this is turned off. 01253 To turn this on, send the message 01254 \verbatim /xbee/autosend 1 \endverbatim 01255 and to turn it off, send 01256 \verbatim /xbee/autosend 0 \endverbatim 01257 All autosend messages send at the same interval. You can set this interval, in 01258 milliseconds, by sending the message 01259 \verbatim /system/autosend-interval 10 \endverbatim 01260 so that messages will be sent every 10 milliseconds. This can be anywhere from 1 to 5000 milliseconds. 01261 \par 01262 You also need to select whether the board should send to you over USB or Ethernet. Send 01263 \verbatim /system/autosend-usb 1 \endverbatim 01264 to send via USB, and 01265 \verbatim /system/autosend-udp 1 \endverbatim 01266 to send via Ethernet. Via Ethernet, the board will send messages to the last address it received a message from. 01267 01268 \par io16 01269 The \b io16 property corresponds to an incoming message from an XBee module with samples 01270 from its IO pins. The best way to use this is to turn the XBee system's autosend property 01271 on - then the Make Controller can relay io16 messages as soon as they're received. 01272 \par 01273 Once you've turned on autosend, if there are boards on your network that are sending IO packets, 01274 you'll receive messages like 01275 \verbatim /xbee/io16 1234 28 12 0 0 1023 1023 0 512 0 1023 \endverbatim 01276 The first two numbers are: 01277 -# the address of the module that sent the message (1234 in the example above) 01278 -# signal strength (28 above) 01279 \par 01280 The next 9 numbers are the values from the 9 IO pins on the XBee module. 01281 01282 \par io64 01283 The \b io64 property corresponds to an incoming message from an XBee module with samples from its IO 01284 pins. This message is just like the \b io16 message, except it's coming from a board with a 64-bit 01285 address, rather than a 16-bit address. The structure of the message is the same (see above). 01286 01287 \par rx16 01288 The \b rx16 property corresponds to an incoming message from a 16-bit address XBee module with arbitrary data. 01289 The best way to use this is to turn the XBee system's autosend property 01290 on - then the Make Controller can relay rx16 messages as soon as they're received. 01291 \par 01292 Once you've turned on autosend, if there are boards on your network that are sending IO packets, 01293 you'll receive messages like 01294 \verbatim /xbee/rx16 1234 28 0 [43 44 45 32 46 47 48] \endverbatim 01295 The first three numbers are: 01296 -# the address of the module that sent the message (1234 in the example above) 01297 -# signal strength (28 above) 01298 -# the options byte (0 above), respectively. 01299 \par 01300 Following those is an OSC blob with the data (enclosed in square brackets above). These are the hex values for each byte of data. 01301 01302 \par rx64 01303 The \b rx64 property corresponds to an incoming message from an XBee module with samples from its IO 01304 pins. This message is just like the \b io16 message, except it's coming from a board with a 64-bit 01305 address, rather than a 16-bit address. The structure of the message is the same (see above). 01306 01307 \par Transmit Status 01308 The \b tx-status property gives you the status of a previously sent message. It tells you the frameID of the message 01309 that was sent and its status, which can be one of: 01310 - \b Success. Message was successfully transmitted and received. 01311 - <b> No acknowledgement received</b>. The message was successfully sent, but not successfully received on the other end. 01312 - <b> CCA Failure</b>. 01313 - \b Purged. 01314 \par 01315 If you don't include a frameID for the message that you sent, a tx-status message will not be generated. An example 01316 tx-status message will look like 01317 \verbatim /xbee/tx-status 52 Success \endverbatim 01318 where 52 is the frameID and "Success" is the status. 01319 01320 \par Active 01321 The \b active property corresponds to the active state of the XBee system. 01322 If you're not seeing appropriate responses to your messages to the XBee system, 01323 check whether it's active by sending the message 01324 \verbatim /xbee/active \endverbatim 01325 \par 01326 You can set the active flag by sending 01327 \verbatim /xbee/active 1 \endverbatim 01328 */ 01329 01330 01331 bool XBee_GetAutoSend( bool init ) 01332 { 01333 XBee_SetActive( 1 ); 01334 if( init ) 01335 { 01336 int autosend; 01337 Eeprom_Read( EEPROM_XBEE_AUTOSEND, (uchar*)&autosend, 4 ); 01338 XBee->autosend = (autosend == 1 ) ? 1 : 0; 01339 } 01340 return XBee->autosend; 01341 } 01342 01343 void XBee_SetAutoSend( int onoff ) 01344 { 01345 XBee_SetActive( 1 ); 01346 if( XBee->autosend != onoff ) 01347 { 01348 XBee->autosend = onoff; 01349 Eeprom_Write( EEPROM_XBEE_AUTOSEND, (uchar*)&onoff, 4 ); 01350 } 01351 } 01352 01353 static char* XBeeOsc_Name = "xbee"; 01354 static char* XBeeOsc_PropertyNames[] = { "active", "io16", "rx16", "autosend", "get-message", 0 }; // must have a trailing 0 01355 01356 int XBeeOsc_PropertySet( int property, char* typedata, int channel ); 01357 int XBeeOsc_PropertyGet( int property, int channel ); 01358 01359 const char* XBeeOsc_GetName( void ) 01360 { 01361 return XBeeOsc_Name; 01362 } 01363 01364 int XBeeOsc_ReceiveMessage( int channel, char* message, int length ) 01365 { 01366 XBee_SetActive( 1 ); 01367 int status = Osc_GeneralReceiverHelper( channel, message, length, 01368 XBeeOsc_Name, 01369 XBeeOsc_PropertySet, XBeeOsc_PropertyGet, 01370 XBeeOsc_PropertyNames ); 01371 01372 if ( status != CONTROLLER_OK ) 01373 return Osc_SendError( channel, XBeeOsc_Name, status ); 01374 01375 return CONTROLLER_OK; 01376 } 01377 01378 int XBeeOsc_PropertySet( int property, char* typedata, int channel ) 01379 { 01380 switch ( property ) 01381 { 01382 case 0: // active 01383 { 01384 int value; 01385 int count = Osc_ExtractData( typedata, "i", &value ); 01386 if ( count != 1 ) 01387 return Osc_SubsystemError( channel, XBeeOsc_Name, "Incorrect data - need an int" ); 01388 01389 XBee_SetActive( value ); 01390 break; 01391 } 01392 case 1: // io16 01393 case 2: // rx16 01394 return Osc_SubsystemError( channel, XBeeOsc_Name, "Property is read-only" ); 01395 case 3: // autosend 01396 { 01397 int value; 01398 int count = Osc_ExtractData( typedata, "i", &value ); 01399 if ( count != 1 ) 01400 return Osc_SubsystemError( channel, XBeeOsc_Name, "Incorrect data - need an int" ); 01401 01402 XBee_SetAutoSend( value ); 01403 break; 01404 } 01405 } 01406 return CONTROLLER_OK; 01407 } 01408 01409 int XBeeOsc_PropertyGet( int property, int channel ) 01410 { 01411 switch ( property ) 01412 { 01413 case 0: // active 01414 { 01415 char address[ OSC_SCRATCH_SIZE ]; 01416 int value = XBee_GetActive( ); 01417 snprintf( address, OSC_SCRATCH_SIZE, "/%s/%s", XBeeOsc_Name, XBeeOsc_PropertyNames[ property ] ); 01418 Osc_CreateMessage( channel, address, ",i", value ); 01419 break; 01420 } 01421 case 1: // io16 01422 case 2: // rx16 01423 return Osc_SubsystemError( channel, XBeeOsc_Name, "Can't get specific messages - use /xbee/get-message instead." ); 01424 case 3: // autosend 01425 { 01426 char address[ OSC_SCRATCH_SIZE ]; 01427 int value = XBee_GetAutoSend( false ); 01428 snprintf( address, OSC_SCRATCH_SIZE, "/%s/%s", XBeeOsc_Name, XBeeOsc_PropertyNames[ property ] ); 01429 Osc_CreateMessage( channel, address, ",i", value ); 01430 break; 01431 } 01432 case 4: // get-message 01433 { 01434 XBeePacket xbp; 01435 if( XBee_GetPacket( &xbp, XBEE_OSC_RX_TIMEOUT ) ) 01436 XBeeOsc_HandleNewPacket( XBee->currentPkt, channel ); 01437 break; 01438 } 01439 } 01440 return CONTROLLER_OK; 01441 } 01442 01443 /** \defgroup XBeeConfigOSC XBee Configuration - OSC 01444 Configure an XBee module connected to your Make Controller Kit via OSC. 01445 \ingroup OSC 01446 01447 \section devices Devices 01448 There can only be one XBee board connected to the Make Controller Kit's serial port at a time, 01449 so there is not a device index in XBee Config OSC messages. 01450 01451 \section properties Properties 01452 The XBee Config system has the following properties: 01453 - write 01454 - get-message 01455 - packet-mode 01456 - samplerate 01457 - address 01458 - panid 01459 - channel 01460 - at-command 01461 - io 01462 - active 01463 01464 Reading values from the XBee Config system is a bit different than the other systems. Because we need to see any messages 01465 that arrive at the XBee module and not just the one we're requesting at a given moment, to get any message back you need to 01466 use the \b get-message property. Imagine the case where we want to ask the module its address, but another module is busy 01467 sending us sensor values. If we waited for the address message, we'd miss all the sensor values. 01468 01469 So to read a value, first send the request then call \b get-message until you get the response you're looking for. 01470 If you have autosend turned on, it will get messages for you, so you just need to send the request - this is much 01471 easier. 01472 01473 \par Write 01474 When you change any of the paramters of your XBee module, it will by default revert back to its previous settings 01475 when it gets powered down. The \b write property sets the current values (all of them) into memory. 01476 \par 01477 For example, to set the sample rate to 100 milliseconds, and save it permanently, send the messages 01478 \verbatim 01479 /xbeeconfig/samplerate 100 01480 /xbeeconfig/write 1 \endverbatim 01481 01482 \par Get Message 01483 The \b get-message property fetches the most recent message received by the XBee module. If you have autosend 01484 turned on, you don't need to use get-message and, in fact, it won't have any effect. 01485 To get a message from your XBee module, send the message 01486 \verbatim /xbeeconfig/get-message\endverbatim 01487 and the board will send one back if there were any available. 01488 01489 \par Sample Rate 01490 The \b samplerate property corresponds to how often the XBee module will sample its IO pins and send a message 01491 with those values. If it's set to 0, the module will not sample its IO pins. The maximum sample rate is 65535. 01492 When the sample rate is set very low, the XBee module cannot guarantee that it will be able to keep up with all 01493 the samples requested of it. 01494 \par 01495 To set the sample rate to once a second (every 1000 milliseconds), send the message 01496 \verbatim /xbeeconfig/samplerate 1000\endverbatim 01497 To read the sample rate, send the message 01498 \verbatim /xbeeconfig/samplerate \endverbatim 01499 01500 \par Address 01501 The \b address property corresponds to the address of the XBee module. Valid ranges for the address are 01502 from 0 - 65535. 01503 \par 01504 To set the address to 1234, send the message 01505 \verbatim /xbeeconfig/address 1234\endverbatim 01506 To read the address, send the message 01507 \verbatim /xbeeconfig/address \endverbatim 01508 01509 \par Channel 01510 The \b channel property corresponds to the channel of the XBee module. Valid ranges for the address are 01511 from 11 - 26 for XBee modules and 12 - 23 for XBee Pro modules. 01512 \par 01513 To set the channel to 15, send the message 01514 \verbatim /xbeeconfig/channel 15\endverbatim 01515 To read the channel, send the message 01516 \verbatim /xbeeconfig/channel \endverbatim 01517 01518 \par AT Command 01519 The \b at-command property allows you to read/write AT commands to your XBee module via OSC. The most common 01520 commands are included - samplerate, channel, address, etc. but this is helpful if you need to send any of the 01521 other commands to your module. To write a command, specify the 2-letter command and then the value to set. 01522 To enable encryption, for example, send the message 01523 \verbatim /xbeeconfig/at-command EE 1\endverbatim 01524 \par 01525 To read a value back via an AT command, simply send the 2-letter command you'd like to get the value for. 01526 To read back the hardware version, send the message 01527 \verbatim /xbeeconfig/at-command HV\endverbatim 01528 Check the XBee documentation for a complete list of commands the boards will respond to. 01529 01530 \par PAN ID 01531 The \b panid property corresponds to the Personal Area Network ID of the XBee module. Valid ranges for the address are 01532 from 0 - 65535. The default value is 13106. 01533 \par 01534 To set the PAN ID to 512, send the message 01535 \verbatim /xbeeconfig/panid 512\endverbatim 01536 To read the PAN ID, send the message 01537 \verbatim /xbeeconfig/panid \endverbatim 01538 01539 \par Input/Output Pins 01540 There are several \b io properties that allow you to configure each of the 9 IO pins on the XBee module. 01541 Pins can be set to one of 5 values: 01542 - \b 0 - disabled 01543 - \b 2 - analogin 01544 - \b 3 - digital in 01545 - \b 4 - digital out high 01546 - \b 5 - digital out low 01547 01548 \par 01549 There are 9 IO pins on the XBee module, numbered 0 - 8. Send messages to them by specifying \b io + their number. 01550 Pin 8 cannot be an analogin - it can only be a digital in or out. 01551 For example, to set IO 0 to analogin, send the message 01552 \verbatim /xbeeconfig/io0 2\endverbatim 01553 To set IO 6 to a digital in, send the message 01554 \verbatim /xbeeconfig/io6 3\endverbatim 01555 To read the configuration of pin 5, send the message 01556 \verbatim /xbeeconfig/io5 \endverbatim 01557 01558 \par Active 01559 The \b active property corresponds to the active state of the XBee system. 01560 If you're not seeing appropriate responses to your messages to the XBee system, 01561 check whether it's active by sending the message 01562 \verbatim /xbee/active \endverbatim 01563 \par 01564 You can set the active flag by sending 01565 \verbatim /xbee/active 1 \endverbatim 01566 */ 01567 01568 static char* XBeeConfigOsc_Name = "xbeeconfig"; 01569 static char* XBeeConfigOsc_PropertyNames[] = { "active", "address", "panid", "channel", "samplerate", 01570 "write", "io0", "io1", "io2", "io3", "io4", 01571 "io5", "io6", "io7", "io8", "packet-mode", "at-command", 01572 "get-message", "write-command", "confirm", 0 }; // must have a trailing 0 01573 01574 int XBeeConfigOsc_PropertySet( int property, char* typedata, int channel ); 01575 int XBeeConfigOsc_PropertyGet( int property, int channel ); 01576 01577 const char* XBeeConfigOsc_GetName( void ) 01578 { 01579 return XBeeConfigOsc_Name; 01580 } 01581 01582 int XBeeConfigOsc_PropertySet( int property, char* typedata, int channel ) 01583 { 01584 int value = -1; 01585 int count; 01586 switch ( property ) 01587 { 01588 case 0: // active 01589 count = Osc_ExtractData( typedata, "i", &value ); 01590 if ( count != 1 ) 01591 return Osc_SubsystemError( channel, XBeeConfigOsc_Name, "Incorrect data - need an int" ); 01592 XBee_SetActive( value ); 01593 break; 01594 case 1: // address 01595 count = Osc_ExtractData( typedata, "i", &value ); 01596 if ( count != 1 ) 01597 return Osc_SubsystemError( channel, XBeeConfigOsc_Name, "Incorrect data - need an int" ); 01598 XBeeConfig_SetAddress( value ); 01599 break; 01600 case 2: // panid 01601 count = Osc_ExtractData( typedata, "i", &value ); 01602 if ( count != 1 ) 01603 return Osc_SubsystemError( channel, XBeeConfigOsc_Name, "Incorrect data - need an int" ); 01604 XBeeConfig_SetPanID( value ); 01605 break; 01606 case 3: // channel 01607 count = Osc_ExtractData( typedata, "i", &value ); 01608 if ( count != 1 ) 01609 return Osc_SubsystemError( channel, XBeeConfigOsc_Name, "Incorrect data - need an int" ); 01610 XBeeConfig_SetChannel( value ); 01611 break; 01612 case 4: // samplerate 01613 count = Osc_ExtractData( typedata, "i", &value ); 01614 if ( count != 1 ) 01615 return Osc_SubsystemError( channel, XBeeConfigOsc_Name, "Incorrect data - need an int" ); 01616 XBeeConfig_SetSampleRate( value ); 01617 break; 01618 case 5: // write 01619 count = Osc_ExtractData( typedata, "i", &value ); 01620 if ( count != 1 ) 01621 return Osc_SubsystemError( channel, XBeeConfigOsc_Name, "Incorrect data - need an int" ); 01622 XBeeConfig_WriteStateToMemory( ); 01623 break; 01624 case 6: // io0 01625 case 7: // io1 01626 case 8: // io2 01627 case 9: // io3 01628 case 10: // io4 01629 case 11: // io5 01630 case 12: // io6 01631 case 13: // io7 01632 case 14: // io8 01633 count = Osc_ExtractData( typedata, "i", &value ); 01634 if ( count != 1 ) 01635 return Osc_SubsystemError( channel, XBeeConfigOsc_Name, "Incorrect data - need an int" ); 01636 XBeeConfig_SetIO( property - 6, value ); 01637 break; 01638 case 15: // packet-mode 01639 count = Osc_ExtractData( typedata, "i", &value ); 01640 if ( count != 1 ) 01641 return Osc_SubsystemError( channel, XBeeConfigOsc_Name, "Incorrect data - need an int" ); 01642 XBeeConfig_SetPacketApiMode( value ); 01643 break; 01644 case 16: // at-command 01645 { 01646 char* cmd; 01647 count = Osc_ExtractData( typedata, "si", &cmd, &value ); 01648 if ( count != 2 && count != 1 ) 01649 return Osc_SubsystemError( channel, XBeeConfigOsc_Name, "Incorrect data - need a string, optionally followed by an int" ); 01650 01651 if( count == 2 ) 01652 { 01653 XBeePacket xbp; 01654 uint8 params[4]; // big endian - most significant bit first 01655 XBee_IntToBigEndianArray( value, params ); 01656 XBee_CreateATCommandPacket( &xbp, 0, cmd, params, 4 ); 01657 XBee_SendPacket( &xbp, 4 ); 01658 } 01659 if( count == 1 ) // this is a little wonky, but this is actually a read. 01660 value = XBeeConfig_RequestATResponse( cmd ); 01661 break; 01662 } 01663 case 18: // write-command 01664 { 01665 char* cmd; 01666 count = Osc_ExtractData( typedata, "si", &cmd, &value ); 01667 if ( count != 2 ) 01668 return Osc_SubsystemError( channel, XBeeConfigOsc_Name, "Incorrect data - need a string and an int" ); 01669 XBeePacket xbp; 01670 uint8 params[4]; // big endian - most significant bit first 01671 XBee_IntToBigEndianArray( value, params ); 01672 XBee_CreateATCommandPacket( &xbp, 0, cmd, params, 4 ); 01673 XBee_SendPacket( &xbp, 4 ); 01674 XBee_ResetPacket( &xbp ); 01675 XBee_CreateATCommandPacket( &xbp, 0, "WR", NULL, 0 ); 01676 XBee_SendPacket( &xbp, 0 ); 01677 break; 01678 } 01679 case 19: // confirm 01680 { 01681 char* cmd; 01682 count = Osc_ExtractData( typedata, "si", &cmd, &value ); 01683 if ( count != 2 ) 01684 return Osc_SubsystemError( channel, XBeeConfigOsc_Name, "Incorrect data - need a string and an int" ); 01685 XBeePacket xbp; 01686 uint8 params[4]; // big endian - most significant bit first 01687 XBee_IntToBigEndianArray( value, params ); 01688 01689 XBee->waitingForConfirm = true; 01690 Sleep( System_GetAutoSendInterval( ) + 1 ); // make sure autosend isn't grabbing packets if it's on 01691 XBee_ResetPacket( XBee->currentPkt ); 01692 while( true ) 01693 { 01694 // send the setter 01695 XBee_CreateATCommandPacket( &xbp, 0x53, cmd, params, 4 ); 01696 XBee_SendPacket( &xbp, 4 ); 01697 XBee_ResetPacket( &xbp ); 01698 // then the getter 01699 XBee_CreateATCommandPacket( &xbp, 0x52, cmd, NULL, 0 ); 01700 XBee_SendPacket( &xbp, 0 ); 01701 XBee_ResetPacket( &xbp ); 01702 // and try to get it 01703 if( XBee_GetPacket( XBee->currentPkt, 5 ) ) 01704 { 01705 XBeeOsc_HandleNewPacket( XBee->currentPkt, channel ); 01706 break; 01707 } 01708 Sleep( 1 ); 01709 } 01710 XBee->waitingForConfirm = false; 01711 break; 01712 } 01713 } 01714 return CONTROLLER_OK; 01715 } 01716 01717 int XBeeConfigOsc_PropertyGet( int property, int channel ) 01718 { 01719 char address[ OSC_SCRATCH_SIZE ]; 01720 switch ( property ) 01721 { 01722 case 0: // active 01723 { 01724 int value = XBee_GetActive( ); 01725 snprintf( address, OSC_SCRATCH_SIZE, "/%s/%s", XBeeConfigOsc_Name, XBeeConfigOsc_PropertyNames[ property ] ); 01726 Osc_CreateMessage( channel, address, ",i", value ); 01727 break; 01728 } 01729 case 1: // address 01730 XBeeConfig_RequestAddress( ); 01731 break; 01732 case 2: // panid 01733 XBeeConfig_RequestPanID( ); 01734 break; 01735 case 3: // channel 01736 XBeeConfig_RequestChannel( ); 01737 break; 01738 case 4: // samplerate 01739 XBeeConfig_RequestSampleRate( ); 01740 break; 01741 case 6: // ios 01742 case 7: 01743 case 8: 01744 case 9: 01745 case 10: 01746 case 11: 01747 case 12: 01748 case 13: 01749 case 14: 01750 XBeeConfig_RequestIO( property - 6 ); // send the query 01751 break; 01752 case 15: // packet-mode 01753 XBeeConfig_RequestPacketApiMode( ); // send the query 01754 break; 01755 case 17: // get-message 01756 { 01757 XBeePacket xbp; 01758 if( XBee_GetPacket( &xbp, XBEE_OSC_RX_TIMEOUT ) ) 01759 XBeeOsc_HandleNewPacket( XBee->currentPkt, channel ); 01760 break; 01761 } 01762 } 01763 return CONTROLLER_OK; 01764 } 01765 01766 int XBeeConfigOsc_ReceiveMessage( int channel, char* message, int length ) 01767 { 01768 XBee_SetActive( 1 ); 01769 int status = Osc_GeneralReceiverHelper( channel, message, length, 01770 XBeeConfigOsc_Name, 01771 XBeeConfigOsc_PropertySet, XBeeConfigOsc_PropertyGet, 01772 XBeeConfigOsc_PropertyNames ); 01773 01774 if ( status != CONTROLLER_OK ) 01775 return Osc_SendError( channel, XBeeConfigOsc_Name, status ); 01776 01777 return CONTROLLER_OK; 01778 } 01779 01780 int XBeeOsc_HandleNewPacket( XBeePacket* xbp, int channel ) 01781 { 01782 char address[OSC_SCRATCH_SIZE]; 01783 int retval = xbp->apiId; 01784 switch( xbp->apiId ) 01785 { 01786 case XBEE_RX16: 01787 { 01788 uint16 srcAddr; 01789 uint8 sigStrength; 01790 uint8 opts; 01791 uint8* data; 01792 uint8 datalen; 01793 if( XBee_ReadRX16Packet( xbp, &srcAddr, &sigStrength, &opts, &data, &datalen ) ) 01794 { 01795 snprintf( address, OSC_SCRATCH_SIZE, "/%s/rx16", XBeeOsc_Name ); 01796 Osc_CreateMessage( channel, address, ",iiib", srcAddr, sigStrength, opts, data, datalen ); 01797 } 01798 break; 01799 } 01800 case XBEE_RX64: 01801 { 01802 uint64 srcAddr; 01803 uint8 sigStrength; 01804 uint8 opts; 01805 uint8* data; 01806 uint8 datalen; 01807 if( XBee_ReadRX64Packet( xbp, &srcAddr, &sigStrength, &opts, &data, &datalen ) ) 01808 { 01809 snprintf( address, OSC_SCRATCH_SIZE, "/%s/rx64", XBeeOsc_Name ); 01810 Osc_CreateMessage( channel, address, ",iiib", srcAddr, sigStrength, opts, data, datalen ); 01811 } 01812 break; 01813 } 01814 case XBEE_IO16: 01815 { 01816 int in[9]; 01817 uint16 src; 01818 uint8 sigstrength; 01819 if( XBee_ReadIO16Packet( xbp, &src, &sigstrength, NULL, in ) ) 01820 { 01821 snprintf( address, OSC_SCRATCH_SIZE, "/%s/io16", XBeeOsc_Name ); 01822 Osc_CreateMessage( channel, address, ",iiiiiiiiiii", src, sigstrength, 01823 in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7], in[8] ); 01824 } 01825 break; 01826 } 01827 case XBEE_IO64: 01828 { 01829 int in[9]; 01830 uint64 src; 01831 uint8 sigstrength; 01832 if( XBee_ReadIO64Packet( xbp, &src, &sigstrength, NULL, in ) ) 01833 { 01834 snprintf( address, OSC_SCRATCH_SIZE, "/%s/io64", XBeeOsc_Name ); 01835 Osc_CreateMessage( channel, address, ",iiiiiiiiiii", src, sigstrength, 01836 in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7], in[8] ); 01837 } 01838 break; 01839 } 01840 case XBEE_TXSTATUS: 01841 { 01842 uint8 frameID; 01843 uint8 status; 01844 if( XBee_ReadTXStatusPacket( xbp, &frameID, &status ) ) 01845 { 01846 snprintf( address, OSC_SCRATCH_SIZE, "/%s/tx-status", XBeeOsc_Name ); 01847 char* statusText = "No status received"; 01848 switch( status ) 01849 { 01850 case 0: 01851 statusText = "Success"; 01852 break; 01853 case 1: 01854 statusText = "No acknowledgement received"; 01855 break; 01856 case 2: 01857 statusText = "CCA Failure"; 01858 break; 01859 case 3: 01860 statusText = "Purged"; 01861 break; 01862 } 01863 Osc_CreateMessage( channel, address, ",is", frameID, statusText ); 01864 } 01865 break; 01866 } 01867 case XBEE_ATCOMMANDRESPONSE: 01868 { 01869 uint8 frameID; 01870 char* command; 01871 uint8 status; 01872 int value; 01873 if( XBee_ReadAtResponsePacket( xbp, &frameID, &command, &status, &value ) ) 01874 { 01875 char cmd[3]; 01876 cmd[0] = *command; 01877 cmd[1] = *(command+1); 01878 cmd[2] = '\0'; 01879 if( strcmp( cmd, "IR" ) == 0 ) 01880 { 01881 snprintf( address, OSC_SCRATCH_SIZE, "/%s/samplerate", XBeeConfigOsc_Name ); 01882 Osc_CreateMessage( channel, address, ",i", value ); 01883 } 01884 else if( strcmp( cmd, "MY" ) == 0 ) 01885 { 01886 snprintf( address, OSC_SCRATCH_SIZE, "/%s/address", XBeeConfigOsc_Name ); 01887 Osc_CreateMessage( channel, address, ",i", value ); 01888 } 01889 else if( strcmp( cmd, "CH" ) == 0 ) 01890 { 01891 snprintf( address, OSC_SCRATCH_SIZE, "/%s/channel", XBeeConfigOsc_Name ); 01892 Osc_CreateMessage( channel, address, ",i", value ); 01893 } 01894 else if( strcmp( cmd, "ID" ) == 0 ) 01895 { 01896 snprintf( address, OSC_SCRATCH_SIZE, "/%s/panid", XBeeConfigOsc_Name ); 01897 Osc_CreateMessage( channel, address, ",i", value ); 01898 } 01899 else 01900 { 01901 snprintf( address, OSC_SCRATCH_SIZE, "/%s/at-command", XBeeConfigOsc_Name ); 01902 Osc_CreateMessage( channel, address, ",si", cmd, value ); 01903 } 01904 } 01905 break; 01906 } 01907 } 01908 XBee_ResetPacket( xbp ); 01909 return retval; 01910 } 01911 01912 int XBeeOsc_Async( int channel ) 01913 { 01914 XBee_SetActive( 1 ); 01915 int newMsgs = 0; 01916 01917 if( !XBee_GetAutoSend( false ) || XBee->waitingForConfirm ) 01918 return newMsgs; 01919 01920 while( XBee_GetPacket( XBee->currentPkt, 0 ) ) 01921 { 01922 XBeeOsc_HandleNewPacket( XBee->currentPkt, channel ); 01923 newMsgs++; 01924 } 01925 return newMsgs; 01926 } 01927 01928 #endif // OSC 01929 01930
The Make Controller Kit is an open source project maintained by MakingThings.
MakingThings code is released under the Apache 2.0 license.
Bug tracker, development wiki and status can be found at http://dev.makingthings.com.
This document was last updated on 18 May 2009.