It's easy to use the IoT Button with NeoPixel BFF with CircuitPython and the Adafruit_CircuitPython_NeoPixel module. This module allows you to easily write Python code that lets you control NeoPixels. A second example will use the Adafruit_CircuitPython_AdafruitIO module to let you write Python code to communicate with Adafruit IO, Adafruit's IoT platform.
CircuitPython Microcontroller Wiring
Plug an IoT Button with NeoPixel BFF into your QT Py or Xiao form factor board exactly as shown below. Here's an example of connecting a QT Py ESP32-S2 to the BFF.
Connect the QT Py ESP32-S2 with pin headers into the IoT Button with NeoPixel BFF with socket headers. They should be plugged in with the backs of the boards facing each other.
For more information on soldering socket headers, check out this Learn Guide.
CircuitPython Usage
To use with CircuitPython, you need to first install the NeoPixel library, and its dependencies, into the lib folder on your CIRCUITPY drive. Then you need to update code.py with the example script.
Thankfully, we can do this in one go. In the example below, click the Download Project Bundle button below to download the necessary libraries and the code.py file in a zip file. Extract the contents of the zip file, and copy the entire lib folder and the code.py file to your CIRCUITPY drive.
Your CIRCUITPY/lib folder should contain the following folders and files:
- /adafruit_io
- /adafruit_minimqtt
- adafruit_pixelbuf.mpy
- adafruit_requests.mpy
- neopixel.mpy

# SPDX-FileCopyrightText: 2023 Liz Clark for Adafruit Industries # # SPDX-License-Identifier: MIT """Basic IoT Button with NeoPixel BFF Example""" import time import board from digitalio import DigitalInOut, Direction, Pull from rainbowio import colorwheel import neopixel # setup onboard NeoPixel pixel_pin = board.A3 num_pixels = 1 pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.3, auto_write=False) # setup onboard button switch = DigitalInOut(board.A2) switch.direction = Direction.INPUT switch.pull = Pull.UP # rainbow cycle function def rainbow_cycle(wait): for j in range(255): for i in range(num_pixels): rc_index = (i * 256 // num_pixels) + j pixels[i] = colorwheel(rc_index & 255) pixels.show() time.sleep(wait) while True: # run rainbow cycle animation rainbow_cycle(0) # if the button is not pressed.. if switch.value: # neopixel brightness is zero and appears to be "off" pixels.brightness = 0 # if the button is pressed.. else: # neopixel brightness is 0.3 and rainbow animation is visible pixels.brightness = 0.3
Once everything is saved to the CIRCUITPY drive, you can press and hold the button on the BFF to make the rainbow animation show on the NeoPixel. If you release the button, the NeoPixel will stop showing the animation.
Adafruit IO Example
To run this example for Adafruit IO, be sure to first review the Welcome to Adafruit IO Learn Guide and read how to setup your settings.toml file to store your WiFi and Adafruit IO credentials on your CIRCUITPY drive.
# SPDX-FileCopyrightText: 2023 Liz Clark for Adafruit Industries # SPDX-License-Identifier: MIT """Simple Adafruit IO Example for IoT Button with NeoPixel BFF""" import os import time import ssl import wifi import socketpool import microcontroller import board from digitalio import DigitalInOut, Direction, Pull import neopixel import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError # setup onboard button switch = DigitalInOut(board.A2) switch.direction = Direction.INPUT switch.pull = Pull.UP # setup onboard NeoPixel pixel_pin = board.A3 num_pixels = 1 pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.3, auto_write=False) # neopixel status colors RED = (255, 0, 0) GREEN = (0, 255, 0) BLUE = (0, 0, 255) # red until connecting pixels.fill(RED) pixels.show() wifi.radio.connect(os.getenv('CIRCUITPY_WIFI_SSID'), os.getenv('CIRCUITPY_WIFI_PASSWORD')) aio_username = os.getenv('aio_username') aio_key = os.getenv('aio_key') pool = socketpool.SocketPool(wifi.radio) requests = adafruit_requests.Session(pool, ssl.create_default_context()) # Initialize an Adafruit IO HTTP API object io = IO_HTTP(aio_username, aio_key, requests) print("connected to io") # blue when talking to IO pixels.fill(BLUE) pixels.show() try: # get feed button_feed = io.get_feed("buttonbff") except AdafruitIO_RequestError: # if no feed exists, create one button_feed = io.create_new_feed("buttonbff") # green once connected pixels.fill(GREEN) pixels.show() # button press count sent to IO count = 0 while True: try: # if the button is pressed.. if not switch.value: # blue when talking to IO pixels.fill(BLUE) pixels.show() # increase by 1 with press count += 1 # send count to feed io.send_data(button_feed["key"], count) print("sent %d" % count) print() # delay time.sleep(5) else: # green if connected pixels.fill(GREEN) pixels.show() # pylint: disable=broad-except # any errors, reset board except Exception as e: # neopixels red with an error pixels.fill(RED) pixels.show() print("Error:\n", str(e)) print("Resetting microcontroller in 10 seconds") time.sleep(10) microcontroller.reset()
In the code, the value of the variable count
is sent to Adafruit IO every time you press the button. The value increases by 1
with each button press. You can see this data in your Adafruit IO feed.
The NeoPixel acts as an Adafruit IO status light. If your board is connected, the NeoPixel is green. If your board is actively uploading data to Adafruit IO, the NeoPixel is blue. If there is an error or connection problem, the NeoPixel is red.