Skip to main content

Slim Baldoel met Scorebord

Bouwhandleiding: Slim Balspel met IR-detectie, MQTT en Home Assistant Scorebord

✨ Doel

Een rustig balwerpspel waarbij een ESP32 met IR-sensor herkent of een bal door een poort gegooid is. Elke treffer wordt via MQTT doorgestuurd naar Home Assistant, waar per deelnemer de score zichtbaar is op een dashboard.


📆 Inhoud

  1. Benodigdheden
  2. Hardware-opstelling
  3. ESP32 Code met MQTT
  4. Home Assistant-configuratie
  5. Scorebord in Lovelace
  6. Uitbreidingsideeën

✅ 1. Benodigdheden

OnderdeelAantalOpmerking

ESP32 Devkit

1

WiFi aan boord

IR Break Beam Sensor (3-pin)

1

Bv. Adafruit 2168 of generiek

Jumperkabels + breadboard (of PCB)

enkele

Voor opbouw

USB-kabel

1

Voor voeding & programmering

WiFi-netwerk

1

Voor MQTT

Home Assistant + MQTT broker

1

Mosquitto aanbevolen


🛠️ 2. Hardware-opstelling

  1. Monteer IR-sensor in een ring of poort (bijv. PVC-buis met 2 gaten).
    • Zender (Tx) en ontvanger (Rx) tegenover elkaar
    • Bal onderbreekt de infraroodstraal bij een treffer
  2. Sluit aan op ESP32:

IR-sensor

ESP32 pin

VCC

3.3V

GND

GND

OUT

GPIO 15


💾 3. ESP32-code met MQTT (Arduino IDE)

Installeer bibliotheken:

  • WiFi.h
  • PubSubClient

Voorbeeldcode:

#include <WiFi.h>
#include <PubSubClient.h>

const char* ssid = "JOUW_WIFI_NAAM";
const char* password = "JOUW_WIFI_WACHTWOORD";
const char* mqtt_server = "192.168.1.100";
const int mqtt_port = 1883;
const char* mqtt_user = "mqtt-gebruiker";
const char* mqtt_password = "mqtt-wachtwoord";
const int sensorPin = 15;
const char* spelerNaam = "Jan";  // Pas dit aan

WiFiClient espClient;
PubSubClient client(espClient);
bool beamBroken = false;

void setup_wifi() {
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
}

void reconnect() {
  while (!client.connected()) {
    client.connect("ESP32Client", mqtt_user, mqtt_password);
    delay(5000);
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(sensorPin, INPUT);
  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
}

void loop() {
  if (!client.connected()) reconnect();
  client.loop();

  if (digitalRead(sensorPin) == LOW && !beamBroken) {
    beamBroken = true;
    String payload = "{\"speler\":\"" + String(spelerNaam) + "\",\"score\":1}";
    client.publish("balspel/score", payload.c_str());
  }
  if (digitalRead(sensorPin) == HIGH && beamBroken) {
    beamBroken = false;
  }
}

🏡 4. Home Assistant-configuratie

input_number in configuration.yaml

input_number:
  score_jan:
    name: Score Jan
    initial: 0
    min: 0
    max: 999
    step: 1

Automatisering (automations.yaml):

- alias: 'Verhoog score voor Jan'
  trigger:
    platform: mqtt
    topic: 'balspel/score'
  condition:
    condition: template
    value_template: >
      {{ trigger.payload_json.speler == 'Jan' }}
  action:
    - service: input_number.set_value
      target:
        entity_id: input_number.score_jan
      data:
        value: >
          {{ states('input_number.score_jan') | int + trigger.payload_json.score }}

📊 5. Lovelace Scorebord

type: entities
title: Balspel Scorebord
entities:
  - entity: input_number.score_jan
    name: Jan
  - entity: input_number.score_els
    name: Els
  - entity: input_number.score_kim
    name: Kim

Optioneel: gebruik bar-card, gauge-card of custom:button-card voor visuele weergave.


✨ 6. Uitbreidingsideeën

Idee

Techniek

Meerdere doelen

Extra IR-sensoren op andere GPIO's

Tijdmeting of challenges

millis() of timerfuncties

Resetknop of NFC voor spelerswissel

GPIO of reader integreren

MQTT-retained status

Zichtbaar bij herstart

Geluid of TTS bij score

Home Assistant tts.google_say