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.
-
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.
-
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.
-
Yoto Mini Hacking
ESP32 Pinouts
ESP32 Pin Connection ---LEFT SIDE--- --- GND PROGRAM HEADER, 5 3V3 T67 EN PROGRAM HEADER, 2 SENSOR_VP / IO36 ENC2_A SENSOR_VN / IO39 ENC1_A IO34 IO35 ENC1_B IO32 UARTRX / IRQIN CR95HF IO33 UARTTX / IRQOUT CR95HF IO25 SCL IO26 IO27 ENC2_B IO14 IO12 GND IO13 NC NC NC ---RIGHT SIDE--- --- GND GND IO23 DISPLAY - TOP ROW, PIN 5 (?SPI) IO22 DISPLAY - BOTTOM ROW, PIN 5 (?SPI) TXD0 PROGRAM HEADER, 3 RXD0 PROGRAM HEADER, 4 IO21 SDA NC IO19 I2S_DIN IO18 I2S_WS IO5 I2S_BCLK NC NC IO4 IO0 PROGRAM HEADER, 1 IO2 IO15 NC NC NC Button Test Points
Switch Test Point Power Button TP77 / Battery charger nQON ENC1 Button T8 ENC2 Button T19 Encoder buttons are connected to the IO expander (P05: left, P04: right). Power button is connected to the battery charging IC
-
Serial Programmer for ESP32
If you've ever worked with the ESP32, you'll know that it does not have native USB. Most ESP32 development boards will include a USB to serial converter chip, like the CP2102N that you'll see on the Feather ESP32 V2. If you're working with a bare ESP32 though, or maybe doing some reverse engineering, what do you do?
Parts
I was in this position for a project I'm currently working on. I'm doing some reverse engineering on the Yoto Mini player, which uses an ESP32. I needed to access the chip over serial for programming and it would need to be repeatable. I wanted it to be non-destructive to the board yet stable and to use parts that I already had in my parts bin.
I decided to solder up the programming circuit to a 1/4 size perma proto that I could plug in a USB serial/FTDI cable. You don't need an FTDI cable here, you could just use a USB to TTL Serial Cable, but I always keep the FTDI cable in my desk drawer.
-
Create a Looping Apple Shortcut for Sending Data to itsaSnap
Recently I've been experimenting with Apple Shortcuts to interface with the new itsaSnap app. This app lets you interface with Adafruit IO feeds on your phone. With Apple Shortcuts, you can get data from your phone to Adafruit IO. You can, for example, send health data, weather data, even encoded photos.
One topic that comes up in Apple Shortcuts is not being able to easily create an automated Shortcut that loops. For example, having data be sent every 30 minutes. There is a time automation, but you have to setup an automation instance for every time you need the Shortcut to run.
I wanted to figure out a way to do this and found a helpful post on the Apple Shortcuts subreddit that describes using alarms as a workaround. I normally avoid Reddit but that particular subreddit has had very helpful posts with folks sharing their Shortcuts and tips for folks to accomplish what they're looking for.
Flow Chart
I've adapted the suggested Shortcut from the subreddit post a bit. I've found that wrapping my head around the logic can be a little tricky, so here is a visual explainer before we get into building out the Shortcuts.
-
Accurately Calculating Coordinated Mars Time with CircuitPython
I'm currently working on a clock using a Qualia S3 board with a 4" 720x720 round display. The idea is to display an "analog" clock face on it. The clock will show your timezone on Earth and coordinated Mars time (MTC). In looking into MTC, I found the Mars24 Sunclock, which is a piece of desktop software from NASA that shows your local time, UTC time and then MTC.
The algorithm for calculating MTC was published by NASA researcher Michael Allison in 1997 and then updated in 2000 by Michael Allison and Megan McEwen. It is nicely summarized on the Timekeeping on Mars Wikipedia page:
The Mars Sol Date (MSD) can be computed from the Julian date referred to Terrestrial Time (TT), as[46]
MSD = (JDTT − 2405522.0028779) / 1.0274912517...This leads to the following formula giving MSD from the UTC-referred Julian date:
MSD = (JDUTC + (TAI−UTC)/86400 − 2405522.0025054) / 1.0274912517where the difference TAI−UTC is in seconds. JDUTC can in turn be computed from any epoch-based time stamp, by adding the Julian date of the epoch to the time stamp in days. For example, if t is a Unix timestamp in seconds, then
JDUTC = t / 86400 + 2440587.5It follows, by a simple substitution:
MSD = (t + (TAI−UTC)) / 88775.244147 + 34127.2954262MTC is the fractional part of MSD, in hours, minutes and seconds:[3]
MTC = (MSD mod 1) × 24 hI wish I could tell you that I can read through that and understand it and as a result write a block of Python code that performs that calculation without a lot of trial and error. Unfortunately, I really struggle with math so I turned to ChatGPT-4. I was incredibly reticent about using ChatGPT or any other LLM but I have to say that I've found ChatGPT-4 to be a very helpful tool when writing code that saves a lot of time for tasks like this. I entered that algorithm into ChatGPT-4 and asked it to convert it to CPython and it popped out a script that worked perfectly when compared to the Mars24 clock. You can see my full chat log here.
-
NeoDriver with Le Potato
Image the SD Card
Download the Raspbian image for sml-s905x from the distro server. Use etcher to image the sd card.
First Boot
The first boot is just like booting up Raspberry Pi OS on a Raspberry Pi. Follow the setup steps to create a local account, setup wifi and update the OS.
-
prepping images for an iot rgb matrix project
i'm working on a big rgb matrix project using the espn API to get data for tracking various sports teams. since it's an rgb matrix it makes sense to display the team logos. however, there are a lot of teams across all of the leagues and images for rgb matrices have to be just so. this part of the project was really intimidating.
however, as luck would have it, the espn API includes links to excellent .PNG image files for each team. i wrote a python script that creates folders on your computer for each set of images, downloads the images, names them to match the team abbreviation in the API, resizes them, adds gamma correction from the image correction for led matrices guide, spits out a properly formatted bitmap file and deletes the original .PNG image
-
Using Android with CircuitPython
Recently there was a PR merged into CircuitPython that allows for the mounting of a CIRCUITPY drive on an Android device. Previously this was not possible, so I wanted to try it out. For my testing, I used a Samsung Galaxy A13 phone running Android version 13. The board I used was a Circuit Playground Express running CircuitPython 9.0.0-alpha.4.
The REPL
I asked our resident Android expert FoamyGuy for some advice on where to start to access the REPL. He suggested the Serial USB Terminal app (Google Play Store). The key feature for CircuitPython that this app has is the ability to create macros. With macros, you can setup CTRL+C and CTRL+D shortcuts that otherwise are impossible to do with the default Android keyboard.
To create the macros, you'll long press on the macro button. Select HEX as the edit mode and value 03 for CTRL+C. On a second macro, follow the same procedure and value 04 for CTRL+D.
-
WipperSnapper Plant Grow Light
My mom has two Christmas Cactus plants that have been doing really well for the past few months. However, with winter arriving she had been struggling to find a spot where they were getting enough light. I offered to build her a grow light using DotStar LEDs since they have a color temperature of 6000K, which these particular plants respond to. I decided to use WipperSnapper so that the lights could turn on and off on a schedule and it would be easy to troubleshoot remotely.
I designed up a wooden box in Fusion360. It was designed to be made with 1/2" plywood.
-
Writing CircuitPython Libraries with ChatGPT-4
hiya we're going to do some code porting from Arduino C++ to CircuitPython (Python 3) - begin by reading the cpp and h files in here: https://github.com/adafruit/Adafruit_VCNL4020
i do not need you to summarize or explain code. i do not need you to print out the code, you can ingest it directly. please wait for my direction before starting to port the codestart by converting each #define register name and value pair from the .h file to a const python assignment. const python assignments start with a '_' before the variable name, and the value is wrapped in a 'const()' function call
1. for I2C communication, we'll be using CircuitPython Bus Device: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
2. the circuitpython library will use properties more than get/set functions when applicable. these provide a simpler syntax in user code: thing.foo = 23 vs. thing.set_foo(23) and reading is just: print(thing.foo). this is in line with the circuitpython style guide: https://docs.circuitpython.org/en/latest/docs/design_guide.html#getters-setters
3. do not return bools in the function for error catching, use try/except
4. always include the comments from the arduino functionsok in arduino we have a getter or setter function, and we define the busio_register based on the register map name, and then make a registerbits object that will let us map into the inner bits. in circuitpython its a lot easier, we can create an 'adafruit_register' variable of type RWBit or RWBits. use https://github.com/adafruit/Adafruit_CircuitPython_Register if you need to reference the class documentation. If the register bits we're looking to address is only 1 bit wide, we can use `register_bit_name = RWBit(DEVICE_REGISTER_CONST, bitnumber)` where `register_bit_name` is a descriptive name for the bit field we are working with, DEVICE_REGISTER_CONST is the matching register name from 'adafruit_busio_register' and bitnumber is the location of the single bit. If the register bit field is more than one bit wide, use 'register_bits_name = RWBits(numbits, DEVICE_REGISTER_CONST, shift)' which adds the number of bit width of the bitfield and the shifting required, you can get those from 'adafruit_busio_registerbits'