?? xbee_gpio_client.c
字號:
/***************************************************************************
XBee GPIO Client.c
Digi International, Copyright (C) 2008. All rights reserved.
Description
===========
This sample shows how to set up and use endpoints and clusters with the
Rabbit XBee_API.lib library. It is a command-line version of the Windows
GUI client, and connects to the XBee GPIO Server sample running on another
core module or SBC.
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 and GPIO_VERBOSE
is defined, 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 and run XBee GPIO Server.c on an XBee-enabled core module
or single-board computer.
- Compile and run this sample in the Dynamic C debugger on an
XBee-enabled core module or single-board computer.
- From the STDIO window in Dynamic C, follow the instructions provided
by the sample. You can connect to the XBee GPIO Server sample
wirelessly using the XBee radios to read its inputs and change its
outputs.
*****************************************************************************/
// 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 "GPIO Client"
// Uncomment this define to enable verbose GPIO messages
//#define GPIO_VERBOSE
// ------------------------------------------------------
//
// 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
// ------------------------------------------------------
// Set a default of declaring all local variables "auto" (on stack)
#class auto
// default to storing functions to xmem instead of root
#memmap xmem
#use "xbee_api.lib"
// ------------------------------------------------------
// Sets the maximum number of GPIO servers the client will work with (max. 10)
#define GPIO_MAX_SERVERS 10
// Sets the maximum number of signals on any GPIO server
#define GPIO_MAX_SIGNALS 200
// Sets the number of milliseconds that query_gpio_node allows for response
// of each server request before a timeout error is returned
#define GPIO_TIMEOUT 750
// GPIO endpoint
#define XBEE_ENDPOINT_GPIO 0xDB
// Clusters for the GPIO endpoint
#define XBEE_GPIO_CLUST_INFO 0x40 // get general device info
#define XBEE_GPIO_CLUST_NAME 0x41 // get types and names of I/O signals
#define XBEE_GPIO_CLUST_ANA_RANGE 0x42 // get range info for analog input
#define XBEE_GPIO_CLUST_READ 0x43 // read states of I/O signals
#define XBEE_GPIO_CLUST_WRITE 0x44 // change states of outputs
/*
Frame format for Device Info (XBEE_GPIO_CLUST_INFO cluster) Request
-------------------------------------------------------------------
Payload is a single byte, set to 0. (XBee will not send a packet without
a payload.) All other requests will be ignored (non-zero values are
reserved).
*/
/*
Frame format for Device Info (XBEE_GPIO_CLUST_INFO cluster) Response
--------------------------------------------------------------------
Payload contains an 8-bit cluster version, an 8-bit count of I/O signals on
the device, a 16-bit device manufacturer, a 16-bit device type, and a 16-bit
firmware version.
The firmware version is stored in BCD and can be printed as:
("%u.%02x", firmware_ver >> 8, firmware_ver & 0x00FF))
For example, v1.23 is stored as 0x0123.
*/
typedef struct {
byte protocol_ver; // version of the GPIO Endpoint protocol used
byte io_count; // # of I/O signals on device (0-254)
// the remaining elements can be used to identify a manufacturer-specific
// version of this structure, with additional fields following firmware_ver
word manufacturer; // for this sample, set to 0x101e (Digi)
word device_type; // unique code to identify the device
word firmware_ver; // BCD (0x0123 = v1.23)
} xbee_frame_gpio_info_t;
// Newer versions of this protocol could add fields to the Device Info response,
// more I/O types, or additional features. By querying the server, the GPIO
// Endpoint Client learns about the server's capabilities.
#define XBEE_GPIO_CLUST_VERSION 0x01
/*
Frame format for GPIO Name (XBEE_GPIO_CLUST_NAME cluster) Request
-----------------------------------------------------------------
Payload is variable-length, and is simply a series of 8-bit I/O signal
numbers.
Example to retrieve the names of the first 8 I/O signals:
0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
Valid I/O signal numbers are 0x00 through 0xFE, 0xFF is reserved for future
use. If the server receives a request with an 0xFF, it should ignore the
0xFF byte and all bytes that follow.
*/
/*
Frame format for GPIO Name (XBEE_GPIO_CLUST_NAME cluster) Response
------------------------------------------------------------------
Payload is variable-length, with a record for each I/O signal requested.
Each record starts with the 8-bit I/O number and an 8-bit type. If the
type is not 0xFF, an 8-bit length for its name follows (or 0x00 if it is
unnamed), and <length> bytes of printable characters for the name.
Maximum length for an I/O Signal Name is 20 characters.
Example response to the request example above (with extra line-breaks and
comments for readability:
0x00 0x81 0x04 'D' 'I' 'N' '0' ; I/O #0, digital input, "DIN0"
0x01 0x81 0x04 'D' 'I' 'N' '1' ; I/O #1, digital input, "DIN1"
0x02 0xA3 0x04 'A' 'I' 'N' '0' ; I/O #2, analog input, "AIN0"
0x03 0xA3 0x04 'A' 'I' 'N' '1' ; I/O #3, analog input, "AIN1"
0x04 0x01 0x05 'D' 'O' 'U' 'T' '0' ; I/O #4, digital output, "DOUT0"
0x05 0x01 0x05 'D' 'O' 'U' 'T' '1' ; I/O #5, digital output, "DOUT1"
0x06 0x02 0x04 'L' 'E' 'D' '0' ; I/O #6, LED/Light, "LED0"
0x07 0xFF ; I/O #7 is not a valid I/O signal
Names are sent in the order requested.
If there isn't enough room to fit all of the names in the frame, the
requestor will have to send an updated request asking for the missing
I/O numbers from the first request.
*/
// I/O Types and their setting size (size is 1 octet unless otherwise specified)
// Data Type for I/O Type
#define XBEE_GPIO_TYPE_DISABLED 0x00 // Null (0 octets)
#define XBEE_GPIO_TYPE_INVALID 0xFF // Null (0 octets)
// Output types
#define XBEE_GPIO_TYPE_DIGITAL_OUT 0x01 // Boolean (0/low, 1/high)
#define XBEE_GPIO_TYPE_LED_OUT 0x02 // Boolean (0/off, 1/on)
#define XBEE_GPIO_TYPE_SINK_OUT 0x10 // Enum (0/sink, 2/tristate)
#define XBEE_GPIO_TYPE_SOURCE_OUT 0x11 // Enum (1/source, 2/tristate)
#define XBEE_GPIO_TYPE_TRISTATE_OUT 0x12 // Enum (0/sink, 1/source, 2/tristate)
#define XBEE_GPIO_TYPE_ANALOG_OUT 0x20 // Float (4 octets, IEEE float)
// Input types
#define XBEE_GPIO_TYPE_DIGITAL_IN 0x81 // Boolean (0/low, 1/high)
#define XBEE_GPIO_TYPE_SWITCH_IN 0x82 // Boolean (0/open, 1/closed)
#define XBEE_GPIO_TYPE_ANALOG_IN 0xA3 // Float (4 octets, IEEE float)
// masks for various types
#define XBEE_GPIO_MASK_TYPE_INPUT 0x80 // Bit flag indicating input channel
#define XBEE_GPIO_MASK_TYPE_ANALOG 0x20 // Bit flag indicating analog
// settings for outputs
#define XBEE_GPIO_OUTPUT_LOW 0
#define XBEE_GPIO_OUTPUT_HIGH 1
#define XBEE_GPIO_OUTPUT_OFF 0
#define XBEE_GPIO_OUTPUT_ON 1
#define XBEE_GPIO_OUTPUT_SINK 0
#define XBEE_GPIO_OUTPUT_SOURCE 1
#define XBEE_GPIO_OUTPUT_TRISTATE 2
// settings for inputs
#define XBEE_GPIO_INPUT_LOW 0
#define XBEE_GPIO_INPUT_HIGH 1
#define XBEE_GPIO_INPUT_OPEN 0
#define XBEE_GPIO_INPUT_CLOSED 1
/*
Frame format for Analog Range (XBEE_GPIO_CLUST_ANA_RANGE cluster) Request
-------------------------------------------------------------------------
Payload is identical to GPIO Name Request.
Example to retrieve the analog ranges for of the first 8 I/O signals:
0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
*/
/*
Frame format for Analog Range (XBEE_GPIO_CLUST_ANA_RANGE cluster) Response
--------------------------------------------------------------------------
Payload is variable-length, with a record for each I/O signal requested.
Each record starts with the 8-bit I/O number. If the given I/O signal is
not an analog input or output, the I/O number is followed by 0xFF. Analog
I/O signal numbers are followed by a string description of the units (e.g.,
"V", "mA", "C") sent as follows an 8-bit length followed by <length & 0x0F>
bytes of printable ASCII characters. If bit 7 of length is set
(length & 0x80), the name is followed by two floats (4 octets each)
representing the lower and upper range for the signal.
Bits 4-6 of the length are reserved for future use and should be set to zero
by the server and ignored by the client.
Maximum length for a "units description" is 15 characters. Servers should
send a description for each signal, but Clients must accept a 0-byte
description.
Example response to the request example above (with extra line-breaks and
comments for readability):
0x00 0xFF ; I/O #0 is not an analog I/O
0x01 0x81 'V' <0.000> <20.000> ; I/O #1, 0 to 20 V
0x02 0x82 'm' 'A' <4.000> <20.000> ; I/O #2, 4 to 20 mA
0x03 0x01 'C' ; I/O #3, Celsius with unknown range
0x04 0x80 <-10.000> <10.000> ; I/O #4, +/-10.000, unknown units
0x05 0x00 ; I/O #5, unknown range or units
Ranges are sent in the order requested.
If there isn't enough room to fit all of the responses in the frame, the
requestor will have to send an updated request asking for the missing
I/O numbers from the first request.
*/
/*
Frame format for GPIO Read (XBEE_GPIO_CLUST_READ cluster) Request
-----------------------------------------------------------------
Payload is identical to GPIO Name Request.
Example to retrieve the configuration/readings of the first 8 I/O signals:
0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
*/
/*
Frame format for GPIO Read (XBEE_GPIO_CLUST_READ cluster) Response
------------------------------------------------------------------
Payload is variable-length, with a record for each I/O signal requested.
Each record starts with the 8-bit I/O number, an 8-bit I/O type for its
name (or 0x00 if it is disabled or 0xFF if it's not a valid I/O number),
and a variable number of bytes (depending on type, see table below) for its
current setting (for outputs) or reading (for inputs).
Example response to the request example above (with extra line-breaks and
comments for readability:
0x00 0x81 0x01 ; I/O #0 is a digital input, last read high
0x01 0x81 0x00 ; I/O #1 is a digital input, last read low
0x02 0xA3 0x00 0x00 0xa0 0x40 ; I/O #2 is an analog input, last read 5.00
0x03 0x00 ; I/O #3 is disabled
0x04 0x01 0x00 ; I/O #4 is a digital output, set low
0x05 0x01 0x01 ; I/O #5 is a digital output, set high
0x06 0x02 0x01 ; I/O #6 is an LED output, currently on
0x07 0xFF ; I/O #7 is not a valid I/O signal
If there isn't enough room to fit all of the readings in the frame, the
requestor will have to send an updated request asking for the missing
I/O numbers from the first request.
*/
/*
Frame format for GPIO Write (XBEE_GPIO_CLUST_WRITE cluster) Request
-------------------------------------------------------------------
Payload is variable length, with a record for each output to be written.
Each record is identical to the record format for the GPIO Read Response:
8-bit I/O number, 8-bit I/O type and variable-length setting.
Note that all writes are done asynchronously. Version 1 of the GPIO
Endpoint does not support setting synchronous analog outputs or banked
digital outputs.
Example to set some outputs:
0x00 0x01 0x01 ; Set I/O #0 to digital output, high
0x03 0x02 0x01 ; Set I/O #3 to led output, on
0x04 0x01 0x01 ; Set I/O #4 to digital output, high
0x06 0x02 0x00 ; Set I/O #6 to LED output, off
0x07 0x20 <25.000> ; Set I/O #7 to analog output, 25.000
*/
/*
Frame format for GPIO Write (XBEE_GPIO_CLUST_WRITE cluster) Response
--------------------------------------------------------------------
Payload are byte pairs of a status byte followed by the I/O number.
See table of valid status bytes below.
Example response to example request above:
0x00 0xF1 ; can't set I/O #0, type didn't match
0x03 0xF0 ; can't set I/O #3, it is disabled
0x04 0x00 ; successfully set I/O #4
0x06 0x00 ; successfully set I/O #6
0x07 0xF2 ; setting for I/O #7 outside of valid range
*/
// status bytes for XBEE_GPIO_CLUST_WRITE responses
#define XBEE_GPIO_STATUS_SUCCESS 0x00
#define XBEE_GPIO_STATUS_DISABLED 0xF0
#define XBEE_GPIO_STATUS_BAD_TYPE 0xF1
#define XBEE_GPIO_STATUS_OUT_OF_RANGE 0xF2
#define XBEE_GPIO_STATUS_INVALID 0xFF
//// End of GPIO Endpoint Protocol Definition
// GPIO Client sample follows
// end point to use when sending requests, responses come back to it
#define XBEE_ENDPOINT_RESPONSE 0xDA
// these "Resp" functions handle the responses from the XBee GPIO Server
void xbeeGpioDevInfoResp(char *data, int datalen);
void xbeeGpioNameResp(char *data, int datalen);
void xbeeGpioAnaRangeResp(char *data, int datalen);
void xbeeGpioReadResp(char *data, int datalen);
void xbeeGpioWriteResp(char *data, int datalen);
RabbitClusterIDList_t const gpioEndPointResp = {
{ XBEE_GPIO_CLUST_INFO, XBEE_GPIO_CLUST_NAME, XBEE_GPIO_CLUST_ANA_RANGE,
XBEE_GPIO_CLUST_READ, XBEE_GPIO_CLUST_WRITE },
{ xbeeGpioDevInfoResp, xbeeGpioNameResp, xbeeGpioAnaRangeResp,
xbeeGpioReadResp, xbeeGpioWriteResp }
};
// 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 network 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(XBEE_ENDPOINT_RESPONSE, 0, XB_PROFILE_DIGI, 1, 0, \
5, 0, &gpioEndPointResp, NULL)
ENDPOINT_TABLE_END
typedef struct {
byte signal;
byte type;
byte namelen;
char name[20]; // 0 to 20 character name, not terminated
} xbee_gpio_rec_name_resp_t;
typedef struct {
byte signal;
byte length;
char units[15];
} xbee_gpio_rec_ar_resp_units_t;
typedef struct {
float lower, upper;
} xbee_gpio_rec_ar_resp_range_t;
// Main control structure for communicating with GPIO servers
typedef struct {
int state; // State of request/response operation
int ep_count; // End point counter for processing I/O groups
int last_ep; // Last end point to be read
int node_index; // ZigBee Node Index of this GPIO server
byte io_count; // Count of I/O end points on this GPIO server
word device_type; // Device type code from GPIO server
byte last_request; // Last request sent to this GPIO server
unsigned long request_sent; // Timestamp of when last_request was sent
} gpio_device_t;
gpio_device_t gpio_device[GPIO_MAX_SERVERS];
int gpio_index; // Index of current GPIO device selected
int gpio_last; // Index of last GPIO server found
struct {
byte index;
byte type;
char name[21]; // 0 to 20 character name, null terminated
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -