• 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
Sign In to create your own notes.

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.

New
Featured
  • By ostgate
    AIR PRO: a Pip-Boy style air quality monitor with Qualia S3 and SEN66

    I wanted an air quality monitor I can read from across the room, and I wanted it to look like something from a Fallout vault.

    AIR PRO reads CO2, particles (PM1.0 to PM10), VOC, NOx, temperature and humidity every 2 seconds. It turns all of that into one simple status: OPTIMAL, NORMAL, FAIR, CAUTION, WARNING or CRITICAL. It also tells you the main problem, for example "MAIN THREAT: CO2, VENTILATE ROOM".

    Everything runs on CircuitPython. No cloud, no app. WiFi is only used for a few seconds every hour to get the time.

    Full code, parts list and photos: github.com/ostgate/air-pro

    Parts

    • Adafruit Qualia ESP32-S3 for TTL RGB-666 Displays
    • 4" 720x720 square TFT display (RGB666)
    • Sensirion SEN66 (CO2, PM, VOC, NOx, temperature, humidity)
    • Adafruit SHT45 Temperature and Humidity Sensor (STEMMA QT)
    • Adafruit I2C QT Rotary Encoder with seesaw
    • STEMMA QT / Qwiic cables
    • USB-C cable and a USB charger
    • A small wooden box (for now)

    All sensors and the encoder share one I2C bus through STEMMA QT cables. No soldering needed.

    Build

    The case is a small wooden box I had at home. The display sits in the door, with the Qualia board on its back. The SHT45 and SEN66 are mounted on the outside wall of the box, so they breathe room air and do not get heated by the board and the backlight. The rotary encoder shaft comes out of the top.

    Small wooden box with a square screen showing green Pip-Boy style text: air status NORMAL, CO2 952 ppm, temperature 24.0 C, humidity 48.2 percent.
    Environment Overview: overall air status, CO2, temperature, humidity, dew point, PM2.5 and VOC.
  • By fede2
    Meshtastic-compatible full stack (in 🦀) for CircuitPython

    If you want to get a Meshtastic-compatible library that works great in CircuitPython, of course there is no better place to start than the MeshFruit library!

    Yet, there is another library in town, that might be a have some extra steps to install it, but because it has been written in Rust, and for CircuitPython, it bridges the two things we like the most: an efficient and fast full stack library with the ease of use of CircuitPython.

    The way that it has been designed, you can connect to REPL and have the library already talking with the Meshtastic network, while you send messages or read your inbox using simple commands. But, if you power on the device and to manually take it to REPL, it will start running code.py acting as a Meshtastic client that you can connect with your phone via the official Meshtastic application, or you can interact with it over the network by using the official Meshtastic Python API.

    So, you can use the REPL for simplicity, learning how to use the library, quick serial console or web-workflow testing, use the default code.py that comes with the library to connect your phone with the same app everyone else is using, and of course you can call the library from your own CircuitPython code to let your project start talking with the amazing Meshstastic network.

    Compatible hardware

    Since me, the author of the library, only has a handful of hardware that is both capable of running CircuitPython and that has a LoRa radio, so far the list of hardware is a bit limited to a couple of new and shiny boards that Meshstastic enthusiasts are gravitating to, because of very useful features. With the library released, now I will work on adding support for Adafruit hardware, and later for popular Meshtastic hardware. So far, we got:

    • Muzi Works' Base Duo: nRF52840 with LR1121 radio. Cool features: 915MHz + 2.4GHz LoRa, BLE, integrated solar charger.
    • Meshnology W12: ESP32-S3R8 (same S3 we know and love, but with 8M of PSRAM!) with LR2021 radio. Cool features: 915MHz + 2.4GHz LoRa, FLRC! (more on this, below), WiFi, multi-net navigation device, OLED screen, comes with case, a very decent 915MHz antenna and battery.

    Note: This boards are not official CircuitPython supported hardware, yet. I'm working on it, but we found an external issue that Adafruit is trying to solve.

    Integrated devices

    • The latest generation of LoRa radios from Semtech: LR1121 and LR2021.
    • A navigation device (GNSS or "GPS")
    • An OLED screen

    How to install

    Any device

    • Use a CircuitPython build that has CIRCUITPY_ENABLE_MPY_NATIVE enabled. This might require a manual rebuild, but it's required for Rust support.
    • Copy the mpy files for the radio used in your board to the CIRCUITPY/lib on your board. Current support is for: LR1121 and LR2021
    • Copy the mpy files from the cpy-meshtastic library to the CIRCUITPY/lib on your board. Note: Since Rust is compiled, in a similar way to Turbo, you need to use the mpy files compiled for your board's arch.
    • Copy the code.py, repl.py, and settings.toml to the root of CIRCUITPY on your board. Edit settings.toml to configure the LoRa region, client short and long name, as well as any board specific features like WiFi connection, OLED, navigation device, and to enable how you want to connect to the Phone app.

    This is a short example of a settings.toml file:

    MESH_RADIO = "lr2021"
    MESH_GPS = "gps"
    MESH_PHONE = "tcp"
    CIRCUITPY_WIFI_SSID = "your access point"
    CIRCUITPY_WIFI_PASSWORD = "4d4fru1t-ru13z"
    

    Board specific install

    Meshtastic folks are used to flashing from a web browser, and using a single file to install the firmware.

    Look for the UF2 file that includes both CircuitPython, the radio, and the cpy-meshtastic library, for either the Muzi Works Base Duo, or the Meshnology W12.

    Notes:

    • For the Base Duo board, embedding the library in the UF2 is needed anyway, to save memory.
    • The W12 board is so new that they don't have UF2 support yet. Install TinyUF2 on it, first.

    Usage

    REPL

    If you copied the repl.py file to the root of your CIRCUITPY folder on your board, use CTRL+C as usual to enter the REPL. The power of having repl.py on your board, means that all of the init that has to happen to use cpy-meshtastic is already happening there; so the board is already listening to incomming packets from the Meshtastic network, and if you want to send a message, just ahead and do it. This is an example of what you will see:

    Press any key to enter the REPL. Use CTRL-D to reload.
    repl.py output:
    LR1121 fw 1.1, hw 0x22
    # meshtastic node, firmware v2.7.26.54e0d8d
    # US/LongFast ch 20/104 @ 906.8750 MHz SF11 BW250.00kHz CR4/5
    # node 0x0b9dbde1 relay 0xe1 channel 0x08, key from nvm
    # +22 dBm, duty cycle 0.00% of 100% over 3600s
    # keystore: node_num=4 bytes, channel_key=16 bytes, channel_name=0 bytes, region=2 bytes, preset=8 bytes, channel_num=4 bytes, tx_power_dbm=4 bytes, duty_cycle_pct=4 bytes, nodeinfo_s=4 bytes, long_name=13 bytes, short_name=4 bytes
    # cache: 32 nodes, 25 messages restored
    
    # read() peek() unread() channels() nodes() listen(30)
    # send("text") introduce() poll() status() save() stop()
    # ask(num) ask(num, "environment") node() release()
    # phone() serve()
    # settings() configure(region="EU_868")
    
    Adafruit CircuitPython 10.3.1-rust on 2026-09-14; muzi works Base Duo with nRF52840
    >>> nodes()
    
    # 32 nodes heard
    # number     short   hops  pkts    snr   last  long
    # 0xb2a73a5c          3h   117   10.5   56s  
    # 0xaca9f8e8          1h   549   10.5    1m  
    # 0xe277a008          4h     1   10.5    2m
    (...)
    >>> send("Hi from Costa Rica, using cpy-meshtastic")
    
    # learned 0xcXXXXX is Long-Name (short-name), hw 101
        1  (id=0xAAAA fr=0xBBBBB to=0xffffffff, WantAck=0, HopLim=2 Ch=0x8 Portnum=4 rxSNR=10.25 rxRSSI=-65 signalRSSI=-65 hopStart=7 relay=0xbd)
           node=Hopp port=nodeinfo bytes=73
    # clock set from 0xCCCCCC: 2026-09-25T17:31:49Z UTC
        2 17:31:49  (id=0xDDDDD fr=EEEEEE to=0xffffffff, WantAck=0, HopLim=1 Ch=0x8 Portnum=67 rxSNR=10.5 rxRSSI=-52 signalRSSI=-52 hopStart=3 relay=0xbd)
           node=0xGGGGGG port=telemetry bytes=22
    

    code.py with Phone app

    Install the Meshtastic phone app, power the CircuitPython device (remember to configure settings.toml), and in the settings of the phone app scan for either bluetooth or network devices, depending on the capabilities of the board you are using and it's configuration, and connect to that device.

    The list of nodes, configuration, channels and other settings will be shared from the phone app to the CircuitPython device, and now you can use the phone app as you would if you had the original Meshtastic firmware on your LoRa device.

    It's optional, but if you decide to open up a serial console to the device while running in code.py "mode", it sill show something like this:

    Connected to /dev/tty.usbmodem441B67EA618F1
    # code.py: last reset POWER_ON
    # code.py: bringing the node up, Ctrl-C stops it here
    # no GNSS module 'gps'; the clock will come from elsewhere
    LR2021 fw 1.24
    # meshtastic node, firmware v2.7.26.54e0d8d
    # US/LongFast ch 20/104 @ 906.8750 MHz SF11 BW250.00kHz CR4/5
    # node 0x0f61ea67 relay 0x67 channel 0x08, key from nvm
    # +22 dBm, duty cycle 0.00% of 100% over 3600s
    # keystore: node_num=4 bytes, channel_key=16 bytes, region=2 bytes
    # cache: 24 nodes, 32 messages restored
    # no interrupt support in this firmware, use listen()
    #   (cannot watch that pin: no port support, already in use, or no slot left)
    # code.py: announcing, which keys the sub-GHz amplifier
    # nodeinfo: Meshtastic ea67 (ea67), asking for replies
    # sending 59 bytes, 681 ms on air
    SENT  (id=0x4cba0c09 fr=0x0f61ea67 to=0xffffffff, WantAck=0, HopLim=3 Ch=0x8 Portnum=4 WANTRESP hopStart=3 relay=0x67)
    # phone: tcp starting, 8165120 bytes free
    # phone: tcp on 192.168.123.123:4403 (meshtastic-0f61ea67.local), 8140624 bytes free
    # code.py: node up, panel running -- Ctrl-C for the prompt
    # phone: 192.168.123.123:4403 (meshtastic-0f61ea67.local) connected from 192.168.123.123
    # phone: 12 bytes in, 1 queued, at 0.0s
    # phone: 8 bytes in, 32 queued, at 0.2s
    # clock set from the phone: 2026-09-25T17:54:29Z UTC
    
    

    And if you keep looking you should see one printed line for every message that is received or sent on the Meshtastic network.

    In this screenshot, you can see a connected device, which is shown as a full-compatible to a device that would be using the original Meshtastic firmware!

    Cpy-meshtastic
    Orchids in Costa Rica with a cpy-meshtastic on Meshnology radio
  • Image for user societal_participant
    By societal_participant
    Electronic Cowbell

    One day I thought it'd be fun to take something ordinary that isn't electronic, and make it so, just for fun. 

    Enter the Electronic Cowbell. 

    It's a simple electronic motion-activated cowbell that when you turn it on and gently shake it, it responds to your movement and jingles like a real cowbell. It's a wholly unnecessary object to have, but it's all for fun.

    The Electronic Cowbell uses an Adafruit RP2040 Prop-Maker Feather with built-in LIS3DH accelerometer to detect movement, and a built-in I2S amp that plays a WAV file through an attached speaker.

    This project is also coded using CircuitPython.

    Required Parts

    The following parts are needed for the project.

    In addition to the parts below, you will need to 3D print the cowbell enclosure. The cowbell enclosure is available for download on Thingiverse: Electronic Cowbell

    A photo of the electronic cowbell enclosure.
  • By sandwichman64
    Micro:bit wifi security system

    This project is for kids

    do you need a cookie watcher or a make sure your hidden stash of candy is safe?

    well WSS:bit is here for the job!

     

     

     

     

     

    items you need:

    and tape or twisty ties

    a img of a iot board
  • By afranchuk
    Page Playground: Using Web Serial in Firefox

    Firefox's browser engine, Gecko, added support for Web Serial in release 151. This opens up a fun new path for hardware-to-web experiments and experiences. To try it out, I built Page Playground: a device featuring a variety of novel input methods that allows me to point at elements on a web page and alter their colors, layout, text properties, and transforms in real time. It reveals the potential for powerful and intuitive user experiences integrating hardware with the web.

    Idea

    As seen in the video, the Page Playground can alter various properties of elements on a webpage. It creates a new and fun way to interact with a page, but you can imagine a lot of professional use cases for such a tool, too (like web development, style tweaking, etc).

    Assembly

    Adafruit stocks a great set of essentially plug-n-play parts, so getting this off the ground didn't take much time at all! I decided to use the MACROPAD RP2040 as the base of the device functionality, since it has a nice screen, rotary encoder, and 12 keys with RGB LEDs. This was plenty to work with already, but I also added:

    • two more rotary encoders,
    • an IMU (BNO085),
    • a color/proximity sensor (APDS-9960),
    • a joystick, and
    • a slide potentiometer.

    All of these provide fun and different ways to interact with the webpage.

    The joystick and potentiometer are simple analog devices, so I needed to get another board to access those over I2C (because the MACROPAD doesn't expose anything other than I2C over a STEMMA QT port). Conveniently, my order was large enough that Adafruit provided a KB2040 for free :)

    MACROPAD

    The MACROPAD was very easy to assemble; I just had to add the key switches and caps, and a rotary encoder top (I didn't realize the bare bones kit didn't come with one, so I came up short one top, whoops).

    Your browser does not support the video tag.
  • Image for user AnneBarela
    By AnneBarela
    Using ESP-Claw with a Local LLM

    ESP-Claw is a new tiny AI device for Espressif microcontroller-based boards. Supported boards must have at least 8MB Flash and 8MB PSRAM to run ESP-Claw. 

    ESP-Claw devices require a connection to the real world. This includes:

    1. WiFi (local) for communications
    2. A Large Language Model (LLM) for reasoning (OpenAI, Anthropic, DeepSeek or local)
    3. (Optional) A connection to Telegram for communication (there is now a crude web interface if Telegram is not desired)
    4. (Optional) A connection key to search engines Brave Search or Tavily (both services have fees)

    I have tested ESP-Claw with a Claude API key. While some folks have it working, I found, at the lowest API access paid level, ESP-Claw could exceed tokens per second limits. And I don't want to put $100 on Anthropic's books to get that squared away.

    HTTP 429: This request would exceed your organization's rate limit of 30,000 input tokens per minute (org: fb68d6db-0824-4998-b920-fe36549c9cae, model: claude-sonnet-4-6). For details, refer to: https://docs.claude.com/en/api/rate-limits. You can see the response headers for current usage. Please reduce the prompt length or the maximum tokens requested, or try again later.

    Using a Local Model Instead

    I had set up my local computer to run an LLM per the guide Setting up an LLM model on your own computer. It can generate up to 40 tokens per second which is decent but not using crazy hardware. 

    I wanted to use this local LLM over my home network to connect to my ESP-Claws (yes, I have four 'Claws). 

    The latest builds of the flasher software allow for a local connection to an LLM model with OpenAI, Qwen, Deepseek or Anthropic calling conventions. It took me a bit of time, but I found the right combination of settings to get things working. This is what I'll share below.

    claw_setup.png
  • Image for user AnneBarela
    By AnneBarela
    Setting Up an LLM Model on Your Own Computer

    Many of us have been there: working with Claude, ChatGPT, Copilot, etc. and BOOM, the token allowance runs out and you have to wait a few hours for it to reset. All you want to do is finish your project.

    Well, you are on your personal computer which can compute things. Perhaps your machine can even play some fairly recent games? If so, you have free compute right at your fingertips.

    Some of the AI models used by the big companies are available for free. This is true. The trouble is knowing which model to get, where to get it, what to run it with and how to tune the model to your machine. If this sounds complicated, it's less complicated than installing current games and likely takes up less space. But you'll want to follow this guide for some tips on how to do this.

    There are many models and many ways to run them. I'll show you some of what I have done as an example for you to do similar.

    canirun.png.png
  • By BlitzCityDIY
    Homebridge Plugin for Adafruit IO Feeds

    Recently I wanted to try setting up Homebridge to interface with our Apple Home setup. What is Homebridge?

    Homebridge is a lightweight Node.js server you can run on your home network that emulates the iOS HomeKit API.

    It basically lets you connect non-Apple HomeKit supported devices to Apple Home. There are plugins that you install within Homebridge that can expose more features or let you customize how a device appears within the Apple Home app.

    I decided that I wanted to try creating a plugin for Adafruit IO to send data from Adafruit IO feeds to Apple Home. 

    This was inspired by the work that Trevor did a little while ago with the itsaSNAP app. That iOS app lets you interface with Adafruit IO feeds within iOS. We wrote a lot of fun guides experimenting with the use of Apple Shortcuts combined with Adafruit IO.

    One piece that was missing was the ability to have data go from IO to Apple Home. We could control devices already in Apple Home (usually Matter devices) with Shortcuts that integrated with itsaSNAP, but we couldn't send, for example, temperature sensor data from a feed to Apple Home and have it show up in a Room.

    Screenshot_2026-02-24_151111.png
  • Image for user pixil3d
    By pixil3d
    How to Repair Maschine Mikro Mk3 Pads

    Non-responsive Pads

    Repairing Native Instruments Maschine Mikro MK3 pads involved opening the enclosure to clean the contact traces on the PCB, sensor pad and rubber elastomers with isopropyl alcohol and a Q-tip to remove debris (mostly cat hair).

    This playground note will walk through the device teardown and cleaning the contacts and rubber elastomer pads.

    Remove Bottom Panel screws

    Start flipping the device over with the bottom panel facing up. Then, use a Phillips screwdriver to remove 14 screws from the bottom panel.

  • Image for user tbjers
    By tbjers
    Planck V7 mount for Apple IIe Fruit Jam Enclosure

    I recently came across the absolutely amazing Apple IIe enclosure for the Fruit Jam designed by the Ruiz Brothers. Since I did not have a KPR BM43 on hand and didn't want to spend $43, I did a deep dive into AutoDesk Fusion and I have created a mount for the Planck v7 keyboard PCB for the Apple IIe enclosure.

    Thanks to everyone in the Adafruit Discord server for the helpful pointers and banter while I worked on this!

    You will also need the updated keyboard case, because the USB-C port is in a different place on the Planck v7.

  • By tdprinkipia
    Bringing My Godzilla Collectible To Life

    So this all started right after Thanksgiving 2025 when it was time to put up the Christmas tree. Normally, we put the old Lionel train in a boring circle around the tree. That is about all the room I have for it. So I decided to get some N-scale trains so I could be more ambitious with a train layout. So what kind of scene do we build? Sleepy Christmas village? Nah, Godzilla smashing things up, of course. So I had the idea of taking an 8" Bandai Godzilla Minus 1 Ichibansho Figure

    Godzilla and building a diorama around him. But then I had the idea of making his dorsal fins light up with a NeoPixel strip. This meant learning how to use a microcontroller and making the lights do the atomic breath pattern. And I was hooked. So the trains are now put away, and I have been working on a system for putting action figures on a stepper motor controlled turntable. That system has a dedicated esp32-s3 with a tmc2209 stepper driver and a basic NEMA 17 stepper motor that is accurately positioned using an AS5600 magnetic encoder. Using WiFi, I control the turntable with a built-in web app or via Python software running on my Mac or Raspberry Pi 5. The software can choreograph mock battles, or silly dance routines. It also allows me to use a PS4 Dual Shock controller to manually control the turntable. 


  • Image for user danak
    By danak
    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 phrases

    Generating 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

    Fruit Jam Clock
  • Image for user ntynen
    By ntynen
    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:

    1. Have a list of supported animations - this is done via the animations.json file
    2. Be able to override the default values for animations
    3. 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.

  • By DanCogliano
    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/

     

    title_screen.png
  • By melastmohican
    Rust on Adafruit RP2040 Feather ThinkInk (JD79661 E-Paper)

    I wanted to share my experience experimenting with Rust on the Adafruit RP2040 Feather ThinkInk board, specifically using a bare E-Paper display.

    Hardware:

    • Adafruit RP2040 Feather ThinkInk (https://www.adafruit.com/product/5727)
    • Bare EPD display (JD79661 chipset): {https://www.adafruit.com/product/6373)

    Background

    I went through all the official tutorials for the ThinkInk Feather: https://learn.adafruit.com/adafruit-rp2040-feather-thinkink

    The provided examples are excellent, but they currently focus on CircuitPython and Arduino. Adafruit already provides solid drivers for the JD79661 chipset, and the display is also well supported in the Arduino ecosystem via the GxEPD2 library: https://github.com/ZinggJM/GxEPD2

    This made me curious: can I do the same thing in Rust?

    Rust on RP2040

    The RP2040 has very good Rust support thanks to the rp-rs ecosystem. A great starting point is the RP2040 project template: https://github.com/rp-rs/rp2040-project-template

    There is also an existing HAL board definition for the Adafruit Feather RP2040 here: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit-feather-rp2040

    While it’s not an exact match for the ThinkInk Feather, it’s close enough to serve as a solid base, with only minor adjustments needed.

    Driver work

    At the moment, there is no native Rust driver for the JD79661 E-Paper controller. To move forward, I implemented a custom Rust driver, based directly on the source code from Adafruit’s CircuitPython and Arduino implementations.

    Once the low-level driver was in place, everything integrated nicely with the Embedded Graphics framework. Rendering text and images worked as expected.

    As a proof of concept, I was able to:

    • Convert a JPG image to BMP
    • Render and display it correctly on the E-Paper display

    Results & Code

    All of my experiments and findings are documented here: https://github.com/melastmohican/adafruit-feather-thinkink-discovery

    The repository includes:

    • Project setup for Rust on the ThinkInk Feather
    • A custom JD79661 driver
    • Examples using Embedded Graphics
    • Notes on differences between the standard Feather RP2040 and the ThinkInk variant

    Closing thoughts

    Overall, Rust works very well on the RP2040, and bringing up an E-Paper display was quite feasible even without an existing driver. Hopefully this helps others who want to explore Rust + E-Paper + Adafruit hardware.

  • 1
  • 2
  • 3
  • 4
  • 5
  • …
  • 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
    "Things do not happen. Things are made to happen"
    John F. Kennedy
    Adafruit Logo
    A Minority and Woman-owned Business Enterprise (M/WBE)