XBee API Code for BS2
I am interested in any API code that has been written for the Stamp. I have written my own API comm program and would appreciate comments!
It will talk to any Xbee connected to a serial terminal on a PC that is talking in API mode (subset of full API definition) and I have a C source code terminal program if any body is interested.
I am sure there are lot's better ways to do this and I would like to improve my programs.
It will talk to any Xbee connected to a serial terminal on a PC that is talking in API mode (subset of full API definition) and I have a C source code terminal program if any body is interested.
I am sure there are lot's better ways to do this and I would like to improve my programs.
' {$STAMP BS2px, XbeeTX.bpx, XbeeRX.bpx}
' {$PBASIC 2.5}
' -----[ Program Description ]---------------------------------------------
'
' This program is a Stamp terminal for a Xbee ZB radio with SIP adapter
' written by S.G. Moore 6/5/2011
'
'==============================================================================
'----------------------- XBee definitions ------------------------- 20011-05-27
'==============================================================================
' -----[ XBee I/O Definitions ]-------------------------------------------------
XBeeRX PIN 0
XBeeTX PIN 1
XBeeRTS PIN 2
' -----[ Xbee Constants ]-------------------------------------------------------
DemoAPI CON $0
TxAPI CON $1
RxAPI CON $2
argBuff CON 120
TxOK CON $1
RxOK CON $2
NoRx CON $3
TxBad CON $4
RxBad CON $5
Baud CON 396 ' 9600, 8, N
' -----[ Xbee Variables ]-------------------------------------------------------
char VAR Byte
idx VAR Byte
' -----[ Initialization ]--------------------------------------------------
CONFIGPIN DIRECTION, %0000000000000110
HIGH XbeeTX
GET argBuff, char
SELECT char
CASE TxOK
GOTO transmitComplete
CASE RxOK
GOTO receiveComplete
CASE NoRx
DEBUG "."
RUN RxAPI
CASE TxBad
DEBUG CR, "Bad TX.", CR
CASE RxBad
DEBUG CR, "Bad RX.", CR
ENDSELECT
' -----[ Program Code ]----------------------------------------------------
Main:
DO
DEBUG "Input string.", CR
char = 0
idx = 0
DO WHILE char <> $0D
DEBUGIN char
PUT idx, char
idx = idx + 1
LOOP
PUT (idx-1), 0
RUN TxAPI
transmitComplete:
RUN RxAPI
receiveComplete:
DEBUG CR, "Received string: "
idx = 0
GET idx, char
IF char = "T" THEN transmitComplete
DO WHILE char <> 0
DEBUG char
idx = idx + 1
GET idx, char
LOOP
DEBUG CR
LOOP
END
'XbeeTx.bpx
' {$STAMP BS2px}
' {$PBASIC 2.5}
'==============================================================================
'----------------------- XBee definitions ------------------------- 20011-05-27
'==============================================================================
' -----[ XBee I/O Definitions ]-------------------------------------------------
PIR1 PIN 0
PIR2 PIN 1
XBeeRX PIN 2
XBeeTX PIN 3
' -----------------[ Program Messaging Constants ]-------------------------------------
myApp CON $0 ' These values are slot ID's
TxAPI CON $1
RxAPI CON $2
argBuff CON 120 ' Scratch Pad RAM for passing Xbee messages
notInit CON $0
TxOK CON $1 ' These values are passed through argBuff
RxOK CON $2
NoRx CON $3
TxBad CON $4
RxBad CON $5
chkTX CON $6
initDone CON $7
Baud CON 396 ' 9600, 8, N
'-------------------------------------------------------------------------------
'------------------------[ Xbee TX API Header definition ]----------------------
'-------------------------------------------------------------------------------
'TX Data start, lenMSB, lenLSB, type, id, addr7, addr6, addr5, addr4, addr3, addr2, addr1, addr0, net1, net0, radius, options
' note: this address is for my Xstick on my PC, change if necessary
TX DATA $7E, $00, $00, $10, $01, $00, $13, $A2, $00, $40, $66, $C4, $F9, $FF, $FE, $00, $00
' -----[ Xbee Variables ]-------------------------------------------------------
idx VAR Byte
char VAR Byte
mlen VAR Byte
csum VAR Byte
msgAddr VAR Word
'============================== Message Definitions ===========================
msg1 DATA "Hello.",0
msg2 DATA "Zone 1 detect.",0
msg3 DATA "Zone 1 is clear.",0
' ------------------------------[ Program Code ]----------------------------
main:
GET argBuff, char
SELECT char
CASE 0 ' argBuff is set to 0 if myApp has assembled it's own message
GOTO messageSetup
CASE 1 ' otherwise a pre-recorded message is selected
msgAddr = msg1
CASE 2
msgAddr = msg2
CASE 3
msgAddr = msg3
ENDSELECT
'-------------------------------[ Message Setup ] ---------------------------
idx = 0 ' selects a pre-recorded message from EEPROm
DO WHILE char <> 0
READ msgAddr + idx, char
PUT idx, char
idx = idx + 1
LOOP
messageSetup:
FOR idx = 0 TO 16 ' assemble API TX packet starting at scratchpad RAM address 50
READ (TX + idx), char ' read message header from EEPROM
PUT (50+idx), char ' store Xbee API message starting at RAM 50
NEXT
mlen = 0
GET mlen, char ' get first character of message string
DO WHILE char <> 0
PUT (67 + mlen), char ' move the message to the TxAPI buffer
mlen = mlen + 1 ' count message length in characters
GET mlen, char ' get next character of message sring
LOOP
PUT 52, (mlen + 14)
csum = $00
FOR idx = 53 TO (66 + mlen) ' compute check sum (between LSB message length and CSUM)
GET idx, char
csum = csum + char ' checksum = $FF - sum(between LSB message length and CSUM)
NEXT
csum = $FF - csum
PUT (67 + mlen), csum
FOR idx = 50 TO (67 + mlen)
GET idx, char
SEROUT XbeeTX, Baud, [char] ' transmit the message to the Xbee UART
NEXT
PUT argBuff, ChkTX
RUN RxAPI
END
'XbeeRx.bpx
' {$STAMP BS2px}
' {$PBASIC 2.5}
'==============================================================================
'----------------------- XBee definitions ------------------------- 20011-05-27
'==============================================================================
' -----[ XBee I/O Definitions ]-------------------------------------------------
PIR1 PIN 0
PIR2 PIN 1
XBeeRX PIN 2
XBeeTX PIN 3
' -----------------[ Program Messaging Constants ]-------------------------------------
myApp CON $0 ' These values are slot ID's
TxAPI CON $1
RxAPI CON $2
argBuff CON 120 ' Scratch Pad RAM for passing Xbee messages
notInit CON $0
TxOK CON $1 ' These values are passed through argBuff
RxOK CON $2
NoRx CON $3
TxBad CON $4
RxBad CON $5
chkTX CON $6
initDone CON $7
Baud CON 396 ' 9600, 8, N
' -----[ Xbee Variables ]-------------------------------------------------------
idx VAR Byte
char VAR Byte
start VAR Byte
lenMSB VAR Byte
lenLSB VAR Byte
type VAR Byte
id VAR Byte
add7 VAR Byte
add6 VAR Byte
add5 VAR Byte
add4 VAR Byte
add3 VAR Byte
add2 VAR Byte
add1 VAR Byte
add0 VAR Byte
net1 VAR Byte
net0 VAR Byte
retry VAR Byte
TXstat VAR Byte
disc VAR Byte
option VAR Byte
csum VAR Byte
calc VAR Byte
' -----[ Program Code ]----------------------------------------------------
main:
GET argBuff, char
IF char = ChkTX THEN TXstatus
' read a message of Frame Type $90
SERIN XbeeRX, Baud, 1000, noMessage, [start, lenMSB,lenLSB, type, add7,add6, add5, add4, add3, add2, add1,add0, net1, net0, option]
SERIN XbeeRX, Baud, [SPSTR lenLSB-12, csum]
PUT (lenLSB - 12), 0
' DEBUG CR, "Message start: ", HEX2 start, CR
' DEBUG "Message size MSB: ", HEX2 lenMSB, CR
' DEBUG "Message size LSB: ", HEX2 lenLSB, CR
' DEBUG "Frame type: ", HEX2 type, CR
' DEBUG "Source 64bit ID: ", HEX2 add7, HEX2 add6, HEX2 add5, HEX2 add4, " ", HEX2 add3, HEX2 add2, HEX2 add1, HEX2 add0, CR
' DEBUG "Source net ID: ", HEX2 net1, " ", HEX2 net0, CR
' DEBUG "Packet option: ", HEX2 option, CR
' verify checksum on incoming message
calc = type+add7+add6+add5+add4+add3+add2+add1+add0+net1+net0+option
idx = 0
DO
GET idx, char
calc = calc + char
idx = idx + 1
LOOP WHILE char <> 0
calc = $FF - calc
IF calc = csum THEN
PUT argBuff, RxOK ' return to slot 0 with RxOK success code
ELSE
DEBUG CR, "Check sum error.", CR
PUT argBuff, RxBad
ENDIF
RUN myApp
TXstatus:
' read a message of Frame Type $8B
SERIN XbeeRX, Baud, [start, lenMSB, lenLSB, type,id, net1, net0, retry, TXstat, disc, csum]
IF TXstat <> $00 THEN
DEBUG "Transmission error code: ", TXstat, CR
PUT argBuff, TxBad
ELSE
' DEBUG "Transmission OK.", CR
PUT argBuff, TxOK
ENDIF
RUN myApp
noMessage:
PUT argBuff, NoRx ' signal program running in slot 0 that RX timeout occurred
RUN myApp
END

Comments
'
Your code is pretty slick....CRC to boot.
'
I would like to see your C pc interface.
'
I'm working with the XBee-WiFi units(XB24-WF) now.They are a little harder to use than the RovingNetworks RN-171/RN-174 but they seem to be more popular.
'
Great work on the BS2 code
Transmit
' {$STAMP BS2p} ' {$PBASIC 2.5} #SELECT $STAMP ' Select Baud constants #CASE BS2, BS2E, BS2PE T1200 CON 813 T2400 CON 396 T4800 CON 188 T9600 CON 84 T19K2 CON 32 #CASE BS2SX, BS2P T1200 CON 2063 T2400 CON 1021 T4800 CON 500 T9600 CON 240 T19K2 CON 110 #CASE BS2PX T1200 CON 3313 T2400 CON 1646 T4800 CON 813 T9600 CON 396 T19K2 CON 188 #ENDSELECT Inverted CON $4000 'Value for inverted serial format Baud CON T9600 '+ Inverted 8,N,1 inverted XBFlow1 CON $11 'flow control character XBFlow2 CON $13 'flow control character XBEsc CON $7D 'Escape control character XBDelim CON $7E 'API start delimiter XBModemSt CON $8A 'Modem Status XBATcmd CON $08 'AT command XBQueParm CON $09 'Queue parameter value XBResp CON $88 'AT command response XBRemReq CON $17 'Remote AT command request XBRemResp CON $97 'AT remote command response XBTx64 CON $00 'Request: 64-bit address XBTx16 CON $01 'Request: 16-bit address XBTxStat CON $89 'Transmuit Status XBRx64 CON $80 'Rx Packet: 64-bit address XBRx16 CON $81 'Rx Packet: 16-bit address XBOptions CON $04 'Send packet with Broadcast Pan ID RX PIN 0 ' XBee Receive Pin TX PIN 2 ' Xbee Transmit Pin RTS PIN 6 ' RTS flow control pin XBFrame VAR Byte 'frame number XBDestMSB VAR Byte 'Dest XBee address XBDestLSB VAR Byte 'Dest XBee address XBResult VAR Byte ' checksum calculation: add all bytes keeping only the lowest 8 bits of the result ' AND subtract from 0xFF (exclude frame delimiters AND length) XBCheckSum VAR Byte XBTxID VAR Byte 'Set to XBRx16 or XBRx64 XBData VAR Word 'Data value to transmit 0 to 65535 XBData4 VAR Byte '1st digit XBData3 VAR Byte '2nd XBData2 VAR Byte '3rd XBData1 VAR Byte '4th XBData0 VAR Byte '5th HIGH TX ' Idle transmit pin DEBUG CLS, "API TX - Configuring XBee..." PAUSE 2000 ' Guard time for command sequence SEROUT TX,Baud,["+++"] ' Enter command mode PAUSE 2000 ' Guard time for command sequence SEROUT TX,Baud,["ATNI XBee API TX",CR, ' Set description "ATMY ", HEX 2,CR, ' Set node address "ATDL ", HEX 1,CR, ' Set destination node address "ATD6 1",CR, ' Use RTS for flow control "ATAP 2",CR, ' API with escape characters "ATCN",CR] ' Exit command mode PAUSE 2000 XBTxID = XBTx16 'set for 16-bit transmit packet XBDestMSB = $00 '$FF for broadcast XBDestLSB = $01 '$FF for broadcast Main: FOR XBFrame = 11 TO 50 XBData = 1000 + (5 * XBFrame) ' RANDOM XBData GOSUB XBeeTx16 DEBUG CR PAUSE 500 NEXT PAUSE 3000 ' GOTO main END XBeeTx16: 'Convert to character by adding "0" (decimal 48) to each digit XBData4 = ( XBData DIG 4) + "0" XBData3 = ( XBData DIG 3) + "0" XBData2 = ( XBData DIG 2) + "0" XBData1 = ( XBData DIG 1) + "0" XBData0 = ( XBData DIG 0) + "0" XBCheckSum = XBTxID + XBFrame + XBDestMSB + XBDestLSB + XBOptions + XBData0 + XBData1 + XBData2 + XBData3 + XBData4 XBCheckSum = 255 - XBCheckSum DEBUG "Packet Type(", IHEX2 XBTxID, ")", CR DEBUG "Frame Counter: ", DEC XBFrame, CR DEBUG "Packet Destination: (", IHEX2 XBDestMSB, "), (", IHEX2 XBDestLSB, ")",CR DEBUG "Options: ", IHEX2 XBOptions, CR DEBUG "Data: (", XBData4, "), (", XBData3, "), (", XBData2,"), (", XBData1,"), (", XBData0,")",CR DEBUG "Checksum: ", DEC XBCheckSum, CR DEBUG "Dump: ", IHEX XBDelim, IHEX 0,IHEX 10, IHEX XBTxID,IHEX XBFrame,IHEX XBDestMSB,IHEX XBDestLSB,IHEX XBData0,IHEX XBData1,IHEX XBData2,IHEX XBData3,IHEX XBData4,IHEX XBCheckSum,CR SEROUT TX, Baud, [XBDelim,0,10,XBTxID,XBFrame,XBDestMSB,XBDestLSB,XBOptions,XBData4,XBData3,XBData2,XBData1,XBData0,XBCheckSum] 'SEROUT TX, Baud, [XBDelim,0,10,XBTxID,XBEsc,51,170,170,0,1,1,2,3,4,140] ' TX Good Status packet should look like: XBDelim,0,3,XBTxStat,XBFrame,0,34 SERIN RX, Baud,3000,main2, [WAIT(xbDelim),SKIP 2,WAIT(XBTxStat),XBData0,XBResult,SKIP 1] DEBUG "Packet:", DEC XBData0, ", Tx Result: ", IHEX XBResult,CR Main2: RETURNReceive
' {$STAMP BS2} ' {$PBASIC 2.5} #SELECT $STAMP ' Select Baud constants #CASE BS2, BS2E, BS2PE T1200 CON 813 T2400 CON 396 T4800 CON 188 T9600 CON 84 T19K2 CON 32 #CASE BS2SX, BS2P T1200 CON 2063 T2400 CON 1021 T4800 CON 500 T9600 CON 240 T19K2 CON 110 #CASE BS2PX T1200 CON 3313 T2400 CON 1646 T4800 CON 813 T9600 CON 396 T19K2 CON 188 #ENDSELECT Inverted CON $4000 'Value for inverted serial format Baud CON T9600 '+ Inverted 8,N,1 inverted XBDelim CON $7E 'API start delimiter XBTxStat CON $89 'Transmuit Status XBRx16 CON $81 'Rx Packet: 16-bit address RX PIN 0 ' XBee Receive Pin TX PIN 2 ' Xbee Transmit Pin RTS PIN 6 ' RTS flow control pin 'structure of 16 bit RX packet Delim VAR Byte 'should be 0x7E LenMSB VAR Byte LenLSB VAR Byte APIID VAR Byte 'should be 0x81 SrcMSB VAR Byte 'high part of sending XBee's address SrcLSB VAR Byte 'low part of sending XBee's address RSSI VAR Byte 'signal strength: 0x17-0x5C (XBee), 0x24-0x64 (XBee-PRO) Opts VAR Byte XBData4 VAR Byte XBData3 VAR Byte XBData2 VAR Byte XBData1 VAR Byte XBData0 VAR Byte XBCheckSum VAR Byte XBData VAR Word HIGH TX ' Idle transmit pin DEBUG CLS, "API RX - Configuring XBee..." PAUSE 2000 ' Guard time for command sequence SEROUT TX,Baud,["+++"] ' Enter command mode PAUSE 2000 ' Guard time for command sequence SEROUT TX,Baud,["ATNI XBee API TX",CR, ' Set description "ATMY ", HEX 1,CR, ' Set node address "ATDL ", HEX 2,CR, ' Set destination node address "ATD6 1",CR, ' Use RTS for flow control "ATAP 2",CR, ' API with escape characters "ATCN",CR] ' Exit command mode PAUSE 1000 DEBUG "Ready!", CR DO SERIN RX, Baud, [WAIT(xbDelim), LenMSB, LenLSB, APIID, SrcMSB, SrcLSB, RSSI, Opts, XBData4, XBData3, XBData2, XBData1,XBData0, XBCheckSum] ' SERIN RX, Baud, [WAIT(xbDelim),SKIP 2,WAIT(XBRx16), SKIP 2, RSSI, Opts, XBData4, XBData3, XBData2, XBData1,XBData0, XBCheckSum] 'reconstruct transmitted word from received digits XBData = (10000 *(XBData4 - "0")) + (1000 *(XBData3 - "0")) + (100 *(XBData2 - "0")) + (10 *(XBData1 - "0")) + (XBData0 - "0") DEBUG IHEX APIID," ",IHEX SrcMSB," ",IHEX SrcLSB," ",IHEX Opts," ", XBData4,XBData3,XBData2,XBData1,XBData0, " (", DEC5 XBData, ") RSSI: -", DEC RSSI, " dBm", CR LOOP ENDHi and thanks for looking at my progs. My PC interface is written actually for National Instruments LabWindows but here are the Tx and Rx methods. If you would like the .exe or the full up code you are welcome to it. I am planning on converting it to Microsoft Visual Studio Express since you can get that for free from Microsoft.
#include <utility.h> #include "XbeeTerminal.h" #include <formatio.h> #include <rs232.h> #include <ansi_c.h> #include <cvirte.h> #include <userint.h> static int panelHandle; static int panelHandle2; static int panelHandle3; //============================AT style API frames======================= typedef struct XbeeATcmdObj { int start; int lenMSB; int lenLSB; int frameType; //0x08 int frameID; int cmd; int param; char checkSum[1]; }XbeeATcmdObj; typedef struct XbeeATcmdQparamObj { int start; int lenMSB; int lenLSB; int frameType; //0x09 int frameID; int cmd; int param; char checkSum[1]; }XbeeATcmdQparamObj; typedef struct XbeeRemoteATcmdObj { int start; int lenMSB; int lenLSB; int frameType; //0x17 int frameID; int destAddrHi; int destAddrLo; int netAddr; int options; int cmd; int param; char checkSum[1]; }XbeeRemoteATcmdObj; typedef struct XbeeATcmdStatusObj { int start; int lenMSB; int lenLSB; int frameType; //0x88 int frameID; int cmd; int cmdStatus; char checkSum[1]; }XbeeATcmdStatusObj; //======================================================================== //=============================API Transmit frames ===================== typedef struct XbeeTxObj { int start; int lenMSB; int lenLSB; int frameType; //0x10 int frameID; int destAddrHi; int destAddrLo; int netAddr; int radius; int options; char message[256]; char checkSum[1]; }XbeeTxObj; typedef struct XbeeTxExpObj { int start; int lenMSB; int lenLSB; int frameType; //0x11 int frameID; int destAddrHi; int destAddrLo; int netAddr; int sourceEndPoint; int destEndpoint; int ClusterID; int ProfileID; int radius; int options; char message[256]; char checkSum[1]; }XbeeTxExpObj; typedef struct XbeeTxStatusObj { int start; int lenMSB; int lenLSB; int frameType; //0x8B int frameID; int netAddr; int retries; int status; int discovery; char checkSum[1]; }XbeeTxStatusObj; //============================================================================== //================================API Receive frames============================ typedef struct XbeeRxObj { int start; int lenMSB; int lenLSB; int frameType; //0x90 int sourceAddrHi; int sourceAddrLo; int sourcenetAddr; int options; char message[256]; char checkSum[1]; }XbeeRxObj; typedef struct XbeeRxIOsampleObj { int start; int lenMSB; int lenLSB; int frameType; //0x92 int sourceAddrHi; int sourceAddrLo; int sourcenetAddr; int options; int numSamples; int digMask1; int digMask2; int analogMask; int digData; int analogData; char checkSum[1]; }XbeeRxIOsampleObj; //============================================================================== //=================================General purpose API frames==================== typedef struct XbeeStatusObj { int start; int lenMSB; int lenLSB; int frameType; //0x8A int status; char checkSum[1]; }XbeeStatusObj; typedef struct XbeeSourceRouteObj { int start; int lenMSB; int lenLSB; int frameType; //0x21 int frameID; int destAddrHi; int destAddrLo; int netAddr; int options; int numAddresses; int addr1; //neighbor closest to dest int addr2; int addr3; //neighbor closest to source int cmdParam; char checkSum[1]; }XbeeSourceRouteObj; void CVICALLBACK RxComPort (int portNumber, int eventMask, void *callbackData); XbeeRemoteATcmdObj *XbeeRemoteATcmdTx; XbeeATcmdStatusObj *XbeeATcmdTxStatus; XbeeTxObj *XbeeTx; XbeeTxStatusObj *XbeeTxStatus; XbeeRxObj *XbeeRx; XbeeRxIOsampleObj *XbeeRxIOsample; int ComMode; int ComPort; int changeDetect; int pullUp; int main (int argc, char *argv[]) { if (InitCVIRTE (0, argv, 0) == 0) return -1; /* out of memory */ if ((panelHandle = LoadPanel (0, "XbeeTerminal.uir", PANEL)) < 0) return -1; DisplayPanel (panelHandle); // GetCtrlVal (PANEL, PANEL_NUMERIC_5, &portA); ComMode = 0x01; ComPort = 0x03; OpenComConfig (ComPort, "", 9600, 0, 8, 1, 512, 512); InstallComCallback (ComPort, 1, 0, 0, RxComPort, 0); // Set-up default XbeeTxObj values XbeeTx = (XbeeTxObj *)malloc(sizeof(XbeeTxObj)); XbeeTx->start = 0x7E; XbeeTx->frameType = 0x10; XbeeTx->frameID = 0x01; XbeeTx->destAddrHi = 0x0013A200; //For all Digi Xbee radios // XbeeTx->destAddrLo = 0x40683F5D; // my robot Xbee XbeeTx->destAddrLo = 0x406932B4; // my dev Xbee XbeeTx->netAddr = 0xFFFE; //Leave at this value when using 8 byte address mode XbeeTx->radius = 0x00; //Value 0x00 allow max hops XbeeTx->options = 0x00; //Set to 0x01 to disable ACK // Set-up default XbeeRxObj values XbeeRx = (XbeeRxObj *)malloc(sizeof(XbeeRxObj)); // Set-up default XbeeTxStatusObj values XbeeTxStatus = (XbeeTxStatusObj *)malloc(sizeof(XbeeTxStatusObj)); // Set-up default XbeeRemoteATcmdObj values XbeeRemoteATcmdTx = (XbeeRemoteATcmdObj *)malloc(sizeof(XbeeRemoteATcmdObj)); XbeeRemoteATcmdTx->start =0x7E; XbeeRemoteATcmdTx->lenMSB =0x00; XbeeRemoteATcmdTx->frameType =0x17; XbeeRemoteATcmdTx->frameID =0x01; XbeeRemoteATcmdTx->destAddrHi =0x0013A200; XbeeRemoteATcmdTx->netAddr =0xFFFE; XbeeRemoteATcmdTx->options =0x02; //0x00 = no ACK, 0x02 = apply changes // Set-up default XbeeATcmdStatusObj values XbeeATcmdTxStatus = (XbeeATcmdStatusObj *)malloc(sizeof(XbeeATcmdStatusObj)); // Set-up default XbeeRxIOsampleObj values XbeeRxIOsample = (XbeeRxIOsampleObj *)malloc(sizeof(XbeeRxIOsampleObj)); changeDetect = 0x00; pullUp = 0x00; RunUserInterface (); free(XbeeTx); free(XbeeTxStatus); free(XbeeRx); free(XbeeRemoteATcmdTx); free(XbeeATcmdTxStatus); CloseCom (ComPort); DiscardPanel (panelHandle); return 0; } int CVICALLBACK panelCB (int panel, int event, void *callbackData, int eventData1, int eventData2) { if (event == EVENT_CLOSE) QuitUserInterface (0); return 0; } int TxAPI(void) { char message[18 + strlen(XbeeTx->message)]; int index; XbeeTx->lenMSB = (0x0E + strlen(XbeeTx->message))/256; // 0x0E added for frame size XbeeTx->lenLSB = 0x0E + strlen(XbeeTx->message) - (XbeeTx->lenMSB*256); // masks off lower byte XbeeTx->checkSum[0] = 0x00; message[0] = XbeeTx->start; message[1] = XbeeTx->lenMSB; message[2] = XbeeTx->lenLSB; message[3] = XbeeTx->frameType; message[4] = XbeeTx->frameID; for (index = 0; index <4; index ++) { message[index + 5] = (XbeeTx->destAddrHi >> (3-index)*8) & 0xFF; message[index + 9] = (XbeeTx->destAddrLo >> (3-index)*8) & 0xFF; } message[13] = (XbeeTx->netAddr >> 8) & 0xFF; message[14] = XbeeTx->netAddr & 0xFF; message[15] = XbeeTx->radius; message[16] = XbeeTx->options; for (index = 0; index < strlen(XbeeTx->message); index ++) message[index + 17] = XbeeTx->message[index]; for (index = 3; index < (17 + strlen(XbeeTx->message)); index ++) XbeeTx->checkSum[0] += message[index]; message[17 + strlen(XbeeTx->message)] = 0xFF - XbeeTx->checkSum[0]; ComWrt(ComPort, message, 18 + strlen(XbeeTx->message)); while(GetOutQLen(ComPort)>0); return 0; } int TxRemoteATcmdAPI(void) { int index; char message[4 + XbeeRemoteATcmdTx->lenLSB]; XbeeTx->checkSum[0] = 0x00; message[0] = XbeeRemoteATcmdTx->start; message[1] = XbeeRemoteATcmdTx->lenMSB; message[2] = XbeeRemoteATcmdTx->lenLSB; message[3] = XbeeRemoteATcmdTx->frameType; message[4] = XbeeRemoteATcmdTx->frameID; for (index = 0; index <4; index ++) { message[index + 5] = (XbeeRemoteATcmdTx->destAddrHi >> (3-index)*8) & 0xFF; message[index + 9] = (XbeeRemoteATcmdTx->destAddrLo >> (3-index)*8) & 0xFF; } message[13] = (XbeeRemoteATcmdTx->netAddr >> 8) & 0xFF; message[14] = XbeeRemoteATcmdTx->netAddr & 0xFF; message[15] = XbeeRemoteATcmdTx->options; message[16] = (XbeeRemoteATcmdTx->cmd >> 8) & 0xFF; message[17] = XbeeRemoteATcmdTx->cmd & 0xFF; if(XbeeRemoteATcmdTx->lenLSB == 0x10) message[18] = XbeeRemoteATcmdTx->param; for (index = 3; index < (3 + XbeeRemoteATcmdTx->lenLSB); index ++) XbeeTx->checkSum[0] += message[index]; message[3 + XbeeRemoteATcmdTx->lenLSB] = 0xFF - XbeeTx->checkSum[0]; ComWrt(ComPort, message, 4 + XbeeRemoteATcmdTx->lenLSB); while(GetOutQLen(ComPort)>0); return 0; } void CVICALLBACK RxComPort(int portNumber, int eventMask, void *callbackData) { char RxMsg[128]; char msgHeader[4]; int msgLen; int index; char addrLo[5]; int analogIndex; int analogValue; float scaledAnalog; int switchVal; InstallComCallback(ComPort, 0x00, 0x00, 0x7E, RxComPort, NULL); if(!ComMode) { SetComTime(ComPort, .25); ComRd(ComPort, XbeeRx->message, 128); SetCtrlVal(PANEL, PANEL_STRING_2, XbeeRx->message); goto done; } ComRd(ComPort, msgHeader, 4); XbeeRx->start = msgHeader[0]; XbeeRx->lenMSB = msgHeader[1]; XbeeRx->lenLSB = msgHeader[2]; XbeeRx->frameType = msgHeader[3]&0xFF; msgLen = XbeeRx->lenMSB * 256 + XbeeRx->lenLSB; ComRd(ComPort, RxMsg, msgLen); switch(XbeeRx->frameType) { case 0x90: CopyString (XbeeRx->message, 0, RxMsg, 11, msgLen-12); SetCtrlVal(PANEL, PANEL_STRING_2, XbeeRx->message); XbeeRx->sourceAddrHi = 0; XbeeRx->sourceAddrLo = 0; XbeeRx->sourcenetAddr= 0; for(index = 0; index < 4; index++) { XbeeRx->sourceAddrHi = (XbeeRx->sourceAddrHi << 8) + RxMsg[index]; XbeeRx->sourceAddrLo = (XbeeRx->sourceAddrLo << 8) + RxMsg[index + 4]; } XbeeRx->sourcenetAddr = (XbeeRx->sourcenetAddr + RxMsg[8])<<8 + RxMsg[9]; SetCtrlVal(PANEL, PANEL_NUMERIC, XbeeRx->sourceAddrLo); // SetActivePanel(panelHandle3); // GetCtrlVal(panelHandle3, PANEL_4_BINARYSWITCH, &switchVal); // if (switchVal==1) // UNVmessage(); break; case 0x8B: XbeeTxStatus->status = RxMsg[4]; if(XbeeTxStatus->status != 0x00) SetCtrlVal(PANEL, PANEL_LED, 1); // printf("Message Tx OK."); break; case 0x92: // printf("IO sample received.\n"); XbeeRxIOsample->digMask1 = RxMsg[12]; XbeeRxIOsample->digMask2 = RxMsg[13]; XbeeRxIOsample->analogMask = RxMsg[14]; // Set digital input 1 if (XbeeRxIOsample->digMask2 & 0x1) { SetCtrlAttribute(panelHandle2,PANEL_2_LED, ATTR_DIMMED, 0); if (RxMsg[16] & 0x1) SetCtrlVal(panelHandle2,PANEL_2_LED, 1); else SetCtrlVal(panelHandle2,PANEL_2_LED, 0); } else { SetCtrlVal(panelHandle2,PANEL_2_LED, 0); SetCtrlAttribute(panelHandle2,PANEL_2_LED, ATTR_DIMMED, 1); } // Set digital input 2 if (XbeeRxIOsample->digMask2 & 0x2) { SetCtrlAttribute(panelHandle2,PANEL_2_LED_2, ATTR_DIMMED, 0); if (RxMsg[16] & 0x2) SetCtrlVal(panelHandle2,PANEL_2_LED_2, 1); else SetCtrlVal(panelHandle2,PANEL_2_LED_2, 0); } else { SetCtrlVal(panelHandle2,PANEL_2_LED_2, 0); SetCtrlAttribute(panelHandle2,PANEL_2_LED_2, ATTR_DIMMED, 1); } // Set digitial input 3 if (XbeeRxIOsample->digMask2 & 0x4) { SetCtrlAttribute(panelHandle2,PANEL_2_LED_3, ATTR_DIMMED, 0); if (RxMsg[16] & 0x4) SetCtrlVal(panelHandle2,PANEL_2_LED_3, 1); else SetCtrlVal(panelHandle2,PANEL_2_LED_3, 0); } else { SetCtrlVal(panelHandle2,PANEL_2_LED_3, 0); SetCtrlAttribute(panelHandle2,PANEL_2_LED_3, ATTR_DIMMED, 1); } // Set digital input 4 if (XbeeRxIOsample->digMask2 & 0x8) { SetCtrlAttribute(panelHandle2,PANEL_2_LED_4, ATTR_DIMMED, 0); if (RxMsg[16] & 0x8) SetCtrlVal(panelHandle2,PANEL_2_LED_4, 1); else SetCtrlVal(panelHandle2,PANEL_2_LED_4, 0); } else { SetCtrlVal(panelHandle2,PANEL_2_LED_4, 0); SetCtrlAttribute(panelHandle2,PANEL_2_LED_4, ATTR_DIMMED, 1); } // Check to see if digital IO has been set if ((XbeeRxIOsample->digMask1 + XbeeRxIOsample->digMask2)!=0) analogIndex = 17; else analogIndex = 15; // Set analog input 1 if (XbeeRxIOsample->analogMask & 0x01) { analogValue = RxMsg[analogIndex] * 256 + RxMsg[analogIndex+1]; scaledAnalog = analogValue * 1.2 / 1024; // printf("Analog value = %x\n", analogValue); // printf("Scaled value = %f\n", scaledAnalog); SetCtrlAttribute(panelHandle2,PANEL_2_NUMERIC, ATTR_DIMMED, 0); SetCtrlVal(panelHandle2,PANEL_2_NUMERIC, scaledAnalog); } else { scaledAnalog = 0; SetCtrlVal(panelHandle2,PANEL_2_NUMERIC, scaledAnalog); SetCtrlAttribute(panelHandle2,PANEL_2_NUMERIC, ATTR_DIMMED, 1); } /* // Set analog input 2 if (XbeeRxIOsample->analogMask & 0x02) { analogIndex = analogIndex + 1; analogValue = RxMsg[analogIndex] * 256 + RxMsg[analogIndex+1]; scaledAnalog = analogValue * 1.2 / 1024; printf("Analog value = %x\n", analogValue); printf("Scaled value = %f\n", scaledAnalog); SetCtrlAttribute(panelHandle2,PANEL_2_NUMERIC_2, ATTR_DIMMED, 0); SetCtrlVal(panelHandle2,PANEL_2_NUMERIC_2, scaledAnalog); } else { scaledAnalog = 0; SetCtrlVal(panelHandle2,PANEL_2_NUMERIC_2, scaledAnalog); SetCtrlAttribute(panelHandle2,PANEL_2_NUMERIC_2, ATTR_DIMMED, 1); } */ XbeeRemoteATcmdTx->cmd = 0x49; // ascii I XbeeRemoteATcmdTx->cmd = (XbeeRemoteATcmdTx->cmd << 8) + 0x52; //ascii R XbeeRemoteATcmdTx->param = 0x00; TxRemoteATcmdAPI(); break; case 0x97: XbeeATcmdTxStatus->cmd = RxMsg[11]; XbeeATcmdTxStatus->cmd = (XbeeATcmdTxStatus->cmd)<<8 + RxMsg[12]; XbeeATcmdTxStatus->cmdStatus = RxMsg[13]; // printf("Response for AT cmd = %x%x", RxMsg[11],RxMsg[12]); // printf("Response for AT cmd = %x", XbeeATcmdTxStatus->cmd); // printf(" is %x", XbeeATcmdTxStatus->cmdStatus); // printf("\n"); break; default: printf("No handler for message = 0x"); printf("%x", XbeeRx->frameType); printf("\n"); break; } // end of switch done: InstallComCallback(ComPort, 0x01, 0x00, 0x7E, RxComPort, NULL); } int CVICALLBACK TxComPort (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: SetCtrlVal(PANEL, PANEL_LED, 0); GetCtrlVal(PANEL, PANEL_STRING, XbeeTx->message); SetCtrlVal(PANEL, PANEL_STRING, ""); if (ComMode) TxAPI(); else ComWrt(ComPort, XbeeTx->message, strlen(XbeeTx->message)); break; } return 0; } int CVICALLBACK QuitCallback (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: CloseCom(ComPort); QuitUserInterface (0); break; } return 0; } int CVICALLBACK openPort (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: GetCtrlVal (PANEL, PANEL_NUMERIC_5, &ComPort); OpenComConfig (ComPort, "", 9600, 0, 8, 1, 512, 512); InstallComCallback (ComPort, 1, 0, 0, RxComPort, 0); break; } return 0; } int CVICALLBACK destSet (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { int radioID; switch (event) { case EVENT_COMMIT: GetCtrlVal(PANEL, PANEL_RING, &radioID); switch (radioID) { case 0: XbeeTx->destAddrLo = 0x4066C4F9; break; case 1: XbeeTx->destAddrLo = 0x40683F5D; break; case 2: XbeeTx->destAddrLo = 0x40686462; break; case 3: XbeeTx->destAddrLo = 0x40683F59; break; case 4: XbeeTx->destAddrLo = 0x406932B4; break; } SetCtrlVal(PANEL, PANEL_NUMERIC_2, XbeeTx->destAddrLo); break; } return 0; } int CVICALLBACK displayIO (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: if ((panelHandle2 = LoadPanel (0, "XbeeTerminal.uir", PANEL_2)) < 0) return -1; DisplayPanel(panelHandle2); break; } return 0; } int CVICALLBACK getIOsample (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: XbeeRemoteATcmdTx->lenLSB = 0x10; XbeeRemoteATcmdTx->destAddrLo = XbeeTx->destAddrLo; XbeeRemoteATcmdTx->cmd = 0x49; // ascii I XbeeRemoteATcmdTx->cmd = (XbeeRemoteATcmdTx->cmd << 8) + 0x52; //ascii R XbeeRemoteATcmdTx->param = 0xFE; TxRemoteATcmdAPI(); break; } return 0; } int CVICALLBACK closeIOpanel (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: DiscardPanel(panelHandle2); break; } return 0; } int CVICALLBACK configIO (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: if ((panelHandle3 = LoadPanel (0, "XbeeTerminal.uir", PANEL_3)) < 0) return -1; DisplayPanel(panelHandle3); break; } return 0; } int CVICALLBACK closeConfigPanel (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: DiscardPanel(panelHandle3); break; } return 0; } int CVICALLBACK configChannel (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { int chan; int mode; switch (event) { case EVENT_COMMIT: XbeeRemoteATcmdTx->lenLSB = 0x10; XbeeRemoteATcmdTx->destAddrLo = XbeeTx->destAddrLo; GetCtrlVal(panelHandle3, PANEL_3_RING_2, &chan); switch (chan) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: XbeeRemoteATcmdTx->cmd = 0x44; // ascii D XbeeRemoteATcmdTx->cmd = (XbeeRemoteATcmdTx->cmd << 8) + (chan + 48); // ascii 0-7 break; case 10: case 11: case 12: XbeeRemoteATcmdTx->cmd = 0x50; // ascii P XbeeRemoteATcmdTx->cmd = (XbeeRemoteATcmdTx->cmd << 8) + (chan + 38); // ascii 0-2 break; } GetCtrlVal(panelHandle3, PANEL_3_RING, &mode); XbeeRemoteATcmdTx->param = mode; // ascii 0-5 TxRemoteATcmdAPI(); break; } return 0; } int CVICALLBACK setPullUp (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: XbeeRemoteATcmdTx->lenLSB = 0x10; XbeeRemoteATcmdTx->destAddrLo = XbeeTx->destAddrLo; XbeeRemoteATcmdTx->cmd = 0x50; // ascii P XbeeRemoteATcmdTx->cmd = (XbeeRemoteATcmdTx->cmd << 8) + 0x52; // R if (pullUp == 0x00) pullUp = 0x1F; else pullUp = 0x00; XbeeRemoteATcmdTx->param = pullUp; TxRemoteATcmdAPI(); break; } return 0; } int CVICALLBACK setChangeDetect (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: XbeeRemoteATcmdTx->lenLSB = 0x10; XbeeRemoteATcmdTx->destAddrLo = XbeeTx->destAddrLo; XbeeRemoteATcmdTx->cmd = 0x49; // ascii I XbeeRemoteATcmdTx->cmd = (XbeeRemoteATcmdTx->cmd << 8) + 0x43; // C if (changeDetect == 0x00) changeDetect = 0x1F; else changeDetect = 0x00; XbeeRemoteATcmdTx->param = changeDetect; TxRemoteATcmdAPI(); break; } return 0; } int CVICALLBACK setComMode (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: GetCtrlVal(PANEL, PANEL_BINARYSWITCH, &ComMode); SetCtrlAttribute(PANEL, PANEL_COMMANDBUTTON_2, ATTR_VISIBLE, ComMode); SetCtrlAttribute(PANEL, PANEL_COMMANDBUTTON_3, ATTR_VISIBLE, ComMode); break; } return 0; }The hard part is the Rx method since it has so many possible results.
SM
Which Xbee are you using?
I've got the Series 1 XBee PRO 60mW and XBee PRO 1mW modules.