Library to easily communicate with XBee modules.

Dependencies:   DigiLogger

Dependents:   WaterLogger XbeeGateway XBee_Cooker ProjetReceiver ... more

Handling IO Data Samples from other modu

Introduction

Similarly to how a remote device's IOs can be polled manually through specific methods, it is also possible to configure a remote device to periodically send the status of the IOs and ADCs to a specific address. This library allows you to register a special callback for those events so the information can be retrieved in an easier way. These callbacks have two arguments:

  • A reference to a RemoteXBee object, representing the device that sent the IO Data Sample.
  • A reference to an IOSample object, that contains the methods to retrieve the remote device's DIOs and ADCs.

Retrieving information from IOSample objects

The IOSampleZB, IOSample802 and IOSampleDM classes have the same methods available to retrieve the status of the lines:

IOSample ClassMethodDescriptionParametersReturn value
IOSampleZB IOSample802 IOSampleDMRadioStatus get_dio(IoLine line, DioVal * const val)Gets the value of a Digital Inputline: DIO line being read.
val: pointer where the DIO value read will be stored.
Success: if the value was available in the sample.
Failure: if the sample does not contain information about the line.
RadioStatus get_adc(IoLine line, uint16_t * const val)Gets the value of an ADCline: ADC line being read.
val: pointer where the ADC value read will be stored.
Success: if the value was available in the sample.
Failure: if the sample does not contain information about the line.

Information

The IoLine values that can be used are the same as the ones mentioned in the Handling remote modules DIOs, ADCs and PWMs section.

Example of use

The following examples show how to check for the status of DIO0 and AD3 lines:

ZigBee

#include "XBeeLib.h"
  
using namespace XBeeLib;
 
 
static void io_data_cb(const RemoteXBeeZB& remote, const IOSampleZB& sample_data)
{
    RadioStatus radioStatus;
 
    DioVal dio3;
    radioStatus = sample_data.get_dio(XBeeZB::DIO3_AD3, &dio3);
    if (radioStatus != Success) {
        log_serial->printf("sample_data.get_dio(XBeeZB::DIO3_AD3, &dio3) FAILED\r\n");
    } else {
        log_serial->printf("DIO3 Digital value %d\r\n", dio3);
    }
 
    uint16_t ad2;  
    radioStatus = sample_data.get_adc(XBeeZB::DIO2_AD2, &ad2);
    if (radioStatus != Success) {
        log_serial->printf("sample_data.get_adc(XBeeZB::DIO2_AD2, &ad2) FAILED\r\n");
    } else {
        log_serial->printf("AD2 Analog value %04x\r\n", ad3);
    }
}

802.15.4

#include "XBeeLib.h"
  
using namespace XBeeLib;
 
 
static void io_data_cb(const RemoteXBee802& remote, const IOSample802& sample_data)
{
    RadioStatus radioStatus;
 
    DioVal dio3;
    radioStatus = sample_data.get_dio(XBee802::DIO3_AD3, &dio3);
    if (radioStatus != Success) {
        log_serial->printf("sample_data.get_dio(XBee802::DIO3_AD3, &dio3) FAILED\r\n");
    } else {
        log_serial->printf("DIO3 Digital value %d\r\n", dio3);
    }
 
    uint16_t ad2;  
    radioStatus = sample_data.get_adc(XBee802::DIO2_AD2, &ad2);
    if (radioStatus != Success) {
        log_serial->printf("sample_data.get_adc(XBee802::DIO2_AD2, &ad2) FAILED\r\n");
    } else {
        log_serial->printf("AD2 Analog value %04x\r\n", ad2);
    }
}

DigiMesh

#include "XBeeLib.h"
  
using namespace XBeeLib;
 
 
static void io_data_cb(const RemoteXBeeDM& remote, const IOSampleDM& sample_data)
{
    RadioStatus radioStatus;
 
    DioVal dio3;
    radioStatus = sample_data.get_dio(XBeeDM::DIO3_AD3, &dio3);
    if (radioStatus != Success) {
        log_serial->printf("sample_data.get_dio(XBeeDM::DIO3_AD3, &dio3) FAILED\r\n");
    } else {
        log_serial->printf("DIO3 Digital value %d\r\n", dio3);
    }
 
    uint16_t ad2;  
    radioStatus = sample_data.get_adc(XBeeDM::DIO2_AD2, &ad2);
    if (radioStatus != Success) {
        log_serial->printf("sample_data.get_adc(XBeeDM::DIO2_AD2, &ad2) FAILED\r\n");
    } else {
        log_serial->printf("AD2 Analog value %04x\r\n", ad3);
    }
}

Receiving IO Data Samples from another module

The IO Data Samples event is used when the local (attached) XBee device has received information about the Digital Inputs and ADCs of a remote device on the network. These are the steps to receive IO Data Samples on your XBee device:

  1. Create an XBee object.
  2. Register the desired function callback. This function will be called by the library when corresponding IO Sample frame is received.
  3. Initialize the XBee.
  4. Configure the remote XBee module pins according to the table above.
  5. Configure the sample rate.
  6. Configure remote module to send IO Samples to local node.
  7. Periodically ask the XBee library to process received frames.

Create an XBee object

Create an XBee object of the desired variant:

ZigBee

#include "XBeeLib.h"
  
using namespace XBeeLib;
 
void main()
{
     [...]
      
     XBeeZB xbee = XBeeZB(RADIO_TX, RADIO_RX, RADIO_RESET);
      
     [...]
}

802.15.4

#include "XBeeLib.h"
  
using namespace XBeeLib;
 
void main()
{
     [...]
      
     XBee802 xbee = XBee802(RADIO_TX, RADIO_RX, RADIO_RESET);
      
     [...]
}

DigiMesh

#include "XBeeLib.h"
  
using namespace XBeeLib;
 
void main()
{
     [...]
      
     XBeeDM xbee = XBeeDM(RADIO_TX, RADIO_RX, RADIO_RESET);
      
     [...]
}

Register desired receive function callback

The user has to provide the desired function to be called when specific frames are received. For every protocol, there is a single receive callback. However, depending on the XBee variant the callback function has a different prototype, as it takes different RemoteXBee and IOSample objects.

ZigBee

#include "XBeeLib.h"
  
using namespace XBeeLib;
 
/** Callback function, invoked at packet reception */
void io_data_cb(const RemoteXBeeZB& remote, const IOSampleZB sample_data)
{
    printf("You have an IO Data Sample!\r\n");
}
 
int main()
{
    [...]
     
    /* Register callbacks */
    xbee.register_io_sample_cb(&io_data_cb);
     
    [...]
}

802.15.4

#include "XBeeLib.h"
  
using namespace XBeeLib;
 
/** Callback function, invoked at packet reception */
void io_data_cb(const RemoteXBee802& remote, const IOSample802 sample_data)
{
    printf("You have an IO Data Sample!\r\n");
}
 
int main()
{
    [...]
     
    /* Register callbacks */
    xbee.register_io_sample_cb(&io_data_cb);
     
    [...]
}

Information

If the sender device does not have a 16-bit address configured, the RemoteXBee802 object created by the library will have its 16-bit address set to DR_ADDR16_UNKNOWN and its 64-bit address equal to the actual remote object's 64-bit address (SH and SL parameters).

DigiMesh

#include "XBeeLib.h"
  
using namespace XBeeLib;
 
/** Callback function, invoked at packet reception */
void io_data_cb(const RemoteXBeeDM& remote, const IOSampleDM sample_data)
{
    printf("You have an IO Data Sample!\r\n");
}
 
int main()
{
    [...]
     
    /* Register callbacks */
    xbee.register_io_sample_cb(&io_data_cb);
     
    [...]
}

Initialize the XBee

Next, initialize the XBee. That means calling the init() method (see Initializing modules) and optionally any method required to put the device in the desired network.

#include "XBeeLib.h"
  
using namespace XBeeLib;
 
int main()
{
    [...]
     
    xbee.init();
}

Configure remote module to send IO Samples to local node

The remote module must be configured to send the IO Samples to a specific address periodically. To do so the following functions are available:

MethodDescriptionWrapped parameter
config_io_sample_destination(const RemoteXBee& remote, const RemoteXBee& destination)Configures to which node the remote module will send the IO SamplesDH and DL
set_io_sample_rate(const RemoteXBee& remote, float seconds)Configures how often, in seconds, the remote module will send the IO SamplesIR

ZigBee

#include "XBeeLib.h"
  
using namespace XBeeLib;

#define REMOTE_NODE_ADDR64      0x0013A200AABBCCDD

int main()
{
     XBeeZB xbee = XBeeZB(RADIO_TX, RADIO_RX, RADIO_RESET);
    [...]
    RemoteXBeeZB remote = RemoteXBeeZB(REMOTE_NODE_ADDR64);
    
    xbee.set_io_sample_rate(remote, 1.5);
    
    RemoteXBeeZB localNode = RemoteXBeeZB(xbee.get_addr64());
    xbee.config_io_sample_destination(remote, localNode);
    [...]
}

802.15.4

#include "XBeeLib.h"
  
using namespace XBeeLib;

#define REMOTE_NODE_ADDR64      0x0013A200AABBCCDD

int main()
{
     XBee802 xbee = XBee802(RADIO_TX, RADIO_RX, RADIO_RESET);
    [...]
    RemoteXBee802 remote = RemoteXBee802 (REMOTE_NODE_ADDR64);
    
    xbee.set_io_sample_rate(remote, 1.5);
    
    RemoteXBee802 localNode = RemoteXBee802 (xbee.get_addr64());
    xbee.config_io_sample_destination(remote, localNode);
    [...]
}

DigiMesh

#include "XBeeLib.h"
  
using namespace XBeeLib;

#define REMOTE_NODE_ADDR64      0x0013A200AABBCCDD

int main()
{
     XBeeDM xbee = XBeeDM(RADIO_TX, RADIO_RX, RADIO_RESET);
    [...]
    RemoteXBeeDM remote = RemoteXBeeDM(REMOTE_NODE_ADDR64);
    
    xbee.set_io_sample_rate(remote, 1.5);
    
    RemoteXBeeDM localNode = RemoteXBeeDM(xbee.get_addr64());
    xbee.config_io_sample_destination(remote, localNode);
    [...]
}

Periodically ask the XBee library to process received frames

The process_rx_frames() method must be called periodically by the user so the XBee library delivers the frames to the corresponding registered callbacks.

Help

See more info on Frame Receive Process

Make sure you call this method periodically:

#include "XBeeLib.h"
  
using namespace XBeeLib;
 
void main()
{
    [...]
     
    while (true) {
        xbee.process_rx_frames();
        wait_ms(100);
        printf(".");
    }
     
    [...]
}

Examples

Here is a ready to use example:

For ZigBee modules:

Import programXBeeZB_IO_Sample_Callback

ZigBee IO Sampling Callback example for mbed XBeeLib By Digi

For 802.15.4 modules:

Import programXBee802_IO_Sample_Callback

802.15.4 IO Sampling Callback example for mbed XBeeLib By Digi

For DigiMesh modules:

Import programXBeeDM_IO_Sample_Callback

DigiMesh IO Sampling Callback example for mbed XBeeLib By Digi