PDA

View Full Version : XBee API Code for BS2



StephenMoore
11-06-2011, 05:54 AM
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.




' {$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

$WMc%
11-06-2011, 10:14 PM
S.Moore...
'
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

Ron Czapala
11-06-2011, 10:49 PM
Here is some API code I did in March 2010 - I know it worked but I would need to study it again to make use of it :smile:

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,XB Options,XBData4,XBData3,XBData2,XBData1,XBData0,XB CheckSum]
'SEROUT TX, Baud, [XBDelim,0,10,XBTxID,XBEsc,51,170,170,0,1,1,2,3,4,1 40]
' 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:
RETURN


Receive


' {$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
END

StephenMoore
11-07-2011, 01:11 AM
@$WMc%

Hi 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

StephenMoore
11-07-2011, 01:16 AM
@ Ron Czapala

Which Xbee are you using?

Ron Czapala
11-07-2011, 02:42 AM
@ Ron Czapala

Which Xbee are you using?

I've got the Series 1 XBee PRO 60mW and XBee PRO 1mW modules.