Library to easily communicate with XBee modules.
Dependencies: DigiLogger
Dependents: WaterLogger XbeeGateway XBee_Cooker ProjetReceiver ... more
You are viewing an older revision! See the latest version
Discovering nodes in the network
In most applications the number of nodes in a network is not known beforehand. For this purpose, the XBee modules implement a mechanism for discovering the nodes in the network. However, identifying which node is which only by its 64-bit or 16-bit addresses is not very flexible or scalable in most cases. For this purpose the XBee modules have the Node Identifier (NI parameter), which is an ASCIIZ string of up to 20 characters that allows providing a human-readable name to a node so it is easier to identify it. There are two ways of discovering nodes:
- Search for all nodes to identify
- Search for only one node
Warning
Assigning a unique Node Identifier for each node in the network is responsibility of the user. In case of having duplicated Node Identifiers in the network, the behavior is undetermined.
Information
The default value of NI is a white space (" ").
Search for all nodes¶
The discovered nodes are represented by two parameters, a RemoteXBee object (either RemoteXBee802 or RemoteXBeeZB) and a null-terminated string containing the Node Identifer.
Example of use¶
These are the steps to discover all the nodes in your network:
- Create an XBee object.
- Initialize the XBee.
- Register the function callback. This function will be called by the library when a remote node answers the Node Discovery # request.
- Configure the Node Discovery options (optional).
- Initiate the Node Discovery process.
- 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); [...] }
Initialize the XBee¶
Now initialize the XBee. That means calling to 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(); }
Register desired receive function callback¶
The user has to provide the desired function to be called when specific frames are received. On every protocol, there is a single receive callback for both unicast and broadcast messages. However, depending on the XBee variant the callback function has a different prototype, as they take different RemoteXBee objects.
ZigBee
#include "XBeeLib.h" using namespace XBeeLib; /** Callback function, invoked when a Node Discovery response is received */ void discovery_function(const RemoteXBeeZB& remote, char const * const node_id) { log_serial->printf("Found device '%s'\r\n", node_id); } int main() { [...] /* Register callbacks */ xbee.register_node_discovery_cb(&discovery_function); [...] }
802.15.4
#include "XBeeLib.h" using namespace XBeeLib; /** Callback function, invoked when a Node Discovery response is received */ void discovery_function(const RemoteXBee802& remote, char const * const node_id) { log_serial->printf("Found device '%s'\r\n", node_id); } int main() { [...] /* Register callbacks */ xbee.register_node_discovery_cb(&discovery_function); [...] }
Configure the Node Discovery options (optional)¶
There are two parameters to configure in the Node Discovery process:
- timeout_ms: the maximum time the local node will wait for responses (in milliseconds). The remote nodes will try to reply to the ND request after waiting a random time between 0 and timeout_ms. However it is possible that a response is received after the timeout expired due to the time a message takes to propagate among the network.
- options: other options encoded as a bit field. This is passed to the NO parameter, so you should see the module's reference manual to learn more about the available options. For example:
- 802.15.4:
- XBEE802_ND_OPTION_SELF_RESPONSE: Local device sends ND response frame when ND is issued.
- ZigBee:
- XBEEZB_ND_OPTION_APPEND_DD: Append DD value (to ND responses or API node identification frames)
- XBEEZB_ND_OPTION_SELF_RESPONSE: Local device sends ND response frame when ND is issued.
- 802.15.4:
#include "XBeeLib.h" using namespace XBeeLib; int main() { [...] const uint16_t nd_timeout_in_seconds = 10; const uint16_t nd_timeout_in_milliseconds = nd_timeout_in_seconds * 1000; const uint8_t enable_auto_discovery = XBEEZB_ND_OPTION_SELF_RESPONSE; xbee.config_node_discovery(nd_timeout_in_milliseconds, enable_auto_discovery ); [...] }
Initiate the Node Discovery process¶
Once everything is set up, the Node Discovery process can be started. To do so, simply call start_node_discovery() method, next the callback will be called whenever a node responds the request.
#include "XBeeLib.h" using namespace XBeeLib; int main() { [...] xbee.start_node_discovery(); [...] }
Information
It is not guaranteed that all nodes in a network will reply the Node Discovery process. This could be due to different reasons: sleeping end-devices (ZigBee), a network with a lot of nodes and a timeout too low, etc. Before initiating a new Node Discovery process again, it is recommended to wait the configured timeout plus at least one second to avoid receiving responses for previous request.
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
So 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("."); } [...] }
Search for only one node¶
In some applications the target node's NI is already known, so there is no need to discover all the nodes in the network. For doing so, the get_remote_node_by_id() method takes the remote node's NI and returns a RemoteXBee object ready to be used in other functions (such as send_data(), get_param(), set_param(), etc.)
Information
This function is also affected by the Node Discovery timeout. see the "Configure the Node Discovery options" section in this page.
Example of use¶
802.15.4¶
get_remote_node_by_id()
#include "XBeeLib.h" using namespace XBeeLib; void main() { [...] xbee.init(); [...] RemoteXBee802 remote_node = xbee.get_remote_node_by_id("MyNodeID"); if (remote_node.is_valid()) { const char message[] = "Hello XBee!"; const TxStatus txStatus = xbee.send_data(remote_node, (const uint8_t *)message, sizeof message - 1); if (txStatus != TxStatusSuccess) { printf("Found an error while sending data %d\r\n", txStatus); } } else { printf("Couldn't find MyNodeID node\r\n"); } [...] }
ZigBee¶
get_remote_node_by_id()
#include "XBeeLib.h" using namespace XBeeLib; void main() { [...] xbee.init(); [...] RemoteXBeeZB remote_node = xbee.get_remote_node_by_id("MyNodeID"); if (remote_node.is_valid()) { const char message[] = "Hello XBee!"; const TxStatus txStatus = xbee.send_data(remote_node, (const uint8_t *)message, sizeof message - 1); if (txStatus != TxStatusSuccess) { printf("Found an error while sending data %d\r\n", txStatus); } } else { printf("Couldn't find MyNodeID node\r\n"); } [...] }
Examples¶
Here you have a ready to use example:
For ZigBee modules:¶
Import programXBeeZB_node_discovery
ZigBee Node Discovery example for mbed XBeeLib By Digi
For 802.15.4 modules:¶
Import programXBee802_node_discovery
802.15.4 Node Discovery example for mbed XBeeLib By Digi