Arduino Sport Timing System

Since when I was a young athlete I dreamed my own wireless sport timing system. It was just a dream because these devices were (are) very expensive. One day my friend Lodovico Cortelazzo showed me the prototype of a timing system he built, based on a laser beam. Since that left me astonished, I decided to build my own…cloning the Brower Timing System.

The problem

The very basic problem to solve when creating an automated timing system is to detect when a person is traveling through a specific area. To achieve this the common way is to produce a light beam (mainly infrared) and create a device that can detect when this beam is interrupted by an object (an athlete). The infrared light producer and the infrared light detector can be two different devices, placed one in front of the other creating a “light gate”; sometimes the light emitter and receiver are stuffed in the same device and to create the “light gate” a passive light reflector is placed in front of the device (so it can detect its own emitted light). The crossing of the atlete through the “light gate” is the event that the stopwatch wants to produce times.

The core of the project

Lets go straight to a basic solution! The simplest version of the project is composed by two core components: the infrared led emitter TSAL6200 and its corresponding receiver TSSP4038 both controlled by an Arduino Nano.

The Vishay TSSP4038 can produce a readable output when it detects a 940 nm infrared light pulsing at 38kHz. The trick is to program Arduino to let the TSAL6200 produce a pulse at 38kHz. Connect the TSAL6200 anode (+) to Arduino D3 pin and the cathode (-) to the Arduino ground through a 100 ohm resistor.

the infrared led produces a 38kHz impulse with this Arduino Nano’s code (see forum;wap2)

#define onOffLed 4 

// pin TSAL6200 LED 38KHz
#define LED3 3

void setup() {  
  pinMode(LED3, OUTPUT);
  TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
  TCCR2B = _BV(WGM22) | _BV(CS22);
  OCR2A = 51; 
  OCR2B = 26; 
  TCCR2B = TCCR2B & 0b00111000 | 0x2;       

void loop() {    

Take another Arduino and take the TSSP4038 that is much more simple to handle. This IR receiver got 3 pins (read the specs) 1 = OUT connect it to any Arduino digital pin, 2 = GND connect it to Arduino ground pin, 3 = Vs connect it to Arduino 3.3V. The TSSP3038 will give you 0 when it detects the 38kHz beam light, 1 when the “light gate” is cut.

I want a real sport timing system

This is the point where things become crunchy. We need a portable stopwatch to read times on. This stopwatch has a LCD screen on it, it has buttons and it can receive radio signals from the Arduino that has the IR receiver (the one that detects “light gate” cuts).

Radio communication

the two guys above on the right are the nRF24L01, these are very cheap radio transreceiver modules; on the left there are some useful sockets that stabilize the power supply of the nRF24L01. For more info about this module visit

Here are the Arduino connections. Please pay attention to the note and the warning.

Here is the code to run the scheme above. The library for the nRF24L01 is TMRh20/RF24. The buzzer sounds when an object cut the “light gate”

* Arduino Wireless Communication Tutorial
* Library: TMRh20/RF24,

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00000";

const int buttonPin = 2;
const int onOffPin = 4;
const int detectPin = 5;
const int buzzerPin = 3;

int buttonState = 0;
int IRdetected = 0;

unsigned long waitingTime;
unsigned long elapsedWaitingTime;

bool isBeamCut = false;

void setup() {

  pinMode(onOffPin, OUTPUT);
  pinMode(detectPin, INPUT);
  pinMode(buzzerPin, OUTPUT);
  radio.openReadingPipe(0, address);

  digitalWrite(onOffPin, HIGH);

  waitingTime = millis();

void loop() {
  IRdetected = digitalRead(detectPin);
  elapsedWaitingTime = millis() - waitingTime;

  if(IRdetected &amp;&amp; elapsedWaitingTime > 300 &amp;&amp; !isBeamCut) {
    const char text[] = "C";
    radio.write(&amp;text, sizeof(text));
    waitingTime = millis(); 
    isBeamCut = true;
    digitalWrite(buzzerPin, HIGH);

  if(!IRdetected &amp;&amp; isBeamCut){
    digitalWrite(buzzerPin, LOW);
    isBeamCut = false;

That’s it!! you basically got a gross sport timing system. Just place the two devices one in front of the other, separated by 1 or 2 meters and travel between them, you are going to hear the buzzer beeping.


Above is the sketch of the stopwatch. It receives radio signals from the Arduino circuit that has the IR receiver (TSSP4038). The display is called DSD TECH Display OLED IIC 0.91″ . The library needed to run the display is called U8g2 by Oliver. You can add some buttons to this stuff, my preferred are these from Aliexpress

just connect the button matrix’s ground pin to the Arduino’s ground pin and each button pin to a free Arduino pin set to INPUT_PULLUP.

I provide no code for the stopwatch because it is a matter of taste to add your own functionality. This can be quite complex if you want to record times in memory to recall them.

From engineering to architecture

Well… this post taste like clickbait seeing the image heading this article. From now on the project becomes much more architecture work than engineering because you need to design and 3D print stuff to encapsulate all the electronic components. By architecture I mean you are going to take a lot of measurements, when I say a lot I mean A LOT! Just take a look…

All 3D models are designed with FreeCAD. The purpose of the blocks shown above is to hold some of the electronic components of the circuits we have built. On the left there is the holder of the Arduino Nano, in the middle the holder of the Adapter Module of the nRF24L01 (wich in turn uphold the nRF24L01 itself) and on the right the holder of the TSSP4038 IR receiver. Other holders, not shown here, are the ones for: TSAL6200, 9V battery. These holders are going to be 3D Printed to finally have a fully portable Arduino Sport Timing System. A cheap, nice and out-of-the-box-ready-to-use 3D printer is the Monoprice Mini.

All holders are going to be packed together into nice boxes and closed by their covers. Boxes that include the infrared led and the infrared sensor have holes to isolate and direct the infrared light beam.

Infrared light beam

To increase the range of the infrared light beam and direct it precisely we need to create this situation inside our boxes:

Both TSAL6200 and TSSP4038 have to be placed behind a biconvex lens at the point of its focal length (here you can shop those lens To achieve this you have to take precise measurements.

Electronic components Shop

My favorite site to shop non-common (IR devices for example) and specific electronic components is . You can find things also in amazon and aliexpress (arduinos, buttons, switches and so on).

The final result

…adding a “start pod-contact sensor”, to detect reaction times, and a led display stopwatch