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.
-
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
-
Home Hub - Motion Detector
Introduction
The motion detector will be deployed alongside the driveway camera.
It can be used anywhere you'd like to track and report on motion.
Design
Design The sensor is coded in CircuitPython
The current case is the snap fit case provided by team Adafruit. There will be a smaller case for the sensors mounted on doors and windows.
You will need an MQTT broker for all of this to work together. You can use Adafruit IO.
In my implementation I set up a Mosquitto MQTT broker on a RaspberryPi 4 Model B running Debian Bookworm and Mosquitto v2.022.
Parts
I recently moved from a Raspberry Pi Pico W to a Feather ESP32v2 Huzzah because I will be using a solar to power the project and needed battery storage.
Code
Motion Detector
Home hub projects are all in this parent project.
Here you'll find the motion detector code.
Libraries Required
import os import time import alarm.pin import board import digitalio import wifi import adafruit_minimqtt.adafruit_minimqtt from adafruit_minimqtt.adafruit_minimqtt import MMQTTException import adafruit_connection_manager import adafruit_logging import analogio
Featured Highlights and One Lowlight
- Loads all configurations from settings.toml
- Notifies devices on network when motion is detected
- Suspends sending motion events when recording is in progress
- Does not utilize secure connection for MQTT broker, I have been unable to successfully connect using certificates. Even followed the solution that worked on an ESP32 a last year with no success. Instead uses a special MQTT user that has access restricted by ACL until I can get encryption working.
The TL;DR Nuts and Bolts
The sensor will subscribe to:
- monitoring.recording
The sensor will publish to:
- monitoring.motion-detect
- motion-detect.battery
When the sensor detects motion it will publish to monitoring.motion-detect which will trigger the camera to start working
When sensor receives a message on monitoring.recording that recording has begun, it will enable recording mode and will not send any motion detection events
When the sensor receives a message on monitoring.recording that recording is complete, it will disable recording mode and will begin sending new motion detection events
You will need a local MQTT server or Adafruit IO in order to record and display sensor data.
Currently implemented actions based on motion detection
- Driveway camera: when motion is detected will take a snapshot and record a 30 second clip
- Entryway or trellis lights: when motion is detected will stop the current running animation and set the lights to solid white
Case
I used OpenSCAD and the YAPP Box (Yet Another Parametric Project Box Generator) library from mrWheel. This library is well documented and has a lot of features.
Node-Red
Node-Red subscribes to the monitoring.motion-detect feed. When a message is received it will update the UI LED node on the dashboard and on the sensors page.
Adafruit IO
In order to monitor the sensor status when I'm out of the house, I have configured Node-Red to send the driveway motion sensor data to Adafruit IO.
-
Home Hub - Door and Window Sensors
Introduction
I got burned buying into the Google security ecosystem a while back and promised myself to never do it again. Plus now I know exactly what all the pieces of our home monitoring system are doing and where they're communicating. Easy upgrading too!
All other sensors will use the same code base and construction.
Design
The sensor is coded in CircuitPython
The current case is the snap fit case provided by team Adafruit. There will be a smaller case for the sensors mounted on doors and windows.
You will need an MQTT broker for all of this to work together. You can use Adafruit IO.
In my implementation I set up a Mosquitto MQTT broker on a RaspberryPi 4 Model B running Debian Bookworm and Mosquitto v2.022.
The first sensor built and put into use is for the garage door
Our house has a detached garage. The opening for the garage is perpendicular to the house which is good for esthetics and access, bad for knowing if the door is open.
Parts
Code
Sensor
The code for this project can be found on Github.
It is one part of the larger home monitoring project.
The following libraries are required:
- os
- time
- board
- digitalio
- wifi
- adafruit debouncer
- adafruit minimqtt
- adafruit minimqtt
- adafruit connection_manager
- adafruit logging
Feature Highlights
- When the door is open the sensor publishes a 1 to monitoring.garage-sensor
Node-Red subscribes and will
- Change the indicator on the sensor page; red - open, green - closed
- Change the indicator on the home page; red - open, green - closed. Since we often reference if the door is open or closed, having an indicator on the home page saves having to switch tabs every time we want to know the state of the door
Node-Red
I have a flow dedicated to handling sensor data.
Configuration
Add an MQTT in node and configure it to subscribe to the topic for the sensor. For me it's monitoring.garage-sensor.
After that you'll need to connect it to a UI LED node that will take action based on the message payload.
I have three functions in my flow, two are disabled and will be used when traveling. The active function will generate an email when it's past a certain hour and the garage door is still open.
To build the function nodes, you will need some familiarity with Javascript. Word of caution, there are some differences between Javascript and Javascript within Node-Red. I had to narrow a few searches to get some of the answers I initially needed.
The code in the function for sending a notification looks like this:
context.data = context.data || {}; switch (msg.topic) { case "monitoring.garage-sensor": context.data.garage = msg.payload; msg = null; break; case "home.hour": context.data.hour = msg.payload; msg = null; break; default: msg = null; break; } if (context.data.garage != null && context.data.hour != null) { if (context.data.hour >= 20 && context.data.garage == 1) { var newMsg = { "topic": "Your Attention Needed" ,"payload": "Garage door is open" } } } return newMsgTo receive email, you'll need to have an MTA. I have a secondary Gmail account that I'm using to send mail.
Project Construction
Circuit Board
- Solder breadboard jumper wires to the earth and data pins.
- Connect one side of contact switch to the jumper wires
- Using the snap fit case, secure the QT PY, ensure the jumper wires are hanging outside the case, and close the case
Installation in the Garage
I used Uglu Dashes to secure the magnets to the side of the garage door and to the frame. It's been there now for over 6 months without issue. I did clean both areas with rubbing alcohol before applying the Uglu.
-
Home Hub: Camera
Introduction
Even though we live in a quiet neighborhood I wanted to have a few cameras around the property. I'm sure it will provide hours of watching mongoose, the occasional wild pig, feral cats, chickens, and turkeys in our neighborhood.
The first camera project is for our driveway. It will be paired with a motion detector.
Design
The camera is coded in Python.
You will need an MQTT broker for all of this to work together. You can use Adafruit IO.
In my implementation I set up a Mosquitto MQTT broker on a RaspberryPi 4 Model B running Debian Bookworm and Mosquitto v2.022.
For image and clip storage this project supports both writing to a local file server as well as to Dropbox. For local file storage I have a another Raspberry Pi running Openmediavault.
Parts List
-
Home Hub Project with Node-Red-Dashboard
Introduction
When we moved into our new home I started planning how I wanted to handle sensors and LED lighting projects. I needed a place where I could manage motion, window and door sensors, Raspberry Pi cameras and doorbells, and LED lighting projects.
Design
First step, identify a way to see all the data once I started collecting it. I began by using Adafruit IO. However, as I thought more about what data I was going to be sending and how I wanted to access to that information and dashboard for others, I didn't want it to be public in any way. So I chose, instead, to built a Raspberry Pi 4 based Mosquito MQTT server.
Beside sensor and camera data, I wanted a way to control any LED projects, and I wanted a hub feel where data including date, time, shared calendar events, and weather data can be easily viewed.
After fumbling around a few different options for viewing MQTT data; I landed on Node-Red.
Here's a screenshot of what it looks like.
What is Node-Red
From their website, Node-Red is:
Low-code programming for event-driven applications
I'm definitely not a Node-Red expert, however, what I've learned and implemented so far has yielded results more than I expected. I quickly found modules for communicating with my MQTT server and my WLED LED nets/Sparkle Motion board.
I have Node-Red running on the same Raspberry Pi as the Mosquito MQTT server. Set up was well documented and went smoothly. Right now the service is not exposed outside of my home network so I haven't implemented HTTPS and other security features. It's on the to-do list.
I'm not going to get into the how-to portion of Node-Red, but I will be showing some of the flows I have and providing detail on how I implemented things. Where I provide more detail I will try to include examples from the configuration of buttons, button groups, and functions. In my search for information as I learn, I'm finding a lot of pictures of flows without understanding what's actually happening under the hood.
Once configured, Node-Red runs a webserver and any device can connect from their browser of choice. Node-Red also handles different display sizes so it works on your phone or tablet out of the box.
Things to know before reviewing associated projects that display in Node-Red
@flowfuse Node-Red-Dashboard-2 provides the UI elements needed to monitor and interact with devices in your IOT set up.
While Node-Red-Dashboard-2 provides most of the UI elements you will need, for an LED indicator I chose to install the node-red-dashboard-2-ui-led node.
The flow also needs MQTT communications. These are in the node-red package and do not need to be installed separately.
Because I wanted email notifications, in the event the garage door is still up under certain circumstances, I had to install the node-red-node-email node.
Projects
All projects fall under one of three categories at this point:
- Sensors
- Cameras
- LEDs
In Progress
- LEDs: Trellis/Entryway net project
- Cameras: Driveway
- Sensors: Motion detector
Complete
- Home hub
- Sensors: Garage door sensor
- LEDs: Christmas tree and star lights
-
Christmas Tree & Star Lights with Node-Red
Introduction
We have a 1960's era aluminum Christmas tree. For the time that we've had it we've relied on newer and slightly less dangerous color wheels, then stage lighting. When we moved we didn't bring any of the lighting with us.
I decided to string the poles of the tree with LEDs.
The prior year I made a star topper which used a Bluefruit for lighting. This year I added 24 LEDs for the star that plug into the highest string on the poles.
Design
The current design is written in CircuitPython. For communication it relies on MQTT and Node-Red.
Everything worked great, however, after I worked on a different LED project that used WLED, I think I'll convert this project to WLED. I'm not going to delete this code base, I think it has some interesting implementation features and is worth preserving.
Infrastructure-wise with either implmentation you will need:
- MQTT - you can use AdafruitIO or build your own. In my implementation I set up a broker on a RaspberryPi 4 Model B running Debian Bookworm and Mosquitto.
- Node-Red - my Node-Red journey is chronicled here.
Parts
Code
Tree & Star
The code can be found on Github
As I was coding this project, I found myself thinking I was going to be reusing a lot of it. So I repurposed an old project and replaced what was there with new helper classes.
I did run into an issue where I could not get the LED Animation library to play nicely with MQTT. I tried a few things, including asyncio, and ended up posting on the forums. mikeysklar came to the rescue and you'll see his contribution in the code.
The tree has 196 LEDs and the star has 24.
data = { 'tree_animations': ['multi_chase'] ,'star_animations': ['rainbow_sparkle'] ,'num_pixels' : 220 ,'tree_pixel_subset': [0, 195] ,'star_pixel_subset': [196, 24] ... }Libraries Needed
import json import board import time import os import neopixel import adafruit_logging import wifi import supervisor import adafruit_connection_manager import adafruit_minimqtt.adafruit_minimqtt from adafruit_led_animation.group import AnimationGroup from adafruit_minimqtt.adafruit_minimqtt import MMQTTException from adafruit_led_animation.sequence import AnimationSequence from adafruit_led_animation.helper import PixelSubset from circuitpy_helpers.led_animations import animationBuilder from circuitpy_helpers.led_animations import controlLights from circuitpy_helpers.led_animations import updateAnimationData from circuitpy_helpers.file_helpers import updateFiles from circuitpy_helpers.calendar_time_helpers import timeHelper from circuitpy_helpers.network_helpers import wanChecker
Featured Highlights
The tree subscribes to the following MQTT feeds:
- tree.lights - listens for events from Node-Red to update animation, start time, stop time
- home.time - listens for events from home hub in order to know when to stop or start the lights
- home.sunset - listens for events from home hub in order to know current sunset, uses this for start time
In order to take events from tree.lights and actually change the running animation and colors, I needed to be able to do a couple of things:
- Have a list of supported animations - this is done via the animations.json file
- Be able to override the default values for animations
- Be able to on-the-fly update the data file to implement the new animation/colors choice
When the code first starts it will check if there are overrides for the chosen animation and do an in-line replacement of those values. It will then check to see what the color selection is. Color choice is specified in the animations.json file and can be:
- random - a random color will be selected
- data - in the data file, for each animation is an entry for color. A string representation of the color can be provided or a the name of a color_palette.
Once up and running, about every 30 seconds, the animations will pause long enough for the code to query MQTT for any updates. If a new message arrives the code will update the data file with the appropriate information and perform a
supervisor.reload().You can also change the start and stop times or disable them so that the lights will run continually.
When using start and stop times; when the criteria is met to do either, the code will light sleep until the alarm is met.
Case
I used OpenSCAD and the YAPP Box (Yet Another Parametric Project Box Generator) library from mrWheel for the Feather case. This library is well documented and has a lot of features.
I found a star on Thingiverse years ago and downloaded the SCAD file. I re-mixed it for my own needs. Unfortunatly now I cannot find the Thing anymore. If you recognize the code as yours please let me know so I can give you proper credit.
-
CircuitPython Helpers Project
Maybe It's Just Me
As I work on different projects I find myself implementing similar things across projects. This has led to a lot of copy/paste work. Which in turn leads to having to update multiple projects when I find an issue or improvement.
So I decided to start a helpers project. It is essentially a set of wrapper classes that I can use across projects.
What's In The Big Pink Box?
I've just started to build this project and have started with the ones that were in use with my current projects. I plan to add more as I move to other projects.
- time_lord.py
- Provides a time singleton that supports RTC if desired
- Currently does not support using SPI and Network to get the time (maybe in a later release)
- local_logger.py
- Provides a logging singleton that supports adding/removing different handlers and accessing files on your SD card
- rotating log files is currently incomplete
- local_mqtt.py
- Provides an MQTT singleton that uses SSL by default
- Supports publishing independently or via the MQTTHandler in adafruit_logging
Any Gotchas?
I have done my best to keep all the helpers independent. I didn't want to force anyone to use local_logger just to use the time_lord wrapper.
The responsibility use the helpers together falls to the program.
How Does it Work?
I clone this project into the project in which I want to use the wrappers. From there I just copy the wrappers I'm using to my microcontroller.
Example code - implementing time_lord.py without using a real-time clock:
...
import socketpool
import wifi
import time_lord
...
pool = socketpool.SocketPool(wifi.radio)
my_time = time_lord.configure_time(pool)
...Example code - implementing local_logger with time_lord and a real-time clock:
...
import rtc
import socketpool
import wifi
import time_lord
import local_logger
...
pool = socketpool.SocketPool(wifi.radio)
rtc = RTC() # using a QTPY ESP32 Pico
my_time = time_lord.configure_time(pool, rtc)
my_log = local_logger.getLocalLogger(use_time=True)
...Example code - implementing local_mqtt with local_logger without time_lord:
...
import local_mqtt
import local_logger
...
my_log = local_logger.getLocalLogger()
my_mqtt = local_mqtt.getMQTT(use_logger=True)Where To Get the Project
You can find the project on Github
Please feel free to contribute!
- time_lord.py
-
It's Koozie-licious! (3D Printing)
If you have a lot of koozies and are looking for a custom way to store and access them, this koozie holder might just be for you.
My niece requested a koozie holder for her home so I designed and printed this for her. I've made it so it's configurable.
The text that you see in the photos is what is in the STL.
What can be configured?
- Height - You may want bigger or smaller!
- Width - current is for what I think of when I hear "koozie"
- Depth - see above
- Text
- Font
- Size
- Depth
- Spacing
- One side print or both
- You can also download the source code and change up anything about it
Details of this print
- 3D Printer: FlashForge Adventurer 4
- Filament: 3D Printlife Recycled PLA, color: Night
- Supports: Yes
- Nozzle temp: 220c
- Print bed temp: 55c
- Raft: No
- Ironing: Yes - This may be specific to the FlashForge slicer but it puts a smoother finish on the piece
- Total print time: ~57 hours
Where to get it
Photo shoot!
-
Simple Audio Book Reader
Enjoy audio books without having to be connected to the internet or use a complex application. This book reader is designed for anyone who wants an easy way to listen to their audio books. Load up your SD card with as many books as it can handle, pop it into the player and you're ready to go. Audio book reader supports wav file playback and automatically moves from chapter to chapter, book to book.
Core Parts
You will also need headers for your Feather boards, 22 AWG wire for soldering connections, a keycap, M2.5 screw set with standoffs, and a micro SD card
CAD and Fritzing Files
CAD files
The project assembly was designed in OpenSCAD and mocked up in FreeCAD. You can download the STL and FreeCAD files by following the links. Electronic components like Adafruit's boards, displays, connectors and more can be downloaded from the Adafruit CAD parts GitHub Repo.
For printing you will need these STL files:
- battery_pocket.stl
- enclosure_base.stl
- enclosure_top.stl
You will also find a STL file that shows all three parts in one view (enclosure.stl) and one that shows the entire enclosure with components (book_reader_layout.stl)
Note: 3D printing is in progress, adjustments to CAD models may occur
Wiring Diagram
You can download the Fritzing diagram below. Please note my TFT dispaly did not come with EYESPI. Your project will likely be able to forego that part of the soldering effort.
Printing Notes
All printing was done without supports
- PLA: White PLA
- Extruder: .4
- Extruder Temp: 220C
- Platform Temp: 50C
- Base Print Speed: 50 mm/s
Putting it together
- Install the headphone jack into the base
- Install the slide switch by carefully inserting it - the fit will be tight! - into the slot until it's in solidly
- I do have a gap on either side of the slide switch; you can modify this in the SCAD file or leave the extra venting like I did
- Install 1 cm standoffs to the rotary encoder
- Secure the rotary encoder to the base using nylon screws
- Install 1 cm standoffs to the battery pocket
- Place the battery in the battery pocket and snap the battery pocket into the pinholes in the base
- Attach the assembled Featherwing Doubler and the amp to the battery pocket with nylon screws
- Ensure the battery and rotary encoder are connected to the Feather RP2040
- Secure the TFT Display to the lid using two nylon screws and hex nuts
- Snap the enclosure top onto the enclosure base
- Place the keycap on the Kailh key
- To make connecting the audio book reader to power easier, I used a magnetic USB adapter, but you don't have to