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.
-
Busy Buttons - noisy glowy buttons for babies and toddlers I had a collection of spare parts from Adafruit laying around. My toddler loves mashing buttons, particularly ones that make noise, so I decided to turn those spare parts into something they'd enjoy. As for my own sanity, it'll diminish as the sounds play relentlessly, but I built in a secret "mute" cheat code. I used Adafruit's arcade buttons which can withstand a lot of toddler smashing and used a massive battery so it'll almost never need charging.
You can view more about the project on Printables and see the source code and instructions on GitHub to make your own. The enclosure is 3D printed and the software runs on an ESP32-S2 Feather with CircuitPython.
As a much more advanced project, I also created BabyPod: an interface to Baby Buddy written in a lot of CircuitPython.
-
A Neopixel Floor Lamp with a Twist This is probably the coolest thing I have built with Adafruit electronics! When I viewed the learn guide describing the Floor Lamp with NeoPixels and WLED Custom Animations by Erin St Blaine I knew that I just had to build this work of art. I tend to like building things with wood, so my adaption of Erin's design for the most part replaces some elements with wood structures. I was pleasantly surprised with the results!
Materials
For the most part I followed Erin's design. My parts list is as follows:
-
CircuitPython Core Dev & Debug Tricks This is an evolving collection of tips and tricks about working on the CircuitPython core and related libraries. Topics include code analysis and debugging, working with git and GitHub, maintaining documentation, and install/config for dev tools. Mostly these are notes to future-me, but perhaps they will also help other people who want to improve CircuitPython.
Control Flow Graphs
When you're getting started working on a new-to-you module of complex code, it can be pretty hard to build a picture in your head of how the code works just from reading the text. Fortunately, there are tools which can analyze source code and build actual pictures for you with directed graphs of which functions call which other functions.
Below are some examples of how I've been generating graphs of control flow between the various functions in CircuitPython's usb module and TinyUSB library dependency. To make the graphs, I use Debian with the
cflowcode analysis tool to generate agraphviz(.dot) graph file, then turn that into a PNG image to view with themirageimage viewer. Formirageto work, you need to run the last command in a terminal in X (vnc or physical display will work, but not ssh).shared-bindings/usb/*
-
Fruit Jam Two Gamepad Demo This is my third iteration of a CircuitPython USB host gamepad tester, now with support for two controllers. The main loop in code.py uses asyncio to improve code readability. There's a new boot keyboard to gamepad mapper. For hot-swapping controllers, I devised an unplug detection heuristic to work around limitations in the current CircuitPython USB host implementation. Player numbers get assigned according to Fruit Jam top plate silkscreen port numbers. Player 1 gets USB 1, and Player 2 gets USB 2.
This demo project is meant to help folks who want to make Fruit Jam libraries for writing games. I don't plan to make a library on my own, but I wrote this code with library-making in mind in case somebody else wants to. Note that some of the performance and stability workarounds included here may become unnecessary once USB host implementation bugs get fixed.
The code here was written and tested with CircuitPython 10.0.0-beta.2 on a rev D Fruit Jam that I bought from the first production batch that went up in the shop.
Related work:
- Fruit Jam Gamepad Tester guide (my previous gamepad tester)
- Fruit Jam Fruitris (Tetris) game guide by @relic-se
- Feather TFT Gamepad Tester with Sprites guide (my original gamepad tester)
Overview
-
Fruit Jam Fruitris (Tetris) Parts
I am using a production revision D Fruit Jam board. Most additional components can likely be found around the house such as HDMI cable & display, headphones, power supply, etc. The controller system is designed to be as compatible as possible. So, most USB controller devices should work or even a USB keyboard.
It is possible to use a Metro RP2350 which is discussed in learn guides such as Larsio Paint Music., but this guide will not discuss that procedure nor has the software been tested within that environment.
From the Adafruit Shop
Controls
Action Keyboard Gamepad Buttons Move Left Left Arrow Left Move Right Right Arrow Right Rotate Clockwise Up Arrow or X Up or A Button #2 Drop: Soft Down Arrow Down Button #1 Drop: Hard Z B Quit (reload) Enter Start Button #3
-
TactileAudio Project: Four-Channel Touch-Sensitive Audio Player Audio Adaptor Board
Order 1 (required)Teensy 4.1 Board
Order 1 (required)
-
Build a Brain in your NeoTrinkey! BuildABrain
Simple expert system for NeoTrinkey - yes/no questions, inspired by https://en.wikipedia.org/wiki/20Q
This project lets you put a simple expert system into your neotrinkey! The "brain" will ask yes/no question - touch pad #1 for "Yes" and pad #2 for "No"
Github archive *here*
Uncomment the dataset you want - this is shipped with a Star Wars set and Star Trek.
#from SWBrain import * #for Star Wars dataset from STBrain import * #for Star Trek datasetHere's how the Star Trek set was designed:
Basically, sketch out the decision tree, then number each node. Create a "yes" and "no" array that links each node to the next node (if any).
#Data in nodes for Star Trek info Words = ["Think of someone from Kirk's Enterprise.","Gold uniform", "Captain", "Blue Uniform", "Kirk", "Russian", "Vulcan", "Male", "Chekov", "Sulu", "Spock", "Scotty", "Uhura", "Male", "Are they dead","McCoy", "Chapel"] Yes = [0, 2, 4, 6, 0, 8, 10, 11, 0, 0, 0, 0, 0, 15, 0, 0, 0 ] #node for yes answers No = [0, 3, 5, 7, 0, 9, 13, 12, 0, 0, 0, 14, 0, 16, 0, 0, 0 ] #node for no answersnote: the zeroth node should be the introduction, for Star Trek it's "Think of someone from Kirk's Enterprise."
Files:
-
BuildABrain.py - copy to code.py on NeoTrinkey
-
STBrain.py - Star Trek data
-
SWBrain.py - Star Wars data
-
prt.py - lets you redirect output via HID output, just set REPL=False
Note: if REPL=False the program will blink Neopixels until you touch one of the pads.
Here's how it looks in action:
Think of someone from Kirk's Enterprise. Gold uniform? No Blue Uniform? Yes Vulcan? Yes Spock? Yes I was right! let's try again Think of someone from Kirk's Enterprise. Gold uniform? No Blue Uniform? No Male? Yes Scotty? No Are they dead? No Maybe you should talk to my programmer!Give it a try - see if you can build a brain for you NeoTrinkey!
-
-
Watch Tower - Radio controlled watch transmitter There are some beautiful radio-controlled watches available these days from Citizen, Seiko, Junghans, and even Casio. These timepieces don’t need fiddling every other month, which is great if you have more than one or two and can never remember what comes after “thirty days hath September…”
In the US, these watches work by receiving a 60-bit 1-Hz signal on a 60-kHz carrier wave broadcast from Fort Collins, Colorado called WWVB. The broadcast is quite strong and generally covers the entire continental US, but some areas of the country can have unreliable reception. I live in the SF Bay Area in an area with high RF noise and my reception can be spotty. My watches sync often enough that it’s not an issue 363 days out of the year, but sometimes they can miss DST shifts for a day or two. The east coast is known to be even more challenging.
Wouldn’t it be great if anyone could set up a little repeater to transmit the time so their watches were always in sync?
WWVB has been around awhile and there have been various other projects (1,2) that have demonstrated the feasibility of making your own WWVB transmitter. But these all had very limited range. I wanted to build something that could cover my whole watch stand and be based on a more familiar toolset for the typical hobbyist, namely USB-based 32-bit microcontroller development boards, WiFi, and Arduino. My goal was to make something approachable, reliable, and attractive enough it could sit with my watch collection.
Is this legal?
The FCC requires a license to transmit, but has an exemption for 60 kHz transmitters as long as the field strength is under 40 μV/m40 μV/m at 300 meters. You will definitely not exceed this limit 💪🏼
-
USB Cipher Machine Historically it's been common for militaries to use purpose built mechanical cipher machines like the well known Enigma Machine, or the more mundanely named M-209. Ever since I learned about these devices they fascinated me. This project is a small toy cipher device inspired by them albeit made with a microcontroller instead of mechanical parts and pieces.
I showed this project on Show & Tell, the video is embedded below.
Hardware
-
Fruit Jam Portable MIDI Synth [Update 2025-10-13: revised for CircuitPython 10.0.1, including a fix for the stuck notes issue]
This is a minimalist polyphonic square wave synth for Fruit Jam that's intended for portable use with a USB power bank. The only output is audio to the board's headphone jack. The only input is from a USB MIDI controller connected to the board's USB host port. To set the volume, you can edit the code.
The main interesting thing about this project is that it demonstrates how to make a CircuitPython synth with MIDI events coming from the USB host interface rather than a USB device interface or UART MIDI. Also, this works as a good stress test of the CircuitPython USB host stack in combination with audio output using I2S and synthio.
This code was developed and tested on CircuitPython 10.0.0-beta.0 with a pre-release rev B Fruit Jam prototype which uses a different I2S pinout from the current rev D boards. Keep in mind that what's written here may be out of date by the time CircuitPython 10.0.0 is released and the production revision of the Fruit Jam board becomes available in the shop.
Related guides: Fruit Jam USB Host MIDI Tester, Fruit Jam Gamepad Tester
Transparency note: Adafruit provided the Fruit Jam rev B prototype board I used for this guide (Thanks Adafruit!).
Overview
-
Reviving My Netduino 2 (without the .Net MF) Some History
I've had two Netduino 2's sitting in my electronics box for years, more years than I'm willing to admit. During that time, I'd done very little with them. When I originally bought them, Visual Studio was my daily development environment, and I knew my way around it quite well. I'd tinkered for a bit with an Arduino, but I was eager to use .Net and Visual Studio on this new device. I did build a few things with them, but frankly they didn't grab my interest and at the time, the much more powerful Raspberry Pi was drawing my attention away. So, these boards were relegated to the back of my toolbox. They seemed to be pretty content there, and I kept them cool and dry, so we were all happy for the time being.
A Spark of Blue
Fast forward to 2025 and as I was organizing my development boards into a new case, the Netduino's resurfaced, and my curiosity was rekindled. Did one of those blue LEDs just blink at me? Could these devices still work? Part of me always thought I should do more with them, maybe now is the time. Is the .Net Micro Framework still available? Could these boards be brought back, or would they remain dormant and only come out during my nostalgic times of remembering and reminiscing? Time to start searching and see what I can find.
Surprisingly, a lot of the original content is still available. Unfortunately, the firmware and Visual Studio add-in haven't been maintained in a long time. The last published versions were targeting Visual Studio 2015 and possibly worked with VS2017. Microsoft's download center doesn't even have VS2015 or even VS2017 and the .Net Micro Framework has been archived. But I wasn't going to give up. I found an old copy of VS2015, downloaded the additional tools required for Netduino development and got them installed. However, I wasn't able to connect the boards to the Visual Studio or deploy any code. I couldn't even get the Netduino Updater to flash the latest firmware. Sigh! It was looking like these devices were obsolete or at least too complicated to get any custom program running.
-
Displays and Clocks with Adafruit IO - Back to the Future with timezones Testing the display support recently added to Adafruit IO's no-code Arduino firmware, WipperSnapper, I've come unstuck with my automations a few times due to living over the other side of the pond (🫖) from Adafruit HQ...
"Why?", you ask? Time-zones!
In case you were unaware, Adafruit HQ runs on New York time, also known as EST (Eastern Standard Time), which is currently 4hours behind UTC (daylight savings can alter this 4hr offset).
Now to make life easier, the schedule block uses a timezone location set in the User account page, meaning my schedules run as expected, yay! The tricky bit comes when you want to start comparing time or timestamp values.
Most things live in server time, which is set to New York, but many other bits and bobs are presented in UTC.
For our purposes we want things in our local time, advancing time back to the future, with a no-code clock!Setup DST Change-over Actions
- Create a new feed to store the timezone offset inside if you haven't already got one. Do it on the /feeds page, and then on the new feed page add data manually for the current time-zone offset.
- Create a new Action on the /Actions page, called "Start of DST", with a description of when it should run.
- Add a schedule trigger block to the diagram. Use the cogs to alter the schedule block for your DST changeover. In my case we don't support "last X in Month" yet so I'm using "Every Sunday in March", followed by a check of a liquid template function if it's the last sunday in the month.
- If needed for complex schedules then add a Set Variable block (variable named timezone_offset_hours) with the value set to the timezone offset feed (Get feed block). Otherwise jump to step 7.
- Add a set variable block for a new variable called is_last_sunday, then add a template block as the value.
For the template body, use the following (which adds 7days then compares the month to current)
Template:{%- assign now_s = "now" | date: "%Y-%m-%dT%H:%M:%S" | date: "%s" %}{%- assign now_z_s = "now" | date: "%Y-%m-%dT%H:%M:%SZ%z" | date: "%s" -%}{%- assign server_utc_diff = now_z_s | minus: now_s -%}{%- assign thing = 3600 | times: vars["timezone_offset_hours"] | minus: server_utc_diff -%}{%- assign bst_time_s = now_s | plus: thing -%}{%- assign current_month = bst_time_s | date: "%m" -%}{%- assign next_week_month = bst_time_s | plus: 604800 | date: "%m" -%}{%- if current_month != next_week_month -%}1{%- else -%}0{%- endif -%}
- Add a logic IF condition block, then place a number comparison block from the maths category (=)
Inside the number comparison block, add a Get Variable block for is_last_sunday, and compare to 1.
- Add a Set Feed block to the Actions: section of the diagram, and select the timezone offset feed in the dropdown. For the value enter the local UTC offset in hours during the next daylight savings time period.
- Save and run the action, enabling if asked.
- Create a second action for the end of Daylight savings time, with the appropriate local UTC offset in hours for that next period. Save it and run it, enabling if asked.
Your actions should look similar to this:
- Create a new feed to store the timezone offset inside if you haven't already got one. Do it on the /feeds page, and then on the new feed page add data manually for the current time-zone offset.
-
Using the Terminal and displayio for DVI in CircuitPython See the new guide Using DVI Video in CircuitPython which supersedes this Playground Note. Same author, greatly expanded content.
-
Fruit Jam USB Host MIDI Tester This is a CircuitPython-in-the-middle MIDI filter and visualizer project for Fruit Jam. When you plug a USB MIDI controller into the Fruit Jam, MIDI input events will be shown on the DVI visualizer display and echoed on the usb_midi output port to the Fruit Jam's host computer. You could use this as the starting point for a USB MIDI filtering project.
The note visualizer has a grid of channels and notes to cover the range of a full size piano (midi notes 21 to 108). Dots indicate a note that hasn't played yet. Note-On messages turn the dot into a white rectangle. Note-Off messages turn the rectangle black. It works like a 1-bit heat map showing which notes and channels are active. Pitch bend, CC, aftertouch, etc. get shown as text in the bottom left of the visualizer and echoed to the serial console. USB host port connection status gets shown in the bottom right of the visualizer.
This code was developed and tested on CircuitPython 10.0.0-beta.0 with a pre-release revision B Fruit Jam prototype. Keep in mind that things may change by the time CircuitPython 10.0.0 is released.
Related guide: Fruit Jam Gamepad Tester
Transparency note: Adafruit provided the Fruit Jam rev B prototype board I used for this guide (Thanks Adafruit!).
Overview
-
GPS Tracker Coding in CircuitPython - Going Down the AI Rabbit Hole The Idea
I've lately been dabbling with AI coding assistance and have been impressed with what it can do. So, I thought I'd do a whole project from scratch using several boards I have been meaning to do something with. I thought I'd also take you all on the journey and maybe you will find this useful. I will use this Playground article to document the process. I will go through the components and assembly, list the prompts I used with the AI tool to build the code, and share what value this new tool gives me.
The Build
The project is a GPS tracker. In a nutshell a GPS module, an OLED display and an AdaLogger board. Here are the components I used:
Design Choices
I chose these components for simplicity. Choosing an AdaLogger for the microprocessor gives me an SD card to log the output and gives me one Neopixel, a separate LED I can use as an indicator and an extra input button with board.BUTTON. The OLED display, although small (128x32), can convey a lot of information if done well, plus it gives me three input buttons for controls. The GPS board just works well with little effort.
Assembly
Since the Feather ecosystem is perfectly modular, assembly was simple:
- Solder headers on to the microprocessor, GPS FeatherWing and the OLED FeatherWing
- Solder the sockets on to the Feather Tripler
- Prepare the AdaLogger by inserting a formatted SD card and attach the LiPo battery to the connector.
- Insert a coin cell into the GPS module
- Plug the three boards into the Tripler - I used a couple of rubber bands and a small piece of foam on the bottom to hold it all together
That's all there is to it! With that - we are (almost) ready to code.