Library to easily communicate with XBee modules.
Dependencies: DigiLogger
Dependents: WaterLogger XbeeGateway XBee_Cooker ProjetReceiver ... more
Handling remote modules DIOs ADCs and PW
Digi XBee modules have pins that can be configured to perform as a digital output or input (DIO), as an analog input (ADC) or as an analog output (PWM).
This mbed library offer functionality to manage those pins on Remote Devices (the local device would typically use the mbed microcontroller). This is achieved by sending RF messages to the remote radio from the local radio attached to the mbed processor.
Information
There is no API for setting local device's DIOs/ADCs. In case you need it, it can be done by setting local parameters (See Configuring local and remote modules chapter) accordingly to specifications in the product manual.
Available methods¶
XBee Class | Method | Description | Parameters |
---|---|---|---|
XBee802 XBeeZB XBeeDM | RadioStatus set_pin_config(const RemoteXBee& remote, IoLine line, IoMode mode) | Configures a remote device pin for the desired functionality: Digital Input, Digital Output, ADC or PWM. This step is required before calling the other methods | remote: remote device. line: IO line being configured. mode: configuration mode for the selected line. |
RadioStatus get_pin_config(const RemoteXBee& remote, IoLine line, IoMode * const mode) | Gets the current configuration of a remote device's pin | remote: remote device. line: IO line being read to get its configuration. mode: pointer where the configuration read will be stored. | |
RadioStatus set_pin_pull_up(const RemoteXBee& remote, IoLine line, bool enable) | Enables or disables the internal pull-up resistor of a remote device's pin. | remote: remote device. line: IO line being configured. enable: enable or not internal pull-up | |
RadioStatus enable_dio_change_detection(const RemoteXBee& remote, IoLine line, bool enable); | Enables or disables sending an IO Sample when a digital input changes its value (See Handling IO Data Samples from remote modules). | remote: remote device. line: IO line being configured. enable: enable or not change detection. | |
RadioStatus set_dio(const RemoteXBee& remote, IoLine line, DioVal val) | Sets the value of a Digital Output to High or Low | remote: remote device. line: DIO line being set. val: value that will be set in the DIO line: DIO_LOW or DIO_HIGH | |
RadioStatus get_dio(const RemoteXBee& remote, IoLine line, DioVal * const val) | Gets the value of a Digital Input | remote: remote device. line: DIO line being read. val: pointer where the DIO value read will be stored. DIO_LOW or DIO_HIGH. | |
RadioStatus get_adc(const RemoteXBee& remote, IoLine line, uint16_t * const val) | Gets the value of an ADC | remote: remote device. line: ADC line being read. val: pointer where the value read from the ADC will be stored. | |
XBee802 XBeeDM | RadioStatus set_pwm(const RemoteXBee& remote, IoLine line, float duty_cycle) | Sets the value (duty cycle) of a PWM | remote: remote device. line: PWM line being set. duty_cycle: duty cycle that will be set in the PWM line. |
RadioStatus get_pwm(const RemoteXBee& remote, IoLine line, float * const duty_cycle) | Gets the value (duty cycle) of a PWM | remote: remote device. line: PWM line being read. duty_cycle: pointer where the value of the duty cycle read from the PWM will be stored. |
Getting an IO Sample¶
The previous get_dio() and get_adc() methods will send one message to the remote node and wait for its response every time they are used. When it comes to reading more than one DIO or ADC of the same remote node, it is better to use the get_iosample() method. This method returns the same object that is passed to the IO Data Samples callbacks, querying all DIOs and ADCs in a single transaction, reducing the network traffic and guaranteeing that all lines are sampled at exactly the same time.
XBee Class | Method | Description | Parameters |
---|---|---|---|
XBee802 | IOSample802 get_iosample(const RemoteXBee& remote) | Retrieves an IO Sample from a remote node, so it can be used to get the remote node's ADC and DIO values | remote: remote device. |
XBeeZB | IOSampleZB get_iosample(const RemoteXBee& remote) | Retrieves an IO Sample from a remote node, so it can be used to get the remote node's ADC and DIO values | remote: remote device. |
XBeeDM | IOSampleDM get_iosample(const RemoteXBee& remote) | Retrieves an IO Sample from a remote node, so it can be used to get the remote node's ADC and DIO values | remote: remote device. |
ZigBee
#include "XBeeLib.h" using namespace XBeeLib; void main() { XBeeZB xbee = XBeeZB(RADIO_TX, RADIO_RX, RADIO_RESET); [...] IOSampleZB iosample = xbee.get_iosample(RemoteXBeeZB(0x0013A200AABBCCDD)); RadioStatus radioStatus; DioVal dio2; radioStatus = sample_data.get_dio(XBeeZB::DIO2_AD2, &dio2); [...] DioVal dio3; radioStatus = sample_data.get_dio(XBeeZB::DIO3_AD3, &dio3); }
802.15.4
#include "XBeeLib.h" using namespace XBeeLib; void main() { XBee802 xbee = XBee802(RADIO_TX, RADIO_RX, RADIO_RESET); [...] IOSample802 iosample = xbee.get_iosample(RemoteXBee802(0x0013A200AABBCCDD)); RadioStatus radioStatus; DioVal dio0; radioStatus = sample_data.get_dio(XBee802::DIO0_AD0, &dio3); [...] DioVal dio2; radioStatus = sample_data.get_dio(XBee802::DIO2_AD2, &dio2); }
XBeeDM
#include "XBeeLib.h" using namespace XBeeLib; void main() { XBeeDM xbee = XBeeDM(RADIO_TX, RADIO_RX, RADIO_RESET); [...] IOSampleDM iosample = xbee.get_iosample(RemoteXBeeDM(0x0013A200AABBCCDD)); RadioStatus radioStatus; DioVal dio0; radioStatus = sample_data.get_dio(XBeeDM::DIO0_AD0, &dio3); [...] DioVal dio2; radioStatus = sample_data.get_dio(XBeeDM::DIO2_AD2, &dio2); }
The same functionality is offered for all modules, although the pin (IoLine) names and functionality available on those pins are different:
Line parameter¶
XBee device | Pin | Digital Input | Digital Output | ADC | PWM |
---|---|---|---|---|---|
ZigBee | DIO0_AD0 | Yes | Yes | Yes | |
DIO1_AD1 | Yes | Yes | Yes | ||
DIO2_AD2 | Yes | Yes | Yes | ||
DIO3_AD3 | Yes | Yes | Yes | ||
DIO4 | Yes | Yes | |||
DIO5 | Yes | Yes | |||
DIO6 | Yes | Yes | |||
DIO7 | Yes | Yes | |||
DIO10 | Yes | Yes | |||
DIO11 | Yes | Yes | |||
DIO12 | Yes | Yes | |||
SUPPLY_VOLTAGE* | Yes | ||||
802.15.4 | DIO0_AD0 | Yes | Yes | Yes | |
DIO1_AD1 | Yes | Yes | Yes | ||
DIO2_AD2 | Yes | Yes | Yes | ||
DIO3_AD3 | Yes | Yes | Yes | ||
DIO4_AD4 | Yes | Yes | Yes | ||
DIO5_AD5 | Yes | Yes | Yes | ||
DIO6 | Yes | Yes | |||
DIO7 | Yes | Yes | |||
DI8 | Yes | ||||
PWM0 | Yes | ||||
PWM1 | Yes | ||||
DigiMesh | DIO0_AD0 | Yes | Yes | Yes | |
DIO1_AD1 | Yes | Yes | Yes | ||
DIO2_AD2 | Yes | Yes | Yes | ||
DIO3_AD3 | Yes | Yes | Yes | ||
DIO4 | Yes | Yes | |||
DIO5 | Yes | Yes | |||
DIO6 | Yes | Yes | |||
DIO7 | Yes | Yes | |||
DIO8 | Yes | Yes | |||
DIO9 | Yes | Yes | |||
DIO10_PWM0 | Yes | Yes | Yes | ||
DIO11_PWM1 | Yes | Yes | Yes | ||
DIO12 | Yes | Yes |
Information
- SUPPLY_VOLTAGE is not a real pin. Its ADC value can be queried to get the remote module supply voltage if enabled. See V+ AT command for more information.
Mode parameter¶
IoMode enum used in set_pin_config() and get_pin_config()methods can take following values: Disabled, SpecialFunc, Adc, Pwm, DigitalInput, DigitalOutLow and DigitalOutHigh.
DIO value parameter¶
DioVal enum used in set_dio() and get_dio() methods can take following values: DIO_LOW and DIO_HIGH.
ADC value parameter¶
get_adc() method takes an uint16_t as value argument. The value stored in val represent the analog value of the pin ranging from 0 to 0x3FF.
PWM value parameter¶
set_pwm() and get_remote_pwm() methods take a float as duty_cycle argument ranging from 0.0 to 100.0.
Examples¶
To simplify the examples and make them independent of the hardware and the XBee variant, the following pins are used in this examples set:
Line | Pin | Value |
---|---|---|
DIO2/ADC2 | 18 | ADC (Analog Input) |
DIO3/ADC3 | 17 | Digital Input |
RSSI/DIO10 | 6 | PWM (Analog Output) |
DIO4 | 11 | Digital Output |
Information
All the examples that use Digital IOs and ADC/PWM use the specified pins.
The first step for each example is to create the local and the remote devices. They can be either ZigBee, 802.15.4 or DigiMesh devices:
#include "XBeeLib.h" using namespace XBeeLib; void main() { [...] XBeeZB xbee = XBeeZB(RADIO_TX, RADIO_RX, RADIO_RESET); xbee.init(); RemoteXBeeZB remoteDevice = RemoteXBeeZB(0x0013A200AABBCCDD); [...] }
Setting the value of a Digital Output¶
This example toggles the DIO4 pin every 5 seconds. If a led is connected to this pin as shown in the schematic, it should blink every 5 seconds.
Information
It's not necessary to call set_pin_config() method to use set_remote_dio() method.
[...] while(true) { static bool led_on = false; if (led_on) { radioStatus = xbee.set_dio(remoteDevice, XBeeZB::DIO4, DIO_LOW); } else { radioStatus = xbee.set_dio(remoteDevice, XBeeZB::DIO4, DIO_HIGH); } MBED_ASSERT(radioStatus == Success); led_on = !led_on; wait(5); } [...]
Getting the value of a Digital Input¶
This example samples the digital value of DIO3_AD3 pin every 5 seconds. If this pin is connected to a push button as shown in the schematic, the application should report "DIO3 value = 0" if the button is pressed and "DIO3 value = 1" otherwise.
[...] radioStatus = xbee.set_pin_config(remoteDevice, XBeeZB::DIO3_AD3, DigitalInput); MBED_ASSERT(radioStatus == Success); while(true) { DioVal dio3_val; radioStatus = xbee.get_dio(remoteDevice, XBeeZB::DIO3_AD3, &dio3_val); MBED_ASSERT(radioStatus == Success); log_serial->printf("DIO3 value = %d\r\n", dio3_val); wait(5); } [...]
Getting the value of an ADC¶
This example samples the analog value of DIO2_AD2 pin every 5 seconds. If this pin is connected to a variable resistor as shown in the schematic, the application should report its value ranging from 0x0 to 0x3FF.
[...] radioStatus = xbee.set_pin_config(remoteDevice, XBeeZB::DIO2_AD2, Adc); MBED_ASSERT(radioStatus == Success); while(true) { uint16_t adc2_val; radioStatus = xbee.get_adc(remoteDevice, XBee802::DIO2_AD2, &adc2_val); MBED_ASSERT(radioStatus == Success); log_serial->printf("ADC2 value = 0x%04x\r\n", adc2_val); wait(5); } [...]
Setting the value (duty cycle) of a PWM¶
This example changes the analog value of PWM0 pin. The application walks through 0.0, 50.0, 70.0 and 100.0 values every 5 seconds. If a led is connected to the PWM0 pin as shown in the schematic, it should change the intensity accordingly.
[...] radioStatus = xbee.set_pin_config(remoteDevice, XBee802::PWM0, Pwm); MBED_ASSERT(radioStatus == Success); while(true) { static float pwm2_val_list[] = { 0.0, 50.0, 70.0, 100.0 }; static uint8_t pwm2_val_idx = 0; log_serial->printf("Setting PWM0 to = %f\r\n", pwm2_val_list[pwm2_val_idx]); radioStatus = xbee.set_pwm(remoteDevice, XBee802::PWM0, pwm2_val_list[pwm2_val_idx]); MBED_ASSERT(radioStatus == Success); pwm2_val_idx++; if (pwm2_val_idx == sizeof(pwm2_val_list)/sizeof(pwm2_val_list[0])) { pwm2_val_idx = 0; } wait(5); } [...]
Here is a ready to use example:
For ZigBee modules:¶
Import programXBeeZB_dio_adc
ZigBee DIOs and ADCs example for mbed XBeeLib By Digi
For 802.15.4 modules:¶
Import programXBee802_dio_adc_pwm
802.15.4 DIOs, ADCs and PWM example for mbed XBeeLib By Digi
For DigiMesh modules:¶
Import programXBeeDM_dio_adc_pwm
DigiMEsh DIOs, ADCs and PWMs example for mbed XBeeLib By Digi