Extending the Talking HAL-9000, literally and figuratively
I love this make of HAL-9000 from the Ruiz Bros:
ESP32-S3 MQTT Feather Weather
This has been my main project since 2019 which started on the Adafruit Bluefruit Sense microcontroller with Arduino. I eventually ported it to Circuit Python... and I've never used Arduino since. There are many different versions of this project on my github that are either offline only, offline with GPS, offline & online, offline & online with MQTT.
The project I'm detailing today is offline & online with MQTT to AdafruitIO. This means if for whatever reason your WiFi goes down, OpenWeatherMap.org servers go down, or AdafruitIO goes down it will still display local sensor data and function in an offline capacity waiting patiently until communication is restored.
The display sits in front of my PC monitor and has been running 24/7 for about 3 years now. I've had a lot of time to debug all of the things that might cause it to crash, error, and gracefully fail in a never ending loop. It's not perfect but it's solidly coded.
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.
Ultimate Omnifixo Pinecil Travel Case
After watching this Tested video on YouTube showing of the Omnifixo helping hands, I decided to pick one up. I have found it incredibly useful when soldering small electronics. After a bit of use I decided to 3d print the case recommended in the video, but wasn't happy with it. I looked around for other designs, and found some better options, but still not exactly what I was looking for. So, decided to design my own.
BNo055 Sensor Calibration, User Position Orientation, and Tap Detection
This page of notes was used to develop BNo055 9-DoF sensor algorithms for the PowerWash project and discusses three essential characteristics of the sensor.
First, the relative and absolute calibration of the sensor can be performed to improve initial sensor stability and positioning. Stand-alone sensor calibrator code is shown and was submitted to the driver library's examples folder. The sensor calibration procedure is not well described in existing documentation, so an update to the BNo055 ReadTheDocs page and the primary Learning Guide would be beneficial.
Next we'll talk about how to measure and adjust for user position orientation without changing the sensor's absolute position calibration.
Finally, since tap detection is not native to the BNo055 chip, an example of how to detect single and double-taps with the accelerometer component of the sensor is described.
Since the PowerWash project also included a Nunchuck controller, a brief discussion of tap detection for its slightly less-sensitive accelerometer is included.
A small snap-fit case for a QT Py/NeoPixel driver BFF combo
Currently I have around 18 WLED controller devices deployed around my apartment, most of them built using a NeoPixel Driver BFF and either the QT Py ESP32 Pico or the QT Py ESP32-C3 (currently the only QT Py boards I've been able to get to work with the standard WLED web firmware installer). The BFF series of boards is designed to be soldered back-to-back with the QT Py, but I often find it challenging to design mounting geometry on 3D printed cases for this configuration. To help fit my specific needs a little better, I decided to manually wire the boards together and build a snap-fit case to hold them. I borrowed the idea (and some of the geometry) for the snap-fit from the QT Py Snap Fit Case learn guide.
Any QT Py board can be used with this design, and you don't even *necessarily* have to use it for a lighting project. I've even used this case/configuration as a small driver for an IOT Relay using an ESP32-S2 QT Py from the signal and ground pins of the JST connector of the NeoPixel driver BFF (be aware though that this signal is shifted to 5V!).
MIDI Samplerbox (RaspberryPi)
SamplerBox is an electronic musical instrument. Drop audio samples onto it, hook up a MIDI keyboard, and you'll be able to play with realistic piano, organ, drums, etc. sounds!
The Samplerbox is a small device that plays pre-recorded instrumental sounds when it receives MIDI commands. Vintage products that do this include: ASR-10/EPS/Mirage samplers. Here are other similar products: Sound Modules
It's sample player. It's a MIDI sound module. It is a ROMpler. It stores the sounds of instruments and plays notes from those instruments when it receives MIDI note commands. Those sounds can be any WAV files. You can freely download sound files (samples and sample-sets) over the Internet, or you can record them yourself and copy the sound files into SampleBox. It can then receive MIDI from a MIDI keyboard controller, or any other MIDI device and play the sounds out an ordinary line-out jack.
The original Samplerbox project is described at this website:. https://www.samplerbox.org/ However that's outdated now. We're providing current (May 2023), much easier build instructions at http://chromakinetics.com/samplerbox/.
Extensive, detailed information on the latest Samplerbox development is at: https://homspace.nl/samplerbox/ Note: this website may be offline. Use the Wayback Machine to view the archived version of that website if necessary. There are a whole lot of pro-level features documented there that you can access, depending on how much complexity you want to deal with.
Good article on using a Samplerbox as a Mellotron replacement SamplerboxMellotronArticle.pdf
MIDI Commander (PyGamer)
MIDI SysEx Patch Loader / MIDI snippet player
MidiCommander is a CircuitPython app running on a PyGamer with a MIDI Featherwing plugged in and with an SDcard. It enables a user to "play" syx and .mic files containing snippets of MIDI commands, stored in folders of "playlists" on the SDcard, out to connected MIDI devices. It may be used to send MIDI data to several devices to configure a MIDI setup for each song during a gig.
- Files containing MIDI command bytes are to be stored on the SDcard in the /syx folder and its subfolders. The joystick UI enables navigation to subfolders.
- Filenames and folder names that start with a period are ignored.
- Only files with a .syx or .mic extension are seen by this program
- You can put any MIDI command bytes into a .mic or .syx file and this will send whatever is in the file, so you can send Program Change, CC and other - you are not limited to SYSEX commands. You can put all the MIDI commands needed to configure your rig for a song in one file.
- Arrange the files in a folder in the order of your setlist and then during a gig, simply choose the file and press a button to send it -- and all your MIDI instruments are configured for the song.
- Press the B button for Help
Comparing libgpiod and gpiozero speeds on the Raspberry Pi 5
With the new Raspberry Pi 5 coming out, it is time to add support to Blinka, our CircuitPython library compatibility layer. One of the biggest changes to the Raspberry Pi 5 is the addition of a new southbridge chip, called the RP1, which now handles the GPIOs. Like many other projects, we have been the RPi.GPIO library to handle the General Purpose Input/Outputs. The only issue is that RPi.GPIO does not work on the Raspberry Pi 5 due to a changed memory mapping. Whereas everything was handled by the
/dev/gpiomemdevice before, now everything is dynamically split into multiple gpiomem devices. The 40-pin GPIO header happens to fall into
So this means it's time to look at a couple of new options that do work on the Raspberry Pi 5. The two biggest contenders are libgpiod and gpiozero, though there does appear to be a pure python version of libgpiod called gpiod. RPi.GPIO was written in c, so it should run faster than a pure python implementation, however as mentioned before, that no longer appears to be an option. So the replacement should be able to run as fast as possible.
On the surface, libgpiod appears to be the better option because of several different factors:
- The python bindings use the libgpiod library underneath, which itself is written in c
- We already have multiple other libraries using libgpiod, so adding it is much simpler
- Looking at the source, gpiozero appears to be a pure python implementation
On the other hand, Raspberry Pi is recommending gpiozero as the replacement to use on the the Raspberry Pi 5. So it's time to compare them head to head on speed alone. In order to test the speed, each library will turn a GPIO on and off as rapidly as possible and the results will be measured with a logic analyzer. The environment will be a fresh install of the 64-bit lite version or Raspberry Pi OS Bookworm since that is the minimum that the Raspberry Pi 5 requires. The scripts will be running inside of a virtual environment as is recommended now.
First up will be libgpiod. The script that will be used is:
HAL9000 Sample Code Tweaks
I've been working on building the updated HAL9000 using the Propmaker Feather, and tweaked the code a bit to add a couple of features. Mainly:
- Animate the LED using a slow pulse animation when HAL9000 is "idle" (in other words, not playing a sound)
- Shuffle the list of wave files, and keep track as we play our way through them; then, once we've reached the end, re-shuffle the list and start over. This prevents the same sound repeating over and over, which the current approach is prone to. It also ensures you'll hear every sound if you keep pressing the button (until the list eventually has to repeat).
I ordered a decal to use instead of 3D printing the "HAL9000" label, so I'm waiting on that before I post the photos of my build, but in the meantime, here's my updated code if anyone is interested (you'll need to add the
adafruit_ticks.mpylibrary to your
libfolder in order to use this).
DIY Bubble Machine Using Raspberry Pi Pico
The project aims to create a soap bubble machine using a perforated plastic disc attached to a DC motor and a fan.
The project aims to create a soap bubble machine using a perforated plastic disc attached to a DC motor and a fan. These components are connected to an L298 driver circuit and controlled by a Raspberry Pi Pico microcontroller. This simple and enjoyable project is designed for children to learn about electronics and programming.
Soap bubbles have always fascinated children and adults alike. They bring joy and excitement, creating beautiful floating spheres that reflect light in mesmerizing colors. With this project, children can explore the science behind soap bubbles while having fun building their own machine.
The heart of the machine is the perforated plastic disc, which acts as a bubble wand. When the disc rotates, it dips into a soap solution, creating a film of soap on its surface. As the disc spins, air from the fan blows through the holes, forming bubbles that detach from the disc and float away.
To control the rotation of the disc and fan speed, we use a DC motor connected to an L298 driver circuit. The L298 driver allows us to control the direction and speed of the motor using signals from the Raspberry Pi Pico microcontroller.
We control the speed of the perforated circular bubbles disc through a potentiometer connected to an ADC pin at the Raspberry Pi Pico.
The Raspberry Pi Pico serves as the brain of our project. It runs a program that controls when to start and stop the motor, as well as adjusting its speed. By programming the Raspberry Pi Pico, children can learn about coding concepts such as loops, conditionals, and functions.
This project not only introduces children to basic electronics but also encourages their creativity by allowing them to customize their bubble machine. They can design and decorate their own plastic discs or experiment with different fan sizes for varying bubble sizes.
In conclusion, this DIY project offers an exciting opportunity for children to learn about electronics, programming, and physics while having fun creating their own soap bubble machine. It combines science with creativity in an engaging way that will captivate young minds. So let's dive into this project together and explore the fascinating world of soap bubbles!
The following picture shows the Raspberry Pi Pico pinout (which functions are supported by each pin).
How to Initialize PWM in MicroPython for Raspberry Pi Pico?
We are going to follow the steps stated below in order to configure PWM in our Raspberry Pi Pico.
- Firstly, we have to choose the PWM pin.
- Next, we set a particular frequency for our digital signal. 50Hz is a good value to start off with to work with an LED and L298.
- Raspberry Pi Pico has 12 bit resolution but in MicroPython it is scaled to 16 bits. Hence the duty cycle will be set from 0-65535 which corresponds to 0-100%
You can read this article on Raspberry Pi Pico ADC:
Inside the infinite loop we are reading the analog pin through the method read_u16() from the potentiometer variable and storing it in potentiometer_value. This value will vary from 0-65536 because we have 16 bit resolution. You will be able to see the values getting printed on the screen. This value is given as a parameter inside the duty_u16() method which is being accessed through the led and motor speed.
When you run this code on your Raspberry Pi Pico and rotate the potentiometer knob, you will get the value of ADC after every 1 seconds.
Increasing input values from the potentiometer act as increasing duty cycle hence the brightness of the led increases and the speed of motor of bubbles disk..
The blower fan and Raspberry Pi Pico were powered by a power bank. The drive module L298 is powered by an external battery.
- The smaller the disc area, the greater the possibility of bubbles sticking to each other, so it is preferable to use a larger disc with proper spacing of the holes.
- You should also use a powerful fan to blow bubbles, such as fans that rely on a Brushless motor.
- Using a variable resistor (potentiometer) we calibrate the disk speed to obtain the desired performance.
Test The Machine 😊
1 - Wokwi Simulation Test:
2 - Real Test :
12-Panel Matrix Portal Display
How many matrix panels can you use with the Matrix Portal S3? About 12 seems to be the maximum for usability. If you add more than 12 panels the data stream takes a long time to reach the end. I've calculated about 12 feet of copper travel length in a serpentine arrangement as the maximum for a 5V data signal before degradation/glitches become to unbearable to view. The bit depth (amount of possible colors) is also very important as 12 panels cannot stream more than a bit depth of 4 without significant artifacts. Normally with Circuit Python, images are 8-bit indexed BMP's but matrix panels can only display a maximum of 6-bit color. A TFT can support up to 24-bit so do not make the mistake of treating a matrix display like a TFT. It will still process 8-bit indexed BMP's with some image quality loss due to the nature of RGB LED's in a matrix panel.
For this project I'm using 12x 5mm pitch matrix panels. The pitch denotes the physical distance between pixels. A 3mm pitch panel will be much smaller physically than a 6mm pitch for example.
Make DIY Interactive Paper Robot
Make a robot that reacts to gestures by waving its arms in a cheer!
In this project, we aim to create an interactive paper robot using Hexabitz modules. The robot will be equipped with a servo motor and a motion sensor, enabling it to move its arms and wave in response to any movement detected by the sensor. By combining the versatility of Hexabitz with the simplicity of paper, we hope to create a fun and engaging DIY project that showcases the potential of modular robotics. Whether you're a beginner or an experienced maker, this project is sure to provide a rewarding challenge and a unique addition to your robotics collection. So let's get started and bring this interactive paper robot to life!
The DIY interactive paper robot with Hexabitz is a project aimed at designing a paper robot for children using servo motors and motion sensors. The robot is capable of moving its arms and waving whenever any movement is detected in front of the sensor.
This project combines creativity, engineering, and technology to create an interactive and engaging experience for children. By using simple materials like paper and basic electronic components, we can build a fun and educational toy that encourages children to explore the world of robotics.
The main components used in this project are servo motor, which allow the robot's arms to move in different directions, and a motion sensor that detects any movement in its vicinity.
The DIY interactive paper robot not only introduces children to basic robotics concepts but also encourages them to think creatively and problem-solve. They can customize their robots by decorating them with colors, patterns, or even adding additional features like LED lights or sound effects.
Through this project, children will learn about basic electronics, coding, and how different components work together to create a functional robot. It provides an opportunity for hands-on learning and fosters curiosity and imagination.
How I build it 🛠️
Step 1: Plan the array and assemble the hardware
We prepare the project components and plan our array design by aligning modules side-by-side.
CheerBot Template: If you need to print CheerBot templates, you can download them here: https://www.okdo.com/p/okdo-microbit-build-a-paper-robot-kit
Step 2: Writing codes with STM32CubeIDE software
H0AR9x Firmware H0AR9.h code:
First, reduce the number of ports in the.h file. This can be achieved by replacing the original number of ports with one less, and commenting out the last port along with its related USART port and UART Init prototype. For example, if the original number of ports is 6, it should be reduced to 5 by commenting out (//#define _P6), (//#define _Usart6 1), and (//extern void MX_USART6_UART_Init(void);).
H0AR9x Firmware H0AR9.c code:
Second, comment the MX_USART6_UART_Init() port inside the Module_Peripheral_Init() function in the.c file, also commenting this port inside GetPort function.
H0AR9x Firmware H0AR9_gpio.c code:
Third, add the instructions for configuring the pin you are going to use in H0AR9_gpio.c file.
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
H0AR9x Firmware main.c code:
First, we define the motion variable:
and then defined the other variable used in the code.
And in the repeated closed loop, we made sure that MCU periodically checks the
proxvalue of the sensor using the API from module factsheet.
And if the motion achieves the required condition (i.e. if we wave in front of the PIR motion sensor), the servo motor is turned on at certain angles to move the robot's arms.
if (q > 15)
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
- Check out this project for : How is a Servo Controlled.
Note: For this project, make sure you're using the standard 180° servo.
Step 3: Test the System 🤖👋😊
In conclusion, the DIY interactive paper robot with Hexabitz is an exciting project that combines art, technology, and education. It offers an engaging way for children to learn about robotics while having fun building their own unique robots. Let's dive into this project and unleash our creativity!
Arduino Library Folder Cleanup
I've got hundreds of Arduino libraries that we maintain in my 'libraries' folder, and it can very quickly get difficult to maintain them. There's 4 issues I spent an inordinate amount of time on!
First issue is that whenever a library is updated, the IDE does not delete the previous version, but keeps both around...after a few years this ends in a lot of cruft.
Secondly, libraries downloaded via the IDE are placed into a folder in the format arduino_nnnnn where n is a number, so you don't really know what library is inside it, making the first issue hard to clean up
Thirdly - for Adafruit libraries, they are
git clone'd into the library folder which means I sometimes end up in a branch that I'm working on, and then submit a PR. Days later I've forgotten to change back into my main branch, losing out on any merged updates!
Finally - there's constant updates to our libraries, and the IDE does alert me when this happens - which means I need to do a git pull - but in hundreds of libraries this takes a long time to go to each folder and run the git pull command.
THUS a script! This python code does a number of clean up tasks, I only have to run it a few times a week and it will keep my arduino libraries folder nice n tidy. Thanks to ChatGPT4 Sept 25 for the assist, it made the scripting faster (note I did make some changes beyond what GPT4 wrote)
Google Coral USB Accelerator on Raspberry Pi Bookworm
Google Coral's USB Accelerator (https://coral.ai/docs/accelerator/get-started) currently doesn't work on the Raspberry Pi OS Bookworm. In order to get the USB Accelerator to work we need to do a few extra things like install Python 3.9 and create a python virtual environment.
sudo apt-get install -y build-essential tk-dev libncurses5-dev libncursesw5-dev libreadline6-dev libdb5.3-dev libgdbm-dev libsqlite3-dev libssl-dev libbz2-dev libexpat1-dev liblzma-dev zlib1g-dev libffi-dev
Build Python from scratch
tar xf Python-3.9.18.tar.xz
sudo make altinstall
Make a virtual environment
Python-3.9.18/python -m venv --system-site-packages tf
Next we can install Pycoral
echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | sudo tee /etc/apt/sources.list.d/coral-edgetpu.list
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo apt-get update
sudo apt-get install libedgetpu1-std -y
sudo usermod -aG plugdev
sudo ./tf/bin/pip3 install --extra-index-url https://google-coral.github.io/py-repo/ pycoral
Install any extra python libraries
sudo ./tf/bin/pip3 install opencv-python
sudo apt install libcap-dev libcamera-dev
sudo ./tf/bin/pip3 install rpi-libcamera
sudo ./tf/bin/pip3 install rpi-kms
sudo ./tf/bin/pip3 install picamera2
Note: rpi-libcamera and rpi-kms may need to be updated if your system package is updated.
As of 2/21/2024, If your are installing rpi-libcamera 0.1a2 and have updated to libcamera0.2, you will need to run the following:
sudo ln -s /usr/lib/aarch64-linux-gnu/libcamera-base.so.0.2.0 libcamera-base.so.0.1
sudo ln -s /usr/lib/aarch64-linux-gnu/libcamera.so.0.2.0 libcamera.so.0.1
Run the python virtual environment
At this point you should be able to use the USB Accelerator against the pycoral repo: https://github.com/google-coral/pycoral.git
Groups to get your gears turning