In the introduction I've explained the reason for the mirror, one of the key innovations of the project and the inspiration behind its name.

Another key innovation of this robot is the "finger-follower" feature: the finger position is tracked on the robot's touchscreen, and the ball follows it in real time. By watching the display, the ball continuously "lands" underneath the finger.

This feature was already in my mind during the early stages of the project, when I was considering using a large touchscreen display. By pure coincidence, ELECROW proposed a sponsorship and sent me a 7-inch DSI touchscreen display. The robot also works without a display, but the display is what really makes it enjoyable and complete.

Besides the real-time camera image, with overlayed ball detection, the GUI exposes several additional features:

The main characteristics of this robot are also explained in the below YouTube video:

In the video, several features aren't mentioned, like the PID calibration page, the sensorless homing,  the custom I2C protocol, and many others.


Custom I2C protocol (Python ↔ MicroPython, with pre-encoded parts in C)

This is another key area of the project, worth mentioning here despite being covered in detail across about 10 pages of documentation.

A Raspberry Pi 4B acts as the brain of the robot and sends commands via I2C to three RP2040-Zero boards controlling the stepper drivers.

I wanted to use RP2040-Zero boards because I really like the PIO features, here used to generate precise quantities of motor steps at the intended speed. However, I could not find a suitable MicroPython library to use the RP2040 as an I2C receiver, so I implemented code originally suggested by danjperron on a Raspberry Pi forum.

At a high level, the Raspberry Pi sends 2-byte packets containing speed and step-count information, encapsulated in a custom protocol using STX, escape characters, checksum validation, and ETX markers at at 200KHz.

The RP2040 first validates the received packet and then decodes the data fields into speed, direction, and number of steps.

Since the I2C communication runs on core1 of the RP2040, while core0 handles the remaining tasks, the two cores exchange information through the mem16 shared-memory area.

Thanks to the PIO feature, despite the relatively limited execution speed of the MicroPython interpreter, the RP2040 boards operate very reliably. In practice, this reliability allowed me to design the communication as almost entirely mono-directional: the Raspberry Pi sends commands to the RP2040 boards and simply trusts the job gets done.


Here below the block diagram:

From the diagram you might have noticed the "Sync" signal for the motors; let me explain its purpose.

The Raspberry Pi instructs the three RP2040-Zero boards sequentially, resulting in each board loading the intended motor speed and number of steps into its local PIO buffer.

To prevent the three stepper motors from starting sequentially, the Raspberry Pi 4B sends a dedicated "GO" synchronization signal through a GPIO pin once all three RP2040 boards have been configured.

The PIO State Machines wait for this synchronization signal before generating the motor steps.

In this way, all three stepper motors start moving simultaneously, allowing the platform to tilt along the intended direction instead of following an undesired arc-shaped movement.

The system combines:

This is certainly the most extensive and complex robotic project I've built so far.

If you'd like to know more, you might consider browsing through the documentation:

https://github.com/AndreaFavero71/mirrorballbot/blob/main/doc/How_to_make_MirrorBallBot.pdf