DIY Automate your Football Table Score with Arduino

A complete guide on how to use an Arduino to automate your Foosball Table, including an automatic score counter on any mobile Phone, Tablet, PC or Laptop. Using an Arduino network shield we create a server that will be viewable on the Arduino’s IP. the score-counting will be handled by two lasers and light dependent resistors which will detect balls from crossing the goal line.

– Arduino Duamilanove / Uno : #1 #2 #3Ebay
– Arduino Ethernet Shield : #1 #2 #3– Ebay #1 #2 #3 #4
– 2 Laser Modules : DX.comEbay
– Light Dependent Resistors(LDR) – DX.comEbay

  • A spare network cable you can use for wiring your table.
  • Switch/Button :
  • Power Supply (we need 3.3V, 5V ): PC PSU Guide

  • (A Football table)

Add a 'Reset' Button to your table


I found a ON/OFF switch with a “Start” function, this switch has 3 positions, ON,OFF and START, with Start being spring loaded. This will be connected to the RESET of the Arduino to reset the score.


The Blue&White wire’s are the Reset&GND of the Arduino (Arduino will reset if reset pin is connected to GND). The other wires are the power to the PC’s Powersupply.

Powering your electronics

I used a PC Power Supply I got out of an old PC, a Detailed guide on how to prepare your PSU can be found HERE


Red +5V Powering your Arduino
Yellow +12V Powering any Led-Strips
Orange +3.3V Powering your Laser Modules
Black GND  Ground


Add goal detection

I found some cheap 50mw laser modules which I had to test with some smoke 🙂


For this part you will need 2 Light Dependent Resistors and 2 Laser Modules, the LDR’s will “read” the laser pointer, this will make the value of the resistor drop to a constant (low) value, when the ball passes the laser, the laser will be blocked causing the LDR’s value to rise, whenever the Arduino detects such a change it will know a ball has passed… (a phototransistor would be a better solution here)

So first install the laser modules in your table, drill 2 holes on the same side of the table, make sure the beam will hit the ball on the center(largest part), Insert the laser but don’t glue it in place yet:


Now connect your lasers to your Power Supply (Orange wires 3.3V!). These lasers will be on whenever your table is powered.
(make sure the lasers NEVER short as they will break instantly)

The LDR’s will detect whenever a team scores since there will be one LDR in each goal we can detect who scored. First, solder some wires onto your LDR and make sure they cannot touch each other:


Then drill a hole on the opposite side of the laser, pull the LDR trough and fix it in place with some hot glue:


When both LDR’s are installed, aim the lasers on the LDR’s and use hot glue to fix it in place. Both lasers should now permanently shine directly on the LDR’s:


All LDR’s need an extra resistor, the detailed guide on how to wire your LDR’s can be found HERE, connect the analog in of your LDR’s to your Arduino on Analog pin 0(A0) and 1(A1) but don’t forget to plug in your Network shield first


Arduino code

Now you are done wiring your table, it’s time to program the Arduino, this program should work and start a server on but the IP can be changed manually in the code:

Code Snippet

//timer interrupts
//by Amanda Ghassaei
//June 2012

//storage variables
#include <SPI.h>
#include <Ethernet.h>

//Init LDRReading vars
int LDRReading = 999;
int LDRReading2 = 999;

//Set IP/MAC Settings for Ethernet Shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,177);

//Init variable for points
int points_1 = 0;
int points_2 = 0;

//Set pins for LDR sensors
int LDR_Pin2 = A0; //analog pin 0
int LDR_Pin = A1; //analog pin 0

//Toggle helper variable for LED on interrupt
boolean toggle1 = 0;

//Init new EthernetServer on port 80
EthernetServer server(80);

//Start Arduino's Setup
void setup(){
  //config Ledpin as output
  pinMode(13, OUTPUT);
  //Start serial output
  //start the Ethernet connection
  Ethernet.begin(mac, ip);
  //Start server
  //Print server Address in terminal
  Serial.print("server is at ");
  //Stop interrupts & delays (needed to configure the interrupt timer)

  //set timer1 interrupt
  TCCR1A = 0;  //set entire TCCR1A register to 0
  TCCR1B = 0;  //same for TCCR1B
  TCNT1  = 0;  //initialize counter value to 0
  // set compare match register for 1hz increments
  OCR1A = 200;  //Dont lower value, will randomly freeze arduino (min 90)
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS12 and CS10 bits for 1024 prescaler
  TCCR1B |= (1 << CS12) | (1 << CS10); 
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);

//Interrupt function (will be used when arduino is sending data to client)
 //Read LDR values
 LDRReading = analogRead(LDR_Pin);
 LDRReading2 = analogRead(LDR_Pin2); 
 //Print values to serial
  //Show when the interrupt is called, used for debug if arduino has frozen
  if (toggle1){
    toggle1 = 0;
    toggle1 = 1;

//Arduino's main loop
void loop(){
  // listen for incoming client requests
  EthernetClient client = server.available();
  //If a client is requesting the scoreboard
  if (client) {
     //Allow interrupts, this will make sure there is cointinious reading of die LDR sensors

    //an http request ends with a blank line
    boolean currentLineIsBlank = true;
    //as long as the client is connected
    while (client.connected()) {
      //And available
      if (client.available()) {
        //Read the client request
        char c =;
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == 'n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
      client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println("<!DOCTYPE HTML>");
          //Background Color/Image
          //client.print("<body background=''>");
          client.print("<body bgcolor='GREEN'>");
          //Div Holding the score
          client.print("<div align='center'><p style='font-size: 450%;'> Digital Football </p><p style='font-size: 1000%;'><font color = 'BLUE'>");
          client.print("</font> - <font color = 'RED'>");
          //Break when done sending your Score
        if (c == 'n') {
          // you're starting a new line
          currentLineIsBlank = true;
        else if (c != 'r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
    //give the web browser time to receive the data
    // close the connection:
    //Stop interrupts, main loop will take over again checking the LDR's as fast as possible
  //Read LDR's values
  LDRReading = analogRead(LDR_Pin);
  LDRReading2 = analogRead(LDR_Pin2);

  //Test if any of the LDR's has been "triggered"
  if(LDRReading < 800){
    //Add point   
    //Allow interrupts to use the delay function
    //Delay after a ball has passed to make sure your ball only gets count once
    //Stop interrupts, main loop will take over again   
  //Test LDR 2
  if(LDRReading2 < 800){
    //add point
    //Allow interrupts to use the delay function
    //Delay after a ball has passed to make sure your ball only gets count once
    //Stop interrupts, main loop will take over again   

The Arduino may need to be reset before making network connection.

How to Play

Depending on the IP you chose when programming your Arduino, you should surf to to view your score. To reset your score, Reset your Arduino.

2015-02-22 23.38.42

Your score should now be visible on your device updating every few seconds. Multiple devices will work just fine.

(Extra)You can stick a QR code with your IP on the side of your table

QR Generator :

Example :



Basic Foosball Rules

1 No Spinning – it is a spin if the rod rotates more than 360˚ before striking the ball OR after striking the ball. If a ‘goal’ is disallowed the ball goes to the opponents defence, otherwise to the midfield.

2 Kick-Off – Teams toss a coin for first kick-off (or table side) at the start of the game. Subsequent kick-offs are to the team conceding the most recent goal. Play starts with the ball stationary on the midfield (5-bar). Ask if your opponent is ready to play, and the ball must touch two 5-bar players before it can be played forward in a pass or shot.

3 Dead Ball – A ball on the table is declared ‘dead’ if it cannot be reached by any player figure. If the ball is dead between opposing 5-rods, play is re-started with a new midfield kick-off to the team which conceded the last goal. If the ball goes dead behind the midfield rods, it is re-started in the nearest defensive area. Ensure your opponent is ready to re-start play. The ball must touch two players before being passed or shot.

4 Ball off table – The ball is ‘out’ if it leaves the playing area, defined as the area inside the cabinet or directly above it, including the edges of the table. If the ball hits scoring markers, ashtrays etc and rebounds into play it is dead. Play is re-started in defence by the team which did not initiate the most recent shot (i.e. if the ball is shot by the attacking team and is deflected out of the table by the defending team, it goes to the defence of the defending team). Ensure your opponent is ready to re-start play. The ball must touch two players before being passed or shot.

5 Bounce-outs – a ball which enters the goal and bounces out counts as a goal. Play is re-started with a new midfield kick-off to the team which conceded that goal.

6 Passing – a stopped or pinned ball (‘pinned’ means trapped against the playing surface or side-wall, or where the ball touches the front or back of the player figure before the motion of the pass) cannot be passed directly from the midfield to the forward rod, nor directly from defence to midfield, the ball must touch another player figure and be in motion when a pass is attempted. The ball may only touch the side-wall twice when in midfield.

7 Time Limits – The ball must leave the rod of possession within 10 seconds on the midfield, or within 15 seconds on the forward rod or defence (goal and defence rods count as one rod). Time limits start when the ball comes in range of any player figure on the rod.

8 Time Outs – Teams are allowed 2 time outs per game of up to 30 seconds each. A time out can only be called by the team in possession of the ball and when the ball is stopped or pinned. Either team may call a time out when the ball is not in play (e.g. between balls or when the ball is dead or off the table).

9. Change of Position – either team may change positions (between attack & defence) only between balls, during a time out or before/after a penalty shot. The team with possession must change first.

10 Fouls – no distracting an opponent, spinning (see above), jarring (moving the table such that the roll of the ball is affected), reaching into the playing area without opponents permission (e.g. for dead ball) , unsportsmanlike conduct etc. Penalty is possession to the other team, who have option to continue play (e.g. if foul results in an own-goal from the offending team). In the event of a jar possession is given to the rod which would otherwise have caught the ball.

11 Have Fun!! – Please note that these simplified rules are designed to improve your enjoyment of the game, official ITSF tournament rules are more complex, and can be found at:

My personal twist :

Whenever someone gets a 5 vs 0 score the losing player(s) have to crawl under the table. However, these 5 goals have to be made without letting in a goal from the other side so whenever the other player scores… He gets 1 and you get reset to 0 and the game starts over again 🙂 hours of fun guaranteed.

Personal Drinking Game:

Based on my personal twist, whenever you get reset to 0 you have to take a sip from your drink for every point you have been set-back 🙂 Good Luck!


Ideally you want your score projected on a 150″ Screen 🙂



Leave a Reply

Your email address will not be published. Required fields are marked *

On Key

Related Posts