Costruire un cronometro elettrico per atletica con Arduino

Una soluzione facile, portatile ed economica

8 December 2020

A qualsiasi velocista, nella propria vita sportiva, sarà capitato almeno una volta di dover scontrarsi con qualche giudice per via dei tempi presi "alla buona", o per via di qualche palese errore di scambio corsie. Nonostante i tempi manuali non valgano più una cicca (cit.), in alcune regioni italiane si continuano ad utilizzare anche a livello agonistico. Questo avviene perchè spesso, e ahimè, la federazione o la società organizzatrice della gara non riesce a coprire i costi del noleggio/acquisto del sistema di cronometraggio.

Le attrezzature omologate, infatti, sono relativamente costose e non sono accessibili alla squadretta di provincia o all'allenatore del paesello. Tuttavia, l'atletica leggera si svolge spesso in piccole cittadine e si sa, non è uno sport in cui le società muovono tanto capitale, anzi.

Oltre alle competizioni, molto spesso sarebbe utile per noi velocisti avere a disposizione un sistema di cronometraggio preciso che dia un valore quasi esatto di quello che sarebbe effettivamente il tempo di gara. Ciò soprattutto durante le settimane di test e pre-competizione. L'unico sistema ad un prezzo non troppo alto da me trovato è il Freelap, prodotto in Svizzera e sicuramente non la cinesata da 10 euro che qualsiasi povero atleta potrebbe permettersi. Il costo si aggira attorno ai 500 euro per una versione di base comprendente moduli partenza e arrivo, ed un orologio che fa da ricevitore e display del tempo finale.

A quel punto, ho notato che data la semplicità del sistema, avrei potuto provare a costruire un cronometro elettrico più economico ma ugualmente preciso. Non mi piace tantissimo smanettare, ma per stavolta ho fatto un'eccezione in nome dell'atletica leggera.

Ed eccoci qui, dalla teoria alla prassi, vediamo come costruire un cronometro elettrico portatile per misurare le nostre ripetute (o quelle del vostro cane, cavallo o chicchessia) su una pista di atletica.
Questo tutorial è pensato e scritto per chi non ha conoscenze specifiche. anche se qualche nozione tecnologica o di scienza/elettronica/informatica di base potrebbe naturalmente aiutare.

Panoramica

Il cronometro elettrico che stiamo per costruire è basato su Arduino, una scheda elettronica dotata di un microcontrollore facilmente programmabile, ideata in Italia nel 2005. Ci saranno due moduli comunicanti tra di loro: partenza ed arrivo. Ognuno di essi è composto da una scheda Arduino più vari accessori che permettono di simulare un vero e proprio sistema di cronometraggio professionale.

La partenza sarà azionata da un pulsante che farà partire un bip dopo un tempo casuale, in modo da non "barare" sui tempi di reazione. In quell'istante, il modulo radio partenza comunicherà con quello presente all'arrivo, che farà partire il cronometro. Il tempo verrà stoppato al passaggio dell'atleta davanti alla fotocellula. Il modulo arrivo, dotato di wifi, stamperà i risultati su una pagina web accessibile dalla rete locale creata dal vostro smartphone.

  • 2 Schede Arduino e 2 cavi USB (come quelli delle stampanti): 1 Arduino Uno, 1 Arduino Uno Wi-Fi Rev2 - circa 55 euro. Gli Arduino sono l'anima del sistema, contengono la CPU che esegue il codice per partire, fermare il tempo e stampare i risultati;
  • 2 power banks per alimentare le schede - circa 30 euro. Io ho utilizzato uno Rav-Power e uno Fresh'N Rebel. Anche da 5000mAh vanno bene, gli Arduino consumano poco;
  • 2 breadboard - circa 10 euro. Sono delle basi di plastica dove collegare il tutto. Teoricamente sono fatte per dei circuiti prototipali, ma nel nostro caso vanno bene;
  • 2 moduli radio HC-12 - circa 15 euro. Servono a far comunicare il modulo partenza con il modulo arrivo;
  • 2 buzzers - circa 5 euro. Sono delle casse molto piccole che serviranno per indicare il "colpo di pistola";
  • 1 pulsante - circa 1 euro - per avviare la partenza;
  • cavetti "jumper" maschio/maschio e maschio/femmina, servono per i collegamenti nel circuito;
  • 1 fotocellula ad infrarossi - circa 15 euro - per far cosa? Per rilevare il passaggio dell'atleta sul traguardo, ovviamente!
  • 1 treppiede - circa 20 euro - anche il più scrauso va bene, deve reggere il modulo arrivo, compreso di fotocellula, ad altezza atleta;
  • 2 cassette di derivazione - circa 15 euro - fungono da contenitore dei due moduli. In linea di principio potreste anche usare dei tupper per alimenti facendogli dei buchi o qualcosa del genere;
  • elastici - rubateli alla nonna - li ho usati per attaccare le cassette al treppiede;
  • uno smartphone con funzionalità router wi-fi. Non necessario nel caso di utilizzo display LCD, vedi "possibili estensioni" in basso.

Costo totale: circa 180 euro.

Modulo partenza

La partenza si compone di un Arduino Uno classico alimentato da un powerbank, al quale vengono collegati, tramite la breadboard, il pulsante, il buzzer e un HC-12. Di seguito vediamo come collegare il tutto:

Circuiti del modulo partenza. Le illustrazioni del pulsante, radio e antenna non corrispondono a quelle reali.

Il codice da caricare sull'Arduino è il seguente:

/* Arduino Long Range Wireless Communication using HC-12 Example 01 by Dejan Nedelkovski, www.HowToMechatronics.com */ #include SoftwareSerial HC12(10, 11); // HC-12 TX Pin, HC-12 RX Pin int pinButton = 9; int valButtonOld = LOW; // Memorizza lo stato passato del pulsante (evita letture multiple) const int buzzer = 6; //buzzer to arduino pin 6 void setup() { Serial.begin(1200); // Serial port to computer HC12.begin(1200); // Serial port to HC12 pinMode(pinButton, INPUT); pinMode(buzzer, OUTPUT); } void loop() { int valButton = digitalRead(pinButton); if(valButton==HIGH && valButtonOld==LOW) { //wait some sec ? int temp = random(8000,10000); delay(temp); HC12.write("s"); tone(buzzer, 100); // Send 1KHz sound signal… delay(100); noTone(buzzer); // Stop sound… } valButtonOld = valButton; while (HC12.available()) { Serial.write(HC12.read()); // Send the data to Serial monitor and clear radio data //buzzer for ping back delay(2000); tone(buzzer,500); delay(300); noTone(buzzer); } }

Modulo arrivo

L'arrivo è composto da una scheda Arduino Wifi alimentata da un altro powerbank. A questa scheda collegheremo un buzzer, la fotocellula e l'altro HC-12. Il sensore fotoelettrico da me usato funziona a riflessione e rileva in realtà la distanza tra un oggetto e il sensore stesso. Tuttavia, il programma considera semplicemente l'output del sensore come ON/OFF, cioè se è presente un ostacolo oppure no.
Non dimentichiamo di portare con noi anche il nostro smartphone dotato di funzione router wi-fi. Quello che dobbiamo fare è creare una rete con un dato nome e una data password, e inserire queste due stringhe nel codice caricato sull'Arduino. Così facendo, la scheda si collegherà al telefono e potrà mandare i risultati, visibili aprendo un browser all'indirizzo locale 192.168.43.117 (immagine 14 della Galleria in basso). A volte vengono registrati due o più tempi, il primo è ovviamente quello più preciso.

Ecco invece i collegamenti:

Circuiti del modulo partenza. Le illustrazioni della fotocellula, radio e antenna non corrispondono a quelle reali.

ed il codice:

#define SECRET_SSID "SSID_name" //access point ssid name #define SECRET_PASS "yourPassword" //password #include #include char ssid[] = SECRET_SSID; char pass[] = SECRET_PASS; int status = WL_IDLE_STATUS; #include

Note

  • Attualmente quando avviene lo "sparo", anche il modulo arrivo emette un bip. Inoltre, un impulso viene mandato indietro e il modulo partenza riemette un altro bip dopo 2 secondi. Questa funzione è stata implementata per testare la distanza massima tra i due moduli. Potete cambiare il codice come meglio credete. Se avete bisogno di chiarimenti o consigli su eventuali modifiche, contattatemi.
  • Nella versione corrente, quando almeno un client è connesso al sito web, il cronometro è temporaneamente sospeso. Dovete chiudere il browser prima di poter registrare altri tempi.
  • Ho testato anche il sensore di distanza Adafruit VL53L0X. Nonostante abbia una portata anche superiore a quello inserito in questa guida, viene venduto senza protezione/cover. Risultato è che all'esterno è inutilizzabile poichè la luce solare funge da rumore, producendo false rilevazioni.
  • È importante che le due antenne, o almeno quella ricevente situata al traguardo, siano 1) verticali; 2) più alte possibili. Secondo il produttore dei moduli radio HC-12, la distanza di trasmissione massima raggiunge il chilometro. Però si parla di condizioni ottimali, un po' come quando a scuola studiavi i problemi fisici nel vuoto. Dunque, è bene tenere presente che vari fattori incidono sulla distanza di trasmissione, anche l'umidità dell'aria.
    Dopo aver fatto numerose prove, son giunto ad una configurazione perfettamente funzionante anche per la massima distanza punto-punto in una pista d'atletica, cioè la diagonale che va dal traguardo alla partenza dei 200m. Nel mio caso, il modulo trasmettitore è stato poggiato a terra, mentre il modulo arrivo sta in cima al treppiede, quindi a circa 1.80m.
    Inoltre, il serial port baud rate di entrambi i moduli radio è stato settato a 1200 bps. Come farlo? Basta collegare l'HC-12 con il pin 5 collegato al ground e digitare "AT+B1200" nel monitor seriale di Arduino. Tramite questa modifica, i moduli radio vengono messi in modalità long range.
    Secondo il manuale, la modalità FU4 è quella che garantisce massima distanza. Ho testato anche questa, ma la frequenza di trasmissione è troppo bassa e l'impulso arriva con eccessivo ritardo per avere una misura affidabile. Ho quindi lasciato la modalità di fabbrica "FU3".
  • Alcuni power bank si spengono automaticamente dopo alcuni secondi perchè non rilevano la scheda Arduino attaccata ad essi. Il Fresh'N Rebel mi dà questo problema, lo uso quindi per la partenza. Infatti, il modulo partenza deve rimanere acceso solo per mandare lo start. Se conoscete dei power banks che non danno questi problemi, ben venga.
  • Perchè il sistema è preciso? Perchè la comunicazione tra i due moduli si basa su onde radio, che si trasmettono alla velocità della luce.
L'Adafruit in azione. È possibile intravedere i raggi infrarossi attraverso la fotocamera del telefono, e ovviamente non ad occhio nudo.
Il tentativo di isolamento del sensore Adafruit utilizzando il tubetto Pringles.

Limitazioni e possibili estensioni

  • La prima estensione che viene in mente è sicuramente una funzionalità di intertempo. Per rilevare i passaggi dell'atleta ogni x metri, dobbiamo sicuramente piazzare delle nuove fotocellule. Qui si aprono due possibilità: a) ogni nuova barriera è costituita da un Arduino + radio HC-12 + sensore fotoelettrico; b) ogni nuova barriera è costituita dal solo sensore fotoelettrico, collegato al modulo arrivo tramite un cavo. Nel primo caso, la barriera comunicherebbe il tempo parziale al modulo arrivo via radio: una soluzione senza fili ma molto più costosa. Sarebbe un po' uno spreco usare una nuova scheda. Il secondo caso risulta invece molto più economico, nonostante la necessità di portarsi dietro il cavo. Io opterei per la seconda.
  • Il sistema proposto è in grado di rilevare i tempi di una sola corsia. Questo avviene a causa della scarsa portata della fotocellula, la quale viene venduta con una specifica di 80cm. I miei test arrivano a circa 60cm. Per migliorare, si potrebbero utilizzare fotodiodi infrarossi (come quelli dei telecomandi delle TV) che hanno una portata superiore. In tal modo, potrebbe essere possibile rilevare due o più corsie.
  • Una fotocamera per Arduino, da azionare al momento del passaggio di ciascun atleta, aggiungerebbe la funzione "fotofinish".
  • Un display LCD potrebbe essere aggiunto al modulo traguardo per evitare di maneggiare il telefono durante l'allenamento.
  • Potrebbe essere sviluppata un'app o un sito web più avanzato che, oltre a visualizzare i tempi, aiuterebbe nella gestione dell'allenamento. Qui il limite è solo la fantasia: memorizzazione dei risultati, PB, periodizzazione dell'anno, ecc. ecc.
  • Invece delle cassette di derivazione, abbastanza rudi, si potrebbero usare dei contenitori più cool o trash. Per esempio, qualora aveste una stampante 3D a disposizione, potreste stampare una geometria che si adatta perfettamente ai componenti. Un contenitore a forma di pista di atletica sarebbe fenomenale.
  • Si potrebbe studiare un modo di collegare un sensore di forza ai blocchi di partenza e al sistema. Personalmente ho trovato dei sensori troppo deboli, nell'ordine di pochi newton, e quindi non adatti alla potenza esercitata da un velocista. Accetto volentieri eventuali suggerimenti.

Una volta collegato, implementato e montato il tutto, possiamo mettere all'opera il nostro cronometro elettrico fatto in casa. Accendiamo la funzione router wifi ed entrambi gli Arduino. Siamo pronti a correre!

Lo scopo di quest'articolo è fornire una guida per qualsiasi atleta o allenatore che avesse bisogno di un sistema di cronometraggio preciso. Non servono particolari conoscenze, ma solo un po' di tempo, voglia e qualche soldo. Quest'articolo è open source. Chiunque può copiare e modificare i codici sorgenti e i circuiti Arduino a proprio piacimento. Mi farebbe piacere vedere delle estensioni di questa versione di base. Qualora prendeste spunto da questa guida, un riferimento a questo blog sarebbe molto gradito.

Saluti velocissimi a tutti

Riferimenti

Simple Web Server WiFi
Use a buzzer module with Arduino Uno
Pulsante come interruttore
Arduino and HC-12 Long Range Wireless Communication Module

1 / 7
2 / 7
3 / 7
4 / 7
5 / 7
5 / 7
5 / 7

Athletics timing system (v2.0)

A semi-professional custom stopwatch for individual or team sprint sessions

23 March 2026

Here we are. After long time, I decided to resume the project of the electronic stopwatch, and to make it better. Better means essentially more user-friendly and more sophisticated. The main improvement regarding the start module is a more powerful buzzer, capable to emit ~100 decibels. This is quite fundamental as the starting sound should be clearly audible, particularly during crowded trainings. On the finish module, the main improvement has been using another photoelectric sensor, which has a significantly bigger range. This allows to measure times of all the eight lanes of a track. Overall, the system works as follows: the start module sends the starting signal to the finish module, which starts the timer. When the athlete triggers the photoelectric sensor, placed at the finish line, the timer stops. Let's dig into the technical details.

Start module

I built the module to be placed close to the starting line with the following material: Code:
#include <SPI.h> #include <LoRa.h> int inPin = A6; int aiVostriPostiPin = A2; int buzzerPin = A4; int partenzaDiretta = 0; int aiVostriPosti = 0; void setup() { Serial.begin(9600); randomSeed(analogRead(0)); if(Serial) Serial.println("LoRa Sender - modulo partenza"); if (!LoRa.begin(868E6)) { Serial.println("Starting LoRa failed!"); while (1); } pinMode(inPin, INPUT); pinMode(aiVostriPostiPin, INPUT); pinMode(buzzerPin, OUTPUT); delay(1000); } void loop() { partenzaDiretta = digitalRead(inPin); aiVostriPosti = digitalRead(aiVostriPostiPin); if (partenzaDiretta == HIGH) { Serial.println("Partiti!"); LoRa.beginPacket(); LoRa.print("s"); LoRa.endPacket(); digitalWrite(buzzerPin, HIGH); delay(1000); //suona per 1 s digitalWrite(buzzerPin, LOW); delay(1000); //evita un'altra partenza } if (aiVostriPosti == LOW) { Serial.println("Ai vostri posti"); tone(buzzerPin, 800); delay(500); //suona per 0.5 s noTone(buzzerPin); delay(10000); //10 s per posizionarsi int prontiRit = random(2500,4000); Serial.print("Pronti");Serial.println(prontiRit); tone(buzzerPin, 1000); delay(500); //PRONTI - suona per 0.5 s noTone(buzzerPin); delay(prontiRit); Serial.println("Partiti!"); LoRa.beginPacket(); LoRa.print("s"); LoRa.endPacket(); digitalWrite(buzzerPin, HIGH); delay(1000); //suona per 1 s digitalWrite(buzzerPin, LOW); delay(1000); //evita un altro comando subito } }
Picture: coming soon
Fritzing: coming soon
The yellow button gives the start directly, in the case there is another person around. The little button gives the "on your marks" command. After 10 seconds, another beep gives the "set", and after a random interval of 2.5 s - 4 s, the final "beep" is the actual start! Of course the duration of the intervals can be changed from the code.

Finish module

This module will be placed at the finish line, with two photocells exactly aligned between each other to create a gate that athletes have to pass. One photocell is emitter and the other one, connected to the Arduino, is the receiver. When the athlete passes in between them, the signal is interrupted and the clock stops. This module is equipped with a little LCD display to show the times. The necessary material is: Code:
#include <SPI.h> #include <LoRa.h> #include <LCD-I2C.h> #include <Wire.h> int inPin = A1; // pushbutton connected to digital pin 7 int fotocellula = 0; LCD_I2C lcd(0x27, 16, 2); // Default address of most PCF8574 modules, change according unsigned long initTime; unsigned long endTime; unsigned long raceTime; bool partiti = false; int atleti = 0; int riga = 0; int col = 0; unsigned long oraTuttiArrivati; double tempoDisplay = 10.0; void setup() { Serial.begin(9600); Wire.begin(); lcd.begin(&Wire); lcd.display(); lcd.backlight(); lcd.clear(); lcd.print("Atletica Barbas"); if(Serial) Serial.println("LoRa Receiver - modulo arrivo"); if (!LoRa.begin(868E6)) { Serial.println("Starting LoRa failed!"); while (1); } pinMode(inPin, INPUT); // sets the digital pin 7 as input } void loop() { int packetSize = LoRa.parsePacket(); if (packetSize) { while (LoRa.available()) { Serial.print((char)LoRa.read()); } //qui parte il tempo perché la partenza è arrivata via radio initTime = millis(); partiti = true; Serial.print("Init time "); Serial.println(initTime); lcd.clear(); lcd.print("Partiti!"); riga = col = atleti = 0; } fotocellula = analogRead(inPin); if (fotocellula > 128 && partiti && atleti < 6) { endTime = millis(); raceTime = endTime - initTime; double raceTimeSec = raceTime; raceTimeSec = raceTimeSec/1000; if (atleti == 0) lcd.clear(); if (atleti == 3) { col = 0; riga++; } lcd.setCursor(col, riga); lcd.print(raceTimeSec); atleti++; col += 6; if (atleti == 6) oraTuttiArrivati = millis(); delay(100); //tempo morto della fotocellula per evitare falsi positivi: 0.1 s } if (atleti >= 6 && (millis() - oraTuttiArrivati)/1000 < tempoDisplay) { for (int i = 0; i < 1; i++) { lcd.scrollDisplayLeft(); delay(1000); //velocità scorrimento } for (int i = 0; i < 1; i++) { lcd.scrollDisplayRight(); delay(1000); } } }
Picture: coming soon
Fritzing: coming soon


Misc, box and support

In addition, for making the system, you should have the following items. Items in green are facultative:
  • jumper wires;
  • two micro USB-B cable to connect the Arduino to the power bank;
  • resistors;
  • a welder;
  • terminal blocks;
  • two switch buttons;
  • two tripods;
  • one or two small tripods.
You can use anything as a container for the modules. I decided to use storage boxes, and two standard tripods to support the photocells and two small ones to support the boxes. You can also use fixing brackets to use a single tripod to support the box and the receiving photocell.

Notes

  • The Arduino pins work at 3.3V as input and output voltage. However, the power bank with micro USB-B powers it with 5V. The Arduino can also output 5V from one of the pins, which I used to power the buzzer in the start module, and the display in the finish module.
  • I implemented a 0.1 s interval dead time for the photocell to avoid false positives caused by multiple triggers from a single athlete. This means that after an initial detection, the photocell remains inactive for 0.1 seconds. This interval is reasonable for mid-level sprinters, as it corresponds to a distance of ~1 meter. However, it can be easily adjusted in the finish module code. As it is, if two athletes cross the finish line with a separation of less than 0.1 s, the second one will not be detected. Conversely, disabling this feature would cause the system to report multiple times for the same person, making it difficult to distinguish which ones belong to the first athlete and which ones beloing to the second athlete. Therefore, I decided to include the dead time. Professional timing systems typically solve this by combining photoelectric sensor data with the photo finish camera data, being able to accurately discriminate between close arrivals.


Acknowledgements

I thank Jorge Condor for his suggestions on the design of the finish module circuit.

Display power consumption system

A custom hardware based on Arduino and Raspberry Pi for benchmarking LCD energy consumption

Coming soon