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
- Benodigdheden
- Hardware-opstelling
- ESP32 Code met MQTT
- Home Assistant-configuratie
- Scorebord in Lovelace
- Uitbreidingsideeën
✅ 1. Benodigdheden
| Onderdeel | Aantal | Opmerking |
|---|---|---|
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
- 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
- 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.hPubSubClient
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: 1Automatisering (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: KimOptioneel: 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 |
|
Resetknop of NFC voor spelerswissel | GPIO of reader integreren |
MQTT-retained status | Zichtbaar bij herstart |
Geluid of TTS bij score | Home Assistant |
entities.comment_count