RGB Input Range Sliders

0 20 0

A fun little challenge to myself this week was putting together these HTML input range type sliders to control the color of an LED.
Each color channel change triggers an update to read the value, convert it to a hex code (eg. #FF0000), update the output element value, and finally update the color picker swatch. The color input can also be used as a standard color picker. When a color is selected and the user clicks off the picker, the three sliders get updated appropriately.

Now, input range type sliders have been notoriously difficult to style in the past and I’ll admit I’m running this on Chrome only for myself.
As these sliders in Chrome are normally blue I only needed to style two simply with accent-color: red;accent-color: green;

On my local network I’m running a webserver on a tiny mircocontroller. When a client posts the form data, the LED on the ESP32-S3 changes color. That color persists and any new connections open the page with the latest assiged color.

Adafruit QTPY ESP32-S3

Matter as a Smart home standard

Matter is the name of the smart home standard that promises to bridge IOT devices and different home eco-systems. Amazon Alexa, Google Home, Apple Homekit, Samsung SmartThings, etc.

To prevent 6+ flavours of smart lightbulbs working with 6+ different apps, a standard needed to be found.

When I first heard about the Matter standard I thought it made sense and decided to test it out. In January 2024 Arduino announced a partnership with SiLabs to produce a Matter enabled board. It uses the same chip as Sparkfun’s Thing Plus Matter – MGM240P – Consider me “on-board”. I bought the Sparkfun board.

Sparkfun's Thing Plus Matter - MGM240P

I <3 Sparkfun and their documentation and videos are excellent. However what followed was all new experiences for me, including using SiLabs IDE to Flash and program the device. What, no Arduino or MicroPython? (Turns out there is now an Arduino example.) I eventually kind-of figured out the SiLabs “Simplicy Studio 5” development environment. https://learn.sparkfun.com/tutorials/connecting-thing-plus-matter-to-google-nest-hub

My idea was that Matter was an open standard and works across home ecosystems. However what followed was Vendor IDs and Product IDs authentication, command line conjuring, and QR code scanning.

In the end my oringinal Google Home is not a Thread Border Router and not capable of the example. oof.
However the board is listed as being able to run CircuitPython.
https://circuitpython.org/board/sparkfun_thing_plus_matter_mgm240p/
Most of the time this involves clicking a button twice quickly and dragging over a .UF2 file. Not so on the MGM240P
This article helped me out https://community.silabs.com/s/share/a5U8Y000001a2QoUAI/introducing-circuitpython-support-for-silabs-xg24-boards?language=en_US
Back to SiLabs Simplicity Studio to install Simplicy Commander Tool, flash the .BIN.
And after all that, it still does not simply show as a mounted drive like almost all CircuitPython boards. It requires the PIP installed ampy to run .py programs.

As someone who usually feels quite comfortable with embedded systems, this felt confusing.

Looks like it will take some time for Matter development to be easier.

As for now…

Adafruit CircuitPython 9.0.3 on 2024-04-04; Sparkfun Thing Plus MGM240P with MGM240PB32VNA

Environmental Sensing using an eInk Display and CircuitPython

Measure CO2, temperature, humidity and send that data to the cloud, while displaying results on an 2.9″ e-ink display.

My first choice was to use the display vertically.
It feels a bit less like a price tag in this orientation.

e-ink display showing temperature, humidity, co2, pressure, altitude, and battery level
e-ink displays maintain their data even when power has been disconnected.

This past August 18th marked CircuitPython day, a celebration of Python on Microcontrollers.
CircuitPython is an off-shoot of MicroPython maintained by Adafruit which aims to ease the use Python on constrained devices with limited RAM and Flash memory, reduced CPU.
AKA Microcontrollers.

This project uses:
Adafruit 2.9″ Grayscale eInk / ePaper Display FeatherWing
Adafruit ESP32-S2 Feather
Adafruit SCD-40 – True CO2, Temperature and Humidity Sensor
Adafruit BMP280 Pressure & Altitude Sensor
As well as a small LiPo battery

Adafruit 2.9" Grayscale eInk / ePaper Display FeatherWing
Adafruit ESP32-S2 Feather
Adafruit SCD-40 - True CO2, Temperature and Humidity Sensor
Adafruit BMP280 Pressure & Altitude Sensor
As well as a small LiPo battery
These sensors are easily connected with Stemma/Qwic I2C connectors.
No soldering required.

All of the code is open source and can be found at https://github.com/somenice/EnviroIOT

Beside indoor sensing of CO2, temperature, and humidity I’m also using the ESP32-S2 with Adafruit Requests library to fetch an XML file hourly from my local weather service for current outdoor temperature and humidity. Some challenges include when this xml feed changes due to weather events and warnings. I’ve included lots of try:except: blocks for each step of the Requests, Socket pool, Parsing to find where it was sometimes failing.

This BMP280 library also contains code I have happily contributed to which helps set the altitude of the sensor. Changes in pressure are registered as atmospheric rather than altitude.

E-ink is awesome for it’s low power. Combined with the ESP32-S2 deep-sleep capabilities I’ve managed to get hourly updates for days on a tiny 150mha battery.

All of the data is shared hourly to Adafruit IO. A cloud service which provides dashboards, alerts, events, and recording of historical data.

Online dashboard for environment sensing
Wildfire smoke has forced windows closed and thus high CO2 vlaues

The majority of work was laying out the e-ink display and data labels using the CircuitPython displayio library. Two separate fonts are used separating Inside vs Outside data.

One cool feature is using a spritesheet for the temperature, humidity, and battery icons.
The data depends which icon gets shown:

As a serious microcontroller user or single board computer enthusiast, I have the choice to program with Arduino, C++, Python with Raspberry Pi, CircuitPython, JS etc. More often than not given this choice I choose CircuitPython.

Here is why I personally prefer it:
1) Mountable drive with code.py file – Plug in the device and it mounts like a thumbdrive on Windows, Mac, or Linux. Any text editor can immediately read and change the code running on the board. Not something that is immediate with Arduino.

2) The REPL – Or Read, Evaluate, Print, Loop on the command line.
This allows you to test and run small bits of code without committing permanent changes.

3) Circup – A command line package manager that manages and updates libraries found on any board plugged into the computer.

4) The community – So many great people contributing and sharing in a very welcoming environment.

I have a couple ideas for a case or mount but happy so far and I wanted to share for CircuitPython day.

The Micro One-Armed Bandit

Over the holidays I came up with an idea to create a micro slot machine coded in #CircuitPython using the Adafruit 5×5 NeoBFF Led Matrix. A micro switch, or limit switch is used to ‘pull’ the slot machine arm. A Piezo buzzer bleeps and bloops familiar tones and may signal a win. Ding-ding-ding!

I paired this add-on board with the Atmel SAMD21 QTPY microcontroller which provided some issues with limited memory. This particular microcontroller has constraints which made this a fun challenge. The ESP32 and RP2040 versions of QTPY microcontroller boards on the other hand would allow for more advanced libraries to be used out-of-the-box and thus could have a much different solution.

If you’d like to jump straight to the CircuitPython code you can find it here:
https://github.com/somenice/micro-one-armed-bandit
Otherwise I’ll walk through the build and code.

Parts required:
Adafruit 5×5 NeoPixel Grid BFF Add-On for QT Py and Xiao
Adafruit QT Py – SAMD21 Dev Board with STEMMA QT
Piezo Buzzer
Micro Switch w/Lever
Header pins and a bit of wire
Optional: Right angle USB-C cable

Pins used:
The micro switch – ‘NO’ or Normally Open pin is on A1
The Piezo is on pin A2 which requires PWM
The 5×5 matrix uses pin A3 by default
All share ground

I first clipped 2 header pins of 7 then soldered the 5×5 NeoBFF on top of the headers while fitted in a breadboard. Next I soldered the QT Py board to the bottom of the headers, back-to-back, making sure to line the boards in the correct direction which is smartly printed on the back of matrix.

There is really no case or supports. The lever arm and piezo buzzer were soldered to the back with bits of wire dead bug style. The right angle USB-C cable is perfect to have the matrix sit upright.

Almost all code is derived from some Adafruit CircuitPython tutorial.
One of the key functions of the micro switch as slot machine arm was to have the action happen on the release or rise of the lever.
This was made easy with Adafruit Debounce library.

from adafruit_debouncer import Debouncer
if switch.rose:

The idea of the slot machine was to have 5 “Reels” which get randomly offset as they “spin”. Most physical slot machines will have different reel sequences but this example uses just one.

I declare hex values to identify the colour then manually created the “Reel” with different colour frequencies. Note the number of RED instances vs PURPLE.

RED = 0x100000
REEL = [RED,GREEN,YELLOW,BLUE,PURPLE,YELLOW,RED,GREEN,BLUE,RED,YELLOW,RED,RED]

On release of the lever the first step is animate the existing columns down until coming slowly to rest with a random offset on the reel.

Yup, this whole thing relies on random.randint(0,len(REEL)) So not a hardened gambling system.

I played with piezo tones, simulated physical mechanisms and settled on some familiar notes that some 8-bit fans may remember while collecting coins in another world. The final slot gets a slightly higher note, adding that audio and visual stimulation.

One of the most fun and satisfying puzzles was working with only the Adafruit CircuitPython Neopixel library to animate the 5×5 RGB matrix using a nested loop of columns and rows.

for i in range(5): #COLUMNS
    for j in range(5): #ROWS

Using various math equations, very simple but new-to-me discoveries via trial and error to produce very satisfying results.

pixels[20-(5*i-j)] = #TOP LEFT ACROSS
pixels[20-(5*j-i)] = #TOP LEFT DOWN
pixels[5*i+j] = #BOTTOM LEFT ACROSS
pixels[5*j+i] = #BOTTOM LEFT UP
pixels[24-(5*i+j)] = #TOP RIGHT ACROSS
pixels[24-(5*j+i)] = #TOP RIGHT DOWN

Once again, you can see the code and fork here: https://github.com/somenice/micro-one-armed-bandit

As earlier mentioned, the memory constraints were a fun challenge as well as using minimal parts on a basic microcontroller.
Being a hobbyist with almost endless access to sensors, radios, and actuators can often lead to scope creep. Nothing stopping me from endlessly adding functionality until I get bored and quit. This one was fun to get at least to V 0.1