An example that shows how to use the XBee class/interface

Dependencies:   EALib mbed

main.cpp

Committer:
embeddedartists
Date:
2014-04-09
Revision:
1:fb7d92d3adbe
Parent:
0:50a4a80f3ecd

File content as of revision 1:fb7d92d3adbe:

/******************************************************************************
 * Includes
 *****************************************************************************/
#include "mbed.h"
#include "XBee.h"

/******************************************************************************
 * Typedefs and defines
 *****************************************************************************/

// define NODE_IS_COORDINATOR if this board should act
// as XBee coordinator. Make sure it is undefined it the board
// should act as End-Device
#define NODE_IS_COORDINATOR (1)

#define CMD_BTN_MSG (0)
#define CMD_ACK_MSG (1)

/******************************************************************************
 * Local variables
 *****************************************************************************/

static XBee xbee(P4_22, P4_23, P4_17, P4_19);

// led1 + led 2 -> active low
static DigitalOut xbeeInitLed(LED1);
static DigitalOut remoteBtnLed(LED2);
// led3 + led 4 -> active high
static DigitalOut ackLed(LED3);
static DigitalOut led4(LED4);

static DigitalIn button(p23);
static bool xbeeIsUp = false;

/******************************************************************************
 * Local functions
 *****************************************************************************/

static void xbeeDeviceUp(void) {
    xbeeIsUp = true;
}

static void xbeeDeviceDown(void) {
    xbeeIsUp = false;
}

static void xbeeNodeFound(void) {
    uint32_t addrHi = 0;
    uint32_t addrLo = 0;
    uint8_t rssi = 0;

    xbee.getRemoteAddress(&addrHi, &addrLo);
    xbee.getRssi(&rssi);

    printf("XBee: node found: hi=%lx, lo=%lx, rssi=%d\n",
            addrHi, addrLo, rssi);
}

static void xbeeTxStat(void) {

    uint8_t frameId = 0;
    XBee::XBeeTxStatus status = XBee::TxStatusOk;

    xbee.getTxStatus(&frameId, &status);

    printf("XBee: Tx Stat. Id=%u, status=%d\n", frameId, (int)status);
}



static void xbeeDataAvailable(void) {
    char* data = NULL;
    char ackMsg = CMD_ACK_MSG;
    uint8_t frameId = 0;
    uint8_t len = 0;
    uint32_t addrHi = 0;
    uint32_t addrLo = 0;
    uint8_t rssi = 0;

    xbee.getRemoteAddress(&addrHi, &addrLo);
    xbee.getData(&data, &len);
    xbee.getRssi(&rssi);

    printf("XBee: Data available: len=%d hi=%lx, lo=%lx, rssi=%d\n",
            (int)len, addrHi, addrLo, rssi);

    if (len > 0) {

        switch(data[0]) {
        case CMD_BTN_MSG:
            if (len > 1) {
                // change led to indicate button state
                remoteBtnLed = ((data[1] == 1) ? 1 : 0);


                // Send an ACK directly to the remote node (only for
                // buttons state == 0)
                if (data[1] == 0) {
                    xbee.send(addrHi, addrLo, &ackMsg, 1, &frameId);
                }
            }
            break;
        case CMD_ACK_MSG:
            for (int i = 0; i < 3; i++) {
                ackLed = 1;
                wait_ms(100);
                ackLed = 0;
                wait_ms(100);
            }
            break;
        }

    }

}

static bool xbeeInit()
{
    xbee.registerCallback(xbeeDeviceUp, XBee::CbDeviceUp);
    xbee.registerCallback(xbeeDeviceDown, XBee::CbDeviceDown);
    xbee.registerCallback(xbeeNodeFound, XBee::CbNodeFound);
    xbee.registerCallback(xbeeTxStat, XBee::CbTxStat);
    xbee.registerCallback(xbeeDataAvailable, XBee::CbDataAvailable);

#ifdef NODE_IS_COORDINATOR
    XBee::XBeeError err = xbee.init(XBee::Coordinator, "EAEA");
#else
    XBee::XBeeError err = xbee.init(XBee::EndDevice, "EAEA");
#endif
    if (err != XBee::Ok) {
        return false;
    }

    return true;

}

static void reportInitFailed() {
    while (true) {
        xbeeInitLed = !xbeeInitLed;
        wait_ms(200);
    }
}

static void ledInit() {
    xbeeInitLed = 0;  // turn on
    remoteBtnLed = 1; // turn off
    ackLed = 0;       // turn off
    led4 = 0;         // turn off
}


/******************************************************************************
 * Main function
 *****************************************************************************/

int main() {

    /*
     * For this example to work at least two boards with XBee nodes must
     * be available; one which is configured as Coordinator and another
     * which is configured as End-Device.
     *
     * LED1 shows the state of XBee initialization. This LED is turned
     * on when initialization starts and turned off when initialization
     * is ready and the device us up. If initialization fails LED1
     * will blink.
     *
     * When the Push-button on the LPC4088 QuickStart Board is pushed
     * a message will be broadcasted. The board(s) that receives the message
     * will show the state of the remote board's button by turning LED2
     * on or off.
     *
     * The board that receives the button state message will send back
     * an ACK message (only for button down). The board that receives
     * the ACK message will blink with LED3. This can be used to verify
     * that a board that is not close to you actually received a message
     * without having to look at that board's LED2.
     */

    int buttonState = 1;
    char data[2];
    uint8_t frameId = 0;

    // pull-up must be enabled for button
    button.mode(PullUp);

    ledInit();

    printf("Initializing\n");
    if (!xbeeInit()) {
        reportInitFailed();
    }

    // Wait until XBee node is reported to be up.
    // - For End-device this means that the node is associated with a
    //   coordinator
    // - For a coordinator this means that the node is initialized and ready
    printf("Wait until up\n");
    while(!xbeeIsUp) {
        xbee.process();
    }

    // turn off led to indicate initialization is okay and node is up
    xbeeInitLed = 1;

    printf("Node is Up\n");
    while (1) {

        if (button != buttonState) {
            buttonState = button;

            data[0] = CMD_BTN_MSG;
            data[1] = buttonState;

            // Send the button state. In this example we are broadcasting the
            // message to all nodes on the same network (PAN ID). In reality
            // direct messaging is preferred.
            xbee.send(XBEE_ADDRHI_BROADCAST, XBEE_ADDRLO_BROADCAST,
                    data, 2, &frameId);
        }


        xbee.process();

    }
}