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.
-
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:
- WiFi (local) for communications
- A Large Language Model (LLM) for reasoning (OpenAI, Anthropic, DeepSeek or local)
- (Optional) A connection to Telegram for communication (there is now a crude web interface if Telegram is not desired)
- (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.
-
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.
-
Robots, Robots Everywhere! My granddaughter and I love robots, and thanks to the Goodwill stores and little free libraries, we have a good supply of books, like the one above "Robots, Robots Everywhere!"
So it only made sense that I should try to put together her own robot. I had a spare Circuit Playground Express, two servos, battery pack, a jigsaw and a supply of plywood. And this is what we came up with.
Robot Programming
I decided to use MakeCode to program the robot - mainly because it let me use the microphone to trigger on "loud noise".
Program has multiple functions:
- LeftArm - moves left arm
- Right - moves right arm
- Smile - plays a tune and show "white smile" on the neopixels
- Frown - plays a tune and shows "blue frown" on the neopixels
- GoCrazy - sets up a random loop choosing the four functions above at random
The A/B buttons will trigger the Left/Right arm functions. A+B triggers "GoCrazy."
When the switch is set to the left, clapping your hands (or some other loud noise) sets the left and right arms moving. [When I was first testing, the "loud" sensitivity was too sensitive and the noise from the servos kept it going so it wouldn't stop.]
I wrote another Makecode Circuit Playground program that I could use with another CPX to send commands to the robot. Pushing the A button cycles through 1, 2, 3 and 4 green neopixels showing. Pressing the "B" button transmits the number which the robot uses to choose LeftArm, RightArm, Smile or Frown.
When the switch is set to the right any IR signal from the "controller" CPX will trigger GoCrazy. The same goes for a loud noise.
Future Plans
The fun in using the CPX as the "brain" means reprogramming our robot pal is very easy. I already tweaked it getting it set up, and I expect I'll think of more things - I'm sure my granddaughter will have feedback and suggestions.
And, of course, I expect CircuitPython is in the droid's future - that would let me give it a "voice!"
-
KB2040 as I2C Bridge with GUI Control Use your KB2040 to create a USB to I2C Bridge to connect to your I2C Peripherals. The UXB-300 is a browser-based GUI builder that lets you wire up register-level controls of an IC without touching any code. Below are the details using the LPS22 as the peripheral.
Hardware Used:
USB Bridge: Raspberry Pi - KB2040 : https://www.adafruit.com/product/5302
Peripheral : Temperature & Pressure Sensor - LPS22HB: https://www.adafruit.com/product/4633
Schematic/Datasheet: https://learn.adafruit.com/adafruit-lps25-pressure-sensor/downloads
Cables: USB-C Cable between PC and KB2040 https://www.adafruit.com/product/4474
Qwiic cable between KB204 and LPS22HB https://www.adafruit.com/product/4399
The Arduino IDE 2.3.8 was used to create and load a sketch onto the KB2040. The UXB-300 was used to create a GUI to control the peripheral and display the results in real time.
Links to Sketch and GUI:
Arduino Sketch: kb2040_i2c.ino : https://github.com/labs16/KB2040-I2C-Bridge
UXB-300 LPS22HB GUI: https://apps.labs16.com/poverholt/kb2040_i2c_lps22
Just want to jump in? Connect to your KB2040 with LPS22HB Hardware, click the UXB-300 LPS22HB GUI link above, and skip to the Connect Hardware and Control with GUI step below.
Want to build it yourself? Continue to follow along…
Detailed Steps to do on your own: ( Define | Create | Connect )
The Raspberry Pi has USB OTG capability and is configured in the sketch to use serial protocol to send and fetch I2C commands. The UXB-300 GUI can be easily configured to communicate with the KB2040 and interactively communicate via I2C with the peripherals.
Since the KB2040 is used as a USB bridge, we need to define the serial data I will be sending and receiving between the KB2040 and the UXB-300 GUI over USB. The packet payload definition will, at a minimum, need to support the peripheral being used - in this case an LPS22HB.
Packet Payload Definition: (byte count varies with data length)
< Byte0 > < Byte1 > < Byte3 >< Byte4 >.....< Byte8 >
< Byte0 > = Mode/Size Byte and it contains information on whether it is a Block Transfer and the Size(Bytes) of the Data. The High Nibble determines if it is Block and the Lower Nibble is the size of the Data Transfer. A High Nibble of 0xB indicates a block transfer.
Example: 0xB2 means Block of length two bytes, 0x04 means non-block of length four bytes.
< Byte1 > = R/W Byte: Read = 0x72 and Write = 0x77
< Byte2 > = dev-id = 7-bit Device Address for the peripheral
< Byte3 > = ADDR = register address in Hex
< Byte4:N Bytes > = DATA sent / received
< Byte N+1 > ERROR Byte
The Packet Payload Definition above was used for this project. This definition is flexible — both the sketch and GUI packet builder are easy to adjust per your application.
The peripheral datasheet and peripheral schematic allow us to confirm the settings and that the definition above is sufficient. The peripheral is non-block with a data size of one byte.
Byte0 = 0x01
dev-id (7-bit) Device Address is as follows:
101110xb, where x reflects the SDO/SA0 pad state (labeled SDO/ADR on the schematic, pulled high to 3.3V via R4).
Byte 2 = dev-id (7-bit) = 1011101b = 0x5D
Table 16 from the datasheet provides the supported Register Addresses, which are one byte in size, together with the datalength which is shown to be one byte in size as well.
The ERROR Byte will be returned by the KB2040 (0x00 if no error, 0xFF if error)
This translates to the following for writing and reading from the peripheral using the KB2040 as a USB bridge.
Send: 0x01 0x77 0x5D<ADDR><DATA><ERROR>
Fetch : 0x01 0x72 0x5D<ADDR><DATA><ERROR>
- Bold indicates bytes returned from the KB2040 versus sent from the host.
The Arduino Sketch uses Adafruit’s KB2040 board, which is available via Board Manager on the Arduino IDE under Raspberry Pi Pico/RP2040/RP2350. The Adafruit NeoPixel Library was installed.
Normally you'd write something custom on the host side to read these registers — UXB-300 handles that, letting you go skip straight to the hardware. The tool is available at
Click Create to start a new project. Choose the sign-in path or create the device from scratch. If you are already signed in, you can select the LPS22 from the list of devices available, Otherwise, name your project, type in the Device ID (as noted above, the Device ID for this board is 0x5D) and select custom. Click on Create.
-
Klingon Fun for the Fruit Jam github project repository HERE
Search for Klingon words from the books "Kahless" and "The Final Reflection"
Files
ASCII ART IMAGES
- D7
- bird
- emblem
- fleet
- ship
- warbird
- blade
CODE
- code.py
- kahless.bmp
- kahless.py
- metadata.json
TEXT FILES
-
kahless.txt - info from "Kahless" by Michael Jan Friedman
-
klingonaase.txt - info from "The Final Reflection" my John M Ford
-
worf - Worf quotes
-
kahless.bas BASIC version of Kahless
Project description
KAHLESS is a reengineering of a C64 Basic program I wrote almost 30 years ago after I found a website listing Klingon words used in the novel "Kahless" by Michael Jan Friedman. My C64 program was written and compiled on an emulated C64. Interpreted string operations are SLOW - without the emulator running in "warp" mode, the program would not have been useable.
This project involved recovering the language info from the C64 binary (which I had posted in uuencoded form to a website). I then thought I should include some of John Ford's "Klingonaase" from "The Final Reflection" - happily I found https://afrodita.rcub.bg.ac.rs/~alexp/books/klingon.html which listed the vocabulary (fan and gaming sites have added more, but for this project I stuck to the words from these two classic Klingon novels (Available in the omnibus edition "The Hand of Kahless").
How to Use
On a Fruit Jam, copy all the files except kahless.bas to a directory "apps/KAHLESS". Then you can click on the KAHLESS icon to start the program. When run you'll see:
| | | ' ` | | | | ' ` .-'| |`-. / / \ \ |__,\ / | -' \\ //\_ | ,-' ___\\.// `-__ /__,--' `--.____-- `-._____.-' ------------- What do you want to search for in the Kahless/The Final Reflecton lexicons?Enter any string, for example "op"
------------- What do you want to search for in the Kahless/The Final Reflecton lexicons? op Kerpach(a modern Klingon (shopkeeper) KAHLESS kleon Enemy, or opponent. Same, to a Klingon. [TFR] tai-kleon Worthy opponent. See 'kleon' above. [TFR] teskas tal'tai-kleon Compliments to a worthy opponent. [TFR]Entries from KAHLESS are labeled, and entries from The Final Reflection are marked [TFR].
The program pauses 10 seconds then displays one of the ascii art files and gives the search prompt.
To use it as a sort of screen saver, type "dorandom" for the search. Then the program will display a random artwork, a random word from one of the two lexicons and then a random quote from Worf.
You can customize it by adding more quotes in the "worf" file.
Basic Version
Copy the file kahless.bas to apps/PyBasic/examples on a Fruit Jam. Then you can start PyBasic, and load "examples/kahless" and type "run"
What would you like to search for from Kahless or The Final Reflection? ? op Kerpach(a modern Klingon (shopkeeper) KAHLESS kleon Enemy, or opponent. Same, to a Klingon. [TFR] tai-kleon Worthy opponent. See 'kleon' above. [TFR] teskas tal'tai-kleon Compliments to a worthy opponent. [TFR]
Original C64 program inspiring this project -
Import Eagle Part Libraries into KiCad 10.0 Import Footprints
Open the Footprint Editor. Then click Preferences - Manage Footprint Libraries...
A pop out window will open. Towards the bottom, click the down arrow next to the folder icon and select Eagle (*.lbr). Navigate to your Eagle library and select it.
-
CircuitPython-compatible WASM Port Want to try out a bit of code but don't have a CircuitPython board on hand?
Try out the browser-based CircuitPython WASM port!
This overhaul of the WASM port is built using the wasi-sdk and uses web assembly, an emerging technology finding increasing support in web browsers.
Here's what you can expect:
-
Obstacle avoidance for dji mini 3 Raspberry Pi 4/5 + SHIM, Adafruit TCA9548A (STEMMA QT), Adafruit VL53L1X (STEMMA QT), thinking of a plug n play vs. soldering.
-
Octoprint LED Status Crystal A LED status lamp for your Octoprint-enabled printer
github repo - GarronAnderson/octoprint-status-crystal: A 3D-printed status lamp for your octoprint-enabled printer
This lamp shows your printer's status and connects via the Octoprint API. It has a LDR for automatic brightness sensing.
The STL files are adapted from this Printables link.
Assembly instructions and photos are in the GitHub repo!
-
A NeoTrinkey "Small Friend" SmallFriend
A NeoTrinkey Morse code blinker -github repository
Project files to copy to your neotrinkey:
- friend.py - Program - rename as code.py to run on neotrinkey
- morse.py - encodes text to Morse code, prints it and blinks via neopixels
- tolkien - a batch of Tolkien quotes
- wise.py - code to select a random line from tolkien file
I was revisiting my earlier project "Teach your NeoTrinkey Morse code!" and thought it would be fun to add to it, coding a "small friend" that delivers messages in Morse code.
Project blinks some colors, then blinks out Morse for "hello." Then, touch #2 and two blue neopixels blink on and off, followed by blinking one of these words at random:
message1 = "friend" message2 = "love" message3 = "joy" message4 = "peace" message5 = "hi" message6 = "hello"If you touch #1 the blue "eyes" will wink and then one of the Tolkien quotes will be blinked out in code.
If you run the program while running an IDE like Mu or Thonny, it will print the text and the morse code.
You can replace the quotes in "tolkien" or create a new file with the text you want to have blinked out. If you create a new file, then change this line:
docode(getWD("tolkien"))to name the new file.
-
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.
-
Bluesound Node Companion Introduction
We wanted an easy way to control a few aspects of our Bluesound Node box. While we could control the volume with the television remote, we could not easily switch inputs. Accessing favorites was limited to the set-top box and is restricted. For example we could not easily select a favorite saved in the Tune-In service.
This controller is simple on purpose. However, the way it's written it can easily be modified and gain expanded functionality. Pretty much if you can craft the URL to the Bluesound API, the sky is the limit!
Before You Begin
You'll need to familiarize yourself with the Bluesound API.
Full disclosure I found this document later in my efforts and only referenced it a little bit.
What I did find are some wonderful libraries with extremely helpful README documents. This is the one I referenced the most.
Once you get the gist of the URL format, it becomes finding exactly what you're looking for. The toughest for me was locating the specific URLs for the Tune-In favorites. Here's where to find them:
http://<IP of your Bluesound Node>:11000/RadioBrowse?service=TuneIn&url=presets
-
How To 3D Print Models from The Met Tools Needed
- Mobile Phone (iPhone used)
- 3D printer (Bambulab X1LC used) and filament (PLA used)
- Slicer Software - BambuStudio
- ImageToSTL website (https://imagetostl.com/convert/file/usdz/to/obj)
- STL repair website (https://www.formware.co/onlinestlrepair)
In this article from This Is Colossal, dozens of scanned objects from The Metropolitan Museum of Art are available to see. The page on The Mets website shows a decent list of artifacts that can be viewed in 3D in your browser. They feature high-resolution models with textures and even QR codes to scan for viewing in AR on mobile phones.
This got us thinking, if there's a model, we should be able to 3D print them, right?
-
Project StarTraffic Project Star Traffic Github repository
(scroll down to "How to Use" to see how to use the code)
My first PyBasic-->CircuitPython project, Project Starflight involved defining a set of ten star systems linked with three "tramline" exits to other starsystems. The goal of the project was two-fold
- See if I could write in BASIC after decades, using PyBasic and
- To try to use an LLM to translate it into Python, Python that I could adapt to work as CircuitPython
This worked pretty well, and I admit the bot did a decent job documenting my undocumented PyBasic code.
Following that I wanted to try something different.
I'm a big fan of the Star Wars ride at Disney, "Star Tours," both for the fun flight simulator effect AND the whole spaceport ambiance of the ride queue, including (see above) the Arrival and Departure displays (ala flight info in an airport). I thought it would be fun to create a running display of spaceship arrivals and departures in a Star Wars mode.
So beginning with my Starflight BASIC code, I reused the data structures defining ships, stars, planets and hyperspace exits. I used fantasynamegenerators.com to create "Star Wars"-esque ships, stars and planets, and now refer to the exits as "hyperspace lanes" (as is the current SW parlance :).
The program then generates the set of exits from each star, and in a new array, assigns each ship to one of the 10 star systems.
Next, in a continuous loop, a ship is chosen, and (if not currently in motion) it is assigned a new destination from one of the exits available. The location array for that ship now has the number of the destination star - to indicate it is moving there the number is recorded as negative (i.e. if going to star #3, "-3") is logged.
When being set in motion TO a star the program prints
Departing from [planet name] vessel [ship name] heading for [destination]note: each star has a "planet" associated with it. So departures originate from the planet to a star
if the ships location is a negative number, then the program prints:
[Ship name] arrived!! [Ship name] arriving at [destination star]Then changes the location value to a positive number to indicate it has arrived, so the next time the ship is chosen by the main loop, it will start from there.
Output looks like:
Do you need instructions? (y/n) ? y This system will display current starship traffic across a span of ten interconnected systems. Ships travel from system to system via hyperspace lanes and you will see arrivals and departures. Departing from Uverrooith Vessel: Hellhound heading for Krithuc. Departing from Codachaa Vessel: BS Khan heading for Pluedurs. Hellhound arrived!! Hellhound arriving at Krithuc Departing from Guvor Vessel: Omen heading for Krithuc. Departing from Yorar Vessel: Hellhound heading for Olutsos. Departing from Vuthadoh Vessel: SC Providence heading for Pluedurs. Hellhound arrived!! Hellhound arriving at Olutsos SC Providence arrived!! SC Providence arriving at Pluedurs Departing from Uusnes Vessel: BS Nuria heading for Sleak. Departing from Lesti Vessel: Saber heading for Sleak. Saber arrived!! Saber arriving at SleakHow to Use:
There are three sets of code here: a PyBasic version, a CircuitPython app for FruitJam and a CircuitPython version for the NeoTrinkey.
PyBasic
- StarTraffic.bas - copy this to the examples/ directory under apps/PyBasic/ on a FruitJam. Then load and run. [note: you can run this under any PyBasic install]
FruitJam App
Copy these files into a directory on your FruitJam "apps/StarTraffic"
- code.py
- metadata.json
- startraffic.bmp (icon)
- startraffic.py
Then you can navigate on the FruitJam to the icon, click and let the program start.
NeoTrinkey
Copy these files to your NeoTrinkey:
- neoStarTraffic.py (rename as code.py)
- ncount.py support file for neostartraffic.py [provides blinky lights]
- prt.py support file for neostartraffic.py [allows redirect of output as if typed]
Change the variable REPL to True or False depending on whether you are running the program in a REPL like Mu or Thonny. If not the output will be directed via HID as if typed. If REPL=False the program will wait, blinking red and green till you touch one of the touch pads. This gives you a chance to move the cursor on the computer to where you want the output to show up (eg. in an editor window).
Touching the touch pads when the program is running will terminate it.
-
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.