This article describes a simple way to connect XBee® ZigBee® devices in a wireless personal area network to an MQTT broker in the Cloud for prototyping IoT solutions.


ZigBee, XBee and MQTT

802.15.4 is a wireless network communications protocol defined by the Institute of Electrical and Electronics Engineers (IEEE).  It is designed for applications that have low-cost and low-power requirements which take precedence over speed and range.  It is used to implement Wireless Personal Area Networks (WPANs), so called because they were used typically to interconnect personal devices like phones, computers, and electronic organizers.

WPANs can also be useful in connecting sensor devices in IoT applications.  One technology based on 802.15.4 is the ZigBee specification, which is intended to provide encrypted wireless communications between devices where low-cost and long battery life are important. XBee is the name of a popular set of ZigBee radios made by Digi International® Inc.

The 802.15.4 definition states that each WPAN has a single coordinator that acts as the primary controller for the network. On an XBee radio this is known as the ZigBee Coordinator and can be configured to run in a number of modes.


Figure 1: XBee Coordinator and mini-router running OpenWRT

In this article we demonstrate a simple technique to interconnect the sensor data from one or more ZigBee WPANs to an SSL-secured MQTT broker in the Cloud (see Figure #2). It is particularly useful when you are prototyping an IoT solution because in most cases it requires no modifications to the sensor endpoints, and instead relies solely on accessing the data stream though the radio that is acting as the ZigBee coordinator.

To accomplish this we install the coordinator XBee radio on a USB adapter that we connect to the USB port of a processor or PC running a small C daemon that we wrote.

We often use mini-routers that we’ve flashed with OpenWRT as the processor because it gives us a low-power small-footprint solution that we can either connect to the Internet wirelessly or hard-wired using CAT 5 with it’s built-in RJ45 jack (see Figure #1).


Figure 2: XBee ZigBee network diagram

Figure #3 shows a simplified version of the daemon that we wrote to intercept the ZigBee data frames being sent by the sensors and publish them to a MQTT broker.  To accomplish this you must configure the XBee radio to be in ZigBee Coordinator API (rather than AT) mode (see Figure #4).  XBee radios act like modems and when in AT mode respond to a number of commands that are patterned on the Hayes Modem AT commands.  In API mode, the XBee radios provide the data in frames which include extra information (e.g. the address of the endpoint that originated the message).

In our daemon we use the source address to generate a MQTT topic using the pattern “XBeeData/<src address>”, and send the entire contents of the frame payload as the MQTT message. In fact we prepend it with a timestamp in case the sensor data did not include a clock time.   We use the Mosquitto client library → to provide the API services required to establish an SSL-secured connection the the MQTT broker.

See our previous articles Securing MQTT on Apache ActiveMQ and Mosquitto as a bridge to a secure MQTT brokerfor more information on the MQTT broker setup.

Figure 3: XBeeMQTTGateway.c

  [ Note: For clarity, this example keeps the frame handling very simple, and it does not attempt to subscribe to any MQTT topics with the intent of pushing responses back to the sensors. In addition, if you plan to use multiple instances to connect more than one WPAN to the MQTT broker (as shown in Figure # 2), the code needs to be modified to provide a unique client ID for each MQTT connection.  You may want to use the PAN ID or a configuration setting to achieve that. ]


Figure 4: Digi X-CTU Utility Coordinator screenshot


Figure 5: Digi X-CTU Utility Router screenshot

To demonstrate this setup you require a minimum of one XBee radio that you can configure to be the ZigBee Coordinator and at least one ZigBee radio or sensor device acting as a ZigBee router or endpoint.  As an alternative to a sensor, you can use an Arduino with a second radio in an XBee shield to generate data (see Figure #8).

Digi provides a Windows utility called X-CTU → to allow you to configure the radios.  In most cases the default values should be fine after you define one radio to be the Coordinator (Figure #4) and the other to be the Router/Endpoint (Figure #5).  We’ve set both devices to use a PAN ID of “1234” in this scenario.

Figure #7 shows a simple Arduino sketch that demonstrates that no special knowledge of the ZigBee network is required for this technique to work. The sketch takes a simple analog measurement and prints it and the current timer value to the serial interface.

IBM wrote a WMQTT → client utility that is very useful when working with MQTT brokers and bridges. By connecting to the same MQTT broker that is used by the daemon, and subscribing to the MQTT topic “XBeeData/#”, you can see all of the data when it is published. [Note: WMQTT does not allow SSL connections to brokers. The mosquitto_sub → command line utility will work with SSL MQTT brokers.]


Figure  6: WMQTT Utility screenshot

Figure #6 shows some sensor data from XBee device 0013A20040B405F5.

Figure 7: Simple Arduino Test Sketch


Figure 8: Arduino UNO, XBee radio & shield


There is also a protocol called MQTT for Sensor Networks (MQTT-SN) which is patterned on MQTT, but is designed specifically for network technologies like ZigBee that don’t use TCP/IP. It is be better suited to handling the lower transmission rates, higher interference rates, and smaller frame sizes typically found in sensor networks.

We did not use it in the circumstances described in this article as we wanted a solution that didn’t require any changes to be made inside the WPAN other than to gain access to the ZigBee Coordinator node.


The “XBee” name is a registered trademark of Digi International Inc. The word “ZigBee” is a registered trademark of the ZigBee Alliance. 

Leave a Reply

You must be logged in to post a comment.