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

Dependencies:   XBeeLib mbed

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 is not expected to have communication with the coordinator, so the device will not be able to receive packets and can to save as much power as possible; so the radio is set into low power mode.

The example does the following cycle endlessly:

  • Some sensor is read. For demonstration, a counter is incremented.
  • A message containing the collected data is sent to the coordinator.
  • After the data has been sent, the radio will go to sleep:
  • First, the radio is requested to go to sleep. When radio finally sleeps, then the application waits for the time configured in the SLEEP_SECONDS macro. By default it is set to 40 seconds but it can be changed as desired.
  • After that time, the application will awake the radio through the On/Sleep pin and another cycle starts.

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 is 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.

Firmware

In S2B modules, router firmware will not work for this example, because routers don't support sleep modes.
Make sure the XBee module has end-device firmware.
To flash a new firmware onto an XBee module, you need to use the XCTU software.

On S2C XBee modules, the SLEEP_RQ and ON/SLEEP# pins can be used not only for power management but also as a GPIO. To run this example they have to be configured as power management functionality (mode 1):

  • SLEEP_RQ pin: "D8"=1
  • ON/SLEEP# pin: "D9"=1

Network

Make sure the coordinator has the 'Cyclic Sleep Period' (SP) and at 'Number of Cyclic Sleep Periods' (SN) options values configured so that (3*SP*10*SN) is greater than the XBee module sleep time (in this example 40 s = 40000 ms).

If SP parameter in coordinator is pre-established for example to 0x1F4=500 based on other devices requirements, SN should be configured in coordinator for this example as:

  • MaxPinSleepTime= 3 * SP * 10 * SN
  • SN= MaxPinSleepTime / 3 / SP / 10
  • SN = 40000 / 3 / 500 / 10 = 2.666 -> Rounding high -> 3 = 0x3

Remember to change this parameter in the coordinator if SLEEP_SECONDS is changed in the example.

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 coordinator is receiving the frames by accessing the "Console" tab of the X-CTU.
If the frames are successfully sent, they will be displayed there. One message like the ones below should be seen every 40 seconds.

     Sensor sample: 0, next sample in 40 seconds
     Sensor sample: 1, next sample in 40 seconds
Committer:
hbujanda
Date:
Fri Jul 29 12:13:58 2016 +0200
Revision:
7:d6ce8bb743db
Parent:
4:247facc3db2a
Automatic upload

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hbujanda 2:507c28e0461a 1 /**
hbujanda 2:507c28e0461a 2 * Copyright (c) 2015 Digi International Inc.,
hbujanda 2:507c28e0461a 3 * All rights not expressly granted are reserved.
hbujanda 2:507c28e0461a 4 *
hbujanda 2:507c28e0461a 5 * This Source Code Form is subject to the terms of the Mozilla Public
hbujanda 2:507c28e0461a 6 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
hbujanda 2:507c28e0461a 7 * You can obtain one at http://mozilla.org/MPL/2.0/.
hbujanda 2:507c28e0461a 8 *
hbujanda 2:507c28e0461a 9 * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
hbujanda 2:507c28e0461a 10 * =======================================================================
hbujanda 2:507c28e0461a 11 */
hbujanda 2:507c28e0461a 12
hbujanda 2:507c28e0461a 13 #include "mbed.h"
hbujanda 2:507c28e0461a 14 #include "XBeeLib.h"
hbujanda 2:507c28e0461a 15 #if defined(ENABLE_LOGGING)
hbujanda 2:507c28e0461a 16 #include "DigiLoggerMbedSerial.h"
hbujanda 2:507c28e0461a 17 using namespace DigiLog;
hbujanda 2:507c28e0461a 18 #endif
hbujanda 2:507c28e0461a 19
hbujanda 2:507c28e0461a 20 using namespace XBeeLib;
hbujanda 2:507c28e0461a 21
hbujanda 2:507c28e0461a 22 #define SLEEP_SECONDS (40) /* 40 seconds, for demo */
hbujanda 2:507c28e0461a 23
hbujanda 2:507c28e0461a 24 #if !defined(RADIO_SLEEP_REQ)
hbujanda 2:507c28e0461a 25 #error "Please define RADIO_SLEEP_REQ pin in config.h"
hbujanda 2:507c28e0461a 26 #endif
hbujanda 2:507c28e0461a 27 #if !defined(RADIO_ON_SLEEP)
hbujanda 2:507c28e0461a 28 #error "Please define RADIO_ON_SLEEP pin in config.h"
hbujanda 2:507c28e0461a 29 #endif
hbujanda 2:507c28e0461a 30
hbujanda 2:507c28e0461a 31 Serial *log_serial;
hbujanda 2:507c28e0461a 32
hbujanda 2:507c28e0461a 33 DigitalOut* sleep_req = NULL;
hbujanda 2:507c28e0461a 34 DigitalIn* on_sleep = NULL;
hbujanda 2:507c28e0461a 35
hbujanda 2:507c28e0461a 36 bool is_radio_sleeping()
hbujanda 2:507c28e0461a 37 {
hbujanda 2:507c28e0461a 38 assert(on_sleep != NULL);
hbujanda 2:507c28e0461a 39
hbujanda 2:507c28e0461a 40 return on_sleep->read() == 0;
hbujanda 2:507c28e0461a 41 }
hbujanda 2:507c28e0461a 42
hbujanda 2:507c28e0461a 43 void sleep_radio()
hbujanda 2:507c28e0461a 44 {
hbujanda 2:507c28e0461a 45 assert(sleep_req != NULL);
hbujanda 2:507c28e0461a 46
hbujanda 2:507c28e0461a 47 sleep_req->write(1);
hbujanda 2:507c28e0461a 48 }
hbujanda 2:507c28e0461a 49
hbujanda 2:507c28e0461a 50 void awake_radio()
hbujanda 2:507c28e0461a 51 {
hbujanda 2:507c28e0461a 52 assert(sleep_req != NULL);
hbujanda 2:507c28e0461a 53
hbujanda 2:507c28e0461a 54 sleep_req->write(0);
hbujanda 2:507c28e0461a 55
hbujanda 2:507c28e0461a 56 /* Wait until radio awakes. Typically 14 mS */
hbujanda 2:507c28e0461a 57 while(is_radio_sleeping());
hbujanda 2:507c28e0461a 58 }
hbujanda 2:507c28e0461a 59
hbujanda 2:507c28e0461a 60 static void send_sample(XBeeZB& xbee)
hbujanda 2:507c28e0461a 61 {
hbujanda 2:507c28e0461a 62 char data[60];
hbujanda 2:507c28e0461a 63 static uint16_t sample = 0;
spastor 4:247facc3db2a 64 const uint16_t data_len = sprintf(data, "\r\nSensor sample: %u, next sample in %lu seconds\r\n",
hbujanda 2:507c28e0461a 65 sample++, (uint32_t)SLEEP_SECONDS);
hbujanda 2:507c28e0461a 66
hbujanda 2:507c28e0461a 67 const TxStatus txStatus = xbee.send_data_to_coordinator((const uint8_t *)data, data_len);
hbujanda 2:507c28e0461a 68 if (txStatus == TxStatusSuccess)
hbujanda 2:507c28e0461a 69 log_serial->printf("send_data_to_coordinator OK\r\n");
hbujanda 2:507c28e0461a 70 else
hbujanda 2:507c28e0461a 71 log_serial->printf("send_data_to_coordinator failed with %d\r\n", (int) txStatus);
hbujanda 2:507c28e0461a 72 }
hbujanda 2:507c28e0461a 73
hbujanda 2:507c28e0461a 74 int main()
hbujanda 2:507c28e0461a 75 {
hbujanda 2:507c28e0461a 76 AtCmdFrame::AtCmdResp cmdresp;
hbujanda 2:507c28e0461a 77
hbujanda 2:507c28e0461a 78 /* Configure cpu pins to control the radio power management pins:
spastor 4:247facc3db2a 79 * - RADIO_SLEEP_REQ: This pin connected to the radio SLEEP_RQ pin (pin 9 on THT modules, pin 10 on SMT modules) will
hbujanda 2:507c28e0461a 80 * allow the cpu to request the radio to sleep or awake.
hbujanda 2:507c28e0461a 81 * - RADIO_ON_SLEEP: This pin connected to radio ON/SLEEP# pin (pin 13 on THT modules, pin 26 on SMT modules) will
hbujanda 2:507c28e0461a 82 * allow the cpu to know if the radio is awaked or sleept.
hbujanda 2:507c28e0461a 83 */
hbujanda 2:507c28e0461a 84 sleep_req = new DigitalOut(RADIO_SLEEP_REQ);
hbujanda 2:507c28e0461a 85 on_sleep = new DigitalIn(RADIO_ON_SLEEP);
hbujanda 2:507c28e0461a 86
hbujanda 2:507c28e0461a 87 log_serial = new Serial(DEBUG_TX, DEBUG_RX);
hbujanda 2:507c28e0461a 88 log_serial->baud(9600);
hbujanda 2:507c28e0461a 89 log_serial->printf("Sample application to demo pin sleep power management with the XBeeZB\r\n\r\n");
hbujanda 2:507c28e0461a 90 log_serial->printf(XB_LIB_BANNER);
hbujanda 2:507c28e0461a 91
hbujanda 2:507c28e0461a 92 #if defined(ENABLE_LOGGING)
hbujanda 2:507c28e0461a 93 new DigiLoggerMbedSerial(log_serial, LogLevelInfo);
hbujanda 2:507c28e0461a 94 #endif
hbujanda 2:507c28e0461a 95
hbujanda 2:507c28e0461a 96 XBeeZB xbee = XBeeZB(RADIO_TX, RADIO_RX, RADIO_RESET, NC, NC, 9600);
hbujanda 2:507c28e0461a 97
hbujanda 2:507c28e0461a 98 RadioStatus radioStatus = xbee.init();
hbujanda 2:507c28e0461a 99 MBED_ASSERT(radioStatus == Success);
hbujanda 2:507c28e0461a 100
hbujanda 2:507c28e0461a 101 /* Configure Sleep mode */
hbujanda 2:507c28e0461a 102 cmdresp = xbee.set_param("SM", 1); /* Pin Sleep */
hbujanda 2:507c28e0461a 103 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
hbujanda 2:507c28e0461a 104 log_serial->printf("SM Failed!!\r\n");
hbujanda 2:507c28e0461a 105 }
hbujanda 2:507c28e0461a 106
spastor 4:247facc3db2a 107 awake_radio();
spastor 4:247facc3db2a 108
hbujanda 2:507c28e0461a 109 /* Wait until the device has joined the network */
hbujanda 2:507c28e0461a 110 log_serial->printf("Waiting for device to join the network: ");
hbujanda 2:507c28e0461a 111 while (!xbee.is_joined()) {
hbujanda 2:507c28e0461a 112 wait_ms(1000);
hbujanda 2:507c28e0461a 113 log_serial->printf(".");
hbujanda 2:507c28e0461a 114 }
hbujanda 2:507c28e0461a 115 log_serial->printf("OK\r\n");
hbujanda 2:507c28e0461a 116
hbujanda 2:507c28e0461a 117 /* Start sending samples */
hbujanda 2:507c28e0461a 118 while (1) {
hbujanda 2:507c28e0461a 119 if (xbee.is_joined()) {
hbujanda 2:507c28e0461a 120 /* Awake the radio */
hbujanda 2:507c28e0461a 121 awake_radio();
hbujanda 2:507c28e0461a 122
hbujanda 2:507c28e0461a 123 send_sample(xbee);
hbujanda 2:507c28e0461a 124
hbujanda 2:507c28e0461a 125 /* Sleep the radio again */
hbujanda 2:507c28e0461a 126 sleep_radio();
hbujanda 2:507c28e0461a 127 }
hbujanda 2:507c28e0461a 128
hbujanda 2:507c28e0461a 129 wait(SLEEP_SECONDS);
hbujanda 2:507c28e0461a 130 }
hbujanda 2:507c28e0461a 131
hbujanda 2:507c28e0461a 132 delete(log_serial);
hbujanda 2:507c28e0461a 133 }