Maker.io main logo

Adafruit Sparkle Motion

424

2025-05-13 | By Adafruit Industries

License: See Original Project Addressable LEDs LED Strips Microcontrollers Wifi

Courtesy of Adafruit

Guide by Erin St Blaine and 2 other contributors

Overview

On macOS, you need to use this board with a hub and USB A to USB ā€ŽC cable to upload any software. If you plug the board directly into a ā€ŽUSB C port on your Mac, it will assume it needs power delivery (PD) ā€Žand the USB to Serial port will not work.ā€Ž

board_1

We mainly recommend this board for use with WLED and Xlights, ā€Žbut examples are included in this guide for CircuitPython and ā€ŽArduino.ā€Ž

The Adafruit Sparkle Motion is the flagship in our series of "Sparkle ā€ŽMotion" boards, which are our attempt to make the best ā€Žsmall WLED-friendly smart LED driving board in the whole world. ā€ŽOur resident mermaid, firepixie makes a lot of projects with WLED ā€Žand she loves it! So how can we make something that will be ā€Žpowerful enough to drive advanced LED projects with built-in ā€Žsensors.ā€Ž

This version has a built-in antenna so it's ready to go out-of-the-box.ā€Ž

This board has everything you could possibly want for big, small, or ā€Ževen massive WLED/xLights projects:ā€Ž

  • Power option 1 via USB Type C PD with a slide switch that ā€Žselects between 5, 12 and 20V (24V pixels can usually run fine at ā€Žā€Ž20V)ā€Ž

  • Power option 2 via 2.1mm DC jack, center positive

  • Low forward-voltage diodes so it’s good for up to 5A from ā€Žeither

  • ā€Ž5 Amp fuse to protect from over-current drive

  • ESP32 mini module with built in antenna port - the classic ā€ŽESP32 has the best WLED support even if we'd prefer the 'S2 or ā€Žā€Ž'S3. Comes with 4 MB of flash, dual core 240MHz Tensilica, WiFi, ā€ŽBluetooth LE, and Bluetooth Classic support

  • USB-serial converter with auto-reset

  • Three output signal terminal block sets with power and ā€Žground for each - they'll be level shifted to 5V. Use 26-20AWG ā€Žstranded or solid core wires, 5A rated

  • ā€Ž6 GPIO breakout pads with a fourth level-shifted output, and 3 ā€Žmore GPIO plus power and ground

  • Built-in I2S microphone for audio-reactive projects with digital ā€Žquality audio

  • Built-in IR receiver for easy remote-control integration

  • Stemma QT I2C port to connect external sensors/OLED/etc

  • Separate analog/digital input JST port for analog input, ā€Žpotentiometer, microphone, or external IR receiver

  • User button on GPIO 0 plus Reset button

  • Red built-in LED on pin 4ā€Ž

  • Small built-in NeoPixel on pin 2ā€Ž

  • Compact enough you can use it for wearable projects - ā€Žā€Ž1.3"x1.75" / 33mm x 45mm size with mounting holesā€Ž

To make it super-fast to get started, terminal blocks are pre-installed: ā€Žuse any 20-26 AWG stranded or solid core wires with a flat-head ā€Žscrewdriver to attach semi-permanently.ā€Ž

While we recommend it for use with WLED, it will also work just fine ā€Žas a compact ESP32 board for use with Arduino, ESP-IDF, ā€ŽMicroPython, CircuitPython or any other ESP32 supported codebase. ā€Ž

scale_2

The Sparkle Motion board has it all. Designed with ease of use for ā€Žlarger scale LED projects using WLED and Xlights, we've packed it ā€Žwith features and components that will enable users to create ā€Žincredible things.ā€Ž

  • Power via USB Type C PD with a slide switch that selects ā€Žbetween 5, 12 and 20V (24V pixels can usually run fine at 20V)

OR via 2.1mm DC jackā€Ž

  • Low forward-voltage diodes so it's good for up to 5A from ā€Žeither USB or the DC jack

  • ā€Ž5 Amp fuse to protect from overcurrent drive

  • ESP32 mini module with built in or optionally wFL antenna port ā€Žā€Ž(the classic '32 has broad support even if we'd prefer the 'S2 or ā€Žā€Ž'S3)ā€Ž

  • Three output signal terminal block sets with power and ā€Žground for each: level shifted to 5V

  • ā€Ž6 GPIO breakout pads with a fourth level-shifted output, and 3 ā€Žmore GPIO plus power and ground

  • Built-in I2S microphone

  • Built-in IR receiver

  • Stemma QT I2C port to connect external sensors/OLED/etc

  • Separate analog/digital input JST port for analog input, ā€Žpotentiometer, microphone or external IR receiver

  • Compact enough you can use it for wearable projects - ā€Žā€Ž1.3"x1.75" / 33mm x 45mm size with mounting holesā€Ž

holes_3

Add-ons: yes! OLEDs! Inertial Measurement Units! Sensors a plenty. ā€ŽAll plug-and-play thanks to the innovative chainable ā€Ždesign: SparkFun Qwiic-compatible STEMMA QT connectors for the ā€ŽI2C bus, so you don't even need to solder! Just plug in a compatible ā€Žcable and attach it to your MCU of choice, and you’re ready to load ā€Žup some software and measure some light. Seeed Grove I2C ā€Žboards will also work with this adapter cable.ā€Ž

In addition to the Stemma QT connector, we also added an RGB ā€ŽNeoPixel (with controllable power pin to allow for ultra-low-power ā€Žusage), a reset button (great for restarting your program or entering ā€Žthe bootloader), and a button on GPIO 0 for entering the ROM ā€Žbootloader or for user input.ā€Ž

Onboard sensors include an IR receiver for easy remote control, and ā€Žan I2S microphone, so you can quickly and easily add sound ā€Žreactivity to your project.ā€Ž

blocks_4

To make it super-fast to get started, terminal blocks are pre-installed: ā€Žuse any 20-26 AWG stranded or solid core wires with a flat-head ā€Žscrewdriver to attach semi-permanently.ā€Ž

attach_5

This board has everything you could possibly want for big, small, or ā€Ževen massive WLED/xLights projects.ā€Ž

Pinouts

On macOS, you need to use this board with a hub and USB A to USB ā€ŽC cable to upload any software. If you plug the board directly into a ā€ŽUSB C port on your Mac, it will assume it needs power delivery (PD) ā€Žand the USB to Serial port will not work.ā€Ž

pinouts_6

The Sparkle Motion is a board with a lot of sparkly features. This page ā€Žcovers it all!ā€Ž

features_7

Pretty Pins on Github (PDF).ā€Ž

Power Pins

power_8

  • USB-C port - This is used for both powering and programming ā€Žthe board. You can power it with any USB C cable that is USB-ā€ŽPD rated for the current you'll draw. It is a 5V 5A input - you can ā€Žuse off-the-shelf USB battery packs for portable operation. It is ā€Žconnected to a 5 Amp resetting fuse to protect from ā€Žovercurrent drive.ā€Ž

  • USB-PD slide switch - selects between 5V, 12V, and 20V. ā€ŽConnected to the built-in HUSB238 power delivery chip, which ā€Žis on the I2C bus with address 0x8 (0x08).ā€Ž

  • Barrel Jack - 2.1mm DC jack, center positive. Accepts power up ā€Žto 24V. It is connected to a 5 Amp resetting fuse to protect from ā€Žovercurrent drive.ā€Ž

  • Power LED - The green LED, located between the USB C port ā€Žand Barrel jack, indicates when the board is powered up.ā€Ž

  • ā€Ž+ Terminal Blocks - The 3 VOUT terminal blocks along right ā€Žside provide 5V-24V power for your pixels. Use 26-20AWG ā€Žstranded or solid core wires, 5A rated.ā€Ž

  • ā€Ž- Terminal Blocks - The 3 GND terminal blocks along the right ā€Žside are common ground for all power and logic. Use 26-ā€Žā€Ž20AWG stranded or solid core wires, 5A rated.ā€Ž

  • ā€Ž3.3V - This pin, located on the top row of the 6 pins broken out ā€Žin the bottom right corner of the board, is the output from the ā€Žā€Ž3.3V regulator. It can supply 500mA peak.ā€Ž

  • G - This pin, located on the bottom row of the 6 pins broken out ā€Žin the bottom right corner, is connected to the common ground.ā€Ž

ESP32 Module

The processor on the Sparkle Motion is an ESP32 mini module. The ā€Žclassic ESP32 has the best WLED support. Comes with 4 MB of flash, ā€Ždual core 240MHz Tensilica, WiFi, Bluetooth LE, and Bluetooth ā€ŽClassic support.ā€Ž

module_9

NeoPixel Output Signals

neopixel_10

On the right side of the board there are 3 terminal blocks for ā€ŽNeoPixel output signals. All signals are level shifted to 5V. Use 26-ā€Žā€Ž20AWG stranded or solid core wires, 5A rated.ā€Ž

  • ā€Ž21 - GPIO21, available as SIG1 in CircuitPython and 21 in Arduino.ā€Ž

  • ā€Ž22 - GPIO22, available as SIG2 in CircuitPython and 22 in ā€ŽArduino.ā€Ž

  • ā€Ž19 - GPIO19, available as SIG3 in CircuitPython and 19 in ā€ŽArduino.ā€Ž

Logic Pins

logic_11

The Sparkle Motion has 4 general purpose "IO" pins broken out near ā€Žthe bottom right corner of the board and 1 additional GPIO available ā€Žvia the 3-pin JST port at the bottom edge of the board.ā€Ž

  • ā€Ž10 - GPIO10. This is the UART RX (receive) pin. Connect to the TX ā€Žpin found on a breakout or device. This is separate than the ā€Žā€Ž'debug UART' which is connected to the USB-to-Serial ā€Žconverter, so it will not interfere during upload. In Arduino ā€Žuse Serial1. In CircuitPython use board.RX.ā€Ž

  • ā€Ž9 - GPIO9. This is the UART TX (transmit) pin. Connect to the RX ā€Žpin found on a breakout or device. This is separate than the ā€Žā€Ž'debug UART' which is connected to the USB-to-Serial ā€Žconverter, so it will not interfere during upload. In Arduino, ā€Žuse Serial1. In CircuitPython, use board.TX.ā€Ž

  • ā€Ž23 - GPIO23. Available as D23 in CircuitPython and 23 in ā€ŽArduino. This is a 5V level shifted output only! You can use it as ā€Žanother LED strip pin.

  • ā€Ž18 - GPIO18. Available as D18 in CircuitPython and 18 in Arduino.ā€Ž

  • ā€Ž27 / JST Port - GPIO27. It uses ADC2. One of the capacitive ā€Žtouch pins. Available as D27 or A0 in CircuitPython and Arduino.ā€Ž

Note you cannot read analog inputs on ADC2 once WiFi has started, ā€Žas it is shared with the WiFi hardware.ā€Ž

STEMMA QT

stemma_12

This JST SH 4-pin STEMMA QT connector breaks out I2C (SCL, SDA, ā€Žā€Ž3.3V, GND). It allows you to connect to various breakouts and sensors ā€Žwith STEMMA QT connectors or to other things using assorted ā€Žassociated accessories. It works great with any STEMMA QT or Qwiic ā€Žsensor/device. You can also use it with Grove I2C devices thanks ā€Žto this handy cable.ā€Ž

  • SCL - GPIO13ā€Ž

  • SDA - GPIO14ā€Ž

You can access this I2C port with board.STEMMA_I2C() in ā€ŽCircuitPython and Wire in Arduino.ā€Ž

NeoPixel and Red LED

led_13

There are two LEDs you can control in code.ā€Ž

  • NeoPixel LED - This addressable RGB NeoPixel LED, ā€Žlabeled Neo on the board, can be controlled with code. It acts ā€Žas a status LED in CircuitPython and is connected to GPIO2. It is ā€Žavailable in CircuitPython as board.NEOPIXEL, and in Arduino ā€Žas PIN_NEOPIXEL.ā€Ž

  • Red LED - This little red LED, labeled LED on the board, is on or ā€Žblinks during certain operations (such as pulsing when in the ā€Žbootloader), and is controllable in code. It is available in ā€ŽCircuitPython as board.LED, and in Arduino ā€Žas LED_BUILTIN or 4.ā€Ž

Buttons

buttons_14

There are two buttons on the Sparkle Motion

  • Reset button - This button restarts the board and helps enter ā€Žthe bootloader. You can click it once to reset the board without ā€Žunplugging the USB cable or battery. ā€Ž

  • Boot button - This button can be read as an input in code. It is ā€Žconnected to pin GPIO0. It is available as board.BUTTON in ā€ŽCircuitPython, and BUTTON in Arduino. Simply set it to be an ā€Žinput with a pullup. This button can also be used to put the ā€Žboard into ROM bootloader mode. To enter ROM bootloader ā€Žmode, hold down boot button while clicking reset button ā€Žmentioned above. When in the ROM bootloader, you can ā€Župload code and query the chip using esptool.ā€Ž

IR Receiver

ir_15

The IR Receiver on the top center of the board makes it easy ā€Žintegrate a remote control into your project.ā€Ž

IR - GPIO32. Available as board.IR in CircuitPython, and 32 in Arduino. ā€ŽIt is connected to ADC1.ā€Ž

I2S Microphone

microphone_16

In the bottom center of the board is an I2S microphone, great for ā€Žadding audio reactivity to your WLED projects. It uses three data ā€Žpins:ā€Ž

  • DATA - GPIO25ā€Ž

  • WS - GPIO33ā€Ž

  • BCLK - GPIO26ā€Ž

You can use the microphone with WLED and Arduino. There is no I2S ā€Žinput support in CircuitPython at this time.ā€Ž

CH343DS1 USB-to-Serial Converter

converter_17

The CH343DS1 USB to serial converter communicates between the ā€ŽESP32 and your computer over USB. It is a full-speed USB device ā€Žinterface and is USB 2.0 compatible. It has an auto-reset circuit that ā€Žworks perfectly with any ESP32 uploading tool. Sometimes these ā€Žchips require drivers to be installed on your computer's operating ā€Žsystem. We have a Learn Guide detailing how to install these drivers.ā€Ž

UART Debug

On the back of the board, the hardware UART debug port has two ā€Žbroken out pads, labeled TX and RX on the board silk. You can ā€Žconnect these to a USB console cable in order to read the debug ā€Žoutput from the ESP32 IDF while connected to a USB PD power ā€Žsupply. This is useful if you are writing software and need to see the ā€Žlow-level debug output.ā€Ž

uart_18

  • ā€Ž ā€ŽTX - The pad on the top (closest to the Adafruit logo) is the TX ā€Žpin.ā€Ž

  • RX - The pad on the bottom (furthest from the Adafruit logo) is ā€Žthe RX pin.ā€Ž

Connecting LEDs

On macOS, you need to use this board with a hub and USB A to USB ā€ŽC cable to upload any software. If you plug the board directly into a ā€ŽUSB C port on your Mac, it will assume it needs power delivery (PD) ā€Žand the USB to Serial port will not work.ā€Ž

Wiring Diagram

wiring_19

There are many different types of pixels available. This is a general ā€Žreference that shows connection points for most types of strips. Your ā€Žproject may have different requirements, but this is a good starting ā€Žpoint.ā€Ž

For NeoPixel strips or other strips that have 3 solder pads or wires, ā€Žconnect to the screw terminal at the base of the board. There are ā€Žmarkings on the PCB showing which terminal is which. It's set up ā€Žwith three 3-pin strip connections in mind, and each strip has its own ā€Žpower and ground connection. The GPIO pins are labeled: 19, 22, and ā€Žā€Ž21, and they're in the middle of each block of 3 wires.ā€Ž

If you'd like to add a fourth instance/strip, connect the data and ā€Žground to the pins next to the screw terminal as shown, and the ā€Žpower wire to one of the +5v screw terminal ports.ā€Ž

The two Stemma connector ports can be used to connect sensors or ā€Žother peripherals.ā€Ž

How many LEDs Can I Connect?ā€Ž

The Sparkle Motion board has four outputs for LED strips: 3 in the ā€Žscrew terminal and one more using the GPIO pins next to the screw ā€Žterminal. It has a "Classic" ESP32 chip onboard.ā€Ž

Estimating Power Requirements

Each individual NeoPixel draws up to 60 milliamps at maximum ā€Žbrightness white (red + green + blue). In actual use though, it’s rare ā€Žfor all pixels to be turned on that way. When mixing colors and ā€Ždisplaying animations, the current draw will be much less. It’s ā€Žimpossible to estimate a single number for all circumstances, but ā€Žwe’ve been using 1/3 this (20 mA per pixel) as a gross rule of thumb ā€Žwith no ill effects. But if you know for a fact that you need every pixel ā€Žon at maximum brightness, use the full 60 mA figure.

ā€ŽTo estimate power supply needs, multiply the number of pixels by 20, ā€Žthen divide the result by 1,000 for the ā€œrule of thumbā€ power supply ā€Žrating in Amps. Or use 60 (instead of 20) if you want to guarantee an ā€Žabsolute margin of safety for all situations. For example:

ā€Žā€Ž60 NeoPixels Ɨ 20 mA Ć· 1,000 = 1.2 Amps minimum

ā€Ž60 NeoPixels Ɨ 60 mA Ć· 1,000 = 3.6 Amps minimum

ā€ŽThe choice of ā€œoverheadā€ in your power supply is up to you. ā€ŽMaximum safety and reliability are achieved with a more generously ā€Žsized power supply, and this is what we recommend. Most power ā€Žsupplies can briefly push a little extra current for short periods. Many ā€Žcontain a thermal fuse and will simply shut down if overworked. So, ā€Žthey may technically work, but this is the electronics equivalent of ā€Žabusing a rental car.ā€Ž

Here is a guide giving more info on what that means in terms of ā€Žpower draw: Powering NeoPixels Guide. The power draw varies ā€Žgreatly depending on the type of pixels and the brightness, as well ā€Žas the color choice. ā€Ž

Keep in mind, 60 mA is a worst-case estimate! We’ve written a ā€Žwhole separate tutorial on getting things under control: Sipping ā€ŽPower with NeoPixels.ā€Ž

Driving Pixels with WLED

From the WLED Knowlege base:ā€Ž

For perfect performance, it is recommended to use 512 LEDs/pin with ā€Žā€Ž4 outputs for a total of 2048 LEDs.

For very good performance, it is recommended to use 800 LEDs/pin ā€Žwith 4 outputs for a total of 3200 LEDs.

For good performance, you can use 1000 LEDs/pin with 4 outputs for ā€Ža total of 4000 LEDs.

For okay performance, you can use 1000 LEDs/pin with 5 outputs for ā€Ža total of 5000 LEDs.

For okay performance, you can use 800 LEDs/pin with 6 outputs for ā€Ža total of 4800 LEDs.

ESP32 can calculate about 65k-85k LEDs per second (that means ā€Žā€Ž1000 LEDs @~70fps, 2000 LEDs @~35fps, 4000 LEDs @~18fps)

ā€Ž4 outputs seem to be the sweet spot.ā€Ž

What Kind of LEDs Can I Use?ā€Ž

The Sparkle Motion board and WLED accept a wide variety of pixel ā€Žtypes. Anything in the Adafruit store labeled as "NeoPixel" or ā€Žā€Ž"Dotstar" will work. You can use rings, strips, jewels, pebble pixels, ā€Žstars, RGBW strips, or just about any RGB addressable pixels you can ā€Žfind in our shop.ā€Ž

This setup will NOT work with "dumb" RGB strips or analog strips. It's ā€Žmeant for strips with individually addressable pixels (strips where ā€Žeach pixel can become a different color) rather than the strips that ā€Žcan only show one color at a time.ā€Ž

How Do I Power It?ā€Ž

The Sparkle Motion board has onboard power management so you ā€Žcan use 5v, 12v, or 24v strips. The board will deliver up to 20v (which ā€Žis usually sufficient for 24v pixels). Be sure your power supply ā€Žmatches the voltage the LEDs expect. Here are a few good options. ā€ŽCheck the shop for more variations including power supplies with ā€Žinline on/off switches.ā€Ž

For wearable or portable projects, you can use a USB battery with 5v ā€Žpixels, plugged into the onboard USB-C port, or this 8xAA battery ā€Žpack for 12v pixels. But if you're making a wearable project, you ā€Žmight also want to check out the Sparkle Motion Mini board. It's not ā€Žquite as powerful and won't drive 12v pixels but can power up to 4A ā€Žat 5v and that's plenty for most costume pieces.ā€Ž

A Word About Connectors

It's possible to direct-wire your LED strips or pixels into the screw ā€Žterminal, but I find it easier and more convenient to use 3-pin JST ā€Žconnectors that can be permanently affixed to the Sparkle Motion ā€Žboard with strain relief, so they don't pull out. Then I can simply plug ā€Žin whatever LED strip or strand I want to use.ā€Ž

LED strips often come with these connectors already attached, but ā€Žthere seems to be no standard for whether the factories attach the ā€Žmale or the female connector on the "in" end. For my own peace of ā€Žmind, I try to be consistent and always use the male side of the ā€Žconnectors on the microcontrollers, and the female on the "in" end of ā€Žmy LED strip. Data is flowing "out" from the microcontroller and "in" ā€Žto the strip, so the male/female metaphor makes good sense in this ā€Žarrangement. ā€Ž

There is also no standard as to which way the color coding is wired ā€Žon these connectors. Some have a red wire on the left side, some on ā€Žthe right side. Some have no color coding at all. Hooking your strips ā€Žup "backwards" (accidentally connecting a red wire to a black wire) ā€Žcan damage your board and your LEDs, so it's important to be really ā€Žcareful when you're setting up your connectors. Be as consistent as ā€Žpossible with color coding and throw away any connectors you've ā€Žgot in the drawer that are wired "backwards" from the rest. ā€Ž

Screw Terminal Connections

Use a tiny precision flat head screwdriver to carefully and gently ā€Žopen the ports on the screw terminal. These are pretty easy to break ā€Žso be gentle. Look carefully at the openings as you turn the screws. ā€ŽWhen you see a square opening appear, stop turning.ā€Ž

Strip about 1/8" of wire from the 3 connector wires and insert ā€Žcarefully into the screw terminals. Use red for +, the middle wire for ā€Ždata, and the remaining wire for -. Gently tighten the screw until it's ā€Žsnug: about 5 turns -- it shouldn't turn freely, if it does, you've got the ā€Žwire in the wrong part of the hole so pull it out and try again.ā€Ž

connections_20connections_21

The wires should not come out easily when you tug. But, as we know, ā€Žthese controllers get tugged on all the time! After testing to be sure ā€Žof my connections, I added a zip tie around the back of the controller ā€Žto create strain relief on the connectors. ā€Ž

wires_22

wires_23

Connect the female side of the JST connector to your LED strip or ā€Žstrand, making sure the wire order matches the male connector in ā€Žyour screw terminal: +5v (red) should match up to +, data IN to GPIO, ā€Žand G to G. Plug in your strand and power up the board. The board ā€Žcomes pre-loaded with a rainbow animation so your lights should ā€Žcome on if you've got everything hooked up right.ā€Ž

strip_24

strip_25

WLED Setup

On macOS, you need to use this board with a hub and USB A to USB ā€ŽC cable to upload any software. If you plug the board directly into a ā€ŽUSB C port on your Mac, it will assume it needs power delivery (PD) ā€Žand the USB to Serial port will not work.ā€Ž

The following pages will walk you through installing WLED and ā€Žsetting up the various features within the software. We will cover ā€Žgetting your lights turned on and responding to sound or IR control. ā€ŽWe'll also show you how to connect sensors via the onboard ā€ŽStemma port and add button control. And we'll show you how to set ā€Žup multiple strands and multiple controllers and sync them together ā€Žfor larger scale projects.ā€Ž

Ready? Set? Let's go.ā€Ž

setup_26

WLED Software

Board Choices

WLED runs on several different boards in Adafruit's collection. There ā€Žare different benefits to each, but the installation process is largely ā€Žthe same. This page contains instructions for multiple boards -- be ā€Žsure to use the pinouts and installation instructions for the one ā€Žyou're using,ā€Ž

Sparkle Motion

This is our flagship ESP32 board, designed with WLED and Xlights in ā€Žmind. It has 4 outputs and is set up to drive either 5v, 12v or 24v ā€Žpixels. It's a workhorse of a board and for larger projects it's the clear ā€Žwinner. It has an onboard microphone for instant sound-reactive ā€Žsupport, and an IR sensor built in, to make it easy to control your ā€Žproject with an infrared remote. It also has a couple stemma ports so ā€Žyou can add your own sensors or peripherals.ā€Ž

Sparkle Motion Mini

The Sparkle Motion Mini is a smaller version of the Sparkle Motion ā€Žboard. It has two LED outputs, a microphone, and two stemma ports ā€Žthat make it easy to add an IR sensor or other peripherals. It's got an ā€Žonboard NeoPixel and a small footprint, making it perfect for ā€Žwearables or smaller projects. It will power a whole lot of pixels ā€Žthrough the onboard USB port: it's safe to draw up to 4A through this ā€Žport, giving you plenty of power for most wearable projects.ā€Ž

At this time, the Sparkle Motion Mini works best with WLED 0.15.1 ā€Žā€Ž-- the extra GPIO for the microphone pins are not supported in ā€ŽWLED 0.15.0. This should be fixed with the release of version 16.ā€Ž

To get mic support now, the following combined .bin file can be used. ā€ŽGet it by downloading this zip file:ā€Ž

esp32_bootloader_v4_WLED_0.16.0-alpha_ESP32.zip

To install, extract the .bin file from the zip and then follow the ā€Žsame ESB Web Flasher process used for installing CircuitPython. ā€ŽAt the "Programming the Board" step, choose the .bin file and leave ā€Žoffset as 0x0.ā€Ž

QT Py Pico ESP32ā€Ž

The QT Py Pico is small and affordable, so usually my go-to for ā€Žsmaller costumes or wearables. It also has a range of BFF add-on ā€Žboards that add functionality. Here's a guide with more QT Py info. ā€ŽThe QT Py will drive up to around 30 pixels through the onboard USB ā€Žport, so if you have more LEDs than that you may want to consider ā€Žthe Sparkle Motion Mini instead, or you can power the board through ā€Žthe +5v pin.ā€Ž

Note: WLED works on the QT Py Pico but NOT on the S2 or S3 ā€Žversions, at the time of writing.ā€Ž

Feather Huzzah ESP32 ā€Ž

The Feather Huzzah ESP32 the top of the line. It's a great choice for ā€Žprojects where you want to add sensors, interaction, or drive a whole ā€Žlot of LEDs. It's the most reliable as well -- I've run these for two ā€Žmonths straight with no power cycling and they just keep on truckin. ā€ŽAdafruit has a very wide selection of Feather Wing boards that ā€Žconnect to the Feather microcontroller line. The sky is the limit with ā€Žthese boards.ā€Ž

It also comes in a version with a high-powered WiFi range extender! ā€ŽIf you're trying to sync multiple instances across distance, check this ā€Žone out Feather Huzzah ESP32 V2 w.FL Antenna.

Feather Huzzah ESP8266ā€Ž

The Feather Huzzah ESP8266 will run WLED as well but won't drive ā€Žas many pixels: the ESP32 limit on WLED is around 1000 pixels per ā€Žinput, but the ESP8266 tops out at around 500. It's about $5 cheaper ā€Žthough, so for smaller projects it's a great way to save a little money ā€Žand still have access to all the Featherwing options in the Adafruit ā€Žstore.ā€Ž

Driver Update

Some versions of our controllers have a new serial chip which needs ā€Ža driver installed before we can install WLED. Head over to our How ā€Žto Install Drivers for WCH USB to Serial Chips tutorial and download ā€Žand install the new driver.ā€Ž

If you have an older QT Py with CP2102 USB-to-Serial bridge, use ā€ŽSiLabs’ driver instead.ā€Ž

ā€ŽInstall WLED

These next steps require a Web Serial-compatible browser. As of ā€Žthis writing, that ā€Žmeans Google Chrome, Microsoft Edge or Opera ā€œdesktopā€ ā€Žbrowsers. Other browsers (Safari, Firefox, Explorer ā€Žand anything mobile) won’t work.ā€Ž

Visit https://install.wled.me/ā€Ž

Plug your microcontroller into your computer with a known good ā€ŽUSB cable. Click "Install" and select the port for your board.ā€Ž

Depending on the USB-to-serial bridge chip on the board, you might ā€Žsee one or two serial ports. On Mac, for instance, there might be both ā€Žā€Žā€œ/dev/cu.usbmodem[number]ā€ and ā€œ/dev/cu.wchusbserial[number]ā€. ā€ŽUse the ā€œwchusbserialā€ one.ā€Ž

browser_26

After successful installation, enter your WiFi network name and ā€Žpassword when prompted. This must be a 2.4 GHz WiFi network; ā€ŽESP32 does not support 5 GHz networks. If it can’t connect, then as a ā€Žfallback WLED will create its own 2.4 GHz WiFi access point.ā€Ž

network_27

Sometimes the "Connect to Wi-Fi" prompt doesn't show up. Don't ā€Žpanic, just see the step below on connecting your computer or ā€Žmobile device to the WLED-AP access point created on the ā€Žmicrocontroller itself!ā€Ž

If you don't see the "Connect to Wi-Fi" prompt, you'll need to set up ā€Žyour WiFi network using AP (access point) mode. Open up your WiFi ā€Žsettings and look for a WiFi network called WLED-AP. (Note, this ā€Žaccess point can take up to 30 seconds to appear sometimes.) ā€ŽConnect to this network using the default password wled1234. The ā€ŽWLED interface will pop up in its own captive browser window.ā€Ž

From here, go into Config/Wifi Settings and enter your WiFi ā€Žcredentials for the access point you normally use near the top.ā€Ž

Give your project a name in the mDNS field a little further down the ā€Žpage. Now you can type in "projectname.local" (where "projectname" ā€Žis your mDNS name) into any web browser on the same wifi network ā€Žto access your microcontroller.ā€Ž

You can also scan the QR code below to open access point mode. ā€Ž

For more help and troubleshooting tips visit the Getting Started ā€Žpage on the WLED knowledge base.ā€Ž

dashboard_28

dashboard_29

dashboard_30

qr_31

Setup & Preferences

WiFi Setup

Head to the WiFi Setup screen under Config and create a good URL ā€Žso you can control your project from any web-enabled device. Call it ā€Žsomething you'll remember, that's easy to type into any web ā€Žbrowser on your WiFi network in order to connect to your project.ā€Ž

In Safari or Chrome on your phone or computer, type in this web ā€Žaddress to access the WLED ā€Žinterface: http://projectname.local (where "projectname" is whatever ā€Žyou put into this field).ā€Ž

Check out the Additional Settings page for more info on accessing ā€Žyour project. WLED has an "access point mode" that doesn't require ā€Ža WiFi network for when you're out on the go. It's also helpful to ā€Ždownload one of the WLED apps to help manage and organize your ā€Žprojects.ā€Ž

create_32

create_33

LED Preferences

Next, head to the LED Preferences tab under the Config menu.ā€Ž

Scroll down to Hardware Setup. Put your total number of LEDs into ā€Žthe "Length" field and change GPIO to the pin number associated ā€Žwith the pin you soldered to. Check the pinout diagram for the board ā€Žyou're using (it's the number in yellow).ā€Ž

preferences_34

Use It

useit_35

Now you can use any computer or handheld device to control your ā€ŽLEDs. ā€Ž

Make sure your device is on the same WiFi network as your board. ā€ŽNavigate to your custom URL (projectname.local/ ) in a web browser. ā€ŽYou'll see a color picker above a whole bunch of color palette choices.ā€Ž

Choose a color, choose an effect, and watch your lights animate and ā€Žglow!ā€Ž

Save your favorite combinations as presets, create playlists, control ā€Žthe speed and intensity of the animations, and lots more. This web ā€Žapp is incredibly intuitive and easy to use.ā€Ž

Head over to the WLED wiki at https://kno.wled.ge/ to delve into all ā€Žthe particulars.ā€Ž

WLED Config

Next, we'll tell WLED about our physical setup. We'll give our project ā€Ža name and easy-to-remember URL and tell the software how many ā€ŽLEDs we have set up on each pin.ā€Ž

WiFi Setup

Head to the WiFi Setup screen under Config. This is where your ā€Žnetwork credentials live, so you can change them if needed. Scroll ā€Ždown to the mDNS field and create a good URL so you can control ā€Žyour project from any web-enabled device. Call it something you'll ā€Žremember, that's easy to type into any web browser on your WiFi ā€Žnetwork in order to connect to your project. ā€Ž

In this example, I'd go to my web browser on my phone, iPad, or ā€Žcomputer, and type in "http://projectname.local" to open up the ā€ŽWLED interface on my screen. Your device must be on the same ā€ŽWiFi network as your board.

name_36

name_37

LED Preferences

Next, head to the LED Preferences tab under the Config menu.ā€Ž

Scroll down to Hardware Setup. The Sparkle Motion board has 4 ā€Žspots to attach LED strips: the screw terminal uses GPIO 19, 22, and ā€Žā€Ž21 and the through-hole solder pads to the left of the screw terminal ā€Žis GPIO 23.ā€Ž

WLED allows up to 4 strips to be connected at once. The strips can ā€Žbe of different types, lengths, and color order. Select your LED type, ā€Žlength, and GPIO pin. If you have multiple strips connected, click the ā€Žā€Ž+ button and enter the additional strips in the same way. ā€Ž

menu_38

menu_39

Click "save" and if you've done everything correctly, your light ā€Žstrands should come on in a warm, cheerful yellow color. Success! ā€ŽTime to start making pretty light animations. ā€Ž

Troubleshooting

If your lights didn't come on, here are a few things to try:ā€Ž

  1. Head back to WLED and check your pinout configuration ā€Žunder LED Preferences. Be sure the pin number is the correct ā€ŽGPIO for the attachment point you used.ā€Ž

  2. Check your wiring! Be sure you connected to the IN end of the ā€ŽLED strip. These strips can be inconsistent, so this is a pretty ā€Žcommon problem. Use an alligator clip to try connecting the ā€Ždata wire on the other end (the power and ground wires should ā€Žwork from either end).ā€Ž

  3. Try re-uploading the WLED software. ā€Ž

  4. If the lights come on but you can't control them: i.e. you type in ā€Žā€Ž"projectname.local" into your browser and it won't connect, ā€Žmake sure you're on the correct WiFi network. If you're on a ā€Ždifferent network than the one you set up the software on, you ā€Žwon't see the WLED connection.ā€Ž

  5. If your lights came on in blue or green instead of yellow, your ā€Žcolor order is wrong. See below to fix.ā€Ž

  6. If only half your lights came on, be sure you've got the correct ā€Žnumber in the "length" field under LED preferences.ā€Ž

  7. If your lights came on in a variety of weird colors and looking ā€Žlike a 1950s diner interior, you may have the wrong LED strip ā€Žtype selected. RGBW strips and RGB strips are not the same, so ā€Žbe sure you've got the correct strip type, or you'll get very odd ā€Žbehavior.ā€Ž

  8. If your microcontroller hangs or keeps rebooting, or gets really ā€Žhot, you may have the power and ground lines switched. ā€ŽUnplug right away and check: this is a fast way to brick your ā€Žcontroller.ā€Ž

Color Order

If your lights have come on in any color other than a warm yellow, ā€Žthere's one more setting to change. LED strips and pixels are not all ā€Žstandardized, and sometimes the red, green, and blue LEDs inside ā€Žare connected in a different order. ā€Ž

In the main interface window, choose "solid" as your effect and red ā€Žas your color from the color picker. ā€Ž

If your lights come on in any color other than red, your color order is ā€Žset incorrectly. This is an easy fix. Head back to the LED settings tab ā€Žand find the Hardware Setup section (this is where you set up your ā€Žpin number earlier). Choose BRG from the dropdown, click save, and ā€Žsee if your pixel colors match your color picker now. If not, try ā€Žanother combo until the lights look correct.ā€Ž

color_40

color_41

IR Remote Setup

Adding infrared control to your project is easy. WLED comes ā€Žpreprogrammed to use a variety of common IR remote controls, so ā€Žyou can get instant functionality with just a little bit of setup.ā€Ž

The Sparkle Motion board has an onboard IR sensor on pin 32. It's ā€Žalso not too hard to set up your own IR sensor on the stemma port ā€Žon GPIO 27 in case you want a more accessible sensor if your board ā€Žis hidden inside an enclosure or inconveniently located. ā€Ž

Click the LED Preferences tab and scroll down to Hardware Setup.ā€Ž

Change the IR GPIO pin to 32 and select which remote you're using ā€Žfrom the dropdown. I like this 44 key remote since it gives me quick ā€Žfull-strip color control as well as plenty of customizable buttons to ā€Žuse with my different presets.ā€Ž

presets_42

Remote Usage: 44 Key Remote

Change the brightness or turn the strip on and off with the buttons ā€Žon the top row.ā€Ž

When you have the "solid" effect selected in WLED, the color buttons ā€Žnear the top of the remote will change the colors, making the pixels ā€Žact like a "dumb" RGB strip. ā€Ž

On my 44-key remote, there are buttons near the bottom labeled ā€Žā€Ž"DIY1", "DIY2" etc. WLED will automatically assign your animation ā€Žpresets to these buttons so you can select your favorite presets or ā€Žplaylists. Simply save the presets you want to the first 6 preset slots ā€Žand the buttons will pull them up. ā€Ž

Head over to the WLED wiki at https://kno.wled.ge/ to delve into all ā€Žthe particulars.ā€Ž

Adding a Wired IR Sensor

Sometimes you want to place your IR sensor further away from your ā€Žmicrocontroller to make an easier line-of-sight for the remote control. ā€ŽHere's how to add a wired IR sensor or IR breakout to the Stemma ā€Žport on the Sparkle Motion board to make this easy. Use GPIO 27 in ā€Žconfig.ā€Ž

You'll need an IR sensor and a STEMMA JST 3-pin connector with ā€Žfemale sockets. Plug the connector into the smaller of the two ā€ŽStemma ports. Looking at the sensor with the bump facing you:ā€Ž

  • White wire on the left

  • Black wire in the middle

  • Red wire on the right

You can lengthen the wires as needed so your IR sensor ends up ā€Žright where you want it. ā€Ž

We also have these handy IR breakout boards available.ā€Ž

adding_43

WLED Autoreactive Setup

The Sparkle Motion board comes with an onboard PDM microphone, ā€Žso adding audio reactivity to your project is easy. Here's how to get it ā€Žset up.ā€Ž

Click Config and then select the Usermods tab.

config_42

Scroll down a bit ā€Žand you'll find the Autoreactive section. ā€Ž

Click the box to enable, then enter the settings and the Digitalmic ā€Žsection as follows:ā€Ž

  • Type: Generic I2S

  • Pin I2S SD: 25ā€Ž

  • Pin I2S WS: 33ā€Ž

  • Pin I2S SCK: 26ā€Ž

The other pins are unused.ā€Ž

Reboot your microcontroller for changes to take effect.ā€Ž ā€ŽThat means either pressing the reset button or unplugging the board from power completely for a few seconds.

reboot_44

If you want the audio to work well in both loud and quiet settings, you may want to turn on AGC - automatic gain control. Start with Normal and then experiment with other options if you want more or less 'gain speed'.

settings_43

There are a lot of other settings you can adjust in WLED. I found that ā€Žthe default settings for this mic seem to work perfectly, but you can ā€Ždelve into the particulars at https://kno.wled.ge/advanced/audio-ā€Žreactive/ā€Ž.

To use audio reactive mode, head back to the main interface and ā€Žselect any effect that has a music note icon next to the name. You can also search for musical-reactive effects that are built in.

Make ā€Žsome noise and see how your lights react.ā€Ž If it doesn't work, check your pins, try turning on AGC, tapping on the mic, and rebooting (removing power completely, waiting a few seconds then turn back on).

noise_45

If you happen to have a 2D matrix as an output, the GEQ effect shows a 'binned' frequency response graph which can be good for debugging!

matrix_46a

matrix_47b

WLED 2d Matrix

If you're using a 2-d matrix such as an LED curtain or net, WLED has ā€Ža handy 2d-matrix setup feature that will take care of the mapping ā€Žfor you. Head to Config and choose the 2D Configuration tab.ā€Ž

Check out these tutorials for more about 2d mapping with WLED:ā€Ž

Change the dropdown to read 2d Matrix, and additional options will ā€Žappear. If you want to sync more than one panel, you can do it here. ā€Ž

Set up your layout numbers to match the number of rows and ā€Žcolumns in your project. You can also change orientation here - my ā€Žpixels start in the lower left corner and finish in the upper right.ā€Ž

matrix_45

matrix_46

Matrix Effects

WLED has a hefty number of matrix effects that appear in the list ā€Žwhen you've got your 2d matrix set up. Many of them can be ā€Žcustomized with speed and intensity sliders, or different color ā€Žpalettes. Go wild! ā€Ž

effects_47

Create Presets

Animation Presets

Once your lights are working, it's time for the fun part: creating light ā€Žanimations using WLED presets. This is easy and intuitive in WLED. ā€ŽChoose a color palette and an effect, then play with the sliders at the ā€Žbottom of the Effect Mode column to customize the effect.ā€Ž

When you find something, you like, click the +Preset button in the ā€ŽPresets tab and give your preset a name, then save it. You can ā€Žreorder them using the "Save to ID" field. ā€Ž

You can create hundreds of presets using the preprogrammed ā€Žeffects, so take some time to play around and see what looks good ā€Žon your LED strip.ā€Ž

presets_48

Create at least 3 presets and be sure they are saved to ID numbers 1-ā€Žā€Ž3. Our next step will be to set up the switch to toggle between these ā€Žpresets. ā€Ž

Control Presets

The WLED preset interface can also be used to send control ā€Žcommands to the LED strip. Once you've set up a button or switch, it ā€Žcan be used for a wide variety of control functions: change modes, ā€Žchange brightness, toggle the lights on and off, or a whole host of ā€Žother features. ā€Ž

Each button function in WLED has 3 options: a short press, a long ā€Žpress, or a double press. I want my lights to cycle through presets ā€Žwith a short press, and to turn on or off with a long press. Here's how ā€ŽI set up a control preset for each of these features.ā€Ž

Cycle through Presets

Click +Preset and then uncheck the "Use current state" checkbox. ā€ŽThis will open up an API command window within the preset ā€Žmodule.ā€Ž

Call the effect "Next_FX" and type {"ps":"1~3~"} into the API command ā€Žbox. This tells WLED to cycle through presets 1-3. If you'd like to cycle ā€Žthrough more presets, change the 3 to the number of presets you ā€Žhave. ā€Ž

Be sure your preset IDs include all the numbers -- skipping a ā€Žnumber will break this command.ā€Ž

Give your preset an ID number that's above the range of your preset ā€Žnumbers -- I called mine 9. ā€Ž

cycle_49

It's also possible to cycle between playlists. I made a playlist of sound ā€Žreactive effects and a separate playlist of "standard" effects. I set up a ā€Žpreset that toggles between the two playlists -- effectively turning ā€Žā€Ž"sound reactive" mode on and off.ā€Ž

cycle_50

Toggle On/Off

Create another preset and call it "Toggle". Uncheck the "use current ā€Žstate" checkbox and enter T=2 into the API command box. This will ā€Žtell the LEDs to toggle between on and off. Save this one to ID 10.ā€Ž

create_51

On the next page we'll connect these control presets to our button.ā€Ž

Find out more about creating these control presets here: ā€Ž

https://kno.wled.ge/features/presets/ā€Ž

You can enter either JSON commands or HTTP commands into this ā€Žcommand box, giving you a lot of control over your WLED project. ā€Ž

https://kno.wled.ge/interfaces/json-api/ā€Ž

WLED Button Setup

Adding a control button is easy with the Sparkle Motion board. Any ā€Žmomentary switch will work. I'm using this chonky 12mm Tactile ā€ŽSwitch Button and a STEMMA JST PH 2mm 3-Pin connector with ā€Žfemale sockets.ā€Ž

Plug the JST connector into the smaller of the two stemma ports. ā€ŽStraighten out the legs on one side of your button and slip the legs ā€Žinto the female connectors: one leg goes to white (data GPIO 27), the ā€Žother to black (G). ā€Ž

It's fine to extend these wires so they're longer. For a more solid ā€Žconnection you can cut the connectors off and solder directly to the ā€Žbutton legs.ā€Ž

legs_52

Open up the LED settings screen in WLED under "Config". Scroll to ā€Žthe button setup section and set button 1 to use pin 27, with the type ā€Žset as "Pushbutton".ā€Ž

Click save. Try pressing your button and see if your effects change. ā€ŽThe default behavior for button 1 is to cycle through effects, but we ā€Žcan change this and set up the button for any number of behaviors ā€Žusing the Presets panel.

open_53

I advise against using button 0. WLED's buttons have some default ā€Žbehaviors written in, and one of button 0's default behaviors is that ā€Žwhen it's pressed for more than a few seconds, it resets your ā€Žmicrocontroller to factory settings. I originally had button 0 selected, ā€Žand I held the button down a bit too long while I was sewing it onto ā€Žthe hat, and .. POOF. All my settings and presets were wiped out. ā€Ž

Check out the "Backup" section under the Additional Settings page ā€Žto learn to back up your configuration and presets, in case this kind ā€Žof thing happens to you.ā€Ž

Next, head to the Time & Macros config screen. Scroll down to the ā€ŽButton actions area. ā€Ž

For button 1, enter the number assigned to the two control presets ā€Žyou made on the last page. My Next_FX preset is number 22, so I ā€Žentered 22 under "short press", and my Toggle preset is number 21, ā€Žso I've got that set up as a "long press". ā€Ž

I also added my playlist toggle to preset 20, so a double-click of my ā€Žbutton will turn sound reactive mode on or off.ā€Ž

toggle_54

toggle_55

Troubleshooting

If your button isn't working, here are some things to try:ā€Ž

  1. ā€ŽDouble check both the LED preferences page and the Time & ā€ŽMacros page to be sure your settings are correct and have ā€Žsaved.ā€Ž

  2. Be sure your presets are correctly numbered. WLED gets ā€Žconfused if the presets have non-sequential IDs (so make sure ā€Žthey're numbered 1, 2, 3 rather than 2, 5, 7).ā€Ž

  3. Be sure you're connected to the correct legs on your button. ā€ŽYou want the legs on the same side (facing the same way), ā€Žrather than connecting to the two top legs or the two bottom ā€Žlegs. Those pins are connected together inside the button so ā€Žwon't work when the switch is activated.ā€Ž

WLED Additional Settings

Brightness Limiter

Find this on the LED Settings screen.ā€Ž

WLED automatically limits the brightness of your project, so your ā€Žpower supply doesn't get over-taxed. The default amperage is ā€Žā€Ž850mA, which is a little low for most power supplies.ā€Ž

For some projects, especially battery-powered projects, having the ā€Žlimiter turned on is a good idea. But if you're not getting the ā€Žbrightness you expect, try adjusting this number to match the ā€Žamperage of your power supply or battery pack.ā€Ž

brightness_56

Access Point (AP) Mode

While your home, it's easy to control your project over your local WiFi ā€Žnetwork. But when you're out at a festival you probably don't have ā€ŽWiFi access. It's still possible to connect to your project and control it ā€Žusing WLED's Access Point Mode.ā€Ž

Turn your project on and give it a minute or two to start broadcasting. ā€ŽLook in your WiFi networks and find WLED-AP - this is a mini-WiFi ā€Žnetwork being broadcast by the Feather. Connect to it - the default ā€Žpassword is "wled123". An instance of WLED will automatically pop ā€Žup and you can control your project from anywhere.ā€Ž

If you're putting your lights up in public, it's a good idea to change ā€Žthe AP Mode default password so strangers can't log in and control ā€Žyour lights. This could be a security risk.ā€Ž

AP Mode only broadcasts for a few minutes after you boot up the ā€Žboard so if you don't see the WLED-AP network try rebooting.ā€Ž

access_57

WLED App

There are a couple different apps available to manage your WLED ā€Žprojects. Name and organize your projects and find them quickly ā€Žwithout having to type in a URL. Check the Apple or Android store for ā€Ždownloads. ā€Ž

My favorite is "WLED Native". It allows you to organize multiple ā€Žinstances and easily switch between devices without having to ā€Žremember any URLs. ā€Ž

native_58

Backup Config & Presets

Under Config / Security & Updates you will find a place to back up ā€Žyour data. It's a good idea to back up your config file as soon as ā€Žyou're happy with the settings. Save it as a .json file on your ā€Žcomputer. Now you can prototype and experiment to your heart's ā€Žcontent, and if everything breaks, just re-upload this file. Or, if you're ā€Ždoing another build you can use this feature to copy all your settings ā€Žfrom one board to another.

backup_59

Install CircuitPython

CircuitPython is a derivative of MicroPython designed to simplify ā€Žexperimentation and education on low-cost microcontrollers. It ā€Žmakes it easier than ever to get prototyping by requiring no upfront ā€Ždesktop software downloads. ESP32 CircuitPython firmware is ā€Župloaded to the board via the USB serial port.ā€Ž

Follow this step-by-step to get CircuitPython running on your board.ā€Ž

Driver Install

If this is your first time using an ESP32 board on Windows or MacOS, ā€Žyou may need to install the USB to serial drivers. There are two ā€Žoptions for the USB to serial chipset on your board. If you are unsure ā€Žwhich one you have, install both drivers.ā€Ž

For instructions and more information regarding the CH9102F chip ā€Žand driver install, please visit the How to Install Drivers for WCH USB ā€Žto Serial Chips guide.ā€Ž

For driver downloads for the CP2104 and CP2012N, please visit ā€Žthe Silicon Labs Downloads page.ā€Ž

For those running Linux, the drivers are already included.ā€Ž

CircuitPython Download

On macOS, you need to use this board with a hub and USB A to USB ā€ŽC cable to upload any software. If you plug the board directly into a ā€ŽUSB C port on your Mac, it will assume it needs power delivery (PD) ā€Žand the USB to Serial port will not work.ā€Ž

Download the latest version of CircuitPython for this board via ā€Žcircuitpython.org

Click the link above to download the latest CircuitPython .bin file.ā€Ž

Save it wherever is convenient for you.ā€Ž

download_60

Connecting to the Web Flasher

To begin, plug your board into your computer via USB, using a ā€Žknown-good data-sync cable, directly, or via an adapter if needed.ā€Ž

You will have to use the Chrome or a Chromium-based browser to ā€Žinstall CircuitPython. For example, Edge and Opera are Chromium ā€Žbased.ā€Ž

Safari and Firefox, etc. are not supported - they have not ā€Žimplemented Web Serial!ā€Ž

In the Chrome ā€Žbrowser visit https://adafruit.github.io/Adafruit_WebSerial_ESPTool/ā€Ž

The main page of the ESP Web Flasher should look something like ā€Žthis.ā€Ž

Note: The site now displays an alert that it is no longer maintained ā€Žand suggests using a different option. The ESP Web Flasher has still ā€Žproven to be more consistent and easier to use, so it is highly ā€Žsuggested that you continue with this version.ā€Ž

flasher_61

You should remove all other USB devices so only the target board ā€Žis attached. This eliminates confusion over multiple ports!ā€Ž

Press the Connect button in the top right of the web browser. You ā€Žwill get a pop up asking you to select the COM or Serial port. Look ā€Žfor USB Single Serial.ā€Ž

On some systems, such as MacOS, there may be additional system ā€Žports that appear in the list (as shown in the image).ā€Ž

connect_62

The JavaScript code will now try to connect to the board. It may ā€Žtimeout for a bit until it succeeds. On success, you will see that it ā€Žis Connected and will print out a unique MAC address identifying ā€Žthe board along with other information that was detected.ā€Ž

core_63

Once you have successfully connected, the command toolbar will ā€Žappear.ā€Ž

toolbar_64

Erasing the Board Contents

If you would like to erase the entire flash area so that you can start ā€Žwith a clean slate, you can use the erase feature. We recommend ā€Ždoing this every time before installing or updating CircuitPython.ā€Ž

To erase the contents, click the Erase button. You will be prompted ā€Žas to whether you want to continue. Click OK to continue. If you do ā€Žnot wish to continue, click Cancel.

erasing_65

You'll see "Erasing flash memory. Please wait..." This will eventually ā€Žbe followed by "Finished." and the amount of time it took to erase.ā€Ž

Do not disconnect! Immediately continue on to Programming the ā€ŽBoard.ā€Ž

disconnect_66

Do not disconnect after erasing! You should immediately continue ā€Žon to programming your board. If you do not, you may end up with ā€Žyour board in a bad state that makes it more difficult to continue. ā€ŽYou can avoid this!ā€Ž

Programming the Board

You can click on Choose a file... from any of the available buttons. It ā€Žwill only attempt to program buttons with a file and a unique ā€Žlocation. Select the .bin file you downloaded at the beginning of this ā€Žpage from the file chooser dialogue.ā€Ž

Verify that the Offset box next to the file location you used is 0x0. ā€ŽThe offset defaults to 0x0, so unless you changed it manually, it ā€Žshould be good to go.ā€Ž

programming_67

programming_68

Once you choose a file, the button text will change to match your ā€Žfilename. You can then click the Program button to start flashing.

choose_69

A progress bar will appear and after a minute or two, you will have ā€Žwritten the firmware.ā€Ž

bar_70

You've now successfully programmed CircuitPython onto your board! ā€ŽAs suggested in the output, press reset to run the new firmware.

press_71

As the ESP32 does not have native USB, no USB drive will show up ā€Žon your computer when you reset. With CircuitPython firmware ā€Žloaded, the REPL can be accessed over a serial/COM port.ā€Ž

For more details on installation, how to configure your ESP32, and ā€Žinfo on getting started with CircuitPython on your ESP32 using the ā€ŽWeb Workflow, check out the CircuitPython on ESP32 Quick Start ā€Žguide.ā€Ž

Connecting to the USB Workflow Code Editor

The USB workflow is a new feature and there may be bugs! If you ā€Žfind a bug, please file an issue on GitHub.ā€Ž

To use the Code Editor, you will need an internet browser such as ā€ŽGoogle Chrome or Microsoft Edge. It's possible that it may work in ā€Žother browsers as well, but these have been more thoroughly tested.ā€Ž

Open your browser and navigate to https://code.circuitpython.org/. ā€ŽSelect USB on the dialog prompt that comes up.ā€Ž

workflow_72

This will display a page of instructions along with a button to bring ā€Žup a list of devices to connect to.ā€Ž

Click Connect to Device and then select your board in the pop-up ā€Žwindow. Click Connect to connect your board to the editor.ā€Ž

click_73

click_74

Once you have connected, the Connect button in the upper right-ā€Žhand corner should change to a Disconnect button.ā€Ž

disconnect_75

Navigating USB Workflow

Opening and Saving Files

Opening and Saving files is designed to be like to most other ā€Žapplications. Just use the buttons along the top of the editor window.ā€Ž

Clicking the Open or Save As buttons along the top will open the ā€ŽFile Dialog. Clicking the Save + Run button will save your file and run ā€Žthe code. If your file hasn't been saved yet, this will also bring up the ā€Žfile dialog box.ā€Ž

dialog_75

The file dialog that appears is a simplified dialog that displays the ā€Žcurrent path at the top, allows you to navigate through the file tree ā€Žto select the file you would like to open, and has buttons on the ā€Žbottom to open or save the file you would like to use.ā€Ž

Canceling will tell the editor that you do not want to continue with ā€Žthe current operation.ā€Ž

dialog_76

The X at the top performs the same function as the Cancel button as ā€Ždoes clicking outside of the dialog.ā€Ž

On the Save As dialog, you can also type in a filename in the field ā€Žnext to the button.ā€Ž

function_77

Running Code

As mentioned above, the Save + Run button will first save your file, ā€Žthen run the code. The logic to run the code however is currently ā€Žvery simplistic in that it will try a couple of basic strategies to run ā€Žyour code but doesn't currently do much beyond that.ā€Ž

The way it works is if you are working on code.py in the root folder, a ā€Žsoft reset will be performed, which automatically runs code.py. If you ā€Žwere working on some code in another file, the editor will attempt to ā€Žperform an import on this code, which should run it. When you run ā€Žyour code, it will automatically switch over to the serial terminal.ā€Ž

Click the Save + Run button to save and run the code current code.ā€Ž

save_78

File Dialog Toolbar

The file Dialog toolbar along the top allows you to perform common ā€Žoperations on files and folders regardless of whether you are saving ā€Žor opening. Clicking the cancel button at the bottom will not undo ā€Žany operations that were performed with these buttons.ā€Ž

Renaming and Deleting Files and Folders

You can rename or delete both files and folders. An item must be ā€Žselected first for the buttons to become available.ā€Ž

Use the delete and rename buttons here to perform the ā€Žcorresponding operation on the currently selected file or folder.ā€Ž

renaming_79

Creating New Folders

This feature allows you to create a new folder to store your work ā€Žinside of.ā€Ž

Clicking the new folder button at the top will prompt you for a folder ā€Žname. It will inform you of invalid folder names such as the same ā€Žname as an existing file or folder or a folder that begins with a period.ā€Ž

folder_80

folder_81

Uploading and Downloading Files and Folders

This feature allows you to upload or download files as long as they fit ā€Žin the available space. If you need to add images or sound files for ā€Žyour project, you can use the upload button to add them. If you need ā€Žto retrieve a file from your device for whatever reason, the download ā€Žbutton will give you access to do that.ā€Ž

You can also download folders. When you select a folder and click ā€Ždownload, the contents of that folder are automatically zipped into a ā€Žsingle file. If nothing is selected when you click the download button, ā€Žthe current folder will be used.ā€Ž

Use the upload or download buttons to easily add files or retrieve ā€Žthem from your board.ā€Ž

downloading_82

Moving Files and Folders

This feature allows you to move files and folders to a different ā€Žlocation on the device. When you click the move button, another ā€Žprompt will appear on top of the dialog that allows you to navigate ā€Žto where you would like to move the currently selected item. ā€Ž

Use the move button to move files or folders to a new location on ā€Žthe device.ā€Ž

The second dialog that appears will show only folders and allow you ā€Žto navigate to where you would like to move the file.ā€Ž

moving_83

moving_84

Using the Serial Terminal

The serial terminal allows you to watch the output of your device as ā€Žwell as type inputs just like you can from a separate application like ā€ŽPuTTY, except there's nothing you need to configure. This allows you ā€Žto access the REPL or view the output of your currently running code.ā€Ž

Use the mode buttons in the bottom left-hand corner to open and ā€Žclose the serial and editor panes.ā€Ž

serial_85

More Features to Come

The CircuitPython Code Editor is still under development, so expect ā€Žmore features to be added. If you would like to contribute on GitHub, ā€Žyou can submit any new issues or pull requests for review.ā€Ž

Blink

In learning any programming language, you often begin with some ā€Žsort of Hello, World! program. In CircuitPython, Hello, World! is ā€Žblinking an LED. Blink is one of the simplest programs in ā€ŽCircuitPython. It involves three built-in modules, two lines of set up, ā€Žand a short loop. Despite its simplicity, it shows you many of the ā€Žbasic concepts needed for most CircuitPython programs and ā€Žprovides a solid basis for more complex projects. Time to get blinky!ā€Ž

LED Location

location_86

Blinking an LED

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, open the ā€Ždirectory CircuitPython_Templates/blink/ and then click on the ā€Ždirectory that matches the version of CircuitPython you're using.ā€Ž

Download Project Bundle

Copy Code
# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries
# SPDX-License-Identifier: MIT
"""CircuitPython Blink Example - the CircuitPython 'Hello, World!'"""
import time
import board
import digitalio

led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT

while True:
    led.value = True
    time.sleep(0.5)
    led.value = False
    time.sleep(0.5)

View on GitHub

In the editor window in your browser, click the Open button to view ā€Žthe file dialog. Then, click the Upload button and select Upload Files.ā€Ž

editor_87

Navigate to the project bundle that you downloaded and select ā€Žthe code.py file.ā€Ž

navigate_88

You'll be asked if you want to overwrite the previous code.py with ā€Žthe new code.py file from the Project Bundle. Click OK.ā€Ž

overwrite_89

You'll see a new code.py file appear in the file browser. Select it and ā€Žclick Open to view it in the code editor.ā€Ž

newcode_90

You'll see the LED blink code.py file contents. Click Restart above ā€Žthe Serial monitor to run the LED blink code.ā€Ž

run_91

The built-in LED begins blinking!ā€Ž

Note that the code is a little less "Pythonic" than it could be. It could ā€Žalso be written as led.value = not led.value with a ā€Žsingle time.sleep(0.5). That way is more difficult to understand if ā€Žyou're new to programming, so the example is a bit longer than it ā€Žneeded to be to make it easier to read.ā€Ž

It's important to understand what is going on in this program.ā€Ž

First you import three modules: time, board, and digitalio. This makes ā€Žthese modules available for use in your code. All three are built-in to ā€ŽCircuitPython, so you don't need to download anything to get started.ā€Ž

Next, you set up the LED. To interact with hardware in CircuitPython, ā€Žyour code must let the board know where to look for the hardware ā€Žand what to do with it. So, you create a digitalio.DigitalInOut() object, ā€Žprovide it the LED pin using the board module, and save it to the ā€Žvariable led. Then, you tell the pin to act as an OUTPUT.ā€Ž

Finally, you create a while True: loop. This means all the code inside ā€Žthe loop will repeat indefinitely. Inside the loop, you set led.value = ā€ŽTrue which powers on the LED. Then, you use time.sleep(0.5) to tell ā€Žthe code to wait half a second before moving on to the next line. The ā€Žnext line sets led.value = False which turns the LED off. Then you use ā€Žanother time.sleep(0.5) to wait half a second before starting the loop ā€Žover again.ā€Ž

With only a small update, you can control the blink speed. The blink ā€Žspeed is controlled by the amount of time you tell the code to wait ā€Žbefore moving on using time.sleep(). The example uses 0.5, which is ā€Žone half of one second. Try increasing or decreasing these values to ā€Žsee how the blinking changes.ā€Ž

That's all there is to blinking an LED using CircuitPython!ā€Ž

Digital Input

The CircuitPython digitalio module has many applications. The basic ā€ŽBlink program sets up the LED as a digital output. You can just as ā€Žeasily set up a digital input such as a button to control the LED. This ā€Žexample builds on the basic Blink example but now includes setup ā€Žfor a button switch. Instead of using the time module to blink the ā€ŽLED, it uses the status of the button switch to control whether the ā€ŽLED is turned on or off.ā€Ž

LED and Button

ledbutton_92

Controlling the LED with a Button

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, open the ā€Ždirectory CircuitPython_Templates/digital_input_built_in_button_led/ and then click on the directory that matches the version of ā€ŽCircuitPython you're using.ā€Ž

Download Project Bundle

Copy Code
# SPDX-FileCopyrightText: 2022 Kattni Rembor for Adafruit Industries
# SPDX-License-Identifier: MIT
"""
CircuitPython Digital Input Example - Blinking an LED using the built-in button.
"""
import board
import digitalio

led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT

button = digitalio.DigitalInOut(board.BUTTON)
button.switch_to_input(pull=digitalio.Pull.UP)

while True:
    if not button.value:
        led.value = True
    else:
        led.value = False

View on GitHub

In the editor window in your browser, click the Open button to view ā€Žthe file dialog. Then, click the Upload button and select Upload Files.ā€Ž

editor_93

Navigate to the project bundle that you downloaded and select ā€Žthe code.py file.ā€Ž

bundle_94

You'll be asked if you want to overwrite the previous code.py with ā€Žthe new code.py file from the Project Bundle. Click OK.ā€Ž

overwrite_95

You'll see a new code.py file appear in the file browser. Select it and ā€Žclick Open to view it in the code editor.ā€Ž

new_96

You'll see the digital input code.py file contents. Click Restart above ā€Žthe Serial monitor to run the digital input code.ā€Ž

digital_97

Now, press the button. The LED lights up! Let go of the button and ā€Žthe LED turns off.ā€Ž

adafruit_products_digitalio_btn_led_v2_scaled

Note that the code is a little less "Pythonic" than it could be. It could ā€Žalso be written as led.value = not button.value. That way is more ā€Ždifficult to understand if you're new to programming, so the example ā€Žis a bit longer than it needed to be to make it easier to read.ā€Ž

First you import two modules: board and digitalio. This makes these ā€Žmodules available for use in your code. Both are built-in to ā€ŽCircuitPython, so you don't need to download anything to get started.ā€Ž

Next, you set up the LED. To interact with hardware in CircuitPython, ā€Žyour code must let the board know where to look for the hardware ā€Žand what to do with it. So, you create a digitalio.DigitalInOut() object, ā€Žprovide it the LED pin using the board module, and save it to the ā€Žvariable led. Then, you tell the pin to act as an OUTPUT.ā€Ž

You include setup for the button as well. It is similar to the LED setup, ā€Žexcept the button is an INPUT, and requires a pull up.ā€Ž

Inside the loop, you check to see if the button is pressed, and if so, ā€Žturn on the LED. Otherwise, the LED is off.ā€Ž

That's all there is to controlling an LED with a button switch!ā€Ž

Analog Input

The CircuitPython analogio module has many applications. You can ā€Žset up an analog input with a potentiometer connected to an analog ā€Žinput pin on your board.ā€Ž

Necessary Hardware

You'll need the following additional hardware to complete the ā€Žexamples on this page.ā€Ž

Wiring

  • JST-SH signal to potentiometer wiper (white wire)ā€Ž

  • JST-SH 3.3V to potentiometer positive (red wire)ā€Ž

  • JST-SH GND to potentiometer ground (black wire)ā€Ž

wiring_98

Reading the Potentiometer

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, open the ā€Ždirectory CircuitPython_Templates/analog_voltage_values/ and ā€Žthen click on the directory that matches the version of CircuitPython ā€Žyou're using.ā€Ž

Download Project Bundle

Copy Code
# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries
# SPDX-License-Identifier: MIT
"""CircuitPython analog voltage value example"""
import time
import board
import analogio

analog_pin = analogio.AnalogIn(board.A0)


def get_voltage(pin):
    return (pin.value * 3.3) / 65535


while True:
    print(get_voltage(analog_pin))
    time.sleep(0.1)

View on GitHub

In the editor window in your browser, click the Open button to view ā€Žthe file dialog. Then, click the Upload button and select Upload Files.ā€Ž

window_99

Navigate to the project bundle that you downloaded and select ā€Žthe code.py file.

bundle_100

You'll be asked if you want to overwrite the previous code.py with ā€Žthe new code.py file from the Project Bundle. Click OK.ā€Ž

ok_101

You'll see a new code.py file appear in the file browser. Select it and ā€Žclick Open to view it in the code editor.ā€Ž

select_101

You'll see the analog input code.py file contents. Click Restart above ā€Žthe Serial monitor to run the analog input code.ā€Ž

analog_102

Now, twist and turn the potentiometer. You'll see the analog voltage ā€Žvalues print to the serial console.ā€Ž

console_103

Built-In NeoPixel

Your board has a built-in RGB NeoPixel status LED. You can use ā€ŽCircuitPython code to control the color and brightness of this LED. It ā€Žis also used to indicate the bootloader status and errors in your ā€ŽCircuitPython code.ā€Ž

A NeoPixel is what Adafruit calls the WS281x family of addressable ā€ŽRGB LEDs. It contains three LEDs - a red one, a green one and a blue ā€Žone - alongside a driver chip in a tiny package controlled by a single ā€Žpin. They can be used individually (as in the built-in LED on your ā€Žboard) or chained together in strips or other creative form factors. ā€ŽNeoPixels do not light up on their own; they require a ā€Žmicrocontroller. So, it's super convenient that the NeoPixel is built ā€Žinto your microcontroller board!ā€Ž

This page will cover using CircuitPython to control the status RGB ā€ŽNeoPixel built into your microcontroller. You'll learn how to change ā€Žthe color and brightness, and how to make a rainbow. ā€ŽTime to get started!ā€Ž

NeoPixel Location

location_104

NeoPixel Color and Brightness

To use with CircuitPython, you need to first install a few libraries, into ā€Žthe lib folder on your board. Then you need to update code.py with ā€Žthe example script.ā€Ž

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, open the ā€Ždirectory CircuitPython_Templates/status_led_one_neopixel_rgb/ and then click on the directory that matches the version of ā€ŽCircuitPython you're using.ā€Ž

Download Project Bundle

Copy Code
# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries
# SPDX-License-Identifier: MIT
"""CircuitPython status NeoPixel red, green, blue example."""
import time
import board
import neopixel

pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)

pixel.brightness = 0.3

while True:
    pixel.fill((255, 0, 0))
    time.sleep(0.5)
    pixel.fill((0, 255, 0))
    time.sleep(0.5)
    pixel.fill((0, 0, 255))
    time.sleep(0.5)

View on GitHub

Update the /lib Folder

In the editor window in your browser, click the Open button to view ā€Žthe file dialog. Then, click the Upload button and select Upload ā€ŽFolders.ā€Ž

view_105

Navigate to the project bundle that you downloaded and select ā€Žthe /lib folder.ā€Ž

lib_106

You'll be asked if you want to upload the /lib folder from the Project ā€ŽBundle. Click Upload.ā€Ž

asked_107

After the upload finishes, you can open the lib folder to view the two ā€Žlibrary files required for the NeoPixel examples.ā€Ž

after_108

Update code.py

In the editor window in your browser, click the Open button to view ā€Žthe file dialog. Then, click the Upload button and select Upload Files.ā€Ž

files_109

Navigate to the project bundle that you downloaded and select ā€Žthe code.py file.ā€Ž

bundle_110

You'll be asked if you want to overwrite the previous code.py with ā€Žthe new code.py file from the Project Bundle. Click OK.ā€Ž

overwrite_111

The built-in NeoPixel begins blinking red, then green, then blue, and ā€Žrepeats!ā€Ž

adafruit_products_sparkle_builtin_neopixel_rgb_scaled

First you import two modules, time, and board, and one ā€Žlibrary, NeoPixel. This makes these modules and libraries available ā€Žfor use in your code. The first two are modules built-in to ā€ŽCircuitPython, so you don't need to download anything to use those. ā€ŽThe NeoPixel library is separate, which is why you needed to install it ā€Žbefore getting started.ā€Ž

Next, you set up the NeoPixel LED. To interact with hardware in ā€ŽCircuitPython, your code must let the board know where to look for ā€Žthe hardware and what to do with it. So, you create ā€Ža neopixel.NeoPixel() object, provide it the NeoPixel LED pin using ā€Žthe board module, and tell it the number of LEDs. You save this ā€Žobject to the variable pixel.ā€Ž

Then, you set the NeoPixel brightness using ā€Žthe brightness attribute. brightness expects float between 0 and 1.0. ā€ŽA float is essentially a number with a decimal in it. The brightness ā€Žvalue represents a percentage of maximum brightness; 0 is 0% ā€Žand 1.0 is 100%. Therefore, setting pixel.brightness = 0.3 sets the ā€Žbrightness to 30%. The default brightness, which is to say the ā€Žbrightness if you don't explicitly set it, is 1.0. The default is really ā€Žbright! That is why there is an option available to easily change the ā€Žbrightness.ā€Ž

Inside the loop, you turn the NeoPixel red for 0.5 seconds, green for ā€Žā€Ž0.5 seconds, and blue for 0.5 seconds.ā€Ž

To turn the NeoPixel red, you "fill" it with an RGB value. Check out ā€Žthe section below for details on RGB colors. The RGB value for red ā€Žis (255, 0, 0). Note that the RGB value includes the parentheses. ā€ŽThe fill() attribute expects the full RGB value including those ā€Žparentheses. That is why there are two pairs of parentheses in the ā€Žcode.ā€Ž

You can change the RGB values to change the colors that the ā€ŽNeoPixel cycles through. Check out the list below for some examples. ā€ŽYou can make any color of the rainbow with the right RGB value ā€Žcombination!ā€Ž

That's all there is to changing the color and setting the brightness of ā€Žthe built-in NeoPixel LED!ā€Ž

RGB LED Colors

RGB LED colors are set using a combination of red, green, and blue, ā€Žin the form of an (R, G, B) tuple. Each member of the tuple is set to a ā€Žnumber between 0 and 255 that determines the amount of each ā€Žcolor present. Red, green, and blue in different combinations can ā€Žcreate all the colors in the rainbow! So, for example, to set an LED to ā€Žred, the tuple would be (255, 0, 0), which has the maximum level of ā€Žred, and no green or blue. Green would be (0, 255, 0), etc. For the ā€Žcolors between, you set a combination, such as cyan which is (0, 255, ā€Žā€Ž255), with equal amounts of green and blue. If you increase all values ā€Žto the same level, you get white! If you decrease all the values to 0, ā€Žyou turn the LED off.ā€Ž

Common colors include:ā€Ž

  • red: (255, 0, 0)ā€Ž

  • green: (0, 255, 0)ā€Ž

  • blue: (0, 0, 255)ā€Ž

  • cyan: (0, 255, 255)ā€Ž

  • purple: (255, 0, 255)ā€Ž

  • yellow: (255, 255, 0)ā€Ž

  • white: (255, 255, 255)ā€Ž

  • black (off): (0, 0, 0)ā€Ž

NeoPixel Rainbow

You should have already installed the library necessary to use the ā€Žbuilt-in NeoPixel LED. If not, follow the steps at the beginning of the ā€ŽNeoPixel Color and Brightness section to install it.ā€Ž

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, open the ā€Ždirectory CircuitPython_Templates/status_led_one_neopixel_rainbow/ and then click on the directory that matches the version of ā€ŽCircuitPython you're using.ā€Ž

Download Project Bundle

Copy Code
# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries
# SPDX-License-Identifier: MIT
"""CircuitPython status NeoPixel rainbow example."""
import time
import board
from rainbowio import colorwheel
import neopixel

pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)
pixel.brightness = 0.3


def rainbow(delay):
    for color_value in range(255):
        pixel[0] = colorwheel(color_value)
        time.sleep(delay)


while True:
    rainbow(0.02)

View on GitHub

Update the code.py file in the USB code editor with the ā€Žrainbow code.py file. The same libraries from the RGB blinking ā€Žexample are used. The NeoPixel displays a rainbow cycle!

adafruit_products_builtin_neopixel_rainbow_scaled

ā€ŽThis example builds on the previous example.ā€Ž

First, you import the same three modules and libraries. In addition to ā€Žthose, you import colorwheel.ā€Ž

The NeoPixel hardware setup and brightness setting are the same.ā€Ž

Next, you have the rainbow() helper function. This helper displays the ā€Žrainbow cycle. It expects a delay in seconds. The higher the number ā€Žof seconds provided for delay, the slower the rainbow will cycle. The ā€Žhelper cycles through the values of the color wheel to create a ā€Žrainbow of colors.ā€Ž

Inside the loop, you call the rainbow helper with a 0.2 second delay, ā€Žby including rainbow(0.2).ā€Ž

That's all there is to making rainbows using the built-in NeoPixel ā€ŽLED!ā€Ž

Sparkle Motion NeoPixel Demo

adafruit_products_sparkle_circuitpython_neopixel_animat

The main use of the Sparkle Motion is lighting up RGB LEDs to ā€Ždazzle and delight. CircuitPython has ā€Žthe Adafruit_CircuitPython_Neopixel module, which allows you to ā€Žeasily write Python code that lets you control NeoPixels, as well as ā€Žthe Adafruit_CircuitPython_LED_Animation module that provides ā€Žmore advanced control with an assortment of fun and colorful ā€Žanimations. In the example below, you'll run two different LED ā€Žanimations on two strips of NeoPixels at the same time. ā€Ž

Wiring

NeoPixels

  • terminal block - to GND on both NeoPixel strips. (black wire)ā€Ž

  • terminal block + to 5V on both NeoPixel strips. (red wire)ā€Ž

  • terminal block 21 to DIN on the first NeoPixel strip. (green wire)ā€Ž

  • terminal block 22 to DIN on the second NeoPixel strip. (green ā€Žwire)ā€Ž

diagram_112

CircuitPython Usage

To use with CircuitPython, you need to first install a few libraries, into ā€Žthe lib folder on your board. Then you need to update code.py with ā€Žthe example script.ā€Ž

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, open the ā€Ždirectory Sparkle_Motion_Examples/CircuitPython_Sparkle_Motionā€Ž_Neopixel_Animation/ and then click on the directory that matches ā€Žthe version of CircuitPython you're using.ā€Ž

Example Code

Download Project Bundle

Copy Code
# SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""
Example illustrating two different LED Animations running on
Neopixels connected to 2 of the main outputs of the Sparkle Motion
"""
import board
import neopixel

from adafruit_led_animation.animation.comet import Comet
from adafruit_led_animation.animation.rainbow import Rainbow
from adafruit_led_animation.color import GREEN

strip1_pixel_pin = board.D21
strip2_pixel_pin = board.D22

pixel_count = 8

strip1_pixels = neopixel.NeoPixel(
    strip1_pixel_pin, pixel_count, brightness=0.1, auto_write=False
)
strip2_pixels = neopixel.NeoPixel(
    strip2_pixel_pin, pixel_count, brightness=0.1, auto_write=False
)

comet = Comet(strip1_pixels, speed=0.05, color=GREEN, tail_length=3, bounce=True)
rainbow = Rainbow(strip2_pixels, speed=0.05, period=3)

while True:
    comet.animate()
    rainbow.animate()

View on GitHub

Update the /lib Folder

In the editor window in your browser, click the Open button to view ā€Žthe file dialog. Then, click the Upload button and select Upload ā€ŽFolders.ā€Ž

update_113

Navigate to the project bundle that you downloaded and select ā€Žthe /lib folder.ā€Ž

select_114

You'll be asked if you want to upload the /lib folder from the Project ā€ŽBundle. Click Upload.ā€Ž

bundle_115

After the upload finishes, you can open the lib folder to view the two ā€Žlibrary files required for the NeoPixel examples.ā€Ž

Your CIRCUITPY/lib folder should contain the following folders:ā€Ž

  • adafruit_led_animation/ā€Ž

  • adafruit_pixelbuf.mpy

  • neopixel.mpy

library_116

In the editor window in your browser, click the Open button to view ā€Žthe file dialog. Then, click the Upload button and select Upload Files.ā€Ž

editor_117

Navigate to the project bundle that you downloaded and select ā€Žthe code.py file.ā€Ž

project_118

You'll be asked if you want to overwrite the previous code.py with ā€Žthe new code.py file from the Project Bundle. Click OK.ā€Ž

previous_119

This example utilizes both of the NeoPixel outputs on terminal ā€Žblocks D21 and D22. It starts by initializing variables for the pixel pins ā€Žand count of how many NeoPixels are in each strip. Next it creates ā€Žinstances of neopixel.NeoPixel for each strip. Then it creates ā€Ža Comet animation on one strip, and a Rainbow animation on the ā€Žother. Inside of the main while True: each animation object has ā€Žit's animate() function called to advance it by one step.ā€Ž

IR Remote

adafruit_products_ir_remote_neopixel_scaled_800

The Adafruit Sparkle Motion has an IR Receiver built-in for all of your ā€Žremote controlling needs. The Adafruit CircuitPython ā€ŽIRRemote library makes it easy to decode the signals sent to the ā€Žreceiver. This example will get you started by demonstrating how to ā€Žuse one of our mini remote controls to change the color and ā€Žbrightness of a connected strip of NeoPixels.ā€Ž

IR Receiver & NeoPixel Output Location

receiver_120

The IR Receiver is connected with the pin alias board.IR. This ā€Žexample assumes the NeoPixel strip will be plugged in to the ā€Žterminal blocks for pin board.D21.ā€Ž

Necessary Hardware

You can use any IR remote with basic NEC codes that are supported ā€Žby the Adafruit CircuitPython IRRemote library, and any NeoPixel ā€Žstrip that you like. The following items are the ones depicted on this ā€Žpage.ā€Ž

Wiring

NeoPixels

  • terminal block - to GND on the NeoPixel strip. (black wire)ā€Ž

  • terminal block + to 5V on the NeoPixel strip. (red wire)ā€Ž

  • terminal block 21 to DIN on the NeoPixel strip. (green wire)ā€Ž

wiring_121

CircuitPython Usage

To use with CircuitPython, you need to first install a few libraries, into ā€Žthe lib folder on your board. Then you need to update code.py with ā€Žthe example script.ā€Ž

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, open the ā€Ždirectory Sparkle_Motion_Examples/CircuitPython_Sparkle_Motionā€Ž_IR_Remote/ and then click on the directory that matches the ā€Žversion of CircuitPython you're using.ā€Ž

Example Code

Download Project Bundle

Copy Code
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries
# SPDX-License-Identifier: MIT
"""CircuitPython Adafruit Sparkle Motion IR remote control NeoPixels example."""
import time

import board
import pulseio
from rainbowio import colorwheel

import neopixel
import adafruit_irremote

pulsein = pulseio.PulseIn(board.IR, maxlen=120, idle_state=True)
decoder = adafruit_irremote.NonblockingGenericDecode(pulsein)

IR_CODE_UP = (0, 253, 160, 95)
IR_CODE_DOWN = (0, 253, 176, 79)

IR_CODE_RIGHT = (0, 253, 80, 175)
IR_CODE_LEFT = (0, 253, 16, 239)

t0 = next_heartbeat = time.monotonic()

pixel = neopixel.NeoPixel(board.D21, 8)

brightness = 1
pixel.brightness = brightness / 10

color_number = 160
pixel.fill(colorwheel(color_number))
while True:
    for message in decoder.read():
        print(f"t={time.monotonic() - t0:.3} New IR Message")
        if isinstance(message, adafruit_irremote.IRMessage):
            if message.code == IR_CODE_UP:
                brightness = min(brightness + 1, 10)
            elif message.code == IR_CODE_DOWN:
                brightness = max(brightness - 1, 0)
            elif message.code == IR_CODE_RIGHT:
                color_number = (color_number + 32) % 256
            elif message.code == IR_CODE_LEFT:
                color_number = (color_number - 32) % 256

            pixel.brightness = brightness / 10
            pixel.fill(colorwheel(color_number))

            print("Decoded:", message.code)
            print("Brightness: ", brightness/10, " Color: ", hex(colorwheel(color_number)))
        elif isinstance(message, adafruit_irremote.NECRepeatIRMessage):
            print("NEC repeat!")
        elif isinstance(message, adafruit_irremote.UnparseableIRMessage):
            print("Failed to decode", message.reason)
        print("----------------------------")

View on GitHub

Update the /lib Folder

In the editor window in your browser, click the Open button to view ā€Žthe file dialog. Then, click the Upload button and select Upload ā€ŽFolders.ā€Ž

browse_122

Navigate to the project bundle that you downloaded and select ā€Žthe /lib folder.ā€Ž

downloaded_123

You'll be asked if you want to upload the /lib folder from the Project ā€ŽBundle. Click Upload.ā€Ž

click_124

After the upload finishes, you can open the lib folder to view the two ā€Žlibrary files required for the NeoPixel examples.ā€Ž

Your CIRCUITPY/lib folder should contain the following folders:ā€Ž

  • adafruit_irremote.mpy

  • adafruit_pixelbuf.mpy

  • neopixel.mpy

finishes_125

In the editor window in your browser, click the Open button to view ā€Žthe file dialog. Then, click the Upload button and select Upload Files.

window_126ā€Ž

Navigate to the project bundle that you downloaded and select ā€Žthe code.py file.

open_127

You'll be asked if you want to overwrite the previous code.py with ā€Žthe new code.py file from the Project Bundle. Click OK.ā€Ž

new_128

This example utilizes the NeoPixel output terminal blocks for pin D21. ā€ŽIt starts by initializing PulseIn and the IR Decoder instance. Then the ā€ŽNeoPixel instance. Inside of the main while True: loop it reads any ā€Žincoming messages from the decoder. When the up or down ā€Žcommands are received it raises or lowers the brightness of the ā€ŽNeoPixels, when the right or left commands are received it changes ā€Žthe color of the NeoPixels.ā€Ž

I2C Scan

scan_129

A QT Py ESP32-S2 connected to an MCP9808 Temperature Sensor ā€Žfor I2C via STEMMA QT.ā€Ž

The I2C, or inter-integrated circuit, is a 2-wire protocol for ā€Žcommunicating with simple sensors and devices, which means it ā€Žuses two connections, or wires, for transmitting and receiving data. ā€ŽOne connection is a clock, called SCL. The other is the data line, ā€Žcalled SDA. Each pair of clock and data pins are referred to as a bus.ā€Ž

Typically, there is a device that acts as a controller and sends ā€Žrequests to the target devices on each bus. In this case, your ā€Žmicrocontroller board acts as the controller, and the sensor breakout ā€Žacts as the target. Historically, the controller is referred to as the ā€Žmaster, and the target is referred to as the slave, so you may run into ā€Žthat terminology elsewhere. The official terminology is controller and ā€Žtarget.ā€Ž

Multiple I2C devices can be connected to the same clock and data ā€Žlines. Each I2C device has an address, and as long as the addresses ā€Žare different, you can connect them at the same time. This means ā€Žyou can have many different sensors and devices all connected to ā€Žthe same two pins.ā€Ž

Both I2C connections require pull-up resistors, and most ā€ŽAdafruit I2C sensors and breakouts have pull-up resistors built in. If ā€Žyou're using one that does not, you'll need to add your own 2.2-10kΩ ā€Žpull-up resistors from SCL and SDA to 3.3V.ā€Ž

I2C and CircuitPython

CircuitPython supports many I2C devices and makes it super simple ā€Žto interact with them. There are libraries available for many I2C ā€Ždevices in the CircuitPython Library Bundle. (If you don't see the ā€Žsensor you're looking for, keep checking back, more are being ā€Žwritten all the time!)ā€Ž

In this section, you'll learn how to scan the I2C bus for all connected ā€Ždevices. Then you'll learn how to interact with an I2C device.ā€Ž

Necessary Hardware

You'll need the following additional hardware to complete the ā€Žexamples on this page.ā€Ž

While the examples here will be using the Adafruit MCP9808, a high ā€Žaccuracy temperature sensor, the overall process is the same for just ā€Žabout any I2C sensor or device.ā€Ž

The first thing you'll want to do is get the sensor connected so your ā€Žboard has I2C to talk to.ā€Ž

Wiring the MCP9808ā€Ž

The MCP9808 comes with a STEMMA QT connector, which makes ā€Žwiring it up quite simple and solder-free.ā€Ž

Connect the STEMMA QT cable from the STEMMA QT port on your ā€Žboard to the STEMMA QT port on the MCP9808.ā€Ž

cable_130

Find Your Sensor

The first thing you'll want to do after getting the sensor wired up, is ā€Žmake sure it's wired correctly. You're going to do an I2C scan to see if ā€Žthe board is detected, and if it is, print out its I2C address.ā€Ž

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, open the ā€Ždirectory CircuitPython_Templates/i2c_scan/ and then click on the ā€Ždirectory that matches the version of CircuitPython you're using.ā€Ž

Download Project Bundle

Copy Code
# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries
# SPDX-License-Identifier: MIT
"""CircuitPython I2C Device Address Scan"""
import time
import board

i2c = board.I2C()  # uses board.SCL and board.SDA
# i2c = board.STEMMA_I2C()  # For using the built-in STEMMA QT connector on a microcontroller

# To create I2C bus on specific pins
# import busio
# i2c = busio.I2C(board.GP1, board.GP0)    # Pi Pico RP2040

while not i2c.try_lock():
    pass

try:
    while True:
        print(
            "I2C addresses found:",
            [hex(device_address) for device_address in i2c.scan()],
        )
        time.sleep(2)

finally:  # unlock the i2c bus when ctrl-c'ing out of the loop
    i2c.unlock()

View on GitHub

In the editor window in your browser, click the Open button to view ā€Žthe file dialog. Then, click the Upload button and select Upload Files.ā€Ž

upload_131

Navigate to the project bundle that you downloaded and select ā€Žthe code.py file.

file_132

You'll be asked if you want to overwrite the previous code.py with ā€Žthe new code.py file from the Project Bundle. Click OK.ā€Ž

new_133

You'll see a new code.py file appear in the file browser. Select it and ā€Žclick Open to view it in the code editor.ā€Ž

open_134

Adafruit Sparkle Motion comes with one I2C device built in: HUSB238 ā€Žpower delivery chip. The I2C scan code will show the addresses from ā€Žthe built-in device and the MCP9808.ā€Ž

scancode_135

If you run this and it seems to hang, try manually unlocking your I2C ā€Žbus by running the following two commands from the REPL.ā€Ž

Copy Code
import board
board.I2C().unlock()

First you create the i2c object, using board.I2C(). This convenience ā€Žroutine creates and saves a busio.I2C object using the default ā€Žpins board.SCL and board.SDA. If the object has already been ā€Žcreated, then the existing object is returned. No matter how many ā€Žtimes you call board.I2C(), it will return the same object. This is called ā€Ža singleton.ā€Ž

To be able to scan it, you need to lock the I2C down so the only thing ā€Žaccessing it is the code. So next you include a loop that waits until ā€ŽI2C is locked and then continues on to the scan function.ā€Ž

Last, you have the loop that runs the actual scan, i2c_scan(). Because ā€ŽI2C typically refers to addresses in hex form, the example includes ā€Žthis bit of code that formats the results into hex ā€Žformat: [hex(device_address) for device_address in i2c.scan()].ā€Ž

Open the serial console to see the results! The code prints out an ā€Žarray of addresses. You've connected the MCP9808 which has a 7-bit ā€ŽI2C address of 0x18. The result for this sensor is I2C addresses found: ā€Žā€Ž['0x18']. If no addresses are returned, refer back to the wiring ā€Ždiagrams to make sure you've wired up your sensor correctly.ā€Ž

WiFi Test

In this example, you'll test your Sparkle Motion WiFi connection by ā€Žconnecting to your SSID, printing your MAC address and IP address ā€Žto the REPL and then pinging Google.ā€Ž

settings.toml File

If you've worked on WiFi projects with CircuitPython before, you're ā€Žprobably familiar with the secrets.py file. This file is a Python file that ā€Žis stored on your CIRCUITPY drive that contains all of your secret ā€ŽWiFi information, such as your SSID, SSID password and any API keys ā€Žfor IoT services. ā€Ž

As of CircuitPython 8, there is support for a settings.toml file. Similar ā€Žto secrets.py, the settings.toml file separates your sensitive ā€Žinformation from your main code.py file.ā€Ž

Your settings.toml file should be stored in the main directory of your ā€Žboard. It should not be in a folder.ā€Ž

settings.toml File Example

Here is an example on how to format your settings.toml file.ā€Ž

Download File

Copy Code
# Comments are supported
CIRCUITPY_WIFI_SSID="guest wifi"
CIRCUITPY_WIFI_PASSWORD="guessable"
CIRCUITPY_WEB_API_PORT=80
CIRCUITPY_WEB_API_PASSWORD="passw0rd"
test_variable="this is a test"
thumbs_up="\U0001f44d"

In a settings.toml file, it's important to keep these factors in mind:ā€Ž

  • Strings are wrapped in double quotes; ex: "your-string-here"ā€Ž

  • Integers are not quoted and may be written in decimal with ā€Žoptional sign (+1, -1, 1000) or hexadecimal (0xabcd).ā€Ž

    • Floats, octal (0o567) and binary (0b11011) are not ā€Žsupported.ā€Ž

  • Use \u escapes for weird characters, \x and \ooo escapes are not ā€Žavailable in .toml files

    • Example: \U0001f44d for šŸ‘ (thumbs up emoji) ā€Žand \u20ac for € (EUR sign)ā€Ž

  • Unicode emoji, and non-ASCII characters, stand for themselves ā€Žas long as you're careful to save in "UTF-8 without BOM" formatā€Ž

When your settings.toml file is ready, you can save it in your text ā€Žeditor with the .toml extension.ā€Ž

ready_136

CircuitPython WiFi Example

In the example below, click the Download Project Bundle button ā€Žbelow to download the code.py file in a zip file. Extract the contents ā€Žof the zip file and then click on the directory that matches the ā€Žversion of CircuitPython you're using.ā€Ž

Download Project Bundle

Copy Code
# SPDX-FileCopyrightText: 2022 Liz Clark for Adafruit Industries
#
# SPDX-License-Identifier: MIT

from os import getenv
import ipaddress
import wifi
import socketpool

# Get WiFi details, ensure these are setup in settings.toml
ssid = getenv("CIRCUITPY_WIFI_SSID")
password = getenv("CIRCUITPY_WIFI_PASSWORD")

if None in [ssid, password]:
    raise RuntimeError(
        "WiFi settings are kept in settings.toml, "
        "please add them there. The settings file must contain "
        "'CIRCUITPY_WIFI_SSID', 'CIRCUITPY_WIFI_PASSWORD', "
        "at a minimum."
    )

print()
print("Connecting to WiFi")

#  connect to your SSID
try:
    wifi.radio.connect(ssid, password)
except TypeError:
    print("Could not find WiFi info. Check your settings.toml file!")
    raise

print("Connected to WiFi")

pool = socketpool.SocketPool(wifi.radio)

#  prints MAC address to REPL
print("My MAC addr:", [hex(i) for i in wifi.radio.mac_address])

#  prints IP address to REPL
print(f"My IP address is {wifi.radio.ipv4_address}")

#  pings Google
ipv4 = ipaddress.ip_address("8.8.4.4")
print("Ping google.com: %f ms" % (wifi.radio.ping(ipv4)*1000))

View on GitHub

In the editor window in your browser, click the Open button to view ā€Žthe file dialog. Then, click the Upload button and select Upload Files.ā€Ž

editor_137

Navigate to the project bundle that you downloaded and select ā€Žthe code.py file.

select_138

You'll be asked if you want to overwrite the previous code.py with ā€Žthe new code.py file from the Project Bundle. Click OK.ā€Ž

bundle_139

Update Your settings.toml File

Remember to add your settings.toml file as described earlier in this ā€Žpage. You'll need to include ā€Žyour CIRCUITPY_WIFI_SSID and CIRCUITPY_WIFI_PASSWORD in the ā€Žfile. ā€Ž

You can edit the file manually in the USB code editor by ā€Žclicking Open, selecting settings.toml and clicking Open at the ā€Žbottom of the dialog box.ā€Ž

box_140

With settings.toml open in the editor, you can add your WiFi ā€Žcredentials:ā€Ž

CIRCUITPY_WIFI_SSID = "your-ssid-here"

CIRCUITPY_WIFI_PASSWORD = "your-ssid-password-here"ā€Ž

Once your credentials are entered, click Save above the editor to ā€Žsave your changes to settings.toml.ā€Ž

once_141

Once everything is saved to the board, Restart the Serial Console to ā€Žsee the data printed out!ā€Ž

saved_142

How the CircuitPython WiFi Example Works

In the basic WiFi test, the board connects to your SSID by importing ā€Žyour SSID and SSID password from the settings.toml file.ā€Ž

Download File

Copy Code
wifi.radio.connect(os.getenv('CIRCUITPY_WIFI_SSID'), os.getenv('CIRCUITPY_WIFI_PASSWORD'))

Then, your MAC address and IP address are printed to the REPL.ā€Ž

Download File

Copy Code
#  prints MAC address to REPL
print("My MAC addr:", [hex(i) for i in wifi.radio.mac_address])

#  prints IP address to REPL
print("My IP address is", wifi.radio.ipv4_address)

ā€ŽFinally, google.com is pinged. The amount of time it takes to ping is ā€Žprinted to the REPL and the code stops running.ā€Ž

Download File

Copy Code
#  pings Google
ipv4 = ipaddress.ip_address("8.8.4.4")
print("Ping google.com: %f ms" % (wifi.radio.ping(ipv4)*1000))

By successfully running this WiFi test code, you can confirm that ā€Žyour board is connecting to WiFi with CircuitPython successfully and ā€Žyou can move on to more advanced projects.ā€Ž

Adafruit IO

Adafruit IO gives you the option to disconnect your microcontroller ā€Žfrom your computer and run it off of USB power or a battery, and still ā€Žbe able to see the data. It also allows you to send data to your ā€Žmicrocontroller, such as NeoPixel colors. This example shows how to ā€Žboth send data to and receive data from Adafruit IO. It pulls from a ā€Žā€Ž"random" number generator and sends the "random" ā€Žnumber to Adafruit IO, while simultaneously listening for NeoPixel ā€Žcolor data from Adafruit IO.ā€Ž

NeoPixel Location

neopixel_143

Adafruit IO Feeds and Dashboard

The first thing you'll need to do, is head over to Adafruit IO and make ā€Žsure your account is set up.ā€Ž

Then, you need to create two feeds called neopixel and random. ā€ŽThese are case sensitive!ā€Ž

Next, you'll create a dashboard for the NeoPixel Color Picker. You can ā€Žname the dashboard whatever you like.ā€Ž

Once the dashboard is created, you'll want to add a color picker ā€Žblock. The color picker block is highlighted by a red arrow in the ā€Žimage below.ā€Ž

create_144

Once you choose the color picker block, you'll need to connect a feed ā€Žto it. Check the box next to neopixel.ā€Ž

check_145

Finally, a Block Settings page will come up. You can add an optional ā€Žblock title here. Then you press Create Block.

block_146

The dashboard should look something like the following.ā€Ž

dashboard_147

Now that things are set up on the Adafruit IO end, you can continue ā€Žon to the code on your microcontroller!ā€Ž

Adafruit IO settings.toml

This example requires you to provide your Wi-Fi credentials, and ā€Žyour Adafruit IO username and key. To do this, you'll want to create ā€Ža settings.toml file on your CIRCUITPY drive.ā€Ž

To obtain your Adafruit IO key, follow the initial steps on this page.ā€Ž

Your settings.toml file should be structured in a certain way and ā€Žcontain all the necessary information. Follow these instructions ā€Žto create your settings.toml file.ā€Ž

Adafruit IO Example Code

To run this example, you need to first install the NeoPixel, Adafruit IO, ā€Žand Adafruit MiniMQTT libraries into the lib folder on your board. ā€ŽThen you need to update code.py with the example script.ā€Ž

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. You'll see a code.py file ā€Žand /lib folder.ā€Ž

Download Project Bundle

Copy Code
# SPDX-FileCopyrightText: 2021 Ladyada for Adafruit Industries
# SPDX-FileCopyrightText: 2022 Kattni Rembor for Adafruit Industries
# SPDX-License-Identifier: MIT
import time
import ssl
import os
from random import randint
import microcontroller
import socketpool
import wifi
import board
import neopixel
import adafruit_minimqtt.adafruit_minimqtt as MQTT
from adafruit_io.adafruit_io import IO_MQTT


# WiFi
try:
    print("Connecting to %s" % os.getenv("CIRCUITPY_WIFI_SSID"))
    wifi.radio.connect(os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD"))
    print("Connected to %s!" % os.getenv("CIRCUITPY_WIFI_SSID"))
# Wi-Fi connectivity fails with error messages, not specific errors, so this except is broad.
except Exception as e:  # pylint: disable=broad-except
    print("Failed to connect to WiFi. Error:", e, "\nBoard will hard reset in 30 seconds.")
    time.sleep(30)
    microcontroller.reset()

# Initialise NeoPixel
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.3)


# Define callback functions which will be called when certain events happen.
def connected(client):
    print("Connected to Adafruit IO!  Listening for NeoPixel changes...")
    # Subscribe to Adafruit IO feed called "neopixel"
    client.subscribe("neopixel")


def message(client, feed_id, payload):  # pylint: disable=unused-argument
    print("Feed {0} received new value: {1}".format(feed_id, payload))
    if feed_id == "neopixel":
        pixel.fill(int(payload[1:], 16))


# Create a socket pool
pool = socketpool.SocketPool(wifi.radio)

# Initialize a new MQTT Client object
mqtt_client = MQTT.MQTT(
    broker="io.adafruit.com",
    username=os.getenv("ADAFRUIT_AIO_USERNAME"),
    password=os.getenv("ADAFRUIT_AIO_KEY"),
    socket_pool=pool,
    ssl_context=ssl.create_default_context(),
)

# Initialize Adafruit IO MQTT "helper"
io = IO_MQTT(mqtt_client)

# Set up the callback methods above
io.on_connect = connected
io.on_message = message

timestamp = 0
while True:
    try:
        # If Adafruit IO is not connected...
        if not io.is_connected:
            # Connect the client to the MQTT broker.
            print("Connecting to Adafruit IO...")
            io.connect()

        # Explicitly pump the message loop.
        io.loop()
        # Obtain the "random" value, print it and publish it to Adafruit IO every 10 seconds.
        if (time.monotonic() - timestamp) >= 10:
            random_number = "{}".format(randint(0, 255))
            print("Current 'random' number: {}".format(random_number))
            io.publish("random", random_number)
            timestamp = time.monotonic()

    # Adafruit IO fails with internal error types and WiFi fails with specific messages.
    # This except is broad to handle any possible failure.
    except Exception as e:  # pylint: disable=broad-except
        print("Failed to get or send data, or connect. Error:", e,
              "\nBoard will hard reset in 30 seconds.")
        time.sleep(30)
        microcontroller.reset()

View on GitHub

Update the /lib Folder

In the editor window in your browser, click the Open button to view ā€Žthe file dialog. Then, click the Upload button and select Upload ā€ŽFolders.ā€Ž

click_148

Navigate to the project bundle that you downloaded and select ā€Žthe /lib folder.ā€Ž

bundle_149

You'll be asked if you want to upload the /lib folder from the Project ā€ŽBundle. Click Upload.ā€Ž

want_150

After the upload finishes, you can open the lib folder to view the ā€Žlibrary files required for the Adafruit IO example.ā€Ž

after_151

Update code.py

In the editor window in your browser, click the Open button to view ā€Žthe file dialog. Then, click the Upload button and select Upload Files.ā€Ž

editor_152

Navigate to the project bundle that you downloaded and select ā€Žthe code.py file.ā€Ž

editor_153

You'll be asked if you want to overwrite the previous code.py with ā€Žthe new code.py file from the Project Bundle. Click OK.ā€Ž

overwrite_154

Update Your settings.toml File

Remember to add your settings.toml file as described earlier in this ā€Žpage. You'll need to include, ā€Žyour ADAFRUIT_AIO_USERNAME, ADAFRUIT_AIO_KEY, CIRCUITPY_WIFI_SSID and CIRCUITPY_WIFI_PASSWORD in the file.ā€Ž

You can edit the file manually in the USB code editor by ā€Žclicking Open, selecting settings.toml and clicking Open at the ā€Žbottom of the dialog box.ā€Ž

bottom_155

With settings.toml open in the editor, you can add your WiFi and ā€ŽAdafruit IO credentials:ā€Ž

CIRCUITPY_WIFI_SSID = "your-ssid-here"

CIRCUITPY_WIFI_PASSWORD = "your-ssid-password-here"

ADAFRUIT_AIO_USERNAME = "your-aio-username-here"

ADAFRUIT_AIO_KEY = "your-aio-key-here"ā€Ž

Once your credentials are entered, click Save above the editor to ā€Žsave your changes to settings.toml.ā€Ž

Once everything is saved to the board, Restart the Serial Console to ā€Žrun the new code.py. You'll see the connection info and current ā€Žreadings printed out in the console.ā€Ž

restart_156

NeoPixel Color Change

To change the color of the NeoPixel, go to the NeoPixel Adafruit IO ā€Ždashboard you created at the beginning, and click on the colored ā€Žcircle in the ColorPicker block. It will bring up the following.ā€Ž

color_157

You can move the dot in the box around, and the slider line across ā€Žthe gradient to choose the perfect color. Choose a new color and ā€Žclick SAVE.ā€Ž

The NeoPixel color will update, and you will see the new value ā€Žprinted to the serial console, as shown below.ā€Ž

update_158

Code Walkthrough

This example contains three try/except blocks. These are included ā€Žwhere the code is likely to fail due to WiFi or Adafruit IO connection ā€Žfailures. WiFi can be finicky, and without these code blocks, if the ā€Žconnection was lost, the code would crash. Instead, it is designed to ā€Žreset the board and start the code over again to reestablish the ā€Žconnection, regardless of the cause. This ensures your code will ā€Žcontinue running. The details of these blocks are explained below.ā€Ž

First you import all of the necessary modules and libraries.ā€Ž

Download File

Copy Code
import time
import ssl
import os
from random import randint
import socketpool
import wifi
import board
import neopixel
import adafruit_minimqtt.adafruit_minimqtt as MQTT
from adafruit_io.adafruit_io import IO_MQTT

Note that if a settings.toml file is not present on your CIRCUITPY ā€Ždrive, the code will fail to run, and you will receive an error in the ā€Žserial console. Add a settings.toml file to your CIRCUITPY drive to ā€Žresolve this error.ā€Ž

The WiFi attempts to connect and prints the status to the serial ā€Žconsole. If it connects successfully, the code continues onto the ā€ŽNeoPixel set up.ā€Ž

Download File

Copy Code
try:
    print("Connecting to %s" % os.getenv("CIRCUITPY_WIFI_SSID"))
    wifi.radio.connect(os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD"))
    print("Connected to %s!" % os.getenv("CIRCUITPY_WIFI_SSID"))

If the WiFi connection is not successful, the error will be printed to ā€Žthe serial console, and the board will hard reset after 30 seconds.ā€Ž

Download File

Copy Code
except Exception as e:  # pylint: disable=broad-except
    print("Failed to connect to WiFi. Error:", e, "\nBoard will hard reset in 30 seconds.")
    time.sleep(30)
    microcontroller.reset()

Once the WiFi successfully connects, the NeoPixel object is initiated.ā€Ž

Download File

Copy Code
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.3)

Following that are two callback methods. For more details, check ā€Žout this guide. The connected method subscribes to the NeoPixel ā€Žfeed on Adafruit IO. The message callback checks for updates to the ā€ŽNeoPixel feed and turns the pixel the color from the feed.ā€Ž

Download File

Copy Code
def connected(client):
    print("Connected to Adafruit IO!  Listening for NeoPixel changes...")
    # Subscribe to Adafruit IO feed called "neopixel"
    client.subscribe("neopixel")


# pylint: disable=unused-argument
def message(client, feed_id, payload):
    print("Feed {0} received new value: {1}".format(feed_id, payload))
    if feed_id == "neopixel":
        pixel.fill(int(payload[1:], 16))

ā€ŽYou create a socket pool, use that to initialise the new MQTT Client ā€Žobject, and use that to initialise the Adafruit IO MQTT "helper".ā€Ž

Download File

Copy Code
pool = socketpool.SocketPool(wifi.radio)

mqtt_client = MQTT.MQTT(
    broker="io.adafruit.com",
    username=os.getenv("ADAFRUIT_AIO_USERNAME"),
    password=os.getenv("ADAFRUIT_AIO_KEY"),
    socket_pool=pool,
    ssl_context=ssl.create_default_context(),
)

io = IO_MQTT(mqtt_client)

You set up the callback methods mentioned above.ā€Ž

Download File

Copy Code
io.on_connect = connected
io.on_message = message

Next, you attempt to connect the client to the MQTT broker. If ā€Žconnection is successful, the code continues on to the timestamp.ā€Ž

Download File

Copy Code
try:
    io.connect()

If the MQTT broker connection is not successful, the error is printed ā€Žto the serial console, and the board will hard reset after 30 seconds.ā€Ž

Download File

Copy Code
except Exception as e:
    print("Failed to connect to Adafruit IO. Error:", e, "\nBoard will hard reset in 30 seconds.")
    time.sleep(30)
    microcontroller.reset()

Once the broker is connected, you set ā€Žthe timestamp to 0 immediately before the loop.ā€Ž

Download File

Copy Code
timestamp = 0

Inside the loop, you attempt to do two things. You first explicitly poll ā€Žthe message loop. Check out this guide for more details on that.ā€Ž

Download File

Copy Code
while True:
    try:
        io.loop()

Second, you have a block of code that runs every 10 seconds. Inside, ā€Žyou obtain a "random" value between 0-255 inclusive, print it to the ā€Žserial console, and publish it to an Adafruit IO feed. Finally, you reset ā€Žtimestamp, so the block of code knows when another 10 seconds ā€Žhas passed and runs again.ā€Ž

Download File

Copy Code
[...]
        if (time.monotonic() - timestamp) >= 10:
            random_number = "{}".format(randint(0, 255))
            print("Current 'random' number: {}".format(random_number))
            io.publish("random", random_number)
            timestamp = time.monotonic()

ā€ŽIf at any time WiFi or Adafruit IO disconnects, the code will print the ā€Žerror to the serial console, and the board will hard reset after 30 ā€Žseconds.ā€Ž

Download File

Copy Code
[...]
    except Exception as e:
        print("Failed to get or send data, or connect. Error:", e,
              "\nBoard will hard reset in 30 seconds.")
        time.sleep(30)
        microcontroller.reset()

That's all there is to using CircuitPython and Adafruit IO to send data ā€Žto Adafruit IO and receive data from it!ā€Ž

Arduino IDE Setup

On macOS, you need to use this board with a hub and USB A to USB ā€ŽC cable to upload any software. If you plug the board directly into a ā€ŽUSB C port on your Mac, it will assume it needs power delivery (PD) ā€Žand the USB to Serial port will not work.ā€Ž

We primarily recommend using the ESP32 chipsets with Arduino. ā€ŽDon't forget you will also need to install the SiLabs CP2104 Driver if ā€Žyou are using an ESP32 board with USB-to-Serial converter! ā€Žā€Ž(There's no harm in doing it, so we recommend even if you aren't.)ā€Ž

Install Arduino IDE

The first thing you will need to do is to download the latest release of ā€Žthe Arduino IDE. You will need to be using version 1.8 or higher for ā€Žthis guide.ā€Ž

Arduino IDE Download

Install CP2104 / CP2102N USB Driver

Many ESP32 boards have a USB-to-Serial converter that talks to the ā€Žchip itself and will need a driver on your computer's operating ā€Žsystem. The driver is available for Mac and Windows. It is already ā€Žbuilt into Linux.ā€Ž

Click here to download the CP2104 USB Driver

Install CH9102 / CH34X USB Driver

Newer ESP32 boards have a different USB-to-serial converter that ā€Žtalks to the chip itself and will need a driver on your computer's ā€Žoperating system. The driver is available for Mac and Windows. It is ā€Žalready built into Linux.ā€Ž

If you would like more detail, check out the guide on installing these ā€Ždrivers.ā€Ž

Click here to download the Windows driver

Click here to download the Mac driver

Install ESP32 Board Support Package from GitHub

For this board, we recommend you don't use 'release' version of ā€ŽEspressif's board support package because the current release ā€Ždoesn't include board support.ā€Ž

Instead, we will install the "very latest" by following these ā€Žinstructions (scroll down for mac and Linux as well.ā€Ž

Basically, install by git cloneing the Espressif ESP32 board support to ā€Žget the very latest version of the code.ā€Ž

In the Tools → Board submenu you should see ESP32 Arduino (in ā€Žsketchbook) and in that dropdown it should contain the ESP32 ā€Žboards along with all the latest ESP32 boards.ā€Ž

tools_159

Look for the board called Adafruit Sparkle Motion (ESP32).ā€Ž

look_160

The upload speed can be changed: faster speed makes uploads take ā€Žless time but sometimes can cause upload issues. 921600 should ā€Žwork fine, but if you're having issues, you can drop down lower.ā€Ž

Blink

The first and most basic program you can upload to your Arduino is ā€Žthe classic Blink sketch. This takes something on the board and ā€Žmakes it, well, blink! On and off. It's a great way to make sure ā€Ževerything is working and you're uploading your sketch to the right ā€Žboard and right configuration.ā€Ž

When all else fails, you can always come back to Blink!ā€Ž

On macOS, you need to use this board with a hub and USB A to USB ā€ŽC cable to upload any software. If you plug the board directly into a ā€ŽUSB C port on your Mac, it will assume it needs power delivery (PD) ā€Žand the USB to Serial port will not work.ā€Ž

adafruit_products_sparkle_blink_scaled

Pre-Flight Check: Get Arduino IDE & Hardware Set Up

This lesson assumes you have Arduino IDE set up. This is a ā€Žgeneralized checklist; some elements may not apply to your ā€Žhardware. If you haven't yet, check the previous steps in the guide to ā€Žmake sure you:ā€Ž

  • Install the very latest Arduino IDE for Desktop (not all boards ā€Žare supported by the Web IDE, so we don't recommend it)ā€Ž

  • Install any board support packages (BSP) required for your ā€Žhardware. Some boards are built in defaults on the IDE, but lots ā€Žare not! You may need to install plug-in support which is called ā€Žthe BSP.ā€Ž

  • Get a Data/Sync USB cable for connecting your ā€Žhardware. A significant amount of problems folks have stem ā€Žfrom not having a USB cable with data pins. Yes, these cursed ā€Žcables roam the land, making your life hard. If you find a USB ā€Žcable that doesn't work for data/sync, throw it away ā€Žimmediately! There is no need to keep it around, cables are ā€Žvery inexpensive these days.ā€Ž

  • Install any drivers required - If you have a board with a FTDI or ā€ŽCP210x chip, you may need to get separate drivers. If your ā€Žboard has native USB, it probably doesn't need anything. After ā€Žinstalling, reboot to make sure the driver sinks in.ā€Ž

  • Connect the board to your computer. If your board has a ā€Žpower LED, make sure its lit. Is there a power switch? Make ā€Žsure it’s turned On!ā€Ž

Startup Arduino IDE and Select Board/Port

OK now you are prepared! Open the Arduino IDE on your computer. ā€ŽNow you have to tell the IDE what board you are using, and how you ā€Žwant to connect to it.ā€Ž

In the IDE find the Tools menu. You will use this to select the board. ā€ŽIf you switch boards, you must switch the selection! So always ā€Ždouble-check before you upload code in a new session.ā€Ž

startup_161

New Blink Sketch

OK let’s make a new blink sketch! From the File menu, select New.ā€Ž

blink_162

Then in the new window, copy and paste this text:ā€Ž

Download File

Copy Code
int led = LED_BUILTIN;

void setup() {
  // Some boards work best if we also make a serial connection
  Serial.begin(115200);

  // set LED to be an output pin
  pinMode(led, OUTPUT);
}

void loop() {
  // Say hi!
  Serial.println("Hello!");
  
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(500);                // wait for a half second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(500);                // wait for a half second
}

Note that in this example, we are not only blinking the LED but also ā€Žprinting to the Serial monitor, think of it as a little bonus to test the ā€Žserial connection.ā€Ž

One note you'll see is that we reference the LED with the ā€Žconstant LED_BUILTIN rather than a number. That's because, ā€Žhistorically, the built in LED was on pin 13 for Arduinos. But in the ā€Ždecades since, boards don't always have a pin 13, or maybe it could ā€Žnot be used for an LED. So, the LED could have moved to another ā€Žpin. It's best to use LED_BUILTIN so you don't get the pin number ā€Žconfused!ā€Ž

Verify (Compile) Sketch

OK now you can click the Verify button to convert the sketch into ā€Žbinary data to be uploaded to the board.ā€Ž

Note that verifying a sketch is the same as Compiling a sketch - so ā€Žwe will use the words interchangeably.ā€Ž

note_163

During verification/compilation, the computer will do a bunch of ā€Žwork to collect all the libraries and code, and the results will appear ā€Žin the bottom window of the IDE.ā€Ž

during_164

If something went wrong with compilation, you would get red ā€Žwarning/error text in the bottom window letting you know what the ā€Žerror was. It will also highlight the line with an error.

For example, here I had the wrong board selected - and the selected ā€Žboard does not have a built in LED!ā€Ž

example_165

Here's another common error, in my haste I forgot to add a ; at the ā€Žend of a line. The compiler warns me that it's looking for one - note ā€Žthat the error is actually a few lines up!ā€Ž

common_166

Turning on detailed compilation warnings and output can be very ā€Žhelpful sometimes - It’s in Preferences under "Show Verbose Output During:" and check the Compilation button. If you ever need ā€Žto get help from others, be sure to do this and then provide all the ā€Žtext that is output. It can assist in nailing down what happened!ā€Ž

On success you will see something like this white text output and ā€Žthe message Done compiling. in the message area.ā€Ž

success_167

Upload Sketch

Once the code is verified/compiling cleanly you can upload it to your ā€Žboard. Click the Upload button.ā€Ž

verified_168

The IDE will try to compile the sketch again for good measure, then ā€Žit will try to connect to the board and upload the file.ā€Ž

This is actually one of the hardest parts for beginners because it's ā€Žwhere a lot of things can go wrong.ā€Ž

However, let’s start with what it looks like on success! Here's what ā€Žyour board upload process looks like when it goes right:ā€Ž

start_169

Often times you will get a warning like this, which is kind of vague:ā€Ž

No device found on COM66 (or whatever port is selected)

An error occurred while uploading the sketch

error_170

This could be a few things.ā€Ž

First up, check again that you have the correct board ā€Žselected! Many electronics boards have very similar names or look, ā€Žand often times folks grab a board different from what they thought.ā€Ž

Second, make sure you selected the right port! If you have the ā€Žwrong port or no port selected, Arduino doesn't know where to look ā€Žfor your board.ā€Ž

If both of those are correct, the next step is to enable verbose upload ā€Žmessages.ā€Ž

Before continuing we really really suggest turning on Verbose ā€ŽUpload messages, it will help in this process because you will be ā€Žable to see what the IDE is trying to do. It's a checkbox in ā€Žthe Preferences menu.ā€Ž

menu_171

Now you can try uploading again!ā€Ž

try_172

This time, you should have success!ā€Ž

After uploading this way, be sure to click the reset button - it sort of ā€Žmakes sure that the board got a good reset and will come back to ā€Žlife nicely.ā€Ž

Finally, a Blink!ā€Ž

OK it was a journey but now we're here and you can enjoy your ā€Žblinking LED. Next up, try to change the delay between blinks and ā€Žre-upload. It's a good way to make sure your upload process is ā€Žsmooth and practiced.ā€Ž

adafruit_products_sparkle_blink_scaled

Built-In NeoPixel

Your board has a built-in RGB NeoPixel status LED. You can use ā€ŽArduino code to control the color and brightness of this LED. It is also ā€Žused to indicate the bootloader status.ā€Ž

A NeoPixel is what Adafruit calls the WS281x family of addressable ā€ŽRGB LEDs. It contains three LEDs - a red one, a green one and a blue ā€Žone - alongside a driver chip in a tiny package controlled by a single ā€Žpin. They can be used individually (as in the built-in LED on your ā€Žboard) or chained together in strips or other creative form factors. ā€ŽNeoPixels do not light up on their own; they require a ā€Žmicrocontroller. So, it's super convenient that the NeoPixel is built ā€Žinto your microcontroller board!ā€Ž

This page will cover using Arduino to control the status RGB ā€ŽNeoPixel built into your microcontroller. Time to get started!ā€Ž

NeoPixel Location

location_173

Arduino Library Installation

You can install the necessary libraries from the Library Manager. To ā€Žopen, click Sketch > Include Library > Manage Libraries...ā€Ž

install_174

Search for NeoPixel and install the Adafruit NeoPixel library.ā€Ž

search_175

There are no additional library dependencies for the Adafruit ā€ŽNeoPixel library.ā€Ž

Rainbow Swirl Demo

Download File

Copy Code
// SPDX-FileCopyrightText: 2024 ladyada for Adafruit Industries
//
// SPDX-License-Identifier: MIT

#include <Adafruit_NeoPixel.h>

#define NUMPIXELS 1
Adafruit_NeoPixel pixel(NUMPIXELS, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800);

void setup() {
  Serial.begin(115200);

  pixel.begin();
  pixel.setBrightness(25);
  pixel.show();

}

uint16_t firstPixelHue = 0;

void loop() {  
  firstPixelHue += 256;
  for(int i=0; i<pixel.numPixels(); i++) {
      int pixelHue = firstPixelHue + (i * 65536L / pixel.numPixels());
      pixel.setPixelColor(i, pixel.gamma32(pixel.ColorHSV(pixelHue)));
    }
  pixel.show();
  
  delay(10);

}

Upload the sketch to your board. You'll see the onboard NeoPixel run ā€Žthrough a looping rainbow animation.ā€Ž

Arduino Sparkle Motion Demo

adafruit_products_sparkle_neopixel_anim_scaled

The main use of the Sparkle Motion is lighting up RGB LEDs to ā€Ždazzle and delight. Using the Sparkle Motion with Arduino involves ā€Žinstalling the Adafruit_NeoPixel library and running the provided ā€Žexample code. In the example below, you'll attach two NeoPixel ā€Žstrips to the Sparkle Motion Mini and see how you can write code to ā€Žrun two different LED animations on two strips of NeoPixels at the ā€Žsame time.ā€Ž

Wiring

NeoPixels

  • terminal block - to GND on both NeoPixel strips. (black wire)ā€Ž

  • terminal block + to 5V on both NeoPixel strips. (red wire)ā€Ž

  • terminal block 21 to DIN on the first NeoPixel strip. (green wire)ā€Ž

  • terminal block 22 to DIN on the second NeoPixel strip. (green ā€Žwire)ā€Ž

wiring_176

Library Installation

You can install the Adafruit NeoPixel library for Arduino using the ā€ŽLibrary Manager in the Arduino IDE.ā€Ž

manager_177

Click the Manage Libraries ... menu item, search for Adafruit ā€ŽNeoPixel and select the Adafruit NeoPixel library:ā€Ž

item_178

No additional dependencies are required for the NeoPixel library.ā€Ž

Example Code

Download File

Copy Code
// SPDX-FileCopyrightText: 2025 Liz Clark for Adafruit Industries
//
// SPDX-License-Identifier: MIT

#include <Adafruit_NeoPixel.h>

#define BLOCK_1 21
#define BLOCK_2 22
#define NUM_PIXELS 8

Adafruit_NeoPixel STRIP_1(NUM_PIXELS, BLOCK_1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel STRIP_2(NUM_PIXELS, BLOCK_2, NEO_GRB + NEO_KHZ800);

void setup() {
  STRIP_1.begin();
  STRIP_2.begin();
  STRIP_1.setBrightness(25);
  STRIP_2.setBrightness(50);
}

uint16_t pixelHue_1 = 0;
uint16_t pixelHue_2 = 256;

void loop() {  
  pixelHue_1 += 256;
  for(int i=0; i<STRIP_1.numPixels(); i++) {
      int hue_1 = pixelHue_1 + (i * 65536L / STRIP_1.numPixels());
      STRIP_1.setPixelColor(i, STRIP_1.gamma32(STRIP_1.ColorHSV(hue_1)));
    }
  STRIP_1.show();

  pixelHue_2 -= 256;
  for(int i=STRIP_2.numPixels(); i>-1; i--) {
      int hue_2 = pixelHue_2 + (i * 65536L / STRIP_2.numPixels());
      STRIP_2.setPixelColor(i, STRIP_2.gamma32(STRIP_2.ColorHSV(hue_2)));
    }
  STRIP_2.show();
  
  delay(10);

}

View on GitHub

Upload the example code to the Sparkle Motion. You'll see both ā€Žstrips cycle through the rainbow swirl, but in a different order on ā€Žeach strip.ā€Ž

adafruit_products_sparkle_circuitpython_neopixel_animat

Arduino IR Remote

adafruit_products_sparkle_ir_remote_scaled

The Adafruit Sparkle Motion has an IR Receiver built-in for all of your ā€Žremote controlling needs. The IRremote library makes it easy to ā€Ždecode the signals sent to the receiver. This example will get you ā€Žstarted by demonstrating how to use one of our mini remote ā€Žcontrols to change the color and brightness of a connected strip of ā€ŽNeoPixels.ā€Ž

IR Receiver & NeoPixel Output Location

ir_179

The IR Receiver is connected to pin 32. This example assumes the ā€ŽNeoPixel strip will be plugged in to the terminal blocks for pin 21.ā€Ž

Necessary Hardware

You'll need an IR remote that uses one of the protocols supported by ā€Žthe IRremote library, and any strip of NeoPixels. The following items ā€Žare the ones depicted on this page.ā€Ž

Wiring

NeoPixels

  • terminal block - to GND on the NeoPixel strip. (black wire)ā€Ž

  • terminal block + to 5V on the NeoPixel strip. (red wire)ā€Ž

  • terminal block 21 to DIN on the NeoPixel strip. (green wire)ā€Ž

wiring_180

Library Installation

You can install the Adafruit NeoPixel, and IRremote libraries for ā€ŽArduino using the Library Manager in the Arduino IDE.ā€Ž

ide_181

Click the Manage Libraries ... menu item, search for Adafruit ā€ŽNeoPixel and click the Install button on the Adafruit NeoPixel result:ā€Ž

click_182

Next, search for IRremote and click the install button on ā€Žthe IRremote result:ā€Ž

next_183

No additional dependencies are required for the NeoPixel or ā€ŽIRremote libraries.ā€Ž

Example Code

Download File

Copy Code
// SPDX-FileCopyrightText: 2024 Liz Clark for Adafruit Industries
// SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries
//
// SPDX-License-Identifier: MIT

/*
 * Based on the SimpleReceiver.cpp and SimpleSender.cpp from the
 * Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
 * by Armin Joachimsmeyer
 ************************************************************************************
 * MIT License
 *
 * Copyright (c) 2020-2023 Armin Joachimsmeyer
 *
 */

#include <Arduino.h>

#include <IRremote.hpp> // include the library
#include <Adafruit_NeoPixel.h>

#define NEOPIXEL_STRIP_PIN 21
#define NUM_PIXELS 8

#define IR_RECEIVE_PIN   32

Adafruit_NeoPixel NEOPIXEL_STRIP(NUM_PIXELS, NEOPIXEL_STRIP_PIN, NEO_GRB + NEO_KHZ800);

uint8_t upCmd = 0x5;
uint8_t downCmd = 0xD;
uint8_t rightCmd = 0xA;
uint8_t leftCmd = 0x8;

uint16_t pixelHue = 0;
uint8_t brightness = 25;

void setup() {
    Serial.begin(115200);
    while (!Serial)
        ;
    Serial.println("Adafruit Sparkle Motion IR Remote Control NeoPixels Demo");
    IrReceiver.begin(IR_RECEIVE_PIN);
    Serial.print("IRin on pin ");
    Serial.print(IR_RECEIVE_PIN);
    NEOPIXEL_STRIP.begin();
    NEOPIXEL_STRIP.setBrightness(25);
}

void loop() {
    /*
     * Check if received data is available and if yes, try to decode it.
     * When left or right buttons are pressed, change the pixelHue.
     * When up or down buttons are pressed, change the brightness.
     */
    if (IrReceiver.decode()) {
        if (IrReceiver.decodedIRData.protocol == UNKNOWN) {
            Serial.println("unknown");
            IrReceiver.printIRResultRawFormatted(&Serial, true);
            IrReceiver.resume();
        } else {
            IrReceiver.resume();
            //IrReceiver.printIRResultShort(&Serial);

            // Ignore repeat codes from holding down the button
            if (IrReceiver.decodedIRData.flags == 0){
              //Serial.printf("Command: %d\n",IrReceiver.decodedIRData.command);
              if (IrReceiver.decodedIRData.command == upCmd){
                Serial.println("UP btn");
                brightness = min(brightness + 25, 255);
              }else if (IrReceiver.decodedIRData.command == downCmd){
                Serial.println("DOWN btn");
                brightness = max(brightness - 25, 0);
              }else if (IrReceiver.decodedIRData.command == leftCmd){
                Serial.println("LEFT btn");
                pixelHue = (pixelHue - 8192) % 65536;
              }else if (IrReceiver.decodedIRData.command == rightCmd){
                Serial.println("RIGHT btn");
                pixelHue = (pixelHue + 8192) % 65536;
              }

              NEOPIXEL_STRIP.setBrightness(brightness);
              NEOPIXEL_STRIP.fill(NEOPIXEL_STRIP.gamma32(NEOPIXEL_STRIP.ColorHSV(pixelHue)));
              NEOPIXEL_STRIP.show();
              delay(100);
            }
        }
        Serial.println();
    }
}

View on GitHub

Once the code is running, press the up and down arrow keys on the ā€Žremote to increase and decrease the brightness. Press the left and ā€Žright arrow keys to cycle through the available colors forward or ā€Žbackward.ā€Ž

adafruit_products_sparkle_ir_remote_scaled

I2C

A lot of sensors, displays, and devices can connect over I2C. I2C is a 2-ā€Žwire 'bus' that allows multiple devices to all connect on one set of ā€Žpins so it's very convenient for wiring!ā€Ž

When using your board, you'll probably want to connect up I2C ā€Ždevices, and it can be a little tricky the first time. The best way to ā€Ždebug I2C is go through a checklist and then perform an I2C scan.

Common I2C Connectivity Issues

  • Have you connected four wires (at a minimum) for each I2C ā€Ždevice? Power the device with whatever is the logic level of ā€Žyour microcontroller board (probably 3.3V), then a ground wire, ā€Žand a SCL clock wire, and a SDA data wire.ā€Ž

  • If you're using a STEMMA QT board - check if the power LED ā€Žis lit. It's usually a green LED to the left side of the board.ā€Ž

  • Does the STEMMA QT/I2C port have switchable power or ā€Žpullups? To reduce power, some boards have the ability to cut ā€Žpower to I2C devices or the pullup resistors. Check the ā€Ždocumentation if you have to do something special to turn on ā€Žthe power or pullups.ā€Ž

  • If you are using a DIY I2C device, do you have pullup ā€Žresistors? Many boards do not have pullup resistors built in ā€Žand they are required! We suggest any common 2.2K to 10K ā€Žresistors. You'll need two: one each connects from SDA to ā€Žpositive power, and SCL to positive power. Again, positive ā€Žpower (a.k.a VCC, VDD or V+) is often 3.3V.

  • Do you have an address collision? You can only ā€Žhave one board per address. So, you cannot, say, connect two ā€ŽAHT20's to one I2C port because they have the same address ā€Žand will interfere. Check the sensor or documentation for the ā€Žaddress. Sometimes there are ways to adjust the address.ā€Ž

  • Does your board have multiple I2C ports? Historically, boards ā€Žonly came with one. But nowadays you can have two or even ā€Žthree! This can help solve the "hey, but what if I want two ā€Ždevices with the same address" problem: just put one on each ā€Žbus.ā€Ž

  • Are you hot-plugging devices? I2C does not support dynamic ā€Žre-connection, you cannot connect and disconnect sensors as ā€Žyou please. They should all be connected on boot and not ā€Žchange. (Only exception is if you're using a hot-plug assistant ā€Žbut that'll cost you).ā€Ž

  • Are you keeping the total bus length reasonable? I2C was ā€Ždesigned for maybe 6" max length. We like to push that with ā€Žplug-n-play cables, but really please keep them as short as ā€Žpossible! (Only exception is if you're using an active bus ā€Žextender).ā€Ž

Built-in I2C Device

The Adafruit Sparkle Motion has one built-in device connected to the ā€ŽI2C bus, a HUSB238 power delivery chip using address 0x8.ā€Ž

Perform an I2C scan!ā€Ž

Install TestBed Library

To scan I2C, the Adafruit TestBed library is used. This library and ā€Žexample just make the scan a little easier to run because it takes ā€Žcare of some of the basics. You will need to add support by installing ā€Žthe library. Good news: it is very easy to do it. Go to the Arduino ā€ŽLibrary Manager.ā€Ž

perform_184

Search for TestBed and install the Adafruit TestBed library.ā€Ž

testbed_185

Now open up the I2C Scan example

scan_186

Download File

Copy Code
// SPDX-FileCopyrightText: 2023 Carter Nelson for Adafruit Industries
//
// SPDX-License-Identifier: MIT
// --------------------------------------
// i2c_scanner
//
// Modified from https://playground.arduino.cc/Main/I2cScanner/
// --------------------------------------

#include <Wire.h>

// Set I2C bus to use: Wire, Wire1, etc.
#define WIRE Wire

void setup() {
  WIRE.begin();

  Serial.begin(9600);
  while (!Serial)
     delay(10);
  Serial.println("\nI2C Scanner");
}


void loop() {
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    WIRE.beginTransmission(address);
    error = WIRE.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknown error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);           // wait 5 seconds for next scan
}

View on GitHub

Wire up I2C device

While the examples here will be using the Adafruit MCP9808, a high ā€Žaccuracy temperature sensor, the overall process is the same for just ā€Žabout any I2C sensor or device.ā€Ž

The first thing you'll want to do is get the sensor connected so your ā€Žboard has I2C to talk to.ā€Ž

Wiring the MCP9808ā€Ž

The MCP9808 comes with a STEMMA QT connector, which makes ā€Žwiring it up quite simple and solder-free.ā€Ž

Connect the STEMMA QT cable from the STEMMA QT port on the ā€ŽSparkle Motion to the STEMMA QT port on the MCP9808.ā€Ž

wiring_187

Now upload the scanning sketch to your microcontroller and open ā€Žthe serial port to see the output. You should see something like this:ā€Ž

sketch_188

I2S Mic

mic_189

You can use the onboard I2S microphone with the built-in I2S library ā€Žin the espressif board support package. The I2S microphone is ā€Žconnected to the following pins on the Sparkle Motion:ā€Ž

  • BCLK: 26ā€Ž

  • WS: 33ā€Ž

  • DATA_IN: 25ā€Ž

The example below will plot samples from the mic to the plotter ā€Žinside the Arduino IDE.ā€Ž

No additional libraries need to be installed for this example - the I2S ā€Žlibrary is included in the Espressif board support package.ā€Ž

Example Code

Download File

Copy Code
// SPDX-FileCopyrightText: 2025 Limor Fried for Adafruit Industries
//
// SPDX-License-Identifier: MIT

#include <Arduino.h>
#include "ESP_I2S.h"

// I2S pin definitions for Sparklemotion
const uint8_t I2S_SCK = 26;  // BCLK
const uint8_t I2S_WS = 33;   // LRCLK
const uint8_t I2S_DIN = 25;  // DATA_IN

// Create I2S instance
I2SClass i2s;

void setup() {
  // Fast serial for plotting
  Serial.begin(500000);
  
  // Initialize I2S
  i2s.setPins(I2S_SCK, I2S_WS, -1, I2S_DIN);
  if (!i2s.begin(I2S_MODE_STD, 44100, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO, I2S_STD_SLOT_LEFT)) {
    Serial.println("Failed to initialize I2S bus!");
    return;
  }

  Serial.println("I2S Mic Plotter Ready");
}

void loop() {
  static uint32_t lastPlot = 0;
  
  // Get a sample
  int32_t sample = i2s.read();
  
  // Only plot every 1ms (1000 samples/sec is plenty for visualization)
  if (millis() - lastPlot >= 1) {
    if (sample >= 0) {  // Valid sample
      // Plot both raw and absolute values
      Serial.printf("%d,%d\n", (int16_t)sample, abs((int16_t)sample));
    }
    lastPlot = millis();
  }
}

View on GitHub

Upload the sketch to your board and open up the Serial Plotter ā€Žā€Ž(Tools -> Serial Plotter) at 500000 baud. You'll see the raw samples ā€Žand average samples from the I2S microphone plotted over time.ā€Ž

upload_190

WiFi Test

Thankfully if you have ESP32 sketches, they'll 'just work' with ā€Žvariations of ESP32. You can find a wide range of examples in ā€Žthe File->Examples->Examples for Adafruit Metro ESP32-ā€ŽS2 subheading (the name of the board may vary so it could ā€Žbe "Examples for Adafruit Feather ESP32 V2" etc.)ā€Ž

test_191

Let's start by scanning the local networks.ā€Ž

Load up the WiFiScan example under Examples->Examples for ā€ŽYOUR BOARDNAME->WiFi->WiFiScanā€Ž.

load_192

And upload this example to your board. The ESP32 should scan and ā€Žfind WiFi networks around you.ā€Ž

For ESP32, open the serial monitor, to see the scan begin.ā€Ž

For ESP32-S2, -S3 and -C3, don't forget you have to click Reset after ā€Župloading through the ROM bootloader. Then select the new USB ā€ŽSerial port created by the ESP32. It will take a few seconds for the ā€Žboard to complete the scan.ā€Ž

serial_193

If you cannot scan any networks, check your power supply. You need ā€Ža solid power supply in order for the ESP32 to not brown out. A ā€Žskinny USB cable or drained battery can cause issues.ā€Ž

WiFi Connection Test

Now that you can scan networks around you, it’s time to connect to ā€Žthe Internet!ā€Ž

Copy the example below and paste it into the Arduino IDE:ā€Ž

Download File

Copy Code
// SPDX-FileCopyrightText: 2020 Brent Rubell for Adafruit Industries
//
// SPDX-License-Identifier: MIT


/*
  Web client

 This sketch connects to a website (wifitest.adafruit.com/testwifi/index.html)
 using the WiFi module.

 This example is written for a network using WPA encryption. For
 WEP or WPA, change the Wifi.begin() call accordingly.

 This example is written for a network using WPA encryption. For
 WEP or WPA, change the Wifi.begin() call accordingly.

 created 13 July 2010
 by dlf (Metodo2 srl)
 modified 31 May 2012
 by Tom Igoe
 */

#include <WiFi.h>

// Enter your WiFi SSID and password
char ssid[] = "YOUR_SSID";             // your network SSID (name)
char pass[] = "YOUR_SSID_PASSWORD";    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;                      // your network key Index number (needed only for WEP)

int status = WL_IDLE_STATUS;
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(74,125,232,128);  // numeric IP for Google (no DNS)

char server[] = "wifitest.adafruit.com";    // name address for adafruit test
char path[]   = "/testwifi/index.html";

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
WiFiClient client;

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // attempt to connect to Wifi network:
  Serial.print("Attempting to connect to SSID: ");
  Serial.println(ssid);

  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }

  Serial.println("");
  Serial.println("Connected to WiFi");
  printWifiStatus();

  Serial.println("\nStarting connection to server...");
  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("connected to server");
    // Make a HTTP request:
    client.print("GET "); client.print(path); client.println(" HTTP/1.1");
    client.print("Host: "); client.println(server);
    client.println("Connection: close");
    client.println();
  }
}

void loop() {
  // if there are incoming bytes available
  // from the server, read them and print them:
  while (client.available()) {
    char c = client.read();
    Serial.write(c);
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting from server.");
    client.stop();

    // do nothing forevermore:
    while (true) {
      delay(100);
    }
  }
}


void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

View on GitHub

NOTE: You must change the SECRET_SSID and SECRET_PASS in ā€Žthe example code to your WiFi SSID and password before ā€Župloading this to your board.ā€Ž

note_195

After you've set it correctly, upload and check the serial monitor. You ā€Žshould see the following. If not, go back, check wiring, power, and ā€Žyour SSID/password

password_196

If you have issues establishing a connection, try power cycling the ā€Žboard by unplugging and replugging the USB cable.ā€Ž

Factory Reset

On macOS, you need to use this board with a hub and USB A to USB ā€ŽC cable to upload any software. If you plug the board directly into a ā€ŽUSB C port on your Mac, it will assume it needs power delivery (PD) ā€Žand the USB to Serial port will not work.ā€Ž

Your microcontroller ships running a factory demo. It's lovely, but you ā€Žprobably had other plans for the board. As you start working with ā€Žyour board, you may want to return to the original code to begin ā€Žagain, or you may find your board gets into a bad state. ā€ŽEither way, this page has you covered.ā€Ž

Factory Reset Example Code

If you're still able to load Arduino sketches, you can load the ā€Žfollowing sketch onto your board to return it to its original state.ā€Ž

Download File

Copy Code
// SPDX-FileCopyrightText: 2025 Limor Fried for Adafruit Industries
//
// SPDX-License-Identifier: MIT
#include <Arduino.h>
#include "WiFi.h"
#include <Adafruit_TestBed.h>
#include "ESP_I2S.h"
extern Adafruit_TestBed TB;

// I2S pin definitions
const uint8_t I2S_SCK = 26;  // BCLK
const uint8_t I2S_WS = 33;   // LRCLK
const uint8_t I2S_DIN = 25;  // DATA_IN
I2SClass i2s;

// the setup routine runs once when you press reset:
void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  i2s.setPins(I2S_SCK, I2S_WS, -1, I2S_DIN);
  if (!i2s.begin(I2S_MODE_STD, 44100, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO, I2S_STD_SLOT_LEFT)) {
    Serial.println("Failed to initialize I2S bus!");
    return;
  }
  // TestBed will handle the neopixel swirl for us
  TB.neopixelPin = PIN_NEOPIXEL;
  TB.neopixelNum = 1;
  TB.begin();

  // Set WiFi to station mode and disconnect from an AP if it was previously connected
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
}

// the loop routine runs over and over again forever:
uint8_t wheelColor=0;
void loop() {
  if (wheelColor == 0) {
    // Test I2C!
    Serial.print("I2C port ");
    TB.theWire = &Wire;
    TB.printI2CBusScan();

    // Test WiFi Scan!
    // WiFi.scanNetworks will return the number of networks found
    int n = WiFi.scanNetworks();
    Serial.print("WiFi AP scan done...");
    if (n == 0) {
        Serial.println("no networks found");
    } else {
        Serial.print(n);
        Serial.println(" networks found");
        for (int i = 0; i < n; ++i) {
            // Print SSID and RSSI for each network found
            Serial.print(i + 1);
            Serial.print(": ");
            Serial.print(WiFi.SSID(i));
            Serial.print(" (");
            Serial.print(WiFi.RSSI(i));
            Serial.print(")");
            Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*");
            delay(10);
        }
    }
    Serial.println("");
    for (int i=0; i < 5; i++) {
      int32_t sample = i2s.read();
      if (sample >= 0){
        Serial.print("Amplitude: ");
        Serial.println(sample);
    
        // Delay to avoid printing too quickly
        delay(200);
        }
      }
  }

  TB.setColor(TB.Wheel(wheelColor++)); // swirl NeoPixel
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));

  delay(5);
}

View on GitHub

Your board is now back to its factory-shipped state! You can now ā€Žbegin again with your plans for your board.ā€Ž

Factory Reset .bin

If your board is in a state where Arduino isn't working, you may need ā€Žto use these tools to flash a .bin file directly onto your board.ā€Ž

There are two ways to do a factory reset. The first is using WebSerial ā€Žthrough a Chromium-based browser, and the second is ā€Žusing esptool via command line. We highly recommend using ā€ŽWebSerial through Chrome/Chromium.ā€Ž

First, you'll need to download the factory-reset.bin file. Save the ā€Žfollowing file wherever is convenient for you. You'll need access to it ā€Žfor both tools.ā€Ž

Click to download the Sparkle Motion Factory Reset .BIN

Now that you've downloaded the .bin file, you're ready to continue ā€Žwith the factory reset process. The next two sections walk you ā€Žthrough using WebSerial and esptool.ā€Ž

The WebSerial ESPTool Method

We highly recommend using WebSerial ESPTool method to perform ā€Ža factory reset and bootloader repair. However, if you'd rather use ā€Žesptool via command line, you can skip this section.ā€Ž

This method uses the WebSerial ESPTool through Chrome or a ā€ŽChromium-based browser. The WebSerial ESPTool was designed to ā€Žbe a web-capable option for programming ESP32 boards. It allows ā€Žyou to erase the contents of the microcontroller and program up to ā€Žfour files at different offsets.ā€Ž

You will have to use a Chromium browser (like Chrome, Opera, ā€ŽEdge...) for this to work, Safari and Firefox, etc. are not supported ā€Žbecause we need Web Serial and only Chromium is supporting it to ā€Žthe level needed.ā€Ž

Follow the steps to complete the factory reset.ā€Ž

If you're using Chrome 88 or older, see the Older Versions of Chrome section at the end of this page for instructions on enabling ā€ŽWeb Serial.ā€Ž

Connect

You should have plugged in only the ESP32 that you intend to flash. ā€ŽThat way there's no confusion in picking the proper port when it's ā€Žtime!

In the Chrome ā€Žbrowser visit https://adafruit.github.io/Adafruit_WebSerial_ESPTool/. ā€ŽYou should see something like the image shown.

visit_197

Press the Connect button in the top right of the web browser. You ā€Žwill get a pop up asking you to select the COM or Serial port.ā€Ž

Remember, you should remove all other USB devices so only the ā€ŽESP32 board is attached, that way there's no confusion over ā€Žmultiple ports!ā€Ž

On some systems, such as MacOS, there may be additional system ā€Žports that appear in the list.ā€Ž

systems_198

The JavaScript code will now try to connect to the ROM bootloader. It ā€Žmay timeout for a bit until it succeeds. On success, you will see that ā€Žit is Connected and will print out a unique MAC address identifying ā€Žthe board along with other information that was detected.ā€Ž

javascript_199ā€Ž ā€Ž

ā€Žā€ŽOnce you have successfully connected, the command toolbar will ā€Žappear.ā€Ž

command_200

Erase the Contents

To erase the contents, click the Erase button. You will be prompted ā€Žwhether you want to continue. Click OK to continue or if you ā€Žchanged your mind, just click cancel.ā€Ž

erase_201

ā€Žā€ŽYou'll see "Erasing flash memory. Please wait..." This will eventually ā€Žbe followed by "Finished." and the amount of time it took to erase.ā€Ž

Do not disconnect! Immediately continue on to programming the ā€ŽESP32.ā€Ž

disconnect_202

Do not disconnect after erasing! Immediately continue on to the ā€Žnext step!ā€Ž

Program the ESP32ā€Ž

Programming the microcontroller can be done with up to four files ā€Žat different locations, but with the board-specific factory-ā€Žreset.bin file, which you should have downloaded earlier, you only ā€Žneed to use one file.ā€Ž

Click on the first Choose a file.... (The tool will only attempt to ā€Žprogram buttons with a file and a unique location.) Then, select the ā€Žā€Ž*-factory-reset.bin file you downloaded in Step 1 that matches your ā€Žboard.ā€Ž

Verify that the Offset box next to the file location you used is (0x) 0.ā€Ž

offset_203

Once you choose a file, the button text will change to match your ā€Žfilename. You can then select the Program button to begin flashing.ā€Ž

flashing_204

A progress bar will appear and after a minute or two, you will have ā€Žwritten the firmware.ā€Ž

bar_205

Once completed, you can skip down to the section titled Reset the ā€ŽBoard.ā€Ž

The esptool Method (for advanced users)ā€Ž

If you used WebSerial ESPTool, you do not need to complete the ā€Žsteps in this section!ā€Ž

Alternatively, you can use Espressif's esptool program to ā€Žcommunicate with the chip! esptool is the 'official' programming tool ā€Žand is the most common/complete way to program an ESP chip.ā€Ž

Install ESPTool.py

You will need to use the command line / Terminal to install and ā€Žrun esptool.ā€Ž

You will also need to have pip and Python installed (any version!).ā€Ž

Install the latest version using pip (you may be able to ā€Žrun pip without the 3 depending on your setup):ā€Ž

pip3 install --upgrade esptool

Then, you can run:ā€Ž

esptool.py

Test the Installation

Run esptool.py in a new terminal/command line and verify you get ā€Žsomething like the below:ā€Ž

run_206

Connect

Run the following command, replacing the COM88 identifier after --ā€Žport with the COMxx, /dev/cu.usbmodemxx or /dev/ttySxx you found ā€Žabove.ā€Ž

esptool.py --port COM88 chip_id

You should get a notice that it connected over that port and found ā€Žan ESP32.ā€Ž

notice_207

Installing the Factory Test file

Run this command and replace the serial port name, COM88, with ā€Žyour matching port and *-factory-reset.bin with file you just ā€Ždownloaded

esptool.py --port COM88 write_flash 0x0 *-factory-reset.bin

Don't forget to change the --port name to match.ā€Ž

There might be a bit of a 'wait' when programming, where it doesn't ā€Žseem like it's working. Give it a minute, it has to erase the old flash ā€Žcode which can cause it to seem like it's not running.ā€Ž

You'll finally get an output like this:ā€Ž

output_208

Once completed, you can continue to the next section.ā€Ž

Reset the board

Now that you've reprogrammed the board, you need to reset it to ā€Žcontinue. Click the reset button to launch the new firmware.ā€Ž

In the event that pressing the reset button does not restart the board, ā€Žunplug the board from USB and plug it back in to get the new ā€Žfirmware to start up.ā€Ž

The NeoPixel LED on the Sparkle Motion will perform one rainbow ā€Žcycle. In the serial monitor, you'll see the results of a WiFi scan, I2C ā€Žscan and readings from the onboard I2S microphone.ā€Ž

You've successfully returned your board to a factory reset state!ā€Ž

Older Versions of Chrome

As of chrome 89, Web Serial is already enabled, so this step is only ā€Žnecessary on older browsers.ā€Ž

We suggest updating to Chrome 89 or newer, as Web Serial is ā€Ženabled by default.ā€Ž

If you must continue using an older version of Chrome, follow these ā€Žsteps to enable Web Serial.ā€Ž

If you receive an error like the one shown when you visit the ā€ŽWebSerial ESPTool site, you're likely running an older version of ā€ŽChrome.ā€Ž

You must be using Chrome 78 or later to use Web Serial.ā€Ž

chrome_209

To enable Web Serial in Chrome versions 78 through 88:ā€Ž

  • Visit chrome://flags from within Chrome.ā€Ž

  • Find and enable the Experimental Web Platform features

  • Restart Chrome

restart_210

Downloads

On macOS, you need to use this board with a hub and USB A to USB ā€ŽC cable to upload any software. If you plug the board directly into a ā€ŽUSB C port on your Mac, it will assume it needs power delivery (PD) ā€Žand the USB to Serial port will not work.ā€Ž

Files

Schematic and Fab Print

schematic_211

schematic_212

dimensions are in inches

ā€Ž3D Modelā€Ž

model_213

Codice produttore 6100
SPARKLE MOTION PCB ANTENNA
Adafruit Industries LLC
Codice produttore 1219
HDWR T-PLATE 20X20 ALUM EXTRUSN
Adafruit Industries LLC
Codice produttore 6023
ADAFRUIT NEOPIXEL PEBBLE / SEED
Adafruit Industries LLC
USB TO 2.1MM MALE BARREL JACK CA
Codice produttore 2697
USB TO 2.1MM MALE BARREL JACK CA
Adafruit Industries LLC
Codice produttore 4397
STEMMA QT QWIIC JST SH CABLE 150
Adafruit Industries LLC
Codice produttore 352
AC/DC DESKTOP ADAPTER 12V 60W
Adafruit Industries LLC
Codice produttore 5130
AC/DC DESKTOP ADAPTER 3-24V
Adafruit Industries LLC
Codice produttore 875
BATTERY HOLDER AA 8 CELL LEADS
Adafruit Industries LLC
Codice produttore 4528
4-PIN STEMMA/GROVE - QT/QWIIC 4"
Adafruit Industries LLC
Codice produttore 6160
SPARKLE MOTION MINI ESP32
Adafruit Industries LLC
Codice produttore 5395
ADAFRUIT QT PY ESP32 PICO - WIFI
Adafruit Industries LLC
Codice produttore 3405
HUZZAH32 ESP32 FEATHER LOOSE HDR
Adafruit Industries LLC
Codice produttore 5438
ESP32 FEATHER V2 STEMMA QT
Adafruit Industries LLC
Codice produttore 2821
ESP8266 FEATHER HUZZAH LOOSE HDR
Adafruit Industries LLC
PANEL MOUNT 1K POTENTIOMETER (BR
Codice produttore 1789
PANEL MOUNT 1K POTENTIOMETER (BR
Adafruit Industries LLC
Codice produttore 157
IR (INFRARED) RECEIVER SENSOR -
Adafruit Industries LLC
Codice produttore 5939
ADAFRUIT INFRARED IR REMOTE RECE
Adafruit Industries LLC
Codice produttore 954
CABLE USB TO TTL SERIAL DEBUG
Adafruit Industries LLC
IC SOCKET - FOR 20-PIN 0.3 CHIPS
Codice produttore 2204
IC SOCKET - FOR 20-PIN 0.3 CHIPS
Adafruit Industries LLC
Codice produttore 5755
JST SH COMPATIBLE 1MM PITCH 3 PI
Adafruit Industries LLC
Codice produttore 2540
ADDRESS LED STRIP SERIAL RGB 2M
Adafruit Industries LLC
Codice produttore 1426
ADDRESS LED MODULE SERIAL RGB
Adafruit Industries LLC
Codice produttore 5027
STEMMA QT MCP9808 TEMP SENSOR
Adafruit Industries LLC
Codice produttore 4399
STEMMA QWIIC JST SH CABLE 50MM
Adafruit Industries LLC
Codice produttore 5159
STEMMA QT HOT-SWAP I2C BUFFER
Adafruit Industries LLC
Codice produttore 4756
STEMMA QT I2C EXTENDER LTC4311
Adafruit Industries LLC
Add all DigiKey Parts to Cart
Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.