?? endpoint.c
字號:
/***************************************************************************
endpoint.c
Digi International, Copyright (C) 2007-2008. All rights reserved.
Description
===========
This sample shows how to set up and use endpoints with the Rabbit
XBee_API.lib library. It is meant to be run with another Rabbit
XBee-enabled board.
Note: A node with JN set to 1 will send a broadcast frame when it joins
the network. If this sample receives one of those frames, it will print
"Unknown message arrived" and display a hex dump of the frame.
Having JN set to 1 is the default configuration and should be expected on
ZNet XBee firmware. ZB firmware defaults to a JN setting of 0.
Usage
======
- Compile this sample to two Rabbit XBee-enabled boards.
- If you are not using the Digi XBee USB device as a coordinator,
configure one board as a coordinator and the other as an end device
or router.
- Use the DIAG connector on a programming cable to connect one board to
your PC.
- Using a serial terminal application such as HyperTerminal or Moni,
connect to the serial port at 57600 baud.
- Connect a separate programming cable to the second Rabbit's
programming port. You will use the stdio window for this board.
- After compiling to the second board, it will send messages to the
first board, and both boards will produce output.
- You can reset the first board, and after it initializes it will send
messages to the second board, also producing output from both boards.
(Do not reset the board attached to Dynamic C, as this will cause
a target-communication failure. Instead, use the key sequence
Stop (Ctrl+Q), Reset Program (Ctrl+F2), Run (F9).
*****************************************************************************/
// Set XBEE_ROLE to NODE_TYPE_COORD, NODE_TYPE_ROUTER or NODE_TYPE_ENDDEV to
// match your XBee's firmware. View the function help (Ctrl+H) on XBEE_ROLE
// for additional information on setting up an XBee network.
// XBee-enabled Rabbit products ship with the module set to router.
#define XBEE_ROLE NODE_TYPE_ROUTER
// Set a Node ID to identify this node on the network.
#define NODEID_STR "Rabbit EndPoint"
// Set the WHO macro to the NODE ID you want to send to. For this demo, both
// boards are compiled with the same name, so we'll just re-use NODEID_STR.
#define WHO NODEID_STR
// ------------------------------------------------------
//
// Serial Cable Communication:
//
// The following definitions redirect stdio to serial port A when
// the core module is not attached to the PROG connector of the
// programming cable. Use the DIAG connector of the programming cable
// to access serial port A. See Samples\STDIO_SERIAL.C for more details
// on redirecting stdio.
//
#define STDIO_DEBUG_SERIAL SADR
#define STDIO_DEBUG_BAUD 57600
#define STDIO_DEBUG_ADDCR
// ------------------------------------------------------
#memmap xmem
#use "xbee_api.lib"
void recvString(char *data, int len);
int sendString(char *who, char *data);
// These structures define what an endpoint can do.
// The cluster numbers represent the functions that
// are available on the endpoint. Multiple endpoints
// can use the same cluster IDs, thus performing the
// same functions.
#define CLUSTER_ID 7
#define PROFILE_ID 42
#define ENDPOINT 2
RabbitClusterIDList_t const StringInCluster = {
{ CLUSTER_ID },
{ recvString }
};
// The endpoint table defines what endpoints the application
// has and what Cluster IDs are associated with it. Each
// endpoint is associated with a profile and a device. The
// device is not important, but the profile is very
// important. A profile defines what commands and data formats
// and functions are available on a network. Any device
// implementing some or all of these items may join the network
// and be used or use other devices. A device may support more
// than one profile.
// Applications using the Rabbit XBee_API.lib library must define an
// endpoint table, even if it is empty. For more information,
// perform a function lookup (ctrl-H) on ENDPOINT_TABLE_BEGIN.
ENDPOINT_TABLE_BEGIN
// Endpt desc, profile device flags IC OC \
// ICL OCL
ENDPOINT_TABLE_ENTRY(ENDPOINT, 0, PROFILE_ID, 1, 0, 1, 0, \
&StringInCluster, NULL)
ENDPOINT_TABLE_END
int msgSent;
char testString[48];
// number of seconds between node discovery attempts
#define RETRY_DISCOVER 30
void main (void)
{
int tickres;
unsigned long last_discover;
int initres; // Result of xbee_init()
unsigned long join_start;
int loop;
int error;
int node_discover;
printf("Starting program....\n\n");
// *** Initialization ***
// Initialize the radio portion of the board
join_start = 0;
while ( (initres = xbee_init()) == -EBUSY)
{
if (! join_start)
{
join_start = SEC_TIMER;
printf( "Waiting for sleeping XBee to wake before continuing.");
}
if (join_start != SEC_TIMER)
{
join_start = SEC_TIMER;
printf( ".");
}
}
printf( "\n");
if (initres) {
printf("xbee_init failed. result code: %d (%ls)\n",
initres, error_message(initres));
exit(initres);
}
// Join the network. For more information on ZB_JOINING_NETWORK,
// perform a function lookup (ctrl-H) on ZB_LAST_STATUS().
printf("Waiting to join network...\n");
join_start = MS_TIMER;
while (ZB_JOINING_NETWORK()) {
// If unable to join a network, timeout after arbitrary time
if (MS_TIMER - join_start > XBEE_JOIN_TIMEOUT) {
// There was an error, do something about it
printf("\n*** Error ***\n");
printf("Timed out while trying to join a network, halting.\n");
exit(-ETIME);
}
}
printf( "Done (%s network)\n", xbee_protocol());
last_discover = SEC_TIMER;
// Wait for node discovery (6-7 seconds, can do something else between calls
printf( "Waiting for node discovery...\n");
while (ZB_ND_RUNNING());
printf( "Discovery done.\n\n");
// *** End Initialization ***
msgSent = 0;
loop = 0;
node_discover = 0;
// Send 10 messages "Test String 0" .. "Test String 9"
while ( 1 )
{
switch (node_discover)
{
case 1: // need to perform discovery
if (SEC_TIMER - last_discover > RETRY_DISCOVER)
{
printf( "Starting node discovery...\n");
xb_send_command( xb_ND);
last_discover = SEC_TIMER;
node_discover = 2;
}
break;
case 2: // waiting for discovery to complete
if (!ZB_ND_RUNNING())
{
node_discover = 0;
}
break;
}
if ( ZB_LAST_STATUS() == ZB_JOINED && !msgSent && !node_discover)
{
if (loop < 10)
{
sprintf( testString, "Test String %d", loop);
error = sendString( WHO, testString);
if (error == 1)
{
printf( "Waiting %d seconds before retrying node discovery.\n",
RETRY_DISCOVER - (SEC_TIMER - last_discover));
node_discover = 1;
}
else if (! error)
{
loop++;
msgSent = 1;
}
}
}
// Let the library advance its state
tickres = zb_tick();
if (tickres == ZB_MESSAGE)
{
printf("Unknown message arrived\n");
xb_hexdump( ZB_LAST_MSG_DATA(), ZB_LAST_MSG_DATALEN() );
}
else if (tickres==ZB_RADIO_STAT)
{
printf("Radio status change: %s\n", ZB_LAST_STATUS()==ZB_JOINED ?
"joined" : "unjoined");
}
else if (tickres == ZB_MSG_STAT)
{
printf("Transmission Status received: %d\n",ZB_XMIT_STATUS());
}
}
} //main()
/*--------------------------------------------------------------------------
recvString
Endpoint 2 input function 7: receive a string. This function is called by
the XBee_API.lib library's message interpreter. The interpreter looks through
the endpoint database to find a matching endpoint and cluster ID to those
in the message. If a match is found and there is a function defined that
function is called with the message data and its length.
PARAMETER1: RF payload (the string).
PARAMETER2: Number of bytes in the payload.
RETURN VALUE: none.
--------------------------------------------------------------------------*/
void recvString(char *data, int len)
{
// if the string ends with an "R", it's a response to our original message
if ( data[len-2] == 'R' )
{
printf( "Got Response: %s\n", data);
msgSent = 0;
}
else
{
printf( "Received Message: %s\n", data);
// append "R" to the string and send it back as a response
data[len-1] = 'R';
data[len] = 0;
zb_reply( data, len+1);
}
}
/*--------------------------------------------------------------------------
sendString
Endpoint 2 Output function 7: send a string. This function
always sets the source endpoint, destination endpoint and cluster ID
using the macros ENDPOINT and CLUSTER_ID.
PARAMETER1: NODE ID of destination.
PARAMETER2: String to send to destination.
RETURN VALUE: 1 if node wasn't found in node list; 0 if message sent.
<0 error trying to send
--------------------------------------------------------------------------*/
int sendString(char *who, char *data)
{
int index;
int error;
zb_sendAddress_t sendAddr;
_zb_NodeData_t *node;
index = 0;
while ( node=GET_NODE_DATA(index) )
{
if ( !strcmp(node->remoteID,who) )
{
break;
}
++index;
}
if ( node )
{
zb_MakeEndpointClusterAddr( index, ENDPOINT, ENDPOINT, CLUSTER_ID,
&sendAddr);
sendAddr.msg = data;
sendAddr.msglen = strlen( data)+1;
if ( (error = zb_send( &sendAddr)) )
{
printf( "Error %d trying to send.\n", error);
return error;
}
else
{
printf( "%s : ", data);
return 0;
}
}
else
{
printf( "Can't find [%s] in node table.\n", who);
return 1;
}
} //sendString()
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -