XBee3 Thing Plus Hookup Guide

Contributors: Alex the Giant, Ell C
Favorited Favorite 2


Who doesn't love a Bee? With these 2 versions of SparkFun's XBee3 Thing Plus - the XBee3 Thing Plus (u.FL) and the XBee3 Thing Plus (PCB Antenna), we've taken DIGI's XBEE3 802.15.4 and plopped it into the Thing Plus footprint and the result has us all abuzz. For all intents and purposes, the 2 variants are the same board - the difference being in the antenna.

SparkFun Thing Plus - XBee3 Micro (U.FL)

SparkFun Thing Plus - XBee3 Micro (U.FL)

SparkFun Thing Plus - XBee3 Micro (Chip Antenna)

SparkFun Thing Plus - XBee3 Micro (Chip Antenna)


Required Materials

To follow along with this tutorial, you will need the following materials. You may not need everything, depending on what you have. Add it to your cart with your choice of the XBee3, read through the guide, and adjust the cart as necessary.

Suggested Reading

If you aren’t familiar with the following concepts, we recommend checking out these tutorials before continuing.

How to Solder: Through-Hole Soldering

This tutorial covers everything you need to know about through-hole soldering.

Serial Terminal Basics

This tutorial will show you how to communicate with your serial devices using a variety of terminal emulator applications.

Exploring XBees and XCTU

How to set up an XBee using your computer, the X-CTU software, and an XBee Explorer interface board.

MicroPython Programming Tutorial: Getting Started with the ESP32 Thing

MicroPython is an implementation and subset of the Python 3 programming language that can be used on microcontrollers. This guide will walk you through writing MicroPython programs for the ESP32 Thing development board.

Hardware Overview

Whether you're using the u.fl version or trace antenna version , the XBee3 Thing Plus is chock full of functionality. The XBee3 module itself measures 13 mm x 19 mm and supports multiple protocols, including ZigBee, 802.154, DigiMesh, and BLE. Add into that the capabilities of SparkFun's Thing Plus and we're looking at an amazing amount of functionality.

XBee3 Features

  • Voltage Range: 2.1-3.6V
  • 2μA Power-down current
  • 1MB of flash, 128kB of RAM
  • +8dBm transmitting power (Up to 135mA)
  • -103dBm receiving sensitivity (17mA)
  • Supported protocols: 802.15.4, Bluetooth v4.0, Zigbee
  • RF Data Rate: 250Kbps
  • UART Data Rate: Up to 1Mbps
  • Indoor range: Up to 200ft (60m)
  • Outdoor (Line-Of-Sight): Up to 4000ft (1200m)

Board Highlight

Click the image for a closer look.

Peripherals and I/O

The XBee3 Thing Plus features your standard fare of hardware peripherals including:

  • 20 general purpose input/output pins
  • Up to four 10-bit analog to digital converter (ADC) channels (see note 1)
  • Up to two 10-bit pulse width modulation (PWM) channels (see note 2)
  • UART
  • I2C
  • SPI (see note 3)

1. There are three dedicated ADC channels, with the fourth connected to IO pin 1/SCL if I2C is not being used.

2. There is a dedicated PWM channel connected to IO pin 10, with the second connected to IO pin 11/SDA if I2C is not being used.

3. SPI is currently still under development from Digi and is not yet supported in MicroPython.

Powering the XBee3 Thing Plus

The two main power inputs to the XBee3 Thing Plus are USB and a single-cell lithium-polymer (LiPo battery. If both USB and the LiPo are plugged into the board, the onboard charge controller will charge the LiPo battery at a rate up to 500mA.

⚡ The XBee3's operating voltage range is 2.1 to 3.6V. Under normal operation the XBee3 Thing Plus will power the chip at 3.3V. The I/O pins are not 5V-tolerant! If you interface the board with 5V (or higher) components, you'll need to do some logic level shifting.

The 3.3V regulator on the XBee3 Thing Plus can reliably supply up to 600mA, which should be more than enough overhead for most projects. The XBee3 can pull as much as 135mA during RF transmissions. The output of the regulator is also broken out to the side of the board -- the pin labeled "3V3". This pin can be used to supply external components.

XBee3 power inputs/outputs

In addition to USB and battery connectors, the VBAT, and VUSB pins are all broken out to the sides of the board. These pins can be used as an alternative supply input to the Thing Plus. The maximum, allowable voltage input to VUSB is 5.8V, and VBAT should not be connected to anything other than a LiPo battery. Alternatively, if you have a regulated voltage source between 2.1V and 3.6V, the "3V3" line can be used to directly supply the XBee3 and its peripherals.

Software Setup

The XBee3 Thing Plus was designed to work with MicroPython and XCTU.

Setting Up XCTU

XCTU is free software, provided by Digi (the manufacturer of XBee), which we use to configure and manage XBees as well as test XBee networks. If you haven't worked with XCTU before, head on over to our Exploring XBees and XCTU tutorial to get set up.

Exploring XBees and XCTU

March 12, 2015

How to set up an XBee using your computer, the X-CTU software, and an XBee Explorer interface board.

Firmware/Bootloader Update

If you've never connected an CP2104 device to your computer before, you may need to install drivers for the USB-to-serial converter. Check out our section on How to Install CP2104 Drivers from one of our other tutorials for help with the installation.

Once you have XCTU installed, presumably you'll have the XBee plugged in and visible in XCTU. If not, head on back to the Exploring XBees and XCTU tutorial to get yourself set up. Now you'll need to update the firmware, and likely the bootloader.

In XCTU, click on the Update button:

Update Button

Make sure you have the latest selected and go ahead:

Latest Firmware Version selected

You'll be guided through a number of dialogs. If you are asked to update the bootloader, go ahead and do so.


Most of the settings in the XCTU can be left alone. However, if you plan to upload or edit the code on your XBee, you'll need to enable the API and set it to MicroPython REPL.

MicroPython REPL setting in UART API Enable

Make sure to click the "Write" button to save your changes!

Click the Write Changes button

REPL (Hello, World!)

One of the easiest ways to interact with MicroPython running on the XBee3 Thing Plus is to enter commands via the REPL over a serial connection. This can be extremely helpful if you want to test out various parts of code before writing them down in a (slightly more permanent) text document that is then uploaded to the XBee3 Thing Plus. Fortunately, XCTU offers a MicroPython Terminal in its Tools menu!

To start, connect the XBee3 Thing Plus to your computer using a USB micro-B cable. If you are on Windows, open the Device Manager and find out which COM port your XBee3 Thing Plus is associated with (for example, COM5). On macOS, it will likely be /dev/cu.usbserial-, and on Linux, it’s probably something like /dev/ttyUSB0.

Open up XCTU and load up your XBee3 Thing Plus as outlined in the Software Setup section. Make sure you have MicroPython REPL [4] selected under AP API Enable and make sure you've clicked the pencil button to write your changes to the XBee.

Accessing the MicroPython Terminal

The XCTU provides a MicroPython Terminal under the Tools Menu:

The MicroPython Terminal is accessed within the Tools Menu

Click the image for a closer view

Once you have the terminal window available, click on Configure and make sure you select the correct COM port. Most of this should be pre-populated, but double-checking never hurts.

Selecting the correct COM port in the Configure Dialog

Once you're satisfied that everything is correct, click OK in the configuration window and the hit the Open button.

Once you have a connection, press enter once to get a REPL command prompt (>>>).

When you see that command prompt, enter the following commands one at a time:

import machine
led = machine.Pin(machine.Pin.board.D4, machine.Pin.OUT)

This should turn on the LED found on the XBee3 Thing Plus (the blue LED located at pin 4).

LED is lit up after inputting the above code

Type the following command to turn it off:


MicroPython Terminal Commands

Code to Note:

The first thing we typed was import machine. machine is the MicroPython module that gives us control of the various general purpose input/output (GPIO) pins and special functions, such as I2C and interrupts. We use the keyword import to make all of the functions in the machine module available for us to use.

We then create a machine.Pin object and store it in the label led. When defining a machine.Pin object, we supply a number of arguments, including which pin number we want to use (the pin numbers can be found in white numbers on the side of the XBee3 Thing Plus) and how we want to use that pin (e.g. as an input or output).

Because we set the pin as an output (as given by machine.Pin.OUT), we can drive the pin to logic low (0 V) or logic high (3.3 V) by setting its value to 0 (logic low) or 1 (logic high). To drive the pin high, we write led(1). This has the effect of turning on the LED.

Similarly, we can turn the LED off with led(0), which sets the pin to 0 V.

Experiment 1: AutoRunning MicroPython

As we saw above, it is easy to control an LED by individually calling commands in the REPL. Here we are going to write our code to a file, upload that file to the XBee3 Thing Plus, and then set up the XBee3 Thing Plus to auto-run the MicroPython code.

There's a caveat to writing code that automatically runs on the XBee3 Thing Plus. If your code contains a forever loop, the MicroPython interpreter will continue to run your code (forever!) which means we will never get a REPL prompt, should we want/need one. We're going to upload code that runs a forever loop, but checks for a Button 5 press. When it detects that button press, it will drop to REPL.

Code Part 1: Push Button, Get REPL

In your text editor of choice, enter the following code:

import machine
import sys
import utime

# Pin definitions
repl_button = machine.Pin(machine.Pin.board.D5, machine.Pin.IN, machine.Pin.PULL_UP)

# Wait for button 5 to be pressed, and then exit
while True:

    # If button 5 is pressed, drop to REPL
    if repl_button.value() == 0:
        print("Dropping to REPL")

    # Do nothing

Save the code with the name main.py.

Run It

In most configurations of MicroPython, there are two files stored on the microcontroller: boot.py and main.py. As soon as the microcontroller receives power (or directly after a reset), the code in boot.py will be run. Then, main.py will run. Note that once main.py finished executing, it will be run again (over and over again forever).

Within the File System Manager, we do not see boot.py or main.py; instead we will be uploading our own main.py file to the XBee.

In XCTU, under Tools, select the File System Manager. Go ahead and click on the Configure button, make sure you have the correct port and baud rate selected, and then click OK.

Here we're using COM5 with a baud rate of 9600

Next, click on the Open button, and once the connection is established, you should see your own file system on the left, and the XBee's file system on the right.

Opening the file system connection

In the left side, navigate to your main.py file, and then drag that to the XBee's window on the right. The file will upload to the XBee!

Drag and drop main.py from the left window to the right window and you should se an uploading window

Enable AutoRun

If you wish to have your main.py file automatically run on your XBee, you'll need to go back to XCTU and enable the MicroPython Auto Start. Make sure you click on the pencil button to write your changes to the XBee!

Enabling MicroPython AutoRun in the XCTU Settings

After uploading your code and enabling autostart, go ahead and hit the RST button on your XBee. Your code should now automatically start running. However, because our code simply exits on a button push, there is nothing to see here. Go ahead and hit the Close button on the top left to close the connection, and then exit out of this dialog.

Back in XCTU, select Tools->MicroPython Terminal. Again, verify that you have the correct COM port and baud rate selected, and then open the connection to your XBee. You should see a blank terminal window, and even if you try typing some characters, nothing should appear.

Press the 5 button on your XBee3 Thing Plus board.

Pushing button 5 in order to drop into REPL

As soon as you hit that button, you should see a message appear in your serial terminal saying "Dropping to REPL" followed by the MicroPython version number and a command prompt (>>>).

Dropping to REPL in MicroPython Terminal

Code to Note

Our program is relatively simple. We first import the machine, sys, and utime modules. The machine module allows us to control connected hardware, like pins. The sys module gives us access to underlying interpreter values and the ability to exit out of our forever loop in main.py. Finally, the utime module allows us to get the local machine time (assuming we have a connected real-time clock) or tell our program to wait for a specified amount of time.

Much like in our REPL example, we create a machine.Pin object for pin 5, but we make it an input this time. We supply a third argument: machine.Pin.PULL_UP. This says that we want to enable the XBee's internal pull-up resistor for pin 5. This allows the voltage on pin 5 to stay at 3.3 V until we push the onboard button, which subsequently pulls the voltage on the pin down to 0 V. We can use this technique to determine if the button has been pressed.

Everything indented under while True: runs forever. Each line is executed sequentially before returning to the top of the while loop.

Within the loop, we check to see if the button has been pressed:

if repl_button.value() == 0:
    print("Dropping to REPL")

If it has, we print a message out to the serial terminal and then call sys.exit(), which raises a SystemExit exception. This will force the program to exit (and the MicroPython interpreter will perform any garbage collection or cleanup as necessary).

If no button push is detected, we tell the XBee to do nothing (sleep) for 1 ms:


This process is repeated again within the while loop.

Note: If you have any problems running this code, refer to the Troubleshooting section near the end of this tutorial.

Code Part 2: Blinky

In a text editor, enter the following code:

import machine
import sys
import utime

# Pin definitions
repl_button = machine.Pin(machine.Pin.board.D5, machine.Pin.IN, machine.Pin.PULL_UP)
led = machine.Pin(machine.Pin.board.D4, machine.Pin.OUT)

# Blink forever
while True:

    # If button 5 is pressed, drop to REPL
    if repl_button.value() == 0:
        print("Dropping to REPL")

    # Turn LED on and then off

Save the code to your main.py file on your local file system (overwrite it).

Run It

Make sure you've closed out of the previous connection, and then upload your code via the File System Manager - exactly the same way you did in Code Part 1. You will want to overwrite or first delete the main.py file that exists on your XBee3 Thing Plus file system.

The onboard blue LED should begin blinking on and off every second. If it does not do so right away, push the RST button on the board.

Open up a MicroPython Terminal and connect to your XBee3 Thing Plus. Press and hold button 5 until the blinking LED stops. You should also see a REPL prompt appear.

Code to Note

This time, we combined parts from our first REPL example and our button example. We added the following part in the while loop:


Much like we saw in the REPL example, we turn the LED on with led.value(1) and turn it off with led.value(0). We sleep 500 ms between each action so that we can see the LED blinking.

At the top of our while loop, we added our "drop to REPL" button press code to make debugging or interacting with the XBee3 Thing Plus easier. Note that you need to hold down button 5 this time, as it can take over 1 second for one iteration of the while loop to complete. Execution needs to return to the beginning of the loop before checking for a button 5 press again.

Experiment 2: Pulse Width Modulation (PWM)

Pulse width modulation is the technique of switching a digital signal on and off very quickly to control a variety of electrical components. By varying the amount of time a signal is on vs off, you can vary the amount of electrical power provided to a component. We can use this, for example, to dim an LED or control the speed of a motor. To learn more about PWM, see this tutorial.

In this example, we are going to create a simple LED animation that occurs as long as a button is held down.

Hardware Connections

Connect an LED and a button to the XBee3 Thing Plus as per the following diagram:

Fritzing Diagram showing wire connections for PWM experiment

⚡ Note: It matters how you plug in your LED! Current can only flow in one direction through an LED, so pay careful attention to the leads. The short lead on the LED should be connected on the same row as the 330Ω resistor.

LED polarity diagram

Note: Buttons can be a little weird, if it's the first time you've used them. The pins across from each other are always connected, whereas the pins on the same side are only connected when you push the button.

How a push button is configured on the inside

Note: If you are using the full-size breadboard, the power rails are divided in the middle. This means that to get power to the whole power row, you will need to connect the two halves. See the picture below to see how to use jumper wires to connect the halves of the power rows.

Connect power rows on a full-size breadboard

Code: LED Animation

Open a new file in your favorite text editor, enter the following code:

import machine
import sys
import utime

# Pin definitions
repl_button = machine.Pin(machine.Pin.board.D5, machine.Pin.IN, machine.Pin.PULL_UP)
repl_led = machine.Pin(machine.Pin.board.D4, machine.Pin.OUT)
button = machine.Pin(machine.Pin.board.D11, machine.Pin.IN, machine.Pin.PULL_UP)
pwm_pin = machine.Pin(machine.Pin.board.D10, machine.Pin.OUT)

# Create a PWM object out of our pin object
pwm = machine.PWM(pwm_pin)

# Slowly fade LED brightness
while True:
    # If button 5 is pressed, turn on LED and drop to REPL
    if repl_button.value() == 0:
        print("Dropping to REPL")

    # Increase brightness of LED if button is held
    for i in range(1024):
        if button.value() == 0:

Save your file as main.py on your local file system, overwriting your previous main.py file. Upload the code to your XBee3 Thing Plus as outlined in Experiment 1. Press RST to auto-run the new main.py file.

After the code has been uploaded and the board reset, hold down the button (the one on the breadboard that is connected to pin 11. You should see the LED slowly brighten, turn off, and then begin the brightening animation over again as long as the button is held down.

Code to Note

Much of the code should look familiar from the previous experiment, as we are creating a machine.Pin object for our LED and another one for our button. Note that we are keeping the "drop to REPL" snippet in, as we always want a way to exit out of our code's main loop.

The main difference is that we are creating machine.PWM object out of our machine.Pin object (the pin object that we've created with the pwm_pin variable. With the machine.PWM object, we can call the pwm.duty() method, which allows us to control the amount of on vs. off time on pin 11. A duty cycle of 0 means that the pin is always 0 V. A duty cycle of 511 (about half of 1023) means that pin 11 should rapidly switch between 0 V and 3.3 V equally (50%). Finally, a duty cycle of 1023 means that pin 11 should be always on (always at 3.3 V). Again, refer to the Pulse Width Modulation tutorial for more information on pwm and duty cycles.

By placing pwm.duty() inside a for loop, we can increase the brightness one stage at a time with a 2 ms delay between each stage. This ultimately gives the effect of a slowly increasing LED brightness.

Notice that we check for button 5 at the beginning of the for loop. That means that you need to hold down button 5 until the for loop (LED animation) has completed one iteration before the program realizes you've pressed the button (and should therefore exit to REPL). To help you know when you have successfully exited the program into REPL, we added repl_led.value(1) to turn on the onboard blue LED.


Resources and Going Further

Now that you've successfully got your XBee3 Thing Plus up and running, it's time to incorporate it into your own project! For more information, check out the resources below:

SparkFun XBee Resources

Digi XBee Resources

MicroPython Resources

Need some inspiration? Check out some of these other XBee related tutorials:

Pro Micro & Fio V3 Hookup Guide

An overview of the Atmega32U4-based Pro Micro and FioV3, how to install it, and how to use it with Arduino.

XBee Shield Hookup Guide

How to get started with an XBee Shield and Explorer. Create a remote-control Arduino!

Actobotics Basic Differential Platform

Get started with Actobotics with this simple vehicle. Then expand and customize it for your own evil robot empire.

Wireless Controlled Wearable EL Wire Dance Suit

In this tutorial, we will build an EL wire dance suit that can be controlled by a wireless glove controller!