Over the weekend, I made some significant progress with Geremia, my talking skull project. I was able to finish the print and assembly of the servo motor mounting bracket, and to my surprise, it worked perfectly. I attached the bracket to the back of the skull and used a short string to connect the servo arm to the jaw. The movement was smooth and responsive, even with the short lever.
One minor issue I need to address is finding a reliable way to make this connection in the final assembly. However, I’m confident that this is a problem I can solve quickly.
After finishing up with the hardware, I returned to the software side of the project. I have been working with two finite-state machines, with one running on the Arduino Leonardo and the other on my MacBook. The PC software is written in Python and communicates with the Arduino board via a serial connection.
The PC software monitors Geremia’s health at specific intervals and checks for new events to be notified via the talking skull. When there is a new notification, the software sends the notification over the serial port to Geremia, which then takes the appropriate action. This includes flashing the two LEDs, moving the skull jaw, and playing an MP3 file specific to the notification type.
The challenge with this setup is that everything needs to run in parallel to make the action appear natural. Unfortunately, Arduino does not support multitasking or multithreading, given the limited hardware resources available. However, there is a solution available – I imported the protothreads library, which simulates multithreading via software.
Modifying my source code to incorporate protothreads was not a significant challenge, although there are a few things to be careful about. For example, you cannot declare local variables in protothreads, so you need to use global variables or static variables inside the proto-thread. Additionally, it’s essential to avoid synchronous functions inside the proto-thread, like using the delay() function. Instead, you need to use PT_SLEEP(), which is part of protothreads.
I have five proto-threads in my application, which include one for the left LED, one for the right LED, one for the servo motor, one for the MP3 player, and one for the serial communication. It’s exciting to see how Geremia’s brain has evolved to be multitasking, even though it wasn’t originally designed to be.
I still need to perform some more testing on the finite-state machines to ensure everything is working as expected. Nonetheless, I’m thrilled with the progress I’ve made so far and can’t wait to see what else I can accomplish with Geremia.