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.
-
Getting my Fruit Jam Clock to Speak The Idea
The Fruit Jam, with its built‑in audio, Wi‑Fi, HSTX display, SD card, generous memory, and other little goodies, is a fantastic platform for mixing creativity with a bit of technical magic. Add CircuitPython to the mix and you’ve got a wonderfully flexible development environment.
With one of my Fruit Jams, I built a display that shows an analog clock face, rotates through an album of photos of my grandkids as the background, and pulls weather data from Adafruit IO that I can scroll through using an IR remote.
With the built‑in TLV320 DAC, I also wanted it to sound like a clock — a really big clock. I wrote functions to synthesize polyphonic tones that mimic the classic Westminster Quarters every fifteen minutes, and at the top of each hour it plays a WAV file of a single church‑bell toll, repeated once for each hour. It turned into a great little project that let me explore different elements of CircuitPython and many parts of the Fruit Jam board.
It’s been running for months now and has become a charming addition to my office. And the best part is that I can keep extending it whenever a new idea strikes.
I Discovered Copilot Audio Expression
The other day, while playing with Copilot, I noticed a link to Labs at the top of the screen. Clicking through, I found Copilot Audio Expression, described as “an experimental tool designed for effortless audio creation using Copilot’s latest voice‑generation models.” You simply type a word or phrase, and it “speaks” it for you — then you can download the result as an MP3.
A few quick prompts and some experimenting with the different settings sparked an idea: Why not make my Fruit Jam clock talk?
Everything old is new again...
Stringing together audio samples to form phrases is nothing new — people have been doing it for decades, long before digital audio. One of my earliest Learn Guide projects, the Titano Weather Station, used prerecorded samples as alarms (“time for bed”). But once you go beyond a handful of words, the challenge grows quickly. A talking clock or calendar needs nearly a hundred different clips: dates, day names, months, ordinals, and more. Gathering, recording, editing, and normalizing all of that becomes a real chore.
That’s where this new AI tool shines. I can generate clean, consistent audio samples for every word or phrase I need in just a few minutes.
So let’s build a Fruit Jam clock that can announce the time and date.
Step by Step
This article focuses specifically on adding the talking capability to my existing Fruit Jam clock project. The display, weather integration, IR remote navigation, and Westminster chimes are all already in place — and I can cover those in a future article if there’s interest. For now, we’ll walk through the audio‑generation workflow that makes the clock speak.
The overall process breaks down into four main steps:
1. Generate all the required words and phrases using Copilot Audio Expression
2. Convert the MP3 files to WAV format using FFmpeg
3. Organize the files on the SD card and create logical CircuitPython lists
4. Write functions that assemble and play the spoken phrasesGenerating the samples
For my project, I needed the Fruit Jam to be able to speak:
- The time (hours, minutes, AM, PM, noon, midnight)
- The date (day name, month name, ordinal date, year)
- The quarter hours (“quarter past”, “half past”, “quarter til”)
- And as a bonus: holidays, special days, and fun extras
Copilot Audio Expression made this surprisingly easy.
Before we dive in, note that Copilot Audio Expression is part of Copilot AI Labs and is marked as experimental. It may change or disappear at any time. The site I used is: Copilot Audio Expression Website.
Copilot Audio Expression Website
-
LiPo Storage Voltage Conditioner This is a simple project to discharge Adafruit LiPo packs to 3.8 volts for storage. First you use a computer to set up the ESP32-S3 TFT Feather, then you disconnect the computer and plug in the LiPo. The battery voltage shows on the display until it reaches 3.8 volts. Once the battery discharges to the storage voltage threshold, the Feather goes into deep sleep. When you see the display turn off, you can unplug and store the battery.
Overview
-
Home Hub: Camera Introduction
Even though we live in a quiet neighborhood I wanted to have a few cameras around the property. I'm sure it will provide hours of watching mongoose, the occasional wild pig, feral cats, chickens, and turkeys in our neighborhood.
The first camera project is for our driveway. It will be paired with a motion detector.
Design
The camera is coded in Python.
You will need an MQTT broker for all of this to work together. You can use Adafruit IO.
In my implementation I set up a Mosquitto MQTT broker on a RaspberryPi 4 Model B running Debian Bookworm and Mosquitto v2.022.
For image and clip storage this project supports both writing to a local file server as well as to Dropbox. For local file storage I have a another Raspberry Pi running Openmediavault.
Parts List
-
"Polyglot" screen saver for Fruit Jam Rewrite quotes in "alien" dialects
Github repository here
This project is spun off of an earlier one, "Babel" that generates alien language words based on a rule set. The words resemble Wookie, Klingon, Vulcan, Romulan and Mando'a language vocabulary from Star Wars and Star Trek. The words created might actually be words in those languages - but for this program they are created randomly. This version is based on the previous NeoTrinkey version.
When started the program goes into a loop where a Carl Sagan quote (from the "sagan" file) is selected and printed, and each unique word is assigned one of the generated words, then the quote is displayed "translated" into the alien dialect. The progam then pauses for 20 seconds, then one of the five languages is chosen from random and a new quote is displayed.
NOTE: this absolutely not a real translation, just a fun exercise in generating alien text.
FILES:
- polyglot.py - program code
- code.py
- metadata.json
- polyglot.bmp - Fruit Jam icon
- sagan - set of Carl Sagan quotes. Feel free to replace quotes with any words of wisdom you choose.
OUTPUT:
English
-----------
Imagination will often carry us to worlds that never were. But without
it we go nowhere. Carl SaganWookie
--------------------------
OWOUUUW AORA HUW AOHA UROUH OWOAAAW AHAAUAR HUR HOR ORUOUAW RUAOUW
OUWA WUR OAHO OHOUAAW OWUOAOR OWUOAUR RAOOHTo use, copy all the files to a Polyglot directory in the apps/ directory on your Fruit Jam. You'll find a Polyglot icon in the listed apps - click on that and you'll start seeing different Sagan quotes in English and rendered in a pseudo-Alien language text.
-
Serial Programmer for ESP32 If you've ever worked with the ESP32, you'll know that it does not have native USB. Most ESP32 development boards will include a USB to serial converter chip, like the CP2102N that you'll see on the Feather ESP32 V2. If you're working with a bare ESP32 though, or maybe doing some reverse engineering, what do you do?
Parts
I was in this position for a project I'm currently working on. I'm doing some reverse engineering on the Yoto Mini player, which uses an ESP32. I needed to access the chip over serial for programming and it would need to be repeatable. I wanted it to be non-destructive to the board yet stable and to use parts that I already had in my parts bin.
I decided to solder up the programming circuit to a 1/4 size perma proto that I could plug in a USB serial/FTDI cable. You don't need an FTDI cable here, you could just use a USB to TTL Serial Cable, but I always keep the FTDI cable in my desk drawer.
-
A mini-IBM PC Using an Adafruit Fruit Jam My affinity for IBM PCs, starting with the first IBM PC 5150 is fairly well known in Maker circles. I have had several PCs now over the last few years but had pared back to one PC 5150, one XT 5160 and one AT 5170. Now that has changed, as I have a new PC, which I built. This one is considerably smaller than the others, and so much lighter in weight (it is definitely not a boat anchor).
I present my mini-IBM PC. It bears a striking resemblance to its big sister (background, to the right below), thanks to 3D printing. And the code emulates a PC up to a 386 class machine. I'll show you the details in this guide.
This build has some modular features, so you do not have to build all of the pieces shown. Possible builds:
- With all the features shown including the base system and monitor.
- Just the base system, use your own monitor.
- Optional parts of the base system include the LEDs on the front, the IBM joystick adapter and even the on/off button on the side if you wish.
- Use any USB keyboard you like.
You can start with the base system and build it up how you wish.
The project is open source under an MIT License.
Parts
-
Home Hub - Door and Window Sensors Introduction
I got burned buying into the Google security ecosystem a while back and promised myself to never do it again. Plus now I know exactly what all the pieces of our home monitoring system are doing and where they're communicating. Easy upgrading too!
All other sensors will use the same code base and construction.
Design
The sensor is coded in CircuitPython
The current case is the snap fit case provided by team Adafruit. There will be a smaller case for the sensors mounted on doors and windows.
You will need an MQTT broker for all of this to work together. You can use Adafruit IO.
In my implementation I set up a Mosquitto MQTT broker on a RaspberryPi 4 Model B running Debian Bookworm and Mosquitto v2.022.
The first sensor built and put into use is for the garage door
Our house has a detached garage. The opening for the garage is perpendicular to the house which is good for esthetics and access, bad for knowing if the door is open.
Parts
Code
Sensor
The code for this project can be found on Github.
It is one part of the larger home monitoring project.
The following libraries are required:
- os
- time
- board
- digitalio
- wifi
- adafruit debouncer
- adafruit minimqtt
- adafruit minimqtt
- adafruit connection_manager
- adafruit logging
Feature Highlights
- When the door is open the sensor publishes a 1 to monitoring.garage-sensor
Node-Red subscribes and will
- Change the indicator on the sensor page; red - open, green - closed
- Change the indicator on the home page; red - open, green - closed. Since we often reference if the door is open or closed, having an indicator on the home page saves having to switch tabs every time we want to know the state of the door
Node-Red
I have a flow dedicated to handling sensor data.
Configuration
Add an MQTT in node and configure it to subscribe to the topic for the sensor. For me it's monitoring.garage-sensor.
After that you'll need to connect it to a UI LED node that will take action based on the message payload.
I have three functions in my flow, two are disabled and will be used when traveling. The active function will generate an email when it's past a certain hour and the garage door is still open.
To build the function nodes, you will need some familiarity with Javascript. Word of caution, there are some differences between Javascript and Javascript within Node-Red. I had to narrow a few searches to get some of the answers I initially needed.
The code in the function for sending a notification looks like this:
context.data = context.data || {}; switch (msg.topic) { case "monitoring.garage-sensor": context.data.garage = msg.payload; msg = null; break; case "home.hour": context.data.hour = msg.payload; msg = null; break; default: msg = null; break; } if (context.data.garage != null && context.data.hour != null) { if (context.data.hour >= 20 && context.data.garage == 1) { var newMsg = { "topic": "Your Attention Needed" ,"payload": "Garage door is open" } } } return newMsgTo receive email, you'll need to have an MTA. I have a secondary Gmail account that I'm using to send mail.
Project Construction
Circuit Board
- Solder breadboard jumper wires to the earth and data pins.
- Connect one side of contact switch to the jumper wires
- Using the snap fit case, secure the QT PY, ensure the jumper wires are hanging outside the case, and close the case
Installation in the Garage
I used Uglu Dashes to secure the magnets to the side of the garage door and to the frame. It's been there now for over 6 months without issue. I did clean both areas with rubbing alcohol before applying the Uglu.
-
Home Hub - Motion Detector Introduction
The motion detector will be deployed alongside the driveway camera.
It can be used anywhere you'd like to track and report on motion.
Design
Design The sensor is coded in CircuitPython
The current case is the snap fit case provided by team Adafruit. There will be a smaller case for the sensors mounted on doors and windows.
You will need an MQTT broker for all of this to work together. You can use Adafruit IO.
In my implementation I set up a Mosquitto MQTT broker on a RaspberryPi 4 Model B running Debian Bookworm and Mosquitto v2.022.
Parts
I recently moved from a Raspberry Pi Pico W to a Feather ESP32v2 Huzzah because I will be using a solar to power the project and needed battery storage.
Code
Motion Detector
Home hub projects are all in this parent project.
Here you'll find the motion detector code.
Libraries Required
import os import time import alarm.pin import board import digitalio import wifi import adafruit_minimqtt.adafruit_minimqtt from adafruit_minimqtt.adafruit_minimqtt import MMQTTException import adafruit_connection_manager import adafruit_logging import analogio
Featured Highlights and One Lowlight
- Loads all configurations from settings.toml
- Notifies devices on network when motion is detected
- Suspends sending motion events when recording is in progress
- Does not utilize secure connection for MQTT broker, I have been unable to successfully connect using certificates. Even followed the solution that worked on an ESP32 a last year with no success. Instead uses a special MQTT user that has access restricted by ACL until I can get encryption working.
The TL;DR Nuts and Bolts
The sensor will subscribe to:
- monitoring.recording
The sensor will publish to:
- monitoring.motion-detect
- motion-detect.battery
When the sensor detects motion it will publish to monitoring.motion-detect which will trigger the camera to start working
When sensor receives a message on monitoring.recording that recording has begun, it will enable recording mode and will not send any motion detection events
When the sensor receives a message on monitoring.recording that recording is complete, it will disable recording mode and will begin sending new motion detection events
You will need a local MQTT server or Adafruit IO in order to record and display sensor data.
Currently implemented actions based on motion detection
- Driveway camera: when motion is detected will take a snapshot and record a 30 second clip
- Entryway or trellis lights: when motion is detected will stop the current running animation and set the lights to solid white
Conserving battery
Pin alarms are now implemented. There are two
- Wake on motion
- Wake on call to check battery voltage
The battery voltage will be published to MQTT.
As of now the battery voltage is checked every 5 minutes.
Case
I used OpenSCAD and the YAPP Box (Yet Another Parametric Project Box Generator) library from mrWheel. This library is well documented and has a lot of features.
Node-Red
All sensors share the same flow in Node-Red
Node-Red subscribes to the monitoring.motion-detect feed. When a message is received it will update the UI LED node to be either red (motion detected) or green (all clear).
Node-Red subscribes to the motion-detect.battery feed and does two things with it:
- Updates a UI LED node to be green if voltage is above or equal to 3.7, red if lower
- Sends an email if the voltage drops below 3.7
Adafruit IO
In order to monitor the sensor status when I'm out of the house, I have configured Node-Red to send the driveway motion sensor data to Adafruit IO.
-
Home Hub Project with Node-Red-Dashboard Introduction
When we moved into our new home I started planning how I wanted to handle sensors and LED lighting projects. I needed a place where I could manage motion, window and door sensors, Raspberry Pi cameras and doorbells, and LED lighting projects.
Design
First step, identify a way to see all the data once I started collecting it. I began by using Adafruit IO. However, as I thought more about what data I was going to be sending and how I wanted to access to that information and dashboard for others, I didn't want it to be public in any way. So I chose, instead, to built a Raspberry Pi 4 based Mosquito MQTT server.
Beside sensor and camera data, I wanted a way to control any LED projects, and I wanted a hub feel where data including date, time, shared calendar events, and weather data can be easily viewed.
After fumbling around a few different options for viewing MQTT data; I landed on Node-Red.
Here's a screenshot of what it looks like.
What is Node-Red
From their website, Node-Red is:
Low-code programming for event-driven applications
I'm definitely not a Node-Red expert, however, what I've learned and implemented so far has yielded results more than I expected. I quickly found modules for communicating with my MQTT server and my WLED LED nets/Sparkle Motion board.
I have Node-Red running on the same Raspberry Pi as the Mosquito MQTT server. Set up was well documented and went smoothly. Right now the service is not exposed outside of my home network so I haven't implemented HTTPS and other security features. It's on the to-do list.
I'm not going to get into the how-to portion of Node-Red, but I will be showing some of the flows I have and providing detail on how I implemented things. Where I provide more detail I will try to include examples from the configuration of buttons, button groups, and functions. In my search for information as I learn, I'm finding a lot of pictures of flows without understanding what's actually happening under the hood.
Once configured, Node-Red runs a webserver and any device can connect from their browser of choice. Node-Red also handles different display sizes so it works on your phone or tablet out of the box.
Things to know before reviewing associated projects that display in Node-Red
@flowfuse Node-Red-Dashboard-2 provides the UI elements needed to monitor and interact with devices in your IOT set up.
While Node-Red-Dashboard-2 provides most of the UI elements you will need, for an LED indicator I chose to install the node-red-dashboard-2-ui-led node.
The flow also needs MQTT communications. These are in the node-red package and do not need to be installed separately.
Because I wanted email notifications, in the event the garage door is still up under certain circumstances, I had to install the node-red-node-email node.
Projects
All projects fall under one of three categories at this point:
- Sensors
- Cameras
- LEDs
In Progress
- LEDs: Trellis/Entryway net project
- Cameras: Driveway
- Sensors: Motion detector
Complete
- Home hub
- Sensors: Garage door sensor
- LEDs: Christmas tree and star lights
-
Christmas Tree & Star Lights with Node-Red Introduction
We have a 1960's era aluminum Christmas tree. For the time that we've had it we've relied on newer and slightly less dangerous color wheels, then stage lighting. When we moved we didn't bring any of the lighting with us.
I decided to string the poles of the tree with LEDs.
The prior year I made a star topper which used a Bluefruit for lighting. This year I added 24 LEDs for the star that plug into the highest string on the poles.
Design
The current design is written in CircuitPython. For communication it relies on MQTT and Node-Red.
Everything worked great, however, after I worked on a different LED project that used WLED, I think I'll convert this project to WLED. I'm not going to delete this code base, I think it has some interesting implementation features and is worth preserving.
Infrastructure-wise with either implmentation you will need:
- MQTT - you can use AdafruitIO or build your own. In my implementation I set up a broker on a RaspberryPi 4 Model B running Debian Bookworm and Mosquitto.
- Node-Red - my Node-Red journey is chronicled here.
Parts
Code
Tree & Star
The code can be found on Github
As I was coding this project, I found myself thinking I was going to be reusing a lot of it. So I repurposed an old project and replaced what was there with new helper classes.
I did run into an issue where I could not get the LED Animation library to play nicely with MQTT. I tried a few things, including asyncio, and ended up posting on the forums. mikeysklar came to the rescue and you'll see his contribution in the code.
The tree has 196 LEDs and the star has 24.
data = { 'tree_animations': ['multi_chase'] ,'star_animations': ['rainbow_sparkle'] ,'num_pixels' : 220 ,'tree_pixel_subset': [0, 195] ,'star_pixel_subset': [196, 24] ... }Libraries Needed
import json import board import time import os import neopixel import adafruit_logging import wifi import supervisor import adafruit_connection_manager import adafruit_minimqtt.adafruit_minimqtt from adafruit_led_animation.group import AnimationGroup from adafruit_minimqtt.adafruit_minimqtt import MMQTTException from adafruit_led_animation.sequence import AnimationSequence from adafruit_led_animation.helper import PixelSubset from circuitpy_helpers.led_animations import animationBuilder from circuitpy_helpers.led_animations import controlLights from circuitpy_helpers.led_animations import updateAnimationData from circuitpy_helpers.file_helpers import updateFiles from circuitpy_helpers.calendar_time_helpers import timeHelper from circuitpy_helpers.network_helpers import wanChecker
Featured Highlights
The tree subscribes to the following MQTT feeds:
- tree.lights - listens for events from Node-Red to update animation, start time, stop time
- home.time - listens for events from home hub in order to know when to stop or start the lights
- home.sunset - listens for events from home hub in order to know current sunset, uses this for start time
In order to take events from tree.lights and actually change the running animation and colors, I needed to be able to do a couple of things:
- Have a list of supported animations - this is done via the animations.json file
- Be able to override the default values for animations
- Be able to on-the-fly update the data file to implement the new animation/colors choice
When the code first starts it will check if there are overrides for the chosen animation and do an in-line replacement of those values. It will then check to see what the color selection is. Color choice is specified in the animations.json file and can be:
- random - a random color will be selected
- data - in the data file, for each animation is an entry for color. A string representation of the color can be provided or a the name of a color_palette.
Once up and running, about every 30 seconds, the animations will pause long enough for the code to query MQTT for any updates. If a new message arrives the code will update the data file with the appropriate information and perform a
supervisor.reload().You can also change the start and stop times or disable them so that the lights will run continually.
When using start and stop times; when the criteria is met to do either, the code will light sleep until the alarm is met.
Case
I used OpenSCAD and the YAPP Box (Yet Another Parametric Project Box Generator) library from mrWheel for the Feather case. This library is well documented and has a lot of features.
I found a star on Thingiverse years ago and downloaded the SCAD file. I re-mixed it for my own needs. Unfortunatly now I cannot find the Thing anymore. If you recognize the code as yours please let me know so I can give you proper credit.
-
Show And Tell: A self contained Circuitpython WiFi enabled Ultrasonic Water Flow Sensor! Post I was recently able to get this project working with a UFM01 ultrasonic water flow sensor from ScioSense https://www.sciosense.com/ufm-01-ultras ... ng-module/ (available from Digikey and Mouser for about $37) and an old Metro ESP32-S2 I had laying around. There is a recent Arduino library for the sensor, but I wanted to try it with Circuitpython. The ultrasonic sensor was a huge improvement over the Hall Effect pulse counter sensors I had been using, as they would frequently clog, and Circuitpython isn't as good with interrupts as Arduino.
The sensor itself communicates over UART to a hardware Serial port of the ESP32 (I chose IO5 and 6, as it lined up with my existing Arduino R4 shield). It sends out a BCD hex string with the serial number, flow volume, rate, and -bonus- water temperature, which can be parsed out and displayed on the serial REPL.
Once that was working, it was on to a WiFi enabled interface. The sensors are located away from any wireless networks, so the ESP is set to Access Point (AP) mode, and the user can connect to it as one would any other wireless network (192.168.4.1 and password). Security was not a major factor, so the password was kept simple. The measured parameters are displayed on a web page to either a laptop or cell phone, as well as the max flow rate (the water is pumped through the sensor, so I use it to gauge the pump health). It took a bit to get a reset button working, but the button now resets the accumulated flow logged in the sensor. (the total flow volume remains stored in the sensor's memory after removing power).
I know the styling of the code does not use the standard settings.toml file, but can be modified if needed. The attached code.py and ufm01-circuitpython.py files are all that are needed beyond the stated includes from the adafruit bundle. It is currently working on the ESP32-S2 Metro board; you can try other WiFi enabled boards and tell me how that works.
This is a project ported from the Arduino platform, and has the advantages of much faster changes than re-compiling and downloading, especially if you just need to make minor changes. The Arduino project had the code derive a unique SSID based on the ESP32's MAC address, but I kept it simple here. Most of the code length is for the web page display and controls.Technical notes: The nature of the ultrasonic sensor is that the elements need to be immersed in water. The sensor will throw an error code if no water is present. Be sure to place is in a way that it stays full of water when any is present, like a P-trap or similar. I have mine placed above a pump's check valve.
ScioSense has a good writeup in their data sheet online. I was very happy to see an affordable and easy to implement ultrasonic flow sensor, as the turbine types I had been using would clog constantly due to small debris in the pump discharge.
The only issues I have had with these sensors are: 1: There is no reverse voltage protection diode, so either add one or be very careful when hooking it up. 2: The point where the wires enter the potting compound on the sensor is weather proof but not water proof. If the sensor is immersed in more than about a foot of water, water will eventually seep in and render the sensor inoperable.
There is also a 1-wire version of the library that uses the brown wire (seen unused in the picture). When I was working with the factory tech support (before the Arduino library came out), it was not yet supported. It now seems to work, with Arduino support for ESP32 and Mega 2560 platforms. I am testing it with the Arduino R4 Wifi, and have had some issues, which is why I gave the Circuitpython a try.The first python code is a driver that parses the hex BCD output from the sensor. It is called ufm01_circuitpython. The second code has the webserver, etc. This is my first attempt at posting on adafruit-playground.com, so bear with me, and moderators/admin- please feel free to edit this for style and content.
-
Fruit Jam Code Practice Oscillator This is a Morse code practice oscillator for Fruit Jam with super clean sine wave tones and a 3d-printable straight key. The key uses a Kailh Cherry MX compatible keyswitch for reliable switching and flexures to make a precision hinge that works well when printed in PLA. Set screw adjustment lets you shorten the keyswitch travel. The audio output chain uses an
audiofilter.Filterto bandpass filter the output of asynthio.Synthesizerfor smooth note attacks and releases without keyclick.[Update: You can now use Button #3 to generate tones if you'd rather not build the 3d printed mx straight key (2026-01-07)]
Overview
-
Moon Miner Arcade Game for the Adafruit Fruit Jam Moon Miner is a retro-styled arcade game reminiscent of the Lunar Lander arcade game from the 1980s. Your mission is to retrieve minerals from various moons around the solar system. It is a physics-based game, where you must navigate your rocket ship based on gravity and thrust to make a safe landing for retrieving minerals. Achieve a successful landing by reducing speed to near zero and keeping the lander upright on designated flat areas. It is available to play on the Adafruit Fruit Jam.
Features
- The game employs physics to maneuver based on gravity. The game takes into account each moon has different gravitational properties.
- A heads-up display shows mission flight data in real-time.
- Complete the mission of collecting gems and your best time to complete the mission is saved. Play again to beat your best time.
- There are several ways you can die. Make sure you land on a horizontal surface at a safe velocity (and watch out for volcanos).
- Use fuel locations when running low on fuel. Some locations can be revisited again for additional fuel.
- Four missions are included.
- Written entirely in CircuitPython for the Adafruit Fruit Jam.
The full learn guide, including download and installation instructions can be found at the author's web site at https://danthegeek.com/2025/12/28/moon-miner-learn-guide/
-
Newxie Digital to Analog Thermometer A Newxie display is a modern take on the classic Nixie tube aesthetic. It is a 135 wide x 240 tall TFT display with double pins on the bottom for mechanical stability - see the product page link below.
What's a good use for a Newxie display? How about an analog thermometer - you know, the old-school type with a glass tube with red alcohol inside that rises as the temperature rises. Let's build it!
Original Idea
I've been working of building a weather information center using a Fruit Jam and the AdafruitIO Weather Power-up. AdafruitIO provides over 300 hyper local weather data elements updated every 20 minutes. Using it is like drinking from a fire hose, and most boards can only handle a few data points due to memory constraints. The Fruit Jam changed all that - with a 640x480 display and tons of memory, I can now display pages and pages of weather data.
Once I had the horsepower to show more than just text, I started thinking about more expressive ways to visualize the data. I thought that a classic thermometer would be an ideal way to display temperature data. As an added bonus, by adding a narrow stripe inside the main body, I can show a second temperature, such as the "feels like" temperature. Here is how it came out:
On page 1 of the Fruit Jam Weather Center (I'm up to 10 pages so far) it shows current weather data. The thermometer sits vertically along the right edge, with bold tick marks and a clean red column that rises with the temperature. It shows degrees Fahrenheit for the left scale, degrees Celsius on the right side, and freezing is marked in red.
The graphic was built using rounded rectangles from the adafruit_display_shapes library for the outlines and indicators, lines from display_shapes for the tic marks, and bitmap_fonts for the numbers. When all was said and done, there ended up being a lot of display elements to create this seemingly simple graphic.
After all that work let's make it reusable...
With a little effort I converted the text into a separate helper library. The first hurdle was that not all displays are as large as the Fruit Jam. The original was 440 px high but to be reusable it needs to be scalable. Likewise if it isn't going to be as tall I'd also want to be able to customize the min/max values. Ultimately the goal was to make most of the elements customizable. After several iterations I with AI's help, got it working well enough to try it on a different display.
I had a "multi-board" where I have a Feather RP2350 connected to a 240x320 display, an RTC module, a TLV320 DAC, etc., that I've been using to try things out. So, I added an SPA06-003 temperature breakout and added the thermometer graphic:
-
Polyglot - more alien language fun! Rewrite quotes in "alien" dialects using an Adafruit NeoTrinkey! Github repository here
This project is spun off of an earlier one, "Babel" that generates alien language words based on a rule set. The words resemble Wookie, Klingon, Vulcan, Romulan and Mando'a language vocabulary from Star Wars and Star Trek. The words created might actually be words in those languages - but for this program they are created randomly.
A Carl Sagan quote (from the "sagan" file) is selected and printed, and each unique word is assigned one of the generated words, then the quote is displayed "translated" into the alien dialect. NOTE: this absolutely not a real translation, just a fun exercise in generating alien text.
FILES:
- polyglot.py - rename to code.py on the NeoTrinkey Set REPL=True for the output to go to the repl in Mu or Thonny. set to False and the output will be printed as if keyed in on the device the Neotrinkey is plugged into.
- prt.py - helper file to define prt().
- sagan - set of Carl Sagan quotes. Feel free to replace quotes with any words of wisdom you choose.
Touch pad #1 to select and translate the quote
Touch pad #2 to click through the language choices
OUTPUT:
Wookie Klingon Vulcan We are the representatives of the cosmos; we are an example of what hydrogen atoms can do, given 15 billion years of cosmic evolution. Carl Sagan h hi k t'ity kl k rak h hi nii taai kl lta ht kt te niuhl' naito r'k toat kl taahi w'itka niu kot Mando'a If you wish to make an apple pie from scratch, you must first invent the universe. Carl Sagan te 'aa s olj 'eusa eela res oone crl 'e 'aa 'a' yirtt e'' stna elrh arss nthe Romulan Imagination will often carry us to worlds that never were. But without it we go nowherw. Carl Sagan ihmu eif vuu'i efn leelu ei'h na'dh 'isn uhn uuld ane hemf' enk' feiaf levk' hd viefe muehn