• Skip to main content
  • Shop
  • Learn
  • Blog
  • Forums
  • IO
  • LIVE!
  • AdaBox
Adafruit Logo
0
  • Sign In | Create Account
  • Playground
  • Shop
  • Learn
  • Blog
  • Forums
  • IO
  • LIVE!
  • AdaBox
Sign In
0
Adafruit Logo
  • Learn Categories
    • 3D Printing
    • AdaBox
    • Adafruit Products
    • Arduino Compatibles
    • Breakout Boards
    • Circuit Playground
    • CircuitPython
    • CLUE
    • Community Support
    • Components
    • Crickit
    • Customer & Partner Projects
    • Development Boards
    • Educators
    • EL Wire/Tape/Panel
    • Feather
    • Gaming
    • Hacks
    • Internet of Things - IOT
    • LCDs & Displays
    • LEDs
    • Machine Learning
    • MakeCode
    • Maker Business
    • micro:bit
    • Microcontrollers
    • Programming
    • Raspberry Pi
    • Robotics & CNC
    • Sensors
    • STEMMA
    • Tools
    • Trellis
    • Wearables
    Explore, Groups to get your gears turning
    Explore
    Groups to get your gears turning
    Explore Groups
  • New Guides
  • Playground
SamBlenny Notes

SamBlenny

u/SamBlenny
Badges
17
9

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.

  • By SamBlenny

    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

    ESP32-S3 TFT Feather with LiPo pack and battery voltage shown on the display
    Save
  • By SamBlenny

    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.Filter to bandpass filter the output of a  synthio.Synthesizer for 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

    Closeup photo of mx straight key and Fruit Jam TRRS jack breakout board wiring details
    Save
  • By SamBlenny

    NeoKey TOTP Token

    This is a two factor authentication token to generate TOTP login codes for up to four accounts. You can select which account by pressing a key on the 4-key NeoKey keypad. The design is intended for desktop use in a safe location (wall power + no worries of physical tampering) but where you do want to prevent secrets from leaking over the network due to mis-configured cloud-sync backup features or whatever.

    Design Goals and Features:

    1. Make the codes really easy to read and type, even in low light, by using a dimmable backlit TFT display with a relatively large font.
    2. Support 4 TOTP account slots (one for each key of a 4-key NeoKey keypad).
    3. The NeoPixel under the key for the currently selected account slot lights up. Pressing a different key switches the selected account. Pressing the selected key a second time puts the token in standby mode (backlight and NeoPixels off).
    4. Store secrets in an I2C EEPROM rather than in the CLUE board's flash. This makes it so the secrets aren't trivially accessible to a connected computer as USB mass storage files. This way, they won't get accidentally sucked into backups, and malware would have to work harder to access them.
    5. Set DS3231 RTC time from the USB serial console by opening the REPL, importing the util module, then calling util.set_time().
    6. Add and manage TOTP accounts in the EEPROM's database of account slots by using similar REPL functions (import util then util.menu()).
    7. Use the token fully airgapped after initial setup by powering it from a phone charger and reading codes off the TFT display.

    Overview

    photo of NeoKey TOTP token in use
    Save
  • By SamBlenny

    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 cflow code analysis tool to generate a graphviz (.dot) graph file, then turn that into a PNG image to view with the mirage image viewer. For mirage to 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/*

    control flow graph of c code generated with cflow and graphviz
    Save
  • By SamBlenny

    IRC Display Bot

    A CircuitPython IRC bot for Metro ESP32-S3 to show status notifications on a small dedicated screen.

    This uses a 2.8" TFT display shield to show the topic of an IRC channel in large text. Combined with a local Raspberry Pi hosted IRC server, you can use this to make a wireless status notification system for environmental sensors or whatever. Once you put the wifi and IRC server details in your settings.toml, the display will connect automatically. Then you can use any IRC bot or client you like to set the channel topic to whatever should be shown on the display. For example, I built this to work with my serial-sensor-hub project which forwards USB serial sensor reports from my lora-greenhouse-monitor sensors.

    Overview

    irc-display-bot running on Metro ESP32-S3 with Raspberry Pi and a phone running an IRC client app
    Save
  • By SamBlenny

    3D-Printed Enclosure for IRC Display Bot

    This is an enclosure I designed for an angled desktop notification display with a Metro ESP32-S3 and a 2.8" TFT display shield. I'm using this as an IRC client to run my irc-display-bot code for LoRa temperature monitoring, but the same hardware build would easily work for other CircuitPython IoT projects where you want a little desktop status display.

    I designed this in Blender using geometry nodes to build up a model of the negative space for the Metro, display shield, and cutouts for the viewable screen area and cable ports. The only mildly tricky thing about it was that it's important to use the "Mesh Boolean" node with the "Exact" algorithm to join objects. If you use the Geometry Join node, or a different algorithm, the resulting geometry will be messed up and not usable as a cutting tool with the boolean difference modifier.

    To learn about the code I'm running for the IRC display bot, check out my IRC Display Bot Playground guide.

    Overview

    irc display bot enclosure overhead right view
    Save
  • By SamBlenny

    LoRa Wireless Greenhouse Monitor

    This project uses 900 MHz RFM95W LoRa FeatherWing modules to transmit temperature measurements from greenhouses and receive them at a base station about half a kilometer away. The base station hardware outputs sensor reports over USB serial, an optional 2x16 Character LCD, and an optional ESP-NOW gateway.

    The LoRa radio settings are tuned for extended battery life at a range of up to 500m in suburban or rural conditions (non line of sight with limited obstructions). With a fully charged 400 mAh LiPo battery and a 9 minute reporting interval, typical sensor runtime should be about 4 weeks (~22µA deep sleep current, ~2667ms of time per wake cycle, ~0.222 coulombs of charge per wake cycle).

    To optimize the transmitter for running on a small LiPo cell, I used a Nordic nRF-PPK2 power analyzer to tune the firmware. Some of the power saving tricks I used include reducing the cpu frequency, putting the RFM95W radio in sleep mode, putting the MAX17048 fuel gauge in hibernate mode, and using ESP32-S3 deep sleep. To compare the impact of different changes, I took extensive measurements using Nordic's Power Profiler app with the PPK2 connected to the Feather board's battery jack and GPIO outputs.

    Transparency note: Adafruit provided some of the parts I used for this guide (Thanks Adafruit!).

    Related Projects

    For logging, charting, and IRC status notifications, check out my related projects:

    • serial-sensor-hub
    • irc-display-bot.

    Overview

    LoRa thermometer base station and sensor with PPK2
    Save
  • By SamBlenny

    Exploring the Arduino App Lab Binary

    Overview

    To understand what the new Arduino UNO Q is about, I've been looking at the new the Arduino App Lab coding tool. The App Lab download page links to the source code at https://downloads.arduino.cc/app-lab-release/source-app-lab.zip, but the source seems incomplete. Among other differences, there aren't any build instructions or scripts in the source archive. So, I've been poking around trying to understand how the source works and how it differs from the binaries.

    Highlights of what I found: You need a UNO Q board to get past the first screen. The app is written with Wails which uses Go for the backend and a web app for the frontend (similar to Electron, but using a native web view rather than embedding a browser). The binaries include embedded markdown for examples that don't appear in the source. The app may be using Hotjar telemetry for analytics.

    Download Checksums

    When I downloaded the macOS dmg, Linux tar.gz, and source-app-lab.zip files on October 16, 2025, these are the checksums I got:

    Arduino App Lab start screen
    Save
  • By SamBlenny

    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

    photo of a battery powered synth with MIDI keyboard and earbuds
    Save
  • By SamBlenny

    Pasting in Hard Mode with VNC and SSH

    My main computer is a Mac, but I run third party dev tools on a separate Debian box so they can't mess up my main computer. To control the Debian box from the Mac, I use SSH and VNC over Ethernet. The VNC session runs an Xfce desktop environment.

    Mostly the remote control setup works great, but it's a pain to copy from macOS and paste to apps running in Xfce (macOS Screen Sharing VNC client app doesn't do clipboard sync). For example, suppose I want to copy text from Chrome on the Mac and paste it into VS Code on Debian. Since I can't paste directly into the VNC client, I must go through an SSH shell where pasting works fine.

    In the past, I've used SSH to paste into vim and make a temporary file. But, today I figured out a better way where I can send text directly to the Xfce clipboard from my SSH shell:

    Notes:

    1. If you don't already have xclip installed, you'll need to sudo apt install xclip
    2. The cat <<'EOF' stuff is using bash's heredoc string syntax. Note that in this case the single quotes around EOF are telling bash not to do its normal variable substitution. This is useful if you want to copy and paste code that includes bash variable syntax, perhaps as part of a Makefile. In this case, ${WHATEVER} will get passed through to xclip rather than being evaluated as a variable substitution by bash.
    3. I have TigerVNC server configured to set DISPLAY to :1. Since the instance of bash that's running in my SSH shell is is not part of an X session, it doesn't know about TigerVNC's display. I have to tell xclip which DISPLAY to use, otherwise it would get mad and complain with an error message.
    Save
  • By SamBlenny

    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

    Screenshot of Fruit Jam DVI display showing two gamepad button-press visualizers
    Save
  • By SamBlenny

    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

    screenshot of usb midi tester visualizer display
    Save
  • By SamBlenny

    Fruit Jam Lines Screensaver

    This is a twisty-lines CircuitPython graphics toy inspired by screensavers from the 1990's (Macintosh After Dark 2 NightLines, Windows 95 Mystify, etc). To make the trail of lines, the code keeps track of two bouncing-ball style points and draws a line between them. Each new line gets added to a list, and the oldest line gets dropped off the end. The line colors cycle through a color swirl palette generated from a gradient using the LCh color space. This is meant for picodvi video output on RP2350 boards including Metro RP2350 and Fruit Jam.

    To learn more about how I generated the rainbow swirl color palette, check out my Fruit Jam Color Gradient Generator Playground guide from last week.

    This code was developed and tested on CircuitPython 10.0.0-alpha.7 with a Metro RP2350 (no PSRAM version) and a pre-release revision B Fruit Jam prototype. Keep in mind that things may change by the time CircuitPython 10.0.0 is released.

    Transparency note: Adafruit provided the Fruit Jam rev B prototype board I used for this guide (Thanks Adafruit!).

    Video Demo

    Lines screensaver screenshot
    Save
  • By SamBlenny

    Fruit Jam Color Gradient Generator

    This generates rainbow swirl color palettes in the LCh color space for picodvi displays on RP2350 boards. You can use the WASD keys on the serial console to adjust the Lightness and Chroma, but hue angle is generated automatically. The point of this is to make palettes for Metro RP2350 or Fruit Jam that will look good for making color swirl animations.

    The default picodvi video mode is hardcoded to 320x240 16-bit, using an 8-bit bitmap and a palette of 256 colors selected from the 65536 possible RGB565 colors. On boards with PSRAM (Fruit Jam), you can edit the code to use 320x240 32-bit for smoother gradients.

    This code was developed and tested on CircuitPython 10.0.0-alpha.7 with a Metro RP2350 (no PSRAM version) and a pre-release revision B Fruit Jam prototype. Keep in mind that things may change by the time CircuitPython 10.0.0 is released.

    Transparency note: Adafruit provided the Fruit Jam rev B prototype board I used for this guide (Thanks Adafruit!).

    Overview

    neon palette
    Save
  • By SamBlenny

    Fruit Jam Hypotrochoid Spiral Maker

    This draws hypotrochoid spirals (like Spirograph) for a picodvi display on Fruit Jam or Metro RP2350. I tested this on a Fruit Jam rev B prototype and a Metro RP2350 (no PSRAM version). The 320x480 8-bit video mode works on both, but 640x480 8-bit seems to need a board that has a PSRAM chip. The curves get plotted as individual pixels using a color ramp that cycles through the entire 8-bit RGB332 palette. This might be useful to people looking for sample code showing how to configure picodvi displays for RP2350 boards.

    For more details on the math for Hypotrochoid curves, you can check out the Wikipedia or Wolfram MathWorld Hypotrochoid pages.

    Transparency note: Adafruit provided the Fruit Jam rev B prototype board I used for this guide (Thanks Adafruit!).

    Overview

    Curve 2 at 320x240 resolution
    Save
  • 1
  • 2
  • 3
  • Next
  • Last
Search

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.

    • Contact Us
    • Tech Support Forums
    • FAQs
    • Shipping & Returns
    • Freebies
    • Terms of Service
    • Privacy & Legal
    • Website Accessibility
    • LLMs.txt
    • About Us
    • Press
    • Educators
    • Distributors
    • Jobs
    • Gift Cards
    "People who are really serious about software should make their own hardware"
    Alan Kay
    Adafruit Logo
    A Minority and Woman-owned Business Enterprise (M/WBE)