DigiMesh Power Management using Pin Sleep example for mbed XBeeLib By Digi

Dependencies:   XBeeLib mbed

Fork of XBeeZB_power_mngmnt_pin_sleep by Digi International Inc.

Description

This example characterizes a device that after taking samples from some sensors and sending the information collected through the radio, does nothing for a long period of time that could range from several minutes to several hours.
In that long period of inactivity it's not expected to have communication with the coordinator or other remote devices. The device will not be able to receive packets and should save as much power as possible, therefore the radio is set into low power.

The example does following cycle endlessly:

  • Some sensor is read. For demonstration, a counter is incremented.
  • For demonstration, a message containing the data collected during sampling stage is sent to a remote device.
  • After job has been done the radio will go to sleep:
  • First radio is requested to go to sleep. When radio finally sleeps, then the application waits for the time configured in the SLEEP_SECONDS define (40 seconds).
  • This time can be increased as desired.
  • After that time, the application will awake the radio through the On/Sleep pin and another cycle will start by taking a sample.

Setup

Application

Define RADIO_SLEEP_REQ and RADIO_ON_SLEEP in config.h file according to the mbed micro-controller GPIOs that will be used to control the XBee module power.

Hardware

It's necessary to wire following connections from the mbed micro-controller to the XBee radio according to the configuration done in the application:

  • From the mbed micro-controller RADIO_SLEEP_REQ to the XBee module SLEEP_RQ pin (pin 9 on THT modules, pin 10 on SMT modules) will allow the mbed micro-controller to request the radio to sleep or awake.
  • From the mbed micro-controller RADIO_ON_SLEEP to XBee module ON/SLEEP# pin (pin 13 on THT modules, pin 26 on SMT modules) will allow the mbed micro-controller to know if the radio is awake or slept.

Demo run

While the demo is running, you will see the frames sent by the XBee module through the serial console terminal.

Verify that the remote device is receiving the frames by accessing the "Console" tab of the XCTU.
If the frames are successfully sent, they will be displayed there, every 40 seconds.

     Sensor sample: 0, next sample in 40 seconds
     Sensor sample: 1, next sample in 40 seconds
Revision:
0:5e030e8ab809
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon May 11 18:03:48 2015 +0200
@@ -0,0 +1,128 @@
+/**
+ * Copyright (c) 2015 Digi International Inc.,
+ * All rights not expressly granted are reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
+ * =======================================================================
+ */
+
+#include "mbed.h"
+#include "XBeeLib.h"
+#if defined(ENABLE_LOGGING)
+#include "DigiLoggerMbedSerial.h"
+using namespace DigiLog;
+#endif
+
+using namespace XBeeLib;
+
+//TODO: Configure pin according to your hardware
+#define SLEEP_REQ_PIN   P0_4
+
+//TODO: Configure pin according to your hardware
+#define ON_SLEEP_PIN    P0_5
+
+#define SLEEP_SECONDS			(40)	/* 40 seconds, for demo */
+//#define SLEEP_SECONDS			(86400)	/* 24 hours */
+
+Serial *log_serial;
+
+DigitalOut* _sleep_req = NULL;
+DigitalIn* _on_sleep = NULL;
+
+void radio_sleep()
+{
+     _sleep_req->write(1);
+}
+
+void radio_on()
+{
+    _sleep_req->write(0);
+}
+
+bool is_radio_sleeping()
+{
+    return _on_sleep->read() == 0;
+}
+
+static void send_sample(XBeeZB& xbee)
+{
+    char data[60];
+    static uint16_t sample = 0;
+    const uint16_t data_len = sprintf(data, "\r\nSensor sample: %u, next sample in %lu seconds\r\n", 
+								 sample++, (uint32_t)SLEEP_SECONDS);
+
+    const TxStatus txStatus = xbee.send_data_to_coordinator((const uint8_t *)data, data_len);
+    if (txStatus == TxStatusSuccess)
+        log_serial->printf("send_data_to_coordinator OK\r\n");
+    else
+        log_serial->printf("send_data_to_coordinator failed with %d\r\n", (int) txStatus);
+}
+
+int main()
+{
+    AtCmdFrame::AtCmdResp cmdresp;
+
+    /* Configure cpu pins to control the radio power management pins:
+     *     - _sleep_req: This pin connected to the radio SLEEP_RQ pin (pin 9) will allow the cpu to request the radio 
+     *                   to sleep or awake.
+     *     - _on_sleep: This pin connected to radio ON/SLEEP# pin (pin 13) will allow the cpu to know if the radio
+     *                  is awaked or sleept.
+     */
+    _sleep_req = new DigitalOut(SLEEP_REQ_PIN);
+    _on_sleep = new DigitalIn(ON_SLEEP_PIN);
+
+    /* Set the radio on so we can send initialization messages to the radio */
+    radio_on();
+
+    log_serial = new Serial(DEBUG_TX, DEBUG_RX);
+    log_serial->baud(9600);
+    log_serial->printf("Sample application to demo how to send unicast and broadcast data with the XBeeZB\r\n\r\n");
+    log_serial->printf(XB_LIB_BANNER);
+
+#if defined(ENABLE_LOGGING)
+    new DigiLoggerMbedSerial(log_serial, LogLevelInfo);
+#endif
+
+    XBeeZB xbee = XBeeZB(RADIO_TX, RADIO_RX, RADIO_RESET, NC, NC, 9600);
+
+    RadioStatus radioStatus = xbee.init();
+    MBED_ASSERT(radioStatus == Success);
+
+    /* Configure Sleep mode */
+    cmdresp = xbee.set_param("SM", 1);  /* Pin Sleep */
+    if (cmdresp != AtCmdFrame::AtCmdRespOk) {
+        log_serial->printf("SM Failed!!\r\n");
+    }
+
+    /* Wait until the device has joined the network */
+    log_serial->printf("Waiting for device to join the network: ");
+    while (!xbee.is_joined()) {
+        wait_ms(1000);
+        log_serial->printf(".");
+    }
+    log_serial->printf("OK\r\n");
+
+    /* Start sending samples */
+    while (1) {
+        if (xbee.is_joined()) {
+            /* Awake the radio */
+            radio_on();
+
+            /* Wait until radio awakes. Typically 14 mS */
+            while(is_radio_sleeping());
+
+            send_sample(xbee);
+
+            /* Sleep the radio again */
+            radio_sleep();
+        }
+
+        wait(SLEEP_SECONDS);
+    }
+
+    delete(log_serial);
+}