The Connected World

Creating an Arduino-Powered Foosball Scoreboard

Creating an Arduino-Powered Foosball Scoreboard

Recently, we’ve added a foosball table to our break room in our technology office based in Omsk, Russia. The game got popular quickly and became a regular routine during lunch and breaks. People were lining up to get a charge of positive emotions! Since usability of the hand scoreboards left something to be desired and intense games made it difficult to remember to update the score, we decided to make the scoreboard automatic.


First, we decided to make a minimum viable product (MVP), and once a basic version was created, start to include more advanced functionality.

The MVP would include:

  • Score display,
  • Ball detector elements,
  • Control panel and sounds,
  • And embedding the system into a real table.

We considered the Arduino microcontroller as a main part of the system. Next, we drafted a list of necessary components and split the project into several separate parts, assigning the work to multiple engineers for simultaneous development.

We treated this project like a client project. We used Trello to stay organized, Github for our repository and code review, and held standups to keep the project moving forward.

Soon, the first prototype was created. And we were excited to test it! Despite being a little skeptical, we were glad to see the prototype worked!

The idea of the program detector implementation for MVP was very straight-forward: to read the output value from the sensor (photoresistor) and compare it to the previous value in the infinite loop. If values differed, then the ball scored.

To be more exact, we measured the output values compared to the given threshold, which defines whether the signal has changed enough to consider this change as a scored ball. We noticed, for example, that if someone turned the room lights on or off, we would receive some change in the signal, scoring as a goal.

To determine the threshold, we carried out tests to define the optimal conditions value. We also added a protection against repeated actuating of our detector in the form of a time threshold.

The version iteration on detector source code:


#include "Arduino.h"

#ifndef DETECTOR_H
#define DETECTOR_H


class BallDetector {
    BallDetector (byte ldrPin);
    bool isGoal();
    byte ldrPin;
    int lastLdrValue;
    unsigned long bounce_tag;


#include "BallDetector.h"

BallDetector::BallDetector(byte ldrPin) {
  this->ldrPin = ldrPin;

  lastLdrValue = analogRead(ldrPin);
  bounce_tag = millis();

bool BallDetector::isGoal() {
  bool result = false;
  int currentLdrValue = analogRead(ldrPin);
  if ( lastLdrValue - currentLdrValue >  HEALTH_TRESHOLD ) {
    unsigned long currentTime = millis();
    if ( currentTime - bounce_tag > BOUNCE_INTERVAL) {
      result = true;
    bounce_tag = millis();
  lastLdrValue = currentLdrValue;
  return result;

All in all, the detector worked! That was our first triumph and there was still a lot of assembling work ahead.

To save time, we decided not to apply soldering and use a breadboard for prototyping, making it possible to easily change the assembled circuit. As a result, there were some pushbuttons, a piezo buzzer, a display, a pair of shift registers and necessary resistors on the breadboard. We connected everything using copper wires.

It was very important to make these assembling modules compact and insulate components from each other. Finally, we got a result we were happy with.

The next step was to install the assembled system into the table. After several experiments, we realized the importance of reliable fastening components because small vibrations would cause a false detection. The best decision was to integrate the detector directly into the table construction. We were very happy with our results because the system was very stable to any vibration and worked properly.


Once assembly was complete, we returned to improve and test the software.

Iterative process of internal feedback and improvements let us improve the program’s logic on-the-fly, right during the games.

The Handsome team enjoyed testing the application and their feedback was very useful. The feedback we got let us improve the program’s logic on-the-fly.

In total, it took around a week of everyone’s spare time to get this to a stable MVP version. What we got is a smart foosball table, with scoreboards that registers the goals automatically, a couple of pushbuttons for game mode and score control, a piezo buzzer producing sounds (and even playing the Star Wars movie theme), as well a lot of laughs and a load of pair programming experience while getting familiar with something we never built a product on (Arduino).

There’s a decent roadmap of improvements ahead of us: from basic sensor sensitivity to registering players via NFC-enabled cards and Android phones, compiling every player’s statistics and sending it to a remote server via a wifi module.

You’ll find full source code here on Github and technical schematics below:



Other Journals