Andrea Finollo
5 min readAug 4, 2022


About 3 years ago I started a really new interesting project in collaboration with my boxing gym Glorious Fight Gym.
I still don’t remember how it started, but I ended up developing a machine that can be used to measure boxer reflexes.

This is the third part of a serie of article: first, second.

What’s up readers? it’s been a long time since the second article I had a lot going on and I needed to push back this project a little bit, but here I am with the third and final part.


As already written in the first article this is the second prototype, the first revision of the hardware used

Thinking about the new prototype using a RasperryPI I thought that it would be better to to change the accelerometer with some different types of sensors.

One of the main issue of accelerometers was that in some cases they stopped working, probably due to the high impact sometimes they tend to lock the signal on one axis until another opposite acceleration comes to unlock that axis.

Another issue was wiring, accelerometers were connected to the board using SPI that requires at least 6 wires and also to implement a communication protocol, while I just need a binary information. To be fair notice that accelerometers support different configuration that can use less wires.

Buttons, due to the low stress resistance and the high prices of resistant one were not an options, so I thought about using proximity sensors. Of course in engineering it’s always a matter of trade off. Since I decided to use infra red proximity sensors I knew that the color of the object hitting the sensor would have been a problem.


As proximity sensor I used this protoboard based on TCRT5000 chip, made by phototransitor sensitive to IR light, it has 3 pins VCC, GND and OUT. They have an IR emitter that emits light and a phototransitor receiver. If some light is reflected into the receiver it react with a zero value on the OUT pin.

It has a very small operating range (0.2 mm to 15 mm) and that is exactly what I was looking for. It also comes with a trimmer to calibrate the desired distance.

The tradeoff is that since it uses IR light it can’t detect dark objects because they are going to absorb most of the IR radiation.


To mount the sensor and the led I’ve decided to create 3d printed housings that will be inserted inside the target, this has also required to cut two windows inside each target:

3d printed housing
Housing with embedded sensors and leds
Punching bag with windows
Punch bag with sleeve and windows


To calibrate the sensor a sheet of white paper was used over the surface of the target, measuring the output until a zero value has been received from the sensor OUT pin at the correct distance.


Leds are RGB 4 pins leds (R,G,B, GND) that can be controlled using PWM to make different colors. To use less wires as possible and make things easier, since I need only 6 colors, I just used a single output pin from the Raspberry to drive one or multiple input of the led by connecting them to each other .


To create plugs I’ve build a small board that takes the GPIO pins from the Raspberry and transform them into easy plugs one for each target.

Soldered board with plugs and buttons


To launch the software at the startup we first need to make it executable.

Creating an executable is really easy, just need to type this in the terminal inside the directory of the project.

swift build -c release

After that inside the .build hidden directory in your project you’ll find another directory called release and here you’ll find the executable.

Launching the executable at the startup was a lot harder. Online you can find a lot ways to launch a script at startup:

  • modify rc.local
  • use crontab

In my case I wasn’t able to make these working. The only system that worked for me was the creation of a systemd services. The reason why crontab and rc.local weren’t working probably resides on when my executable is launched, during Raspberry OS boot.

To run my software needs that bluetooth services are up and running, neither rc.local or crontab can guarantee that. The only system that can give you the option to set startup service dependencies is systemd.

To create a startup service we need to create a unit file where we declare:

  • name of the service
  • startup service dependencies
  • the command
  • installation target
Description=Punch service


After creating the file inside the directory (with sudo) /lib/systemd/system/we must enable it, with this series of command.

sudo systemctl daemon-reload
sudo systemctl enable punchBLE.service

After rebooting I was able to see my executable running.


After I finished everything I knew that there was something missing. In fact the RaspberryPI is more like a computer than a MCU and requires safe shutdown and restart this is helpful to avoid any file system corruption.

At the beginning i thought that I could implement a safe reboot in my software, but later I thought it wasn’t a good idea: if my software get stuck, crashes etc, it wouldn’t be possible to make it work.

I started evaluating the option for a momentary button to manage restart and shutdown. Fast press for restart, long press for shutdown. The button is connected from one GPIO pin to ground and that PIN is configured to have a pullup resistor to avoid any floating state.

I found this guide very helpful and I’m using their python script for safe reboot and shutdown.


It has been a long process, but I’m pretty happy with the solution I’ve found even if it comes with plenty of trade-offs.

Working with Swift on Raspberry was pretty easy and super fun, yet is not very easy to debug on linux, but it doesn’t depend on swift or llvm is just a matter of picking the right IDE.