An example that shows how to use the XBee class/interface
main.cpp@1:fb7d92d3adbe, 2014-04-09 (annotated)
- Committer:
- embeddedartists
- Date:
- Wed Apr 09 10:37:30 2014 +0000
- Revision:
- 1:fb7d92d3adbe
- Parent:
- 0:50a4a80f3ecd
Updated to latest version of EALib
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
embeddedartists | 0:50a4a80f3ecd | 1 | /****************************************************************************** |
embeddedartists | 0:50a4a80f3ecd | 2 | * Includes |
embeddedartists | 0:50a4a80f3ecd | 3 | *****************************************************************************/ |
embeddedartists | 0:50a4a80f3ecd | 4 | #include "mbed.h" |
embeddedartists | 0:50a4a80f3ecd | 5 | #include "XBee.h" |
embeddedartists | 0:50a4a80f3ecd | 6 | |
embeddedartists | 0:50a4a80f3ecd | 7 | /****************************************************************************** |
embeddedartists | 0:50a4a80f3ecd | 8 | * Typedefs and defines |
embeddedartists | 0:50a4a80f3ecd | 9 | *****************************************************************************/ |
embeddedartists | 0:50a4a80f3ecd | 10 | |
embeddedartists | 0:50a4a80f3ecd | 11 | // define NODE_IS_COORDINATOR if this board should act |
embeddedartists | 0:50a4a80f3ecd | 12 | // as XBee coordinator. Make sure it is undefined it the board |
embeddedartists | 0:50a4a80f3ecd | 13 | // should act as End-Device |
embeddedartists | 1:fb7d92d3adbe | 14 | #define NODE_IS_COORDINATOR (1) |
embeddedartists | 0:50a4a80f3ecd | 15 | |
embeddedartists | 0:50a4a80f3ecd | 16 | #define CMD_BTN_MSG (0) |
embeddedartists | 0:50a4a80f3ecd | 17 | #define CMD_ACK_MSG (1) |
embeddedartists | 0:50a4a80f3ecd | 18 | |
embeddedartists | 0:50a4a80f3ecd | 19 | /****************************************************************************** |
embeddedartists | 0:50a4a80f3ecd | 20 | * Local variables |
embeddedartists | 0:50a4a80f3ecd | 21 | *****************************************************************************/ |
embeddedartists | 0:50a4a80f3ecd | 22 | |
embeddedartists | 0:50a4a80f3ecd | 23 | static XBee xbee(P4_22, P4_23, P4_17, P4_19); |
embeddedartists | 0:50a4a80f3ecd | 24 | |
embeddedartists | 0:50a4a80f3ecd | 25 | // led1 + led 2 -> active low |
embeddedartists | 0:50a4a80f3ecd | 26 | static DigitalOut xbeeInitLed(LED1); |
embeddedartists | 0:50a4a80f3ecd | 27 | static DigitalOut remoteBtnLed(LED2); |
embeddedartists | 0:50a4a80f3ecd | 28 | // led3 + led 4 -> active high |
embeddedartists | 0:50a4a80f3ecd | 29 | static DigitalOut ackLed(LED3); |
embeddedartists | 0:50a4a80f3ecd | 30 | static DigitalOut led4(LED4); |
embeddedartists | 0:50a4a80f3ecd | 31 | |
embeddedartists | 0:50a4a80f3ecd | 32 | static DigitalIn button(p23); |
embeddedartists | 0:50a4a80f3ecd | 33 | static bool xbeeIsUp = false; |
embeddedartists | 0:50a4a80f3ecd | 34 | |
embeddedartists | 0:50a4a80f3ecd | 35 | /****************************************************************************** |
embeddedartists | 0:50a4a80f3ecd | 36 | * Local functions |
embeddedartists | 0:50a4a80f3ecd | 37 | *****************************************************************************/ |
embeddedartists | 0:50a4a80f3ecd | 38 | |
embeddedartists | 0:50a4a80f3ecd | 39 | static void xbeeDeviceUp(void) { |
embeddedartists | 0:50a4a80f3ecd | 40 | xbeeIsUp = true; |
embeddedartists | 0:50a4a80f3ecd | 41 | } |
embeddedartists | 0:50a4a80f3ecd | 42 | |
embeddedartists | 0:50a4a80f3ecd | 43 | static void xbeeDeviceDown(void) { |
embeddedartists | 0:50a4a80f3ecd | 44 | xbeeIsUp = false; |
embeddedartists | 0:50a4a80f3ecd | 45 | } |
embeddedartists | 0:50a4a80f3ecd | 46 | |
embeddedartists | 0:50a4a80f3ecd | 47 | static void xbeeNodeFound(void) { |
embeddedartists | 0:50a4a80f3ecd | 48 | uint32_t addrHi = 0; |
embeddedartists | 0:50a4a80f3ecd | 49 | uint32_t addrLo = 0; |
embeddedartists | 0:50a4a80f3ecd | 50 | uint8_t rssi = 0; |
embeddedartists | 0:50a4a80f3ecd | 51 | |
embeddedartists | 0:50a4a80f3ecd | 52 | xbee.getRemoteAddress(&addrHi, &addrLo); |
embeddedartists | 0:50a4a80f3ecd | 53 | xbee.getRssi(&rssi); |
embeddedartists | 0:50a4a80f3ecd | 54 | |
embeddedartists | 0:50a4a80f3ecd | 55 | printf("XBee: node found: hi=%lx, lo=%lx, rssi=%d\n", |
embeddedartists | 0:50a4a80f3ecd | 56 | addrHi, addrLo, rssi); |
embeddedartists | 0:50a4a80f3ecd | 57 | } |
embeddedartists | 0:50a4a80f3ecd | 58 | |
embeddedartists | 0:50a4a80f3ecd | 59 | static void xbeeTxStat(void) { |
embeddedartists | 0:50a4a80f3ecd | 60 | |
embeddedartists | 0:50a4a80f3ecd | 61 | uint8_t frameId = 0; |
embeddedartists | 0:50a4a80f3ecd | 62 | XBee::XBeeTxStatus status = XBee::TxStatusOk; |
embeddedartists | 0:50a4a80f3ecd | 63 | |
embeddedartists | 0:50a4a80f3ecd | 64 | xbee.getTxStatus(&frameId, &status); |
embeddedartists | 0:50a4a80f3ecd | 65 | |
embeddedartists | 0:50a4a80f3ecd | 66 | printf("XBee: Tx Stat. Id=%u, status=%d\n", frameId, (int)status); |
embeddedartists | 0:50a4a80f3ecd | 67 | } |
embeddedartists | 0:50a4a80f3ecd | 68 | |
embeddedartists | 0:50a4a80f3ecd | 69 | |
embeddedartists | 0:50a4a80f3ecd | 70 | |
embeddedartists | 0:50a4a80f3ecd | 71 | static void xbeeDataAvailable(void) { |
embeddedartists | 0:50a4a80f3ecd | 72 | char* data = NULL; |
embeddedartists | 0:50a4a80f3ecd | 73 | char ackMsg = CMD_ACK_MSG; |
embeddedartists | 0:50a4a80f3ecd | 74 | uint8_t frameId = 0; |
embeddedartists | 0:50a4a80f3ecd | 75 | uint8_t len = 0; |
embeddedartists | 0:50a4a80f3ecd | 76 | uint32_t addrHi = 0; |
embeddedartists | 0:50a4a80f3ecd | 77 | uint32_t addrLo = 0; |
embeddedartists | 0:50a4a80f3ecd | 78 | uint8_t rssi = 0; |
embeddedartists | 0:50a4a80f3ecd | 79 | |
embeddedartists | 0:50a4a80f3ecd | 80 | xbee.getRemoteAddress(&addrHi, &addrLo); |
embeddedartists | 0:50a4a80f3ecd | 81 | xbee.getData(&data, &len); |
embeddedartists | 0:50a4a80f3ecd | 82 | xbee.getRssi(&rssi); |
embeddedartists | 0:50a4a80f3ecd | 83 | |
embeddedartists | 0:50a4a80f3ecd | 84 | printf("XBee: Data available: len=%d hi=%lx, lo=%lx, rssi=%d\n", |
embeddedartists | 0:50a4a80f3ecd | 85 | (int)len, addrHi, addrLo, rssi); |
embeddedartists | 0:50a4a80f3ecd | 86 | |
embeddedartists | 0:50a4a80f3ecd | 87 | if (len > 0) { |
embeddedartists | 0:50a4a80f3ecd | 88 | |
embeddedartists | 0:50a4a80f3ecd | 89 | switch(data[0]) { |
embeddedartists | 0:50a4a80f3ecd | 90 | case CMD_BTN_MSG: |
embeddedartists | 0:50a4a80f3ecd | 91 | if (len > 1) { |
embeddedartists | 0:50a4a80f3ecd | 92 | // change led to indicate button state |
embeddedartists | 0:50a4a80f3ecd | 93 | remoteBtnLed = ((data[1] == 1) ? 1 : 0); |
embeddedartists | 0:50a4a80f3ecd | 94 | |
embeddedartists | 0:50a4a80f3ecd | 95 | |
embeddedartists | 0:50a4a80f3ecd | 96 | // Send an ACK directly to the remote node (only for |
embeddedartists | 0:50a4a80f3ecd | 97 | // buttons state == 0) |
embeddedartists | 0:50a4a80f3ecd | 98 | if (data[1] == 0) { |
embeddedartists | 0:50a4a80f3ecd | 99 | xbee.send(addrHi, addrLo, &ackMsg, 1, &frameId); |
embeddedartists | 0:50a4a80f3ecd | 100 | } |
embeddedartists | 0:50a4a80f3ecd | 101 | } |
embeddedartists | 0:50a4a80f3ecd | 102 | break; |
embeddedartists | 0:50a4a80f3ecd | 103 | case CMD_ACK_MSG: |
embeddedartists | 0:50a4a80f3ecd | 104 | for (int i = 0; i < 3; i++) { |
embeddedartists | 0:50a4a80f3ecd | 105 | ackLed = 1; |
embeddedartists | 0:50a4a80f3ecd | 106 | wait_ms(100); |
embeddedartists | 0:50a4a80f3ecd | 107 | ackLed = 0; |
embeddedartists | 0:50a4a80f3ecd | 108 | wait_ms(100); |
embeddedartists | 0:50a4a80f3ecd | 109 | } |
embeddedartists | 0:50a4a80f3ecd | 110 | break; |
embeddedartists | 0:50a4a80f3ecd | 111 | } |
embeddedartists | 0:50a4a80f3ecd | 112 | |
embeddedartists | 0:50a4a80f3ecd | 113 | } |
embeddedartists | 0:50a4a80f3ecd | 114 | |
embeddedartists | 0:50a4a80f3ecd | 115 | } |
embeddedartists | 0:50a4a80f3ecd | 116 | |
embeddedartists | 0:50a4a80f3ecd | 117 | static bool xbeeInit() |
embeddedartists | 0:50a4a80f3ecd | 118 | { |
embeddedartists | 0:50a4a80f3ecd | 119 | xbee.registerCallback(xbeeDeviceUp, XBee::CbDeviceUp); |
embeddedartists | 0:50a4a80f3ecd | 120 | xbee.registerCallback(xbeeDeviceDown, XBee::CbDeviceDown); |
embeddedartists | 0:50a4a80f3ecd | 121 | xbee.registerCallback(xbeeNodeFound, XBee::CbNodeFound); |
embeddedartists | 0:50a4a80f3ecd | 122 | xbee.registerCallback(xbeeTxStat, XBee::CbTxStat); |
embeddedartists | 0:50a4a80f3ecd | 123 | xbee.registerCallback(xbeeDataAvailable, XBee::CbDataAvailable); |
embeddedartists | 0:50a4a80f3ecd | 124 | |
embeddedartists | 0:50a4a80f3ecd | 125 | #ifdef NODE_IS_COORDINATOR |
embeddedartists | 0:50a4a80f3ecd | 126 | XBee::XBeeError err = xbee.init(XBee::Coordinator, "EAEA"); |
embeddedartists | 0:50a4a80f3ecd | 127 | #else |
embeddedartists | 0:50a4a80f3ecd | 128 | XBee::XBeeError err = xbee.init(XBee::EndDevice, "EAEA"); |
embeddedartists | 0:50a4a80f3ecd | 129 | #endif |
embeddedartists | 0:50a4a80f3ecd | 130 | if (err != XBee::Ok) { |
embeddedartists | 0:50a4a80f3ecd | 131 | return false; |
embeddedartists | 0:50a4a80f3ecd | 132 | } |
embeddedartists | 0:50a4a80f3ecd | 133 | |
embeddedartists | 0:50a4a80f3ecd | 134 | return true; |
embeddedartists | 0:50a4a80f3ecd | 135 | |
embeddedartists | 0:50a4a80f3ecd | 136 | } |
embeddedartists | 0:50a4a80f3ecd | 137 | |
embeddedartists | 0:50a4a80f3ecd | 138 | static void reportInitFailed() { |
embeddedartists | 0:50a4a80f3ecd | 139 | while (true) { |
embeddedartists | 0:50a4a80f3ecd | 140 | xbeeInitLed = !xbeeInitLed; |
embeddedartists | 0:50a4a80f3ecd | 141 | wait_ms(200); |
embeddedartists | 0:50a4a80f3ecd | 142 | } |
embeddedartists | 0:50a4a80f3ecd | 143 | } |
embeddedartists | 0:50a4a80f3ecd | 144 | |
embeddedartists | 0:50a4a80f3ecd | 145 | static void ledInit() { |
embeddedartists | 0:50a4a80f3ecd | 146 | xbeeInitLed = 0; // turn on |
embeddedartists | 0:50a4a80f3ecd | 147 | remoteBtnLed = 1; // turn off |
embeddedartists | 0:50a4a80f3ecd | 148 | ackLed = 0; // turn off |
embeddedartists | 0:50a4a80f3ecd | 149 | led4 = 0; // turn off |
embeddedartists | 0:50a4a80f3ecd | 150 | } |
embeddedartists | 0:50a4a80f3ecd | 151 | |
embeddedartists | 0:50a4a80f3ecd | 152 | |
embeddedartists | 0:50a4a80f3ecd | 153 | /****************************************************************************** |
embeddedartists | 0:50a4a80f3ecd | 154 | * Main function |
embeddedartists | 0:50a4a80f3ecd | 155 | *****************************************************************************/ |
embeddedartists | 0:50a4a80f3ecd | 156 | |
embeddedartists | 0:50a4a80f3ecd | 157 | int main() { |
embeddedartists | 0:50a4a80f3ecd | 158 | |
embeddedartists | 0:50a4a80f3ecd | 159 | /* |
embeddedartists | 0:50a4a80f3ecd | 160 | * For this example to work at least two boards with XBee nodes must |
embeddedartists | 0:50a4a80f3ecd | 161 | * be available; one which is configured as Coordinator and another |
embeddedartists | 0:50a4a80f3ecd | 162 | * which is configured as End-Device. |
embeddedartists | 0:50a4a80f3ecd | 163 | * |
embeddedartists | 0:50a4a80f3ecd | 164 | * LED1 shows the state of XBee initialization. This LED is turned |
embeddedartists | 0:50a4a80f3ecd | 165 | * on when initialization starts and turned off when initialization |
embeddedartists | 0:50a4a80f3ecd | 166 | * is ready and the device us up. If initialization fails LED1 |
embeddedartists | 0:50a4a80f3ecd | 167 | * will blink. |
embeddedartists | 0:50a4a80f3ecd | 168 | * |
embeddedartists | 0:50a4a80f3ecd | 169 | * When the Push-button on the LPC4088 QuickStart Board is pushed |
embeddedartists | 0:50a4a80f3ecd | 170 | * a message will be broadcasted. The board(s) that receives the message |
embeddedartists | 0:50a4a80f3ecd | 171 | * will show the state of the remote board's button by turning LED2 |
embeddedartists | 0:50a4a80f3ecd | 172 | * on or off. |
embeddedartists | 0:50a4a80f3ecd | 173 | * |
embeddedartists | 0:50a4a80f3ecd | 174 | * The board that receives the button state message will send back |
embeddedartists | 0:50a4a80f3ecd | 175 | * an ACK message (only for button down). The board that receives |
embeddedartists | 0:50a4a80f3ecd | 176 | * the ACK message will blink with LED3. This can be used to verify |
embeddedartists | 0:50a4a80f3ecd | 177 | * that a board that is not close to you actually received a message |
embeddedartists | 0:50a4a80f3ecd | 178 | * without having to look at that board's LED2. |
embeddedartists | 0:50a4a80f3ecd | 179 | */ |
embeddedartists | 0:50a4a80f3ecd | 180 | |
embeddedartists | 0:50a4a80f3ecd | 181 | int buttonState = 1; |
embeddedartists | 0:50a4a80f3ecd | 182 | char data[2]; |
embeddedartists | 0:50a4a80f3ecd | 183 | uint8_t frameId = 0; |
embeddedartists | 0:50a4a80f3ecd | 184 | |
embeddedartists | 0:50a4a80f3ecd | 185 | // pull-up must be enabled for button |
embeddedartists | 0:50a4a80f3ecd | 186 | button.mode(PullUp); |
embeddedartists | 0:50a4a80f3ecd | 187 | |
embeddedartists | 0:50a4a80f3ecd | 188 | ledInit(); |
embeddedartists | 0:50a4a80f3ecd | 189 | |
embeddedartists | 0:50a4a80f3ecd | 190 | printf("Initializing\n"); |
embeddedartists | 0:50a4a80f3ecd | 191 | if (!xbeeInit()) { |
embeddedartists | 0:50a4a80f3ecd | 192 | reportInitFailed(); |
embeddedartists | 0:50a4a80f3ecd | 193 | } |
embeddedartists | 0:50a4a80f3ecd | 194 | |
embeddedartists | 0:50a4a80f3ecd | 195 | // Wait until XBee node is reported to be up. |
embeddedartists | 0:50a4a80f3ecd | 196 | // - For End-device this means that the node is associated with a |
embeddedartists | 0:50a4a80f3ecd | 197 | // coordinator |
embeddedartists | 0:50a4a80f3ecd | 198 | // - For a coordinator this means that the node is initialized and ready |
embeddedartists | 0:50a4a80f3ecd | 199 | printf("Wait until up\n"); |
embeddedartists | 0:50a4a80f3ecd | 200 | while(!xbeeIsUp) { |
embeddedartists | 0:50a4a80f3ecd | 201 | xbee.process(); |
embeddedartists | 0:50a4a80f3ecd | 202 | } |
embeddedartists | 0:50a4a80f3ecd | 203 | |
embeddedartists | 0:50a4a80f3ecd | 204 | // turn off led to indicate initialization is okay and node is up |
embeddedartists | 0:50a4a80f3ecd | 205 | xbeeInitLed = 1; |
embeddedartists | 0:50a4a80f3ecd | 206 | |
embeddedartists | 0:50a4a80f3ecd | 207 | printf("Node is Up\n"); |
embeddedartists | 0:50a4a80f3ecd | 208 | while (1) { |
embeddedartists | 0:50a4a80f3ecd | 209 | |
embeddedartists | 0:50a4a80f3ecd | 210 | if (button != buttonState) { |
embeddedartists | 0:50a4a80f3ecd | 211 | buttonState = button; |
embeddedartists | 0:50a4a80f3ecd | 212 | |
embeddedartists | 0:50a4a80f3ecd | 213 | data[0] = CMD_BTN_MSG; |
embeddedartists | 0:50a4a80f3ecd | 214 | data[1] = buttonState; |
embeddedartists | 0:50a4a80f3ecd | 215 | |
embeddedartists | 0:50a4a80f3ecd | 216 | // Send the button state. In this example we are broadcasting the |
embeddedartists | 0:50a4a80f3ecd | 217 | // message to all nodes on the same network (PAN ID). In reality |
embeddedartists | 0:50a4a80f3ecd | 218 | // direct messaging is preferred. |
embeddedartists | 0:50a4a80f3ecd | 219 | xbee.send(XBEE_ADDRHI_BROADCAST, XBEE_ADDRLO_BROADCAST, |
embeddedartists | 0:50a4a80f3ecd | 220 | data, 2, &frameId); |
embeddedartists | 0:50a4a80f3ecd | 221 | } |
embeddedartists | 0:50a4a80f3ecd | 222 | |
embeddedartists | 0:50a4a80f3ecd | 223 | |
embeddedartists | 0:50a4a80f3ecd | 224 | xbee.process(); |
embeddedartists | 0:50a4a80f3ecd | 225 | |
embeddedartists | 0:50a4a80f3ecd | 226 | } |
embeddedartists | 0:50a4a80f3ecd | 227 | } |