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.
-
GFFA - Aurebesh! I really enjoy coming up with new ways to combine my appreciation for Science Fiction linguistics with Adafruit products (especially the neotrinkey!) and CircuitPython. For this project I combined a classic tool "FIGlet" with the Aurebesh, the alphabet from the Galaxy Far, Far Away... (GFFA).
I started with FIGlet, the computer program that generates text banners, in a variety of typefaces, composed of letters made up of conglomerations of smaller ASCII characters. I modified an existing font file (standard.flf), replacing the letters a-z with my handmade versions of the letters seen above (note: anyone know of a good editor for FIGlet fonts? I'd love to improve the above).
That file was rather big for the neotrinkey - so I just extracted the Aurebesh and made it into an array for aure.py, a module to convert alphabetic English into Aurebesh. Then I made a program, aurebesh.py which could call aure.py's function doAure() for displaying different sayings or the alphabet, character by character - a useful training tool to become familiar with the alphabet. That's an important skill if you come across warnings like this:
All of this work went into a Github repository "Aurebesh" - from the Readme file:
-
Using a modified Figlet font ("standard.flf") I created aurebesh.flf, replacing a-z in the font with Aurebesh symbols.
-
I extracted the text for the a-z from Aurebesh.flf and made them into an array of texts for aure.py
-
aure.py has a function doAure(text,delay,REPL) - text = the text to display in Aurebesh, delay is how long between each letter, and REPL indicates if the output is to go to the REPL or, via HID, out as keyboard input.
-
aurebesh.py is a CircuitPython program that uses prt.py and ncount.py. Touching pad#1 will deliver one-by-one the alphabet, touching #2 will choose a random saying from sayings[] and print the English version, then the Aurebesh letters, one-by-one.
Notes:
Edit the variable REPL in aurebesh.py to True for text to show up in the REPL; make it False for text to be delivered as if typed. Edit the variable "sayings" to the list of sayings you want to display in Aurebesh.
Files (copy these all to your neotrinkey)
- ncount.py
- aure.py
- prt.py
- aurebesh.py -- copy this to "code.py"
If output is going out as if typed, the program will pause when started, blinking red till you touch one of the pads - this gives you a chance to move the cursor to the window you wish to receive the output.
Info:
Figlet: https://en.wikipedia.org/wiki/FIGlet Aurebesh: https://starwars.fandom.com/wiki/Aurebesh
-
-
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
MyState
library delivers a framework to simplify configuration and control of appliance-like devices.MyState
makes 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
SigLink
interface (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
-
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.
-
Guide: Zapper Lights/Sound mod If you grew up with a Nintendo Entertainment System, you probably remember playing games like Duck Hunt that used the Nintendo Zapper "light gun". The Zapper used a clever technique that depended on the game being displayed on a Cathode Ray Tube, or CRT television. These days, CRTs are rare, and are often prized collectors items among retro gaming enthusiasts. Since these Zappers don't work on modern TVs, most people don't have much use for them anymore. So, why not convert it into a toy/prop that lights up and plays sounds?
Overview
This project uses a Prop-Maker Feather RP2040 to repurpose the the Zapper's iconic shell and clicky trigger mechanism into a prop/toy that uses a NeoPixel for a "muzzle flash", a speaker to play sound effects, and 3D printed parts to contain the electronics. The code is written in CircuitPython, and sounds can be changed or added by dragging and dropping files with no code changes required!
-
PC media remote Program your device
Installing CircuitPython environment
- Download .uf2 file here:
- Plug in USB cable from PC to RP2040 board while holding the BOOTSEL button.
- A new drive should get mounted on your system.
- Drag/drop downloaded .uf2 file onto newly mounted drive (RPI-RP2).
Installing libraries and project code
From "CircuitPython Library Bundle" (download here):
- Copy from bundle .zip file to the microcontroller [drive:]\lib\ folder:
adafruit_hid
From the PCMediaRemote release page (download here):
- Download and unzip the "Source code (zip)" file from the "Assets" section.
- Copy the "unzipped" custom project code to microcontroller [drive:]:
- [PCMediaRemote folder]\lib_cktpy\* => [drive:]\lib\
- [PCMediaRemote folder]\pkg_install\MediaRemote_RP2040\*.py => [drive:]\
NOTE: Feel free to check for newer versions of PCMediaRemote on the releases page. Code from the main branch might also be functional, but explicit releases are less likely to have issues.
Customizing your solution
You can directly modify the main.py file on the [drive:]\ folder. Every time you save the file, CircuitPython will restart with the updates applied.
Note that if the file gets corrupted for some reason, your changes will be lost. It is recommended to work from a folder on your PC, and manually upload (ex: drag/drop) the changes to the CircuitPython drive.
Overview
A media remote receiver for your PC/MAC/thing supporting keyboard media keys.
- Also works with many smart TVs and phones.
- Flexible CircuitPython-based solution can easily be adapted to other microcontrollers/IR remotes.
- Built-in IR signal decoder utility on serial monitor output.
- An easy, inexpensive, solderless build! (if desired)
-
Make Code on the Go - Makecode.Adafruit, that is.... I am a big fan of "being able to code whenever/wherever I am." That's why I bought a wireless keyboard for my iPhone, when I realized I could edit CircuitPython programs using my phone. It's one of my favorite things about the Micro:Bit - the App lets you write and upload code from your phone.
But I didn't think I could do that with makecode.adafruit.com programs for the Circuit Playground. I was wrong, in fact it's pretty easy. I just needed a lightning-to-USB adapter so I could download the code!
First - load your code in your browser (like the picture above).
Next - click the download icon in the lower left.
Then, click the file link above, to "open in a new tab."
-
A PyDOS Handheld I was looking to try out my new Adafruit Feather RP2350 and I remembered I had the Solder Party Keyboard Featherwing.
The Keyboard Featherwing is a handy device: it is about the same size as a BlackBerry phone with the same alphanumeric keyboard and a 2.6" 320x240 color display. Plug in a Feather board as the "brains" and you have a portable system.
Alas, one has to program the Feather, preferably with CircuitPython, to use the keyboard, display, and other features. Solder Party has example code snippets for those features. But what about something more holistic, more like a computer with input and output?
I found two solutions that were perfect: PyDOS and Beryllium OS. Both are built on top of CircuitPython.
PyDOS emulates MS-DOS commands used on PC compatible computers. And Beryllium OS, formerly ljinux, acts as a Linux-like computer. Neither are binary compatible (they cannot run native DOS or Linux binaries) but their commands and interactions emulate those operating systems.
This Playground Note will show you how I built my PyDOS handheld in short order.
There are two videos, one from Adafruit Show and Tell and another for Tom's Hardware The PiCast.
Preparing the Feather
Solder male pin headers onto the Feather RP2350. You could use long pin stacking headers to add a FeatherWing, but that would create quite a stack on the back.
See this guide page for soldering details:
-
Pumpkins vs Skeletons Game for CircuitPython This is a game about skeletons, pumpkins, and a catapult having a Spooky experience under the full moon. If you've thought about making a game in CircuitPython but aren't sure where to start, this project might be a useful source of ideas.
Charging a Pumpkin
This is how it looks when you hold the USB gamepad's A button to charge up a pumpkin.
-
Keyboard Featherwing Messenger powered by LVGL Several years ago Solder Party released the Keyboard Featherwing, a PCB that combines a Blackberry keyboard, a 320x240 TFT resistive touchscreen display, a 5-input DPAD, 4 tactile buttons, a microSD card reader, and more, all driven by an Adafruit Feather board of your choice. Eventually these were discontinued, I'm assuming because of the difficulty of sourcing the increasingly rare Blackberry keyboards. I didn't know what I wanted to do with them at the time, but I knew I was gonna want to do something with them at some point, so I ordered several of them before the stock was depleted.
One popular use for the Keyboard Featherwing has been to pair them with LoRa radio transceivers, to create a set of "Doomsday Messengers". These are devices that are able to send short text messages to each other using radio signals, sort of like walkie-talkies, but for text messaging. This makes sense: with the tactile keyboard, huge display, and instant compatibility with the Feather ecosystem (including the ability to use rechargable LiPo batteries), the Keyboard Featherwing practically seems designed for the use case!
I hacked together a quick demo a few years ago allowing for very basic communication between the devices, and then promptly lost interest. I wanted to write firmware that allowed for robust, reliable communication between the devices, but I also wanted something offering some of the affordances of a modern smartphone UI. If you've ever worked on UI for microcontrollers, you probably realize there are a lot of challenges. One of those challenges can be figuring out how to write a custom, complex UI with just the basic drawing functions provided by the commonly available drawing libraries. While possible, it can be really cumbersome once you start to want more modern UI features, such as widgets, scrolling, animation, multi-screen interfaces, and so on. Another challenge is implementing all of that in a performant way, given the limited speed and memory of most microcontrollers. At the time, I wasn't sure how I was to accomplish this without pulling my out my hair, so the project was put on the back burner.
Recently I decided to dig these up and give it another shot. I still wasn't sure exactly how I was going to do it, but I did have a concrete feature set in mind:
- The ability to send encrypted, reliable messages between two paired devices using LoRa technology
- The ability to pair each device with any other device using the same hardware and firmware, via a settings screen (i.e., no re-compilation needed to pair devices)
- The ability to modify and persist device settings and a small message history across power cycles
- Granular battery monitoring; specifically the ability to see the percentage of battery life remaining at any given time
- Heavy focus on physical controls, using the touchscreen to supplement the UI only where practical and/or necessary (if you aren't familiar with any of my previous projects, I'm a huge fan of physical controls)
Which Feather?