Getting Started

Adafruit Playground is a wonderful and safe place to share your interests with Adafruit's vibrant community of makers and doers. Have a cool project you are working on? Have a bit of code that you think others will find useful? Want to show off your electronics workbench? You have come to the right place.
The goal of Adafruit Playground is to make it as simple as possible to share your work. On the Adafruit Playground users can create Notes. A note is a single-page space where you can document your topic using Adafruit's easy-to-use editor. Notes are like Guides on the Adafruit Learning System but guides are high-fidelity content curated and maintained by Adafuit. Notes are whatever you want them to be. Have fun and be kind.
Click here to learn more about Adafruit Playground and how to get started.
-
VarSpeedServoRA4M1 VarSpeedServoRA4M1 is a library for Arduino tha enables precise control over servo motors, including speed, position, and movement sequences.
Developed by Kaled Souky in 2024, based on the Servo library (developed by Michael Margolis in 2009) and VarSpeedServo library (developed by Korman in 2010 and updated by Philip van Allen in 2013). Specifically designed for the Renesas RA4M1 microcontroller architecture (Arm Cortex-M4), present on the Arduino UNO R4 Minima and Arduino UNO R4 WiFi boards.
VarSpeedServoRA4M1 is an interrupt-driven library using 16-bit timers, allowing the use of up to 12 servos moving asynchronously or synchronously. In addition to setting the position, you can set the speed of a movement, optionally wait until the servo movement is completed, and create sequences of movements that execute asynchronously or synchronously.
The 32-bit Renesas RA4M1 processor operating at 48 MHz elevates servo control to a new level, providing higher PWM resolution compared to the ATmega328P used in Arduino UNO R3. Thanks to this power, VarSpeedServoRA4M1 fully exploits the microcontroller's capabilities. With its simple and intuitive syntax, this library facilitates precise control over servo position and speed, even for beginners. Creating complex movement sequences is straightforward with just a few commands.
Features :
- Supports up to 12 servos.
- Allows synchronous and asynchronous movement of all servos.
- Allows you to configure the "position" and "speed" of each servo individually.
- Includes a "wait" parameter to wait for the servo to complete its movement. Philip van Allen, in his update, incorporated it as a boolean variable within the
write()
function, and also as the independentwait()
function. This parameter is not included as a variable in Korman'sslowmove()
function. - The
write()
function now includes the "speed" and "wait" parameters, which can optionally be used in conjunction with the "position" parameter to control servo movement. - The
slowmove()
function is retained for compatibility with the Korman version. It only handles the "position" and "speed" parameters. In this case, the waiting time must be configured (using, for example, the functiondelay()
,delayMicroseconds()
,micros()
ormillis()
), so that the servo completes the position and maintains it for the desired time. Theslowmove()
function does not incorporate the "wait" variable introduced by Philip van Allen in thewrite()
function. - Allows the creation of position sequences.
Examples of use:
Sample code 1: Sweeps a servo motor from 0 to 180 degrees at fast speed and back from 180 to 0 degrees at slow speed, in an infinite loop.
The
write()
function now includes the "speed" and "wait" parameters, which can optionally be used in conjunction with the "position" parameter to control servo movement.The "wait" parameter is used to wait for the servo to complete its movement. It is also available as a standalone
wait()
function.Image taken from the official Arduino website: https://docs.arduino.cc/learn/electronics/servo-motors/
-
The Many Possibilities of Adafruit IO Actions and an Arcade Button Overview
As we get closer to launching the new Adafruit IO Actions, it has been fun thinking of the many fun ways it can be used. Here is a really simple project that has a ton of potential without writing a single line of code. With this project, I simply added a NeoPixel to a simple arcade button (using the below Learn guide), and then use that LED and button to communicate information in different ways. The more I play around with this project, the more ideas I come up with. So be sure to check back here often as I will post more ideas as I come up with them.
Parts Used
I used the NeoPixel Mini Button as shown in the guide above, but used the QT Py ESP32-S3 board with the NeoPixel BFF to drive the NeoPixel, then just soldered one side of the button to 3V on the QT Py, and the other side of the button to A2.
You could also simply skip modifying the arcade button, and just use the built in NeoPixel on the QT Py. You could even just use the built in pushbutton on the QT Py and skip the Arcade Button all together. This guide isn't so much about the specific project, as it is about the possibilities of the new Adafruit IO Actions. You can set this up with any NeoPixel and button.
With that in mind, here are the products I used:
-
Boston MBTA stop prediction sign An LED matrix device to show predictions of arriving buses and trains using the MBTA v3 API
To get to the Git hub repository for this project click here: https://github.com/dufus2506/MBTA-bus-train-stop-prediction-sign
Built on the excellent work of others I've seen, I have designed my own MBTA sign to tell you when the bus or train will be leaving a stop. This sign can show predictions for for bus lines, subway stations, and commuter rail stations.
This is designed to be used on the Adafruit Matrixportal M4 running Circuitpython https://learn.adafruit.com/adafruit-matrixportal-m4 and using a 64x32 RGB LED matrix. https://www.adafruit.com/category/327 Pick whatever size you like.
I managed to keep the code very small, and with a minimum number of libraries so the limited memory of the M4 would not be a problem. And I improved on the code comments a bit to make it easier for you to configure your own sign.
I removed all but the most essential libraries from the board. I have only the libraries shown in the image on my board.
Apart from that I tried to make the sign as useful as possible with the ability to see predictions for more than one stop or bus route. You can add as many stops/routes/lines to a sign as you need, though it's not very practical if the sign has too many. You don't want to be waiting too long for sign updates to see when your ride is leaving.
Because the sign updates every thirty seconds, you won't need an MBTA API Key to make it work. You need one if your project will be checking the API multiple times a second. That's not very practical for this sign, so no API key necessary here. But you will need an Adafruit AIO account so that you can set the clock properly. The free level is just fine for clock setting. Get one here: https://io.adafruit.com/
Your settings.toml file should have the following entries:
CIRCUITPY_WIFI_SSID = "Your_SSID"
CIRCUITPY_WIFI_PASSWORD = "Your_Password"
AIO_USERNAME = "Your_AIO_Username"
AIO_KEY = "aio_Your_Really_Long_AIO_User_Key"
timezone = "US/Eastern"
Don't forget the timezone entry, or your clock may be set to GMT. WiFi settings are case sensitive in the settings.toml file, so be sure to match everything correctly for your WiFi network.
When I was done I had the files and directories seen in the image below on the board. All but the lib directory are empty.
-
Adafruit Memento Time-lapse w/ online upload & email notification Adafruit Memento Time-lapse Camera with Online Upload and Email Notification
This guide shows how to turn your Adafruit Memento (ESP32-S3) board into a time-lapse camera that:
- Captures images on a schedule or with a button press
- Uploads them to Adafruit IO over Wi-Fi
- Triggers email notifications using a feed
- All using CircuitPython and the PyCamera library!What You Need
- Adafruit Memento Board: https://www.adafruit.com/product/5843
- microSD card (optional, for GIF recording)
- USB-C cable
- Wi-Fi network
- Adafruit IO account: https://io.adafruit.com
- CircuitPython is installed on the MementoSetup
1. Installing CircuitPython
To install CircuitPython on the Adafruit Memento, I followed this official guide by Anne Barela and John Park:
🔗 [Memento Camera Quick Start Guide – Install CircuitPython](https://learn.adafruit.com/memento-camera-quick-start-guide/install-circuitpython)
That page walks you through how to:
- Put the board into bootloader mode (double-tap reset)
- Drag the `.uf2` file onto the board
- Verify that the **CIRCUITPY** drive appearsMake sure you use **CircuitPython 9.0.0 or later** to avoid filesystem corruption issues.
2. Install Libraries
- adafruit_io
- adafruit_requests.mpy
- adafruit_ntp.mpy
- adafruit_logging.mpy
- adafruit_pycamera
- adafruit_ov5640
- adafruit_connection_manager.mpy
- gifio.mpy
- bitmaptools.mpy
- ulab (folder)3. Create settings.toml file on CIRCUITPY with this:
CIRCUITPY_WIFI_SSID = "YourNetworkName"
CIRCUITPY_WIFI_PASSWORD = "YourNetworkPassword"
ADAFRUIT_AIO_USERNAME = "your_username"
ADAFRUIT_AIO_KEY = "your_aio_key"4. Main Code
Paste the following into code.py on your CIRCUITPY drive:
What I did
- I used the fancy camera CircuitPython code by Anne Barela and John Park, and the Doorbell Camera code by Brent Rubell to help create the code above.
- My main focus was to get photos uploaded to Adafruit IO with the timelapse and camera shutter options.
How It Works
- The camera connects to Wi-Fi and Adafruit IO
- Takes snapshots using the shutter button or on a time-lapse interval
- Encodes image data as base64 and uploads to Adafruit IO feed
- Sends a "trigger" signal to another feed to notify you via email5. Set up Feeds on Adafruit IO
- Go to io.adafruit.com
- Click on the tab 'IO'
- Go to Feeds and create two. I set up a 'camera' feed and a 'camera-trigger' feed.
- The "camera" feed will take photo uploads, and the "camera-trigger" feed gets a 1 or 0; this is used to trigger an automated email action.
-
🎵️ Media hub 2.0: Media control w/opt Bluetooth Overview
Physical controls for a more enjoyable media playback experience.
Features
- Responsive volume knob & mute button.
- Transport controls (play/pause, stop, FF/REW, skip tracks).
- Pair up with your favourite Bluetooth® speakers.
- Quick, physical connection (don't have to go through menu system to pair with keypad & speakers).
- Customizable controls/scheme.
This project tries to improve over the original "Media hub" presented here.
- More compact design
- Bigger volume knob - not interfering with macropad keys.
🛒️List of main material/hardware
(See section "More tools/materials/hardware" near the end of this note for extras)
-
Rust on the Adafruit Feather RP2350 HSTX Let's start with the Debug Header, the little 3 pin interface lets you peek into the Pons of the Raspberry Pi brain. You can find this header on the Raspberry Pi 5, the Raspberry Pi Pico (H, and WH), and now happily the Adafruit RP23XX boards thus far. By connecting a Pico Probe to this interface, you can get a lot of debug information back on your big main computer. ARM refers to this type of interfacing / debugging as Semihosting.
With the 3-Pin JST cable, cable plugged into the D header on the Pico Probe and the other end of that cable onto the Debug Header on your Feather (Shown above); With the Pico Probe connected to your computer, and you can connect the Feather to any USB power source, or back to your computer as well. Once you've done that, you're ready to issue the
cargo run
command, so long as you have the required software installed below.Back to the code we cloned all of the way at the top of this article. With all of the software above installed, and your computer connected to the debug probe, the probe connected to the feather, and the feather connected to power or your computer you now have a system that is ready to go. We really can run that
cargo run
command and have Rust code on our feather. But what are all of these files and what do they do?.cargo/config.toml
andcargo run
The
.cargo/config.toml
file configurescargo run
to useprobe-rs
to flash to the boards ROM. You will need a Raspberry Pi Debug Probe in order to use this, but it makes development MUCH easier, faster, and more fun! You connect the Debug Probe'sD
(for debug,D
fordefmt
😉) side to the board's Debug Port. Once done connect the Adafruit board, and Debug Probe to your computer. You can flash at will withcargo run
and see any debug messages in your computer's terminal thanks todefmt
.memory.x
If you've never seen a
memory.x
file before, and have no clue what it is; I don't blame you for being curious. It's an odd file, filled with things that aren't Rust or C, or anything else that fits the norm. This file actually tells the linker where to put sections of the binary. It makes sure everything is in order so that when the microcontroller jumps to flash memory, the expected data is there ready for it. It also tells the the linker how much RAM the target board or chip has.build.rs
This build script copies the
memory.x
file from the crate root into a directory where the linker can always find it at build time. For many projects this is optional, as the linker always searches the project root directory -- whereverCargo.toml
is. However, if you are using a workspace or have a more complicated build setup, this build script becomes required. Additionally, by requesting that Cargo re-run the build script whenevermemory.x
is changed, updatingmemory.x
ensures a rebuild of the application with the new memory settings. -
Zephyr Quest: IoT Toggle Switch for Feather TFT This guide shows how to make an IoT toggle switch with an Adafruit Feather TFT ESP32-S3, Zephyr, and Adafruit IO. Key features include: GPIO input for Boot button, LVGL graphics, MQTT over WiFi with TLSv1.2, and USB serial shell commands for saving WiFi and MQTT configuration settings to NVM flash. This guide is intended for people who want to learn how to write applications in C using Zephyr APIs.
Demo video: IoT toggle switch: Zephyr + Feather TFT + Adafruit IO
Previously in this series of guides about using Zephyr on Adafruit hardware, I focused on setting up developer tools and writing Devicetree board definitions. This time, I'm moving up the stack to show how to build an application tying together several Zephyr APIs along with a custom board definition.
Building an IoT app with WiFi, TLS, and graphics is unavoidably a bit complicated. It took me about three weeks to write the code, which totals a bit over 2100 lines. Listing all of that here would be awkward. If you want the details, you can browse the code in my zphqst-03 GitHub repo. The code has lots of comments, including citations for the references I used while learning to use the Zephyr APIs.
This guide will focus on:
- How to build, run, and configure the IoT toggle switch app
- High level tour of the source code with GitHub links: which files do what?
- Understanding C language features that you'll need to use Zephyr APIs effectively: structs, function pointers, etc.
- Zephyr troubleshooting tips: diagnose and fix memory allocation issues, enable various types of debug logging, etc.
- MQTT testing with
openssl
and themosquitto
MQTT broker with its companion command line tools,mosquitto_pub
andmosquitto_sub
-
No-Code Easy Ambient Smart Lights Overview
With all the newest features of Adafruit IO, WipperSnapper firmware, and the new Blockly Actions, you can create really complex projects without writing a single line of code. I've been working on a couple versions of smart lights to notify me of different things using NeoPixels. This project will focus on a super easy smart ambient lighting system that you can stick to the back of your computer monitor.
Components
Using just a few Adafruit components is all you need to create a really simple, but pretty powerful little notification system. We are gonna use a QT Py ESP32-S2 WiFi Dev Board to talk to Adafruit IO, a NeoPixel BFF for the QT Py, and finally a short NeoPixel strip with a JST connector pre-attached (so you can connect right up to the BFF board.
The only soldering you will need to do is to attach the boards together. You can solder the boards together with the included pins, or pick up some female headers so you can detach the boards and use them on any future projects.
-
CircuitPython "Avalanche Noise" RNG with TPS65131 & NPN transistors I've long had an interest in random number generation. In fact, a very early PCB I designed and built was exactly for this purpose: Arduino Random Number Generator.
That project used a property of transistors called "avalanche noise". Inconveniently, it required a supply of +-10V to work properly. Avalanche noise is sometimes explained as being a "quantum effect" and thus is supposed to be a source of true randomness.
When the TPS65131 went into the store, I knew it was time to revisit this project. This little PCB generates positive and negative voltages from a single +5V input.
Parts
-
3D printed Bracket for 4 64x64 2mm RGB matrix panels I wanted to assemble four of those 64x64mm RGB matrix panels. However, my 3D printer is limited to about 250x205mm, and the panels are 256x256mm.
It required a little creativity, but I devised a single print of about 249x136mm such that by printing two and flipping one of them over, it becomes a bracket that can hold the four panels together.
I have a feeling that the injection molded bodies of these panels may change from time to time, potentially moving the screw & post positions. My 4 panels were purchased around February 2025.
I developed the part in OpenSCAD, Free (GPL) 3D modeling software available on Linux, Mac, & Windows. To create a 3D printable STL file, open the SCAD file, press F5 to "render" it to triangles, and then F7 to export to STL.
-
Universal BLE Remote with Keyboard Featherwing Overview
One of the coolest things about Solder Party's Keyboard Featherwing is its versatility. While it offers a fully-featured hardware package all on its own, the ability to pair it with any Feather board allows it to be extended to do pretty incredible things. In this project, I'm pairing it with a Feather nRF52840 Express to create a universal Bluetooth Low Energy (BLE) keyboard/mouse/remote control, programmed in CircuitPython.
Using the nRF52840, CircuitPython has the ability to send BLE keyboard, mouse, and consumer control HID events to control a host device, such as a computer. This firmware combines the ability to send all 3 event types from a single device in an easily configurable way, adding another layer of versatility!
Some possible applications:
- Control a laptop connected to a TV remotely, with physical keyboard and full mouse support
- Control an Apple TV, including navigation. Use a physical keyboard when searching!
- Remotely trigger the camera shutter on iPhone/iPad
- Use the 9 programmable buttons to make a BLE "macro pad"
- Practically anything that could benefit from a BLE keyboard, mouse, and/or consumer control remote
Another nice thing about the nRF52840 for this application is its excellent energy efficiency. When using a 2000mAh LiPo battery, I've been able to get between 70-80 hours of active use on a single charge! The Keyboard Featherwing's built-in on/off switch allows extending the battery life even further.
Firmware Features
- Compact physical keyboard makes it easy to type wirelessly on device like laptops/desktops, Raspberry Pis, or anything else that can connect to BLE keyboards.
- Touch screen behaves as a trackpad/mouse when connected to a host device that supports pointer devices.
- 4 activity presets, selectable through an on-screen preferences menu. Further configuration is possible by connecting device to a computer via USB and editing the configuration files in the user directory.
- Each activity allows you to customize the 4 function buttons and the 5-way direction button (D-BUTTON) to send keyboard, consumer control, and mouse button events
- Adjustable display/keyboard/NeoPixel brightness
- Adjustable primary user interface color
- Power-saving feature: auto-dim keyboard, screen, and NeoPixel after 30 seconds of inactivity, significantly increasing battery life.
- Battery voltage monitoring and "needs charge" indicator.
-
Monitor Indoor Air Quality with Blues, IFTTT, Adafruit IO and a Hue LED Strip If you're working an office job, you're...in an office. Whether that's in your home or not, I'm going to hazard a guess that it's also indoors - and being indoors for an extended period of time without well-ventilated spaces can legitimately lead to low air quality (and in theory health issues).
Now, I'm not hear to spread fear and make you all think you're dying a slow death by breathing in your co-worker's exhalations. However, I am here to show off an easy way to build a cloud-connected indoor air quality system with:
- A variety of Adafruit air quality sensors.
- A Blues Notecard to cloud-connect the project with LTE connectivity.
- Adafruit IO to visualize air quality data and integrate with other services.
- A Philips Hue LED strip to provide real-time visuals for low air quality alerts.
-
A Node Based CAD Add-in for Fusion 360 Gradient is a node-based editor designed for use with Autodesk Fusion 360.
I started working on Gradient after playing with the node based geometry in Blender. The nodes in Blender are fantastic (frankly they work much better than mine do right now) but I wanted to create algorithmically defined geometry right in Fusion 360 using solids and surfaces which are better suited to making 3D models for technical and engineering parts. I wanted to be able to make algorithemic structures that are user defined but and can be finely controlled and tuned to the design needs.
Models like this would be very time consuming to model by hand. However they can be quickly generated and re-generated with different parameters or random seeds.
If you are interested in trying Gradient for yourself you can download it from the github repository below. Please be aware currently Gradient is in an early development stage, meaning only a small fraction of its functionality has been implemented, and there are likely a few bugs to sort through.
-
C3P0, Take the Wheel! I really enjoyed getting my first PyBadge because it gave me a way to make my own arcade games using https://arcade.makecode.com. I did find that, I actually like making the games even more than playing them, so I thought about ways to have someone (or something) else play the game.
I'd heard about the idea of "mouse jigglers" - mechanical or software cheats to make it look like you were busy working on a computer when you weren't, and I knew CircuitPython supported HID (Human Interface Device) so I could send keystrokes. So why not "let C3P0 take the wheel"?
That led to my simple "mouse jiggler" for playing arcade games in a browser. (https://en.wikipedia.org/wiki/Mouse_jiggler) (Yes, this actually is a keyboard jiggler that randomly "fires" by sending spaces, and maneuvers by randomly sending cursor keys up, down, left and right.)
Designed to take over playing a simple arcade game in a browser, for example: https://makecode.com/_JfAKKf2EUcLv This game lets you steer the Millenium Falcon, and shoot asteroids and Star Destroyers.
Touch #1 on the NeoTrinkey to fire lasers, and touch #2 to toggle on/off a random "jiggler" that continuosly moves the ship around, randomly shooting.
Touch #1 and #2 together to end program.
Flashes green when autopilot is engaged, and red when it ends. Ending program flashes gold.
Program file:
AutoPilot.py - copy to code.py on the neotrinkey.
Github repo HERE
IMPORTANT NOTE: Programming something like this, using the HID interface can be tricky, as having a program randomly spewing spaces, and cursor keys will mangle any text you are editing. When I wrote this, the initial testing had touching #2 just call the jiggle() function. That way I didn't have a program going crazy and messing with the program text. Once it was working, it was safe to build the loop that would continuously call jiggle() and shoot().
C3P0 accidently piloting the Starspeeder in Star Tours -
Digital Clock with WiFi and Weather (Huzzah & 128x64OLED) I had an Adafruit Huzzah and an OLED FeatherWing 128 x 64 in my box of goodies and decided to make a smart digital clock for my study.
The clock is connected to internet via WiFi, synchronises the time and via an api displays the temperature in my area. It is set to update every 5 minutes. Also displays an icon of the current weather.
These are parsed from the api response:
{"coord":{"lon":yyyyyy,"lat":xxxxx},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"base":"stations","main":{"temp":1.03,"feels_like":-1.33,"temp_min":0.57,"temp_max":2.64,"pressure":1039,"humidity":76,"sea_level":1039,"grnd_level":1034},"visibility":10000,"wind":{"speed":2.06,"deg":170},"clouds":{"all":0},"dt":1738790391,"sys":{"type":1,"id":1440,"country":"GB","sunrise":1738742403,"sunset":1738773892},"timezone":0,"id":3333224,"name":"xxxxxx City","cod":200}
Next I created a 3D printed bezel that allowed me to fit the stacked boards in my workbench pannel.