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.
-
Build patterns: IR receiver variants Overview
This note presents a few different ways of building an microcontroller-based IR receiver. It is meant as a complement to the "PC media remote" note.
The idea is to somewhat parallel "Software design patterns" -- only for physical hardware builds. The note provides a variety of implementation examples for an IR receiver project. Juxtaposition is used to compare various different mechanical/mounting systems that provide structure, and also different practical connectivity solutions. Hopefully these options will make builds feel a bit more approachable, and possibly inspire new ideas.
Regarding the overall design philosophy: Attempts were made not to solder everything together in one monolithic block. Design often involves making mistakes, so having a way to easily re-configure your solution as it develops really helps. More specifically, I find that building "blocks" in a somewhat modular/generic fashion is preferable to building something that is completely "application-specific". As a bonus, if your blocks don't quite work out the way you want, they can more likely be re-purposed in later projects.
A good way to improve on the original "PC media remote" breadboard example is to use the IR receiver module (#5939). The build pictured above makes use of the STEMMA-QT port from a PiCowbell protoboard, and mounts all components to a 5x5 Adafruit swirly grid. Overall, this build should be a little more robust than what can be obtained with the breadboard solution, yet still be achievable without any soldering (if using Pico board with pre-soldered headers).
Some things to keep in mind:
- Need a custom 4-pin JST-SH to 3-pin JST-PH cable.
- Make sure the pin order is correct to avoid damaging the circuits (especially power/gnd).
Connecting the 2 boards in this fashion requires modifying a pre-built JST-SH cable (this one, for example). Crimping JST-SH connectors can be a bit difficult due to the small size, but removing the 4th (yellow) wire from a 4-pin connector is a bit more manageable. A hobby knife can be used to ⚠️carefully lift the plastic tab to release the pin/wire. Once that's done, JST-PH pins can be crimped to the other end of the cable, which in turn snap into the 3-pin JST-PH connector needed for the IR receiver terminal.
-
CircuitPython "Ring Oscillator" RNG with SN74AHCT14 I've long had an interest in random number generation. In fact, a very early PCB I designed and built was exactly for this purpose: Arduino Random Number Generator.
That project used a property of transistors called "avalanche noise". Inconveniently, it required a supply of +-10V to work properly. Avalanche noise is sometimes explained as being a "quantum effect" and thus is supposed to be a source of true randomness.
There are other types of physical randomness. One actually exists inside the RP2040 chip already: It has a Ring Oscillator peripheral built in. However, this project shows how to build a Ring Oscillator from a simple "78*14" chip and process it into an infinite unguessable string of bytes using CircuitPython.
I built this project with a QT Py RP2040. It's very simple; the only other required parts are the 74*14 chip, a breadboard, and some wire.
This is not a truly robust RNG and you shouldn't use it for anything serious. For example, someone could tamper with it and just remove the connection between the RP2040 and the ring oscillator; the code wouldn't notice, but its outputs would be exactly the same each time it was powered on. Real RNG products will have part of the software that verifies that the random source is behaving like a random source and is not fixed at a single value, or otherwise trivially predictable.
Ring Oscillator Theory
A Ring Oscillator is based on a ring of an odd number of Schmitt-trigger XOR gates. This project uses three gates in its ring.
The output of gate 1 is tied to the input of gate 2; the output of gate 2 is tied to the input of gate 3, and the output of gate 3 is tied to the input of gate 1.
Suppose you want to know the value that will appear at the output of each gate. Well, let's suppose the input to gate 1 is HIGH. Then we must have:
- Gate 1 input: HIGH output: LOW
- Gate 2 input: LOW output: HIGH
- Gate 3 input: HIGH output: LOW
Notice how we concluded that if the gate 1 input is HIGH, then the gate 1 input is LOW. In philosophy class, you'd call this a logical contradiction and just decide that such a thing cannot exist. But in a physical system, what happens is: Each gate takes some length of time to "drive" its output from HIGH to LOW or vice versa; and each gate has some specific input voltage to determine whether it wants to drive its output HIGH or LOW. And in fact these properties vary unpredictably from moment to moment.
The exact period of a ring oscillator like this varies from moment to moment, depending on many physical details. A lot of ink can be spilled by electronic engineers & physicists about exactly "how random" this is, but a screenshot from a scope shows clearly that over even a short period of time the crests and troughs of the output of the ring oscillator "smear out" across all possibilities:
-
Option Map: Microcontroller form factors Overview
This page gives an overview of microcontroller form factors typically used by the maker community (at a beginner/intermediate-level). The intention is to assist in finding the right fit for your projects. To achieve this, a high-level introduction of said form factors, and simple feature/property matrices will be presented. Naturally, coverage will be limited by the author's personal knowledge of available options (even if popular in other circles).
The focus is primarily on Adafruit products (tends be available in these popular form factors), but also makes associations to names used by other companies (aliases).
Common form factors (FF)
The following sections present common form factors in decreasing order of size. A few different feature/property matrices will follow (Sorry. Not sure how to link to a lower section).
FF: Mega/Grand Central
Alias: Uno (Arduino), Metro (Adafruit)
A key development board instrumental in popularizing the entire microcontroller-based DIY/maker movement. The UNO significantly reduced the barrier to entry for microcontroller-based prototyping & development.
Note that there are currently 4 revisions of the UNO format (Currently at UNO R4). Arduino describes the differences over time in this article. Another article describing the differences in more detail is linked here (Not verified by the author, but information looks reasonable).
Other useful information:
- Considered relatively large by Today's standards (though realistically still very tiny at ~2.1x2.7").
- Popularized the idea of stacking "shields" on top of the base microcontroller board.
- ...but newer form factors have become so small, that the trend is to stack add-on boards (like FeatherWings) side-by-side using "doubler", "tripler", and "quadrupler" carrier boards.
FF: Feather
-
EPS32 V2 eInk / ePaper Daily Calendar and Clock I oh so wanted to build Liz Clark's QTPy CH32V203 eInk / ePaper Daily Calendar & Clock but I didn't have much luck with booting and programming the CH32V203 board. I am no expert on how to do this. So I reversed engineered the code to Circuit Python and put in on the Huz/zah ESP32 V2 board. I also wanted some color and used the 1.54" 3 color e-ink display. I don't have a 3-D printer so I cut a strip of plexiglass and used a heat gun to put a 45-degree bend so it looks like a paper calendar. Below is my parts list I used to make this calendar.
The code is fairly simple, and I just pieced it together from Adafruit web pages. Granted I could have used WiFi to pull the time down and I may but for now I wanted to get used to playing around with DS3231 board. I used a wire wrap pen which you can get off of Amazon fairly cheap. I've added the code here as well. I am just a NOOB to programming and mostly hack at it to get it working. If you find this helpful, great. It was a fun little project.
- Huz/zah ESP32 V2 Feather ID 5400
- Adafruit EYSSPI Flex Cable 50mm ID 5462
- Adafruit EYESPI Breakout Board 18 Pin Connector ID 5613
- Adafruit 1.54" Tri-Color eInk / ePaper Display 200x200 with EYESPI ID 4868
- Adafruit DS3231 Precision RCT Breakout Board ID 3013
- STEMMA QT / Qwiic JST SH 4 pin Cable 50MM ID 4399
- Rainbow Wire Wrap ID 4730
- Black Nylon Machine Screws and Stand offs M2.5 ID 3299
Wire connection table
EYESPI connector --> ESP32 V2
- VIN ---> 3v
- Gnd ---> Gnd
- SCK ---> SCK
- MOSI ---> MOSI
- MISO ---> MISO
- DC ---> TX
- TCS ---> RX
- SDCS ---> Pin 33 *
- SDCS ---> Pin 27 *
Note: * I will comment, and maybe someone could tell why but Pin 22 and 37 are not in the code but without them the display would not update. So I am guessing the pins are either floating or pulled to ground.
-
Option Map: Powering your circuit Wired solutions: DC adapters & USB PD
High-power: DC adapters
Regulators built into most microcontroller development boards typically cannot supply much current. A common solution is to use an DC power adapter (barrel/terminal blocks):
Some interesting options to take note of:
Regulators tend to come in 3 flavours:
- Linear regulators: Fed from a higher voltage. Typically less efficient than their "switching regulator" counterparts. Typically powered by another (higher voltage) regulator such as a DC power adapter.
- Step-down ("buck"): A switching (voltage) regulator fed from a higher voltage. Typically powered by another (higher voltage) regulator such as a DC power adapter, but can also be driven by a battery.
- Step-up ("boost"): A switching (voltage) regulator fed from a lower voltage. A useful tool to generate higher voltages on devices that aren't normally expected to need them. Commonly used in battery-driven applications where you cannot (don't want?) rely on batteries to generate the high voltages needed.
🧠️Smart load sharing
Some solutions include "smart load sharing". As with everything, not all "load sharing" is created equal, but will tend to implement the following current/power management features:
- Simultaneously power your project while charging.
- Redirect excess current to charge battery when plugged in.
- Avoid unnecessary battery charge/discharge cycles +extending battery life.
- Can be used without a battery being connected.
- Live disconnection of battery or main power source *without losing power.
- *Check product specs to make sure this is actually supported.
- Otherwise: glitches could result in unreliable power or unsafe conditions (damage circuits).
Watch this Adafruit product video (1000C) for further explanation.
Portable solutions: batteries & solar
At the time of writing, there are 4 popular solutions to power portable projects:
- Non-charging: converting battery voltages up ("boost") or down ("buck") to something better suited for your project.
- "Just charger": Separate battery chargers. Won't directly power the project, but used to complement "non-charging" solution.
- USB-fed battery chargers: Not only can your project be powered by a battery, but some options allow that battery to get charged up automatically when connected through a USB port. This is what happens inside most cell modern phones.
- Solar-capable battery chargers: For even more autonomy, some options allow the connection of solar cells. Many solar capable solutions also allow for safe USB battery charging even when connected to a solar cell. Note that not all solar-capable chargers allow safe charging on USB, and so choosing the right might require some additional investigation.
-
Calibrate Your 3D Printer for Dimensional Accuracy If you want to 3D print press-fit or snap-fit project enclosures, there are a few tricks you can use to get better dimensional accuracy. Unless you print in an extremely dry climate, it helps to dry your filament. You can also calibrate your printer's motion system, filament extrusion, and X-Y hole/contour compensation.
Drying Your Filament
FDM 3D printers work by melting plastic filament and carefully extruding it layer by layer to build up the desired shapes. Filament absorbs water from the air, and manufacturing filament involves a water cooling step. Wet filament can break more easily, and it can cause bubbles and stringing. Keeping your filament dry helps to get stronger prints with a smooth surface finish.
How Dry is Dry Enough?
People have lots of opinions about drying (for example, see r/3dprinting on reddit). For me, starting prints with filament stored in a plastic cereal box at 15% relative humidity has been working great. No bubbles. No splattering. Very little stringing.
How To Dry Filament?
For filament that's relatively dry to begin with, you just can put it in an air-tight plastic box with silica gel desiccant packs. In my experience, a plastic cereal box with about 50g of silica gel packets can take a roll of PLA filament from 25% to 15% relative humidity in less than a day. Starting at 15% out of the cereal box, if I print for a few hours in a room that's about 30% to 40% relative humidity, the hygrometer in my dry box usually reads 20% to 30% when I put the roll away. Within a few hours, that goes back down to 15%. But, it's important to note that silica gel can only absorb so much water before it needs replacement or drying, so this approach might not work well in humid conditions.
For new filament, or filament that's been stored in anything other than crispy dry conditions, starting with a filament dryer may be quicker than relying on silica gel alone. Many makes and models of filament dryers are available, with new models introduced fairly often. To see what people currently recommend, you could check r/3dprinting on reddit.
For new filament, I've been using a Sunlu FilaDryer S2 that I bought. The S2 works fine as long as I prop the lid open slightly (5mm to 8mm-ish gap). Typically, in 6 hours or less, the dryer will get a new roll of PLA filament down to about 25% relative humidity, but then it stops getting drier. From there, I put the roll in a cereal box with desiccant, wait a while, and it goes down to 15%.
Upgrading Your Printer's Firmware
Upgrading your printer's firmware to the latest available version may result in improved print quality compared to the factory firmware. How to go about a firmware upgrade will depend on what type of printer you have. For example, the Bambu Lab wiki has a page, Firmware update guide for P1 Series, that explains how to update the Bambu Lab P1S.
Calibrating Tool Head and Print Bed Movement
FDM printers use stepper motors with belts or drive screws to move the tool head and the print bed on 3 axes (X, Y, and Z). The stepper motors are controlled by the printer's firmware, which takes G-code instructions from a slicer (Bambu Studio, Cura, etc.). Calibration can help the motors move accurately, repeatably, and without problematic resonant vibrations.
Typically, printers will provide some way to make sure the bed is level and to calibrate stepper motor motion. Calibrating the motion system can help to avoid problems with waves in the surface of printed parts. Bed leveling helps with good first layer adhesion, avoiding warping, spaghetti prints, and various other problems.
How motion calibration and bed leveling works depends on what kind of printer you have. My printer is a Bambu Lab P1S, which I bought. The P1S uses a Core X-Y design with automatic bed leveling. Since bed leveling is taken care of automatically, I can pretty much ignore that part.
For calibrating the motion system to avoid problems with vibration and belt tension, the P1S has a calibration feature available in the menu system on the printer's LCD control panel. I did that when I first set up the printer. It made a bunch of noise for a while, but was otherwise unremarkable.
Calibrating Filament Extrusion
To extrude the right volume of filament so that each line your printer lays down will merge smoothly into the previous lines, without gaps or bulges, you can calibrate the extrusion of your filament. Extrusion calibration is complicated. Terms people often use to talk about it include over extrusion, under extrusion, K factor, and pressure advance. Options for calibrating different aspects of the extrusion process vary according to the model of your printer and which slicer software you use.
In the Bambu Studio slicer software, the Calibration tab offers two types of extrusion calibration, Flow Dynamics Calibration and Flow Rate Calibration. According to the Bambu Lab wiki, Flow Rate calibration is typically not necessary, so I ignored that one. But, the wiki recommends doing a Flow Dynamics calibration to set the K factor for new filament. I did a Flow Dynamics calibration for the filament I've been using (Bambu PLA Basic), and came up with a K factor of 0.02. I didn't notice much difference compared to the factory settings. The top surfaces of my prints seemed pretty smooth before and after the calibration.
Calibrating X-Y Compensation
In my experience, this is the really useful part for improving dimensional accuracy. Once you know that your filament is dry, your motion system is working well, and your extrusion flow is reasonable, it's time to check your X-Y hole and contour compensation. By printing a test block, measuring it, doing a little math, then setting the X-Y compensation values, I was able to improve my dimensional accuracy from about ± 0.12mm down to about ±0.5mm. That seems to be good enough for making press-fit bearing mounts without too much of wasted test prints.
In Bambu Studio, under Prepare tab > left sidebar > Process heading, you can turn on the Advanced process settings option. When you do that, it enables input fields for "X-Y hole compensation" and "X-Y contour compensation" under Process heading > Quality tab > Precision sub-heading.
To determine X-Y compensation values, you can print a test block, measure it with calipers, then do some simple math. Note that, similar to flow rate K factor calibration, your results here will likely be specific to the particular filament you're using and how dry it is.
-
MyState: Be one with the electronics universe 🧘♀️Ω🧘♂️. Collaborate. Interoperate. Overview
The
MyStatelibrary delivers a framework to simplify configuration and control of appliance-like devices.MyStatemakes it quick-and-easy to define device state that is readily controllable from the outside world.Writing code to control state and react to sensor inputs is time consuming. Why not (mostly) solve the problem once, and re-use that infrastructure to build up your next project faster?
Features
- Route raw sensed input signals through custom signal-generating filters, and provide a solid, uniform user-interface experience.
- Load custom device configuration/controlled state on startup by calling
ListenerRoot.script_load().- A good way to "recall presets" at the press of a button when manual configuration is a bit of a pain.
- Let anyone control your device using
SigLinkinterface (by means of a serial/other IO connection).- Ex: Let a PC control your device using
MyState"signals" sent across the USB/serial connection. - Configure your device using a custom-built GUI or web interface.
- Ex: Let a PC control your device using
- Applies more formalized (hopefully readable) patterns of "filtering" input/sense signals, and applying a "reactive paradigm" to respond accordingly.
- Aspires to enable a future of composable, modular devices where extension/customization is the norm. Getting our products to cooperate should not be a constant battle requiring mounds of ugly hacks.
✨Highlights
- Call
SigLink.process_signals()to enable quick-and-easy device control via serial/IO connection.
Details
The framework provides access to device state using something the author calls a "Model-React-Controller" (MRC) -- analogous to a Model-View-Controller.
Code Repository
- Development repository on github: MyState.
- Project examples (self contained): HomeLights_Wired. --- Download:v0.1.
SampleProj: HomeLights_Wired
-
Adafruit I2S MEMS Microphone Breakout: CircuitPython Wiring & Test Working with I2S audio input to your project can be daunting, but the CircuitPython_PIO_I2S library helps with the heavy lifting.
This guide is limited to devices supporting a compatible processor RP2xxx such as the Raspberry Pi Pico and Raspberry Pi Pico 2. Python support via Adafruit_Blinka is not supported at this time.
CircuitPython Microcontroller Wiring
Here is how you'll wire your I2S MEMS Microphone breakout (in this case, SPH0645LM4H) to a Raspberry Pi Pico (RP2040):
-
Science + Fiction = Fun! UPDATE! I discovered the "drake.py" file in my github was NOT the program I describe here. I re-wrote the drake.py program and have replaced it in the archive.
I enjoy the prospect of SETI, the Search for Extraterrestrial Intelligence. So it's only natural that I'd like to do something with the Drake equation "... the probabilistic argument used to estimate the number of active, communicative extraterrestrial civilizations in the Milky Way Galaxy." (https://en.wikipedia.org/wiki/Drake_equation)
Happily I found an example of coding this calculation (https://github.com/DeaconDesperado/pydrake) that I could adapt for this project. I've put the code in a repository "Drake"
Files
- drake.py - calculate the Drake equation- based on https://github.com/DeaconDesperado/pydrake
- sagan - Carl Sagan quotes
- wise.py - selects quotes to display
- ncount.py - used for blinking neopixels
- prt.py - allows prt() to print to REPL or HID keyboard input
Copy the files to your NeoTrinkey running (renaming drake.py to "code.py").
Touch pad#1 for the NeoTrinkey to calculate and print out the estimate - since the factors are coded as ranges, you will get different answers every time. After presenting the calculations, the program will also give a random quote from Carl Sagan - he describes the Drake equation in chapter 12 of his book "Cosmos." This is the "Science" part of my project
For fun, touching pad#2 will give a list of the names of the civilized planets - basically generating a random name for as many as the program calculated (plus Earth). Be aware that the number can be large and this will take a while. And yes, this is the "Fiction" part. :)
Change REPL=False to REPL=True to have output go as if typed via the keyboard.
Output looks like this:
How Many Alien Civilations?Number of stars in the Milky Way 1e+11Fraction of stars with planetary systems 0.131585Number of planets suitable for life 4Fraction of suitable planets that develop life 0.283515Fraction of life that becomes sentient and eventually intelligent 0.118758Fraction of intelligent life that advances to the point of communication 0.0128657Adjustment for incidence of self-destruction 1.10132e-06possible number of civilizations 25Who are we? We find that we live on an insignificant planet of a humdrum star lost in a galaxy tucked away in some forgotten corner of a universe in which there are far more galaxies than people. Carl Sagan1: Earth2: Gieuas3: Zoiah4: Syoei5: Mieud6: Zoafas7: Syan8: Theuei9: Kieei10: Zoghie11: Syaie12: Syafnk13: Zoyah14: Paeah15: Miiah16: Miuof17: Reaah18: Ahghd19: Aheei20: Giafn21: Reud22: Kiyah23: Kighn24: Theie25: Miud26: KieuofHope you have fun with this - may it give you something to ponder as you look at the night sky.
The Drake Equation -
Do You Want to Make a Starship? I'm not talking about an ill-named monster rocket booster, but honest-to-goodness STARSHIPS! As Wikipedia puts it:
A starship, starcraft, or interstellar spacecraft is a theoretical spacecraft designed for traveling between planetary systems.[1] The term is mostly found in science fiction.
https://en.wikipedia.org/wiki/Starship
I've certainly not got the resources to make such a vehicle... but what if you could build a really small spacecraft? Say, like this?
This was my inspiration to make a "Starship" on my NeoTrinkey - a simple spaceship program. My "ship on a chip" defines the decks of a ship and a set of potential destinations.
I've included it all in a github repo "Ship on a Chip"
- What IS a "starship?" :https://en.wikipedia.org/wiki/Starship
- Inspired by https://en.wikipedia.org/wiki/Breakthrough_Starshot, https://www.scientificamerican.com/article/inside-the-breakthrough-starshot-mission-to-alpha-centauri/
- trekdecks uses Enterprise deck as found at: https://memory-alpha.fandom.com/wiki/Constitution_class_decks
- Galaxy class decks: https://memory-alpha.fandom.com/wiki/Galaxy_class_decks
- Defiant class decks: https://memory-alpha.fandom.com/wiki/Defiant_class_decks
- Intrepid class decks: https://memory-alpha.fandom.com/wiki/Intrepid_class_decks
- trekdests Destinations used: https://exoplanets.nasa.gov/news/1378/top-10-star-trek-destinations-chosen-by-nasa-scientists/
- exodests from https://en.wikipedia.org/wiki/List_of_nearest_terrestrial_exoplanet_candidates
- sspythondecks created for a simple example
- Copy the files wise.py, prt.py and shipchip.py (as code.py) to neotrinkey.
- Copy a "dests" file (trekdests or exodests) to neotrinkey as "dests" (or create your own set of destinations)
- Copy a "decks" file (trekdecks or sspythondecks) to neotrinkey as "decks" (Or create your own list of decks and dests.)
Change REPL=True to REPL=False if you want output to be "typed" via HID interface.
Change showdecks = False to showdecks = True if you want the decks to be listed on start.
Touch pad #1 to go "up" a deck and pad #2 to go down - holding both jumps to a random deck.
Files:
-
shipchip.py - ship on a chip - copy to code.py
-
prt.py - copy to neotrinkey
-
wise.py - copy to neotrinkey
-
exodests - rename to dests for use
-
sspythondecks - rename to dests for use
-
trekdecks - rename to decks for use
-
trekdests - rename to dests for use
When run, you'll get a message "Welcome aboard" - and you begin on "deck 1" - usually the bridge. A random destination is chosen and after a random number of steps up and down in the turbolift you "arrive" and a new destination is chosen.
Looks like this:
Welcome aboard!Ship destination is: RemusYou are on deck: 1 BridgeYou are on deck: 2 Science labsYou are on deck: 15 Deuterium fuel storageYou are on deck: 14 Engineering support, water storageYou are on deck: 13 Observation deck, dorsal interconnectsYou are on deck: 14 Engineering support, water storageYou are on deck: 1 BridgeArrived at RemusShip new destination is: NbiruYou are on deck: 2 Science labsMake up your own ship with a list of decks in the "decks" file and destinations in the "dests" and you've got your own starship!
How's this for a starship? -
Ringing Tibetan Bowl Timer I replaced the electronics (which had died) in this product from Now and Zen. Original Product
Here is a link to the video where I talk about it. Video
Due to severe RSS, I coded all of this with Talon Voice. There are lots of things I would do to clean up this code (remove globals, clean up use of enums), and given how hard it is to code with my voice, I'm going to leave it as is.
-
Wii Nunchuck USB Adapter I have a confession to make: I don't love playing video games with a keyboard. While the keyboard/mouse combo is the preferred input method for most PC gamers, I find my left hand often gets cramped using WASD-based keyboard input, and wish for a more ergonomic input method sometimes.
I had an idea to make a simple adapter to map Wii Nunchuck input into keyboard events a game would recognize. I figured I could map the Nunchuck's analog stick to keyboard events for movement, and could map the two digital buttons on the Nunchuck to other keys while I was at it.
This setup would allow me to use the Nunchuck to partially or entirely replace input from my keyboard.
Overview
This no-solder adapter is built with either a QT Py RP2040 or a Trinkey QT2040 microcontroller, coupled with a Wii Nunchuck breakout board connected by a Stemma QT cable. The firmware, written in CircuitPython 9, translates Wii Nunchuck analog stick and button events to keyboard events. Thanks to CircuitPython, customization is easy, allowing you to make changes to the generated key events any time. So far, I have used this adapter for games like XCOM-2, FTL: Faster Than Light, and Half-Life 2!
I've included 2 build variants here, one for those with access to a 3D printer, and one for those without. The QT Py build uses a 3D printed case for mounting the QT Py and the Nunchuck breakout board. The Trinkey QT2040 build takes advantage of the identical screw hole placing on the Trinkey and the Nunchuck breakout adapter board, using a handy standoff mounting kit to make a nice tidy little USB-A adapter.
-
ESPTOOL-JS with Partition Table listing + Data saving - Easily backup your device before installing circuitpython/whatever I'm often wanting to list what's on a device in terms of partition table. There's a handy utility included with the ESP-IDF, but it's python only and it only accepts files so you have to first call esptool to save your partition table data. I've had to do it so often that I've saved the two commands in another playground note, but not any longer!
The other thing is I swear that there used to be some online place to download your devices flash for backup using web serial, but try as I might I cant find such a place, and my google-fu is usually on point - ignoring my switch to duckduckgo...I digress, introducing my latest possibly needless project, esptool-js "partition edition":
How to use it?
Well, the image above shows after I've clicked the Read Partition Table button. The default partition offset of 0x8000 should be fine for most boards, otherwise try 0x9000, although custom partition table offsets are supported. You won't even see those options until you've clicked Connect and selected your boards serial port.
Once your partition table has loaded it shows the expected information, the bit most people are usually interested in is the first app partition, or ota_0 in this case, and the user file system (user_fs), which is a FAT partition in this screenshot.
The final column in the table has the download button for each partition, clicking it will start reading from the flash memory of the connected device, and once finished will ask the browser to download it. It will be named according to the chip name, partition type, starting offset, and size in bytes, but all the numbers are in hex not decimal.
-
Tiny Terminal with a Magnetic Connector Those nice magnetic connectors (four pins) were waiting to be used in some small project of mine, until now.
I needed a way to peek in on a UART serial stream, but did not want to add a UI to the project or always have a laptop along for the ride. So I made what is not all that different from those old DEC VT-200 terminal consoles of old (nevermind if you are not nostalgic for those beasts).
With an RP-2040 to listen to the UART and send the text to one of those nice little Monochrome 0.96" 128x64 OLED Graphic Display.
I first used this snap on terminal concept as part of a project that was logging data to an SD card, but really any project that might need to log serial data can also have a snap on terminal added. Wire the UART to a mag connector, in my case I put 5v Power and Ground on either side while the TX and RX pins are in the middle, but there's not really a standard (until now ;) and the RX is optional as it is not used (yet). [Gnd, TX, RX, 5v]The code for any project just needs to send serial data out via UART serial.
import busiouart1 = busio.UART(board.GP8, board.GP9, baudrate=115200)
# then Write out your messages ...
uart1.write(bytes("Hello Terminal\n", "ascii"))The code for the terminal console monitor gadget (to listen and display) is Circuitpython. Easy with a just a bit work to get the all the previous lines of text to linefeed-up like terminals do (at least it DOES NOT using up endless green-&-white stripe fan-fold paper).
Other than the wiring for the display, all you need to do is get your power and serial from the mag-connector and remember to connect the TX coming from your serial sending project to the RX on the tiny terminal.
Once you have this tiny terminal working on a project, adding a little code and mag connector to any new project is easy. Sending Serial Data out on a UART TX pin and providing a little power and ground is all that is needed to light up a very useful, retro and tiny terminal. -
Adding WIFI the Easy Way Adding WIFI the Easy Way
If you start from scratch, the best thing is to buy a board with integrated WIFI. But this is not possible in all cases. Many older boards just don't have a suitable chip. This is especially true for boards that are based on the RP2040.
For example I recently bought the TinyFX from Pimoroni. That is a very small board about the size of a Qt-Py for controlling Lego lighting kits:

Another example is the Tufty2040, a large sized display with a RP2040 on board:

But I have also quite a few other boards lying around that would profit from connectivity e.g. the ItsyBitsy M4 Express. And of course I also own some of the shiny new Pico2 boards.
Airlift
The standard solution for adding WIFI is Airlift. Airlift is a WIFI-coprocessor running a special firmware on an Espressif ESP32-WROOM-32. Besides the "pure" chip on a breakout, there are also addons for specific form-factors like a FeatherWing or a BitsyWing.
But Airlift has two major problems. The first is wiring. Airlift is based on SPI and in addition uses a number of control GPIOs. So if you don't use one of the wings (that block all of your pins) you end up with wiring 7-9 jumper-cables. That is not only cumbersome, but the boards above don't even provide that many pins (the TinyFx e.g. just exposes what you see in the image).
The second problem is software. The Airlift uses a special CircuitPython library that does it's job, but in a slightly different way than the standard WIFI support of CircuitPython does. E.g. instead of connecting with
wifi.radio.connect()you useesp.connect_AP()and instead of usingwifi.radio.connectedyou check the connection state withesp.is_connected. There are many other differences in the API. So all the boilerplate code you have or download from the internet has to be adapted for the Airlift. As long as this is your maincode.pyfile, this is no major problem. But once you start using libraries things get complicated. You have to install the source version of the libs and adapt them. Maintaining this is no fun.ESP-AT
An alternative to Airlift is ESP-AT. This is a firmware maintained and provided by Espressif turning many of their chips into WIFI-coprocessors. ESP-AT is highly customizable but in its standard versions it uses plain UART for the communication with the main MCU. So you basically only need four wires: VCC, GND, RX and TX.
The drawback of ESP-AT is its textual interface: you send so called "AT-commands" to the co-processor and then you have to parse the response to extract the relevant data. Some of these commands are really complicated, e.g. to connect to an AP you would send
AT+CWJAP="myssid","mypasswd",,0,1,3,1,5,1
Wrapping all the complexity in a library really makes sense. For this reason, Adafruit had created the library CircuitPythonESPAT_Control, but it was abandoned in favor of Airlift and is no longer maintained. That library also suffers from the same drawback as the Airlift library, i.e. it uses a different API than standard CircuitPython.
CircuitPython-ESP32AT
For this reason I created a new library called CircuitPython-ESP32AT. This library talks to the ESP-AT on an ESP-coprocessor, but instead of inventing yet another API it uses the standard CircuitPython API for
wifi,ssl,socketpooland so on.At first, this might seem confusing. On boards with native WIFI these modules don't need to be installed, since the CircuitPython firmware already provides them. For other boards, the ESP32AT project now provides drop-in modules with the same names providing (almost) the same set of functionality.
One important function the external modules don't provide is the web-workflow which really needs native WIFI. Otherwise, you need to look hard to spot differences.
You will find installation and setup instructions as well as notes about various hardware alternatives in the repo of the library. Instead of reproducing this information here, I only show some examples I actually use.
Hardware
From hardware side, you need a board with a supported ESP-chip. Any ESP32, ESP32-S2 and ESP32-Cx will do. ESP32-S3 and the ESP32-Hx series are not supported. You can even use very old ESP8266 hardware as long as it has 1MB of flash. But this is not really recommended since the ESP8266 only supports operation in TCP/UDP/SSL client mode. In addition, you have to compile the firmware yourself (which in fact is easy and a matter of a quarter of an hour - see the repo for details).
Wiring is easy: you must connect RX/TX of your host MCU to the AT-UART ports TX/RX of the coprocessor. Besides RX/TX you should also connect GND. Powering the coprocessor directly from the host MCU might or might not work. For example, I had no problems powering the ESP32C3-SuperMini from the 3V3 pin of the Pico/Pico2, but I did not use any other peripherals:

The connection in this image uses a trick: it redefines the I2C-pins of the PiCowbell adapter from I2C to UART. Of course you loose I2C on these pins, so this is not a solution for all problems but it demonstrates how simple wiring can be compared to the Airlift.
I am using the same trick for the TinyFX board from above. The board does not have any dedicated UART-pins, but the pins of the Stemma/Qt can also be repurposed to UART instead of I2C. This allows a very simple connection using a Stemma/Qt-DuPont adapter cable for the connection of the TinyFX to again to an ESP32C3:
Even simpler is the usage together with the Maker Pi Pico Board. This board has a socket designed for the ESP-01S:

Liligo has created a chip with the same form-factor and basically the same pinout, which is called Lilygo T-01 C3. This board works also in the socket and gives full performance and provides all WIFI-functionality.
The Swedish company "iLabs" even has a Feather-sized RP2350 board with an integrated ESP32C6:

Ok, we will see a Pico2-W soon, but until then, this is the best solution for a WIFI-enabled RP2350.
Performance
For most use-cases like updating the time, querying an API (e.g. for weather information) or running an AP with a webserver the performance is just on par with native WIFI. There are some special cases though where native WIFI is better: e.g. I have a high-frequency data-sampling application that sends data using UDP to a reciever. Native WIFI can send with a rate of 0.001s per message, using ESP-AT this is much slower (I measured 0.015s per message).
Also, if you are dealing with large responses the default chunk size of 32 bytes that the
adafruit_requestslibrary uses will slow you down, since every chunk is an AT-transaction. Usingresponse.iter_content()directly is a workaround to speed up processing (this also helps native WIFI a bit and Airlift too).