Berührungsloser Händewasch-Timer mit musikalischen Alerts
Komponenten und Zubehör
| Arduino UNO | × | 1 |
| ProtoStax Gehäuse für Arduino | × | 1 |
| ProtoStax Gehäuse für Breadboards/Custom Boards | × | 1 |
| ProtoStax Horizontal Stacking Kit | × | 1 |
| Ultraschallsensor HC-SR04 | × | 1 |
| ProtoStax Kit für Ultraschallsensor HC-SR04 | × | 1 |
| Adafruit 0,56" 4-stelliges 7-Segment-Display mit I2C Backpack (Blau) | × | 1 |
| Adafruit Piezo Summer PS1240 | × | 1 |
| Lötfreies Breadboard (Halbgröße) | × | 1 |
Apps und Online-Dienste
- Arduino IDE
Über dieses Projekt
Händewaschen war immer wichtig für Krankheitsprävention und Gesundheit, aber durch die COVID-19-Pandemie erhielt es neue Bedeutung als Maßnahme zur Eindämmung der Ausbreitung.
Die CDC empfiehlt, die Hände mindestens 20 Sekunden lang zu schrubben. CDC-Richtlinie
🤓📚 ** Extra Infos ** 🤓📚 Wissenschaft hinter Händewaschen: CDC
Dieser berührungslose musikalische Händewasch-Timer wird durch Winken vor einem Ultraschallsensor aktiviert und zeigt den Countdown auf einem 7-Segment-Display an. Zusätzlich spielt er eine rotierende Auswahl von 20-Sekunden-Jingles aus einer vorprogrammierten Liste. Eigene Melodien lassen sich leicht durch Übertragung von Notenblättern hinzufügen.
Das Touchless Musical Hand Wash Timer in Aktion mit 4 Jingles:
- Happy Birthday
- Do-Re-Mi (Sound of Music)
- We Will Rock You (Queen)
- Jeopardy Theme Music
Meine Hände waren super-duper sauber! 😊
🤓📚 ** Extra Infos ** 🤓📚 „Happy Birthday“ zweimal singen dauert ca. 20 Sekunden und ist zum De-facto-Standard geworden – sogar Kanadas Premierminister Justin Trudeau sang es! Dr. Theresa Tam, Kanadas Chief Public Health Officer, bevorzugt We Will We Will Wash You! 😊 Beide Songs sind in unserem Timer enthalten.
Schritt 1 – Schaltplan
Verwendet: Arduino Uno, 7-Segment LED Backpack (I2C), HC-SR04 Ultraschallsensor, Piezo Summer. Siehe Schaltplan:

Schritt 2 – Planung und Aufbau
Neben Schaltplan und Programmierung wollte ich an das „fertige Produkt“ denken: Gehäuse und Montage. Ich nutzte stapelbare ProtoStax-Gehäuse für Arduino, Breadboard und den Ultraschallsensor (seitlich zugänglich).
Zuerst horizontales Stapeln der Arduino- und Breadboard-Basisplattformen:

Dann Bestückung nach Schaltplan. HC-SR04 an der Seitenwand des ProtoStax-Kits befestigt, damit er nach Gehäusemontage zugänglich bleibt:


Schritt 3 – Programmierung und Test
Nach funktionsfähigem Prototyp entwickelte ich den Code. Details zum Code folgen unten. Hier ein Testvideo – mein iPhone 11 nahm das charakteristische Sonar-Pingen des Ultraschallsensors deutlich auf (sonst kaum hörbares Klicken)! 😊
Nach erfolgreichem Test: Gehäuse komplettieren (Seitenwände, Verbinder, Deckel):

Das Video oben zeigt das finale „Produkt“ im Einsatz! 😊

Code verstehen
Komponenten initialisieren
Wir nutzen die Adafruit_7segment-Klasse der LED Backpack Library für das 7-Segment-Display:
Adafruit_7segment matrix = Adafruit_7segment();
Trig- und Echo-Pins des HC-SR04 als Output/Input definieren:
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
matrix.begin(0x70);
Haupt-Loop (Übersicht)
- Ultraschallsensor prüfen: Hand erkannt → Timer starten.
- Wenn ja: aktuelle Zeit merken, Countdown auf 20 Sekunden setzen, nächstes Jingle auswählen (Round-Robin über Melodie-Array),
startMusicauf 1 setzen.
if (distance < 10 && !startMusic) {
startMusic = 1;
countDown = 20;
currentTime = millis();
melodyNum = (melodyNum+1) % NUM_MELODIES(melodies);
}
Look Ma, kein delay()!
Zwei Dinge gleichzeitig: Countdown-Uhr aktualisieren UND Jingle zeitgerecht abspielen. delay() blockiert – nicht nutzbar.
tone() ist nicht-blockierend (nutzt Timer2). Wir nutzen millis() und lokale Variablen für verstrichene Zeit, um parallel andere Operationen auszuführen.
Musik transkribieren – der einfache Weg (Ganze, Viertel, Achtelnoten…)
Statt zwei separater Arrays (Noten, Dauer in ms) nutze ich ein Struct mit relativer Dauer (ganze, halbe, Viertel, Achtel, Sechzehntel) und Makros für punktierte Noten.
typedef struct Note { int frequency; float duration; } Note;
#define NOTE_WHOLE 1
#define NOTE_HALF 0.5f
#define NOTE_QUARTER 0.25f
#define NOTE_EIGHTH 0.125f
#define NOTE_SIXTEENTH 0.0625f
#define DOTTED(X) (X * 1.5f)
Beispiel „Happy Birthday“ (Notenblatt siehe Bild):

// Happy Birthday
Note melody[] = {
{NOTE_G6, DOTTED(NOTE_EIGHTH)}, {NOTE_G6, NOTE_SIXTEENTH},
{NOTE_A6, NOTE_QUARTER}, {NOTE_G6, NOTE_QUARTER},
{NOTE_C7, NOTE_QUARTER}, {NOTE_B6, NOTE_HALF},
{NOTE_G6, DOTTED(NOTE_EIGHTH)}, {NOTE_G6, NOTE_SIXTEENTH},
{NOTE_A6, NOTE_QUARTER}, {NOTE_G6, NOTE_QUARTER},
{NOTE_D7, NOTE_QUARTER}, {NOTE_C7, NOTE_HALF},
{NOTE_G6, DOTTED(NOTE_EIGHTH)}, {NOTE_G6, NOTE_SIXTEENTH},
{NOTE_E7, NOTE_QUARTER}, {NOTE_D7, NOTE_QUARTER},
{NOTE_C7, NOTE_QUARTER}, {NOTE_B6, NOTE_QUARTER},
{NOTE_A6, NOTE_HALF}, {NOTE_F7, DOTTED(NOTE_EIGHTH)},
{NOTE_F7, NOTE_SIXTEENTH}, {NOTE_E7, NOTE_QUARTER},
{NOTE_C7, NOTE_QUARTER}, {NOTE_D7, NOTE_QUARTER},
{NOTE_C7, NOTE_HALF}
};
Eine Melodie besteht aus Noten-Array, Anzahl Noten und Dauer einer ganzen Note in ms:
typedef struct Melody { Note *notes; int numNotes; int wholeNoteDurationMs; } Melody;
#define MELODY_LENGTH(arr) (sizeof(arr)/sizeof(arr[0]))
Melody melodies[] = {
{melody, MELODY_LENGTH(melody), 1250},
{melody3, MELODY_LENGTH(melody3), 1000},
{melody4, MELODY_LENGTH(melody4), 1000}
};
Im Loop: Countdown-Timer und Musik gleichzeitig. Jingle wird zu Ende gespielt, auch wenn 20 Sekunden schon abgelaufen sind (Countdown wird negativ). Bei zu kurzem Jingle wird es wiederholt, bis 20 Sekunden UND Musikende erreicht sind.
if (startMusic) {
Melody mel = melodies[melodyNum];
Note *m = mel.notes;
int mSize = mel.numNotes;
int speedUp = 1;
noTone(TONE_PIN);
for (int thisNote = 0; thisNote < mSize; thisNote++) {
int noteDuration = mel.wholeNoteDurationMs * m[thisNote].duration / speedUp;
unsigned long noteTime = millis();
tone(TONE_PIN, m[thisNote].frequency, noteDuration);
int pauseBetweenNotes = noteDuration * 1.30;
unsigned long nowTime = millis();
countDown = 20 - (int)((nowTime - currentTime)/1000);
// Look Ma No delay()!
while(millis() - noteTime <= pauseBetweenNotes) {
countDown = 20 - (int)((millis() - currentTime)/1000);
matrix.print(countDown);
matrix.writeDisplay();
delay(10);
}
noTone(TONE_PIN);
matrix.print(countDown);
matrix.writeDisplay();
}
}
Vollständiger Code auf GitHub (Link unten). Empfehlung: Code von dort nehmen, nicht kopieren.
Projekt erweitern
- Eigene Lieblingsmelodie transkribieren (mit
NOTE- und Dauer-Makros). Andere Jingles auskommentieren, um Speicher zu sparen (oder Arrays in PROGMEM verschieben). - Melodien belegen SRAM (bei 4 Melodien 96% – 7-Segment-Library funktionierte nicht mehr). Lösung:
PROGMEMfür Note- und Melody-Arrays nutzen (fortgeschritten). Damit sinkt dynamischer Speicher von 76% auf 22% – Platz für viele Songs!
Weitere Ideen? Teilt sie unten! 😊 Happy Making! 😊
Code
ProtoStax Touchless Musical Handwash Timer Demo
Schaltpläne
Schaltplan für den berührungslosen musikalischen Händewasch-Countdown-Timer:
Herstellungsprozess
- Bluetooth-gesteuerter Arduino-Spybot bauen – Überwachungsroboter mit IP-Kamera
- FlickMote: Gestensteuerung per Ultraschall & IR für Smart Home (Arduino 101)
- DIY Arduino TV-B-Gone: Universelle TV-Aus-Fernbedienung
- Watchdog-Timer am Arduino verstehen & nutzen – Schutz vor Programmabstürzen
- Einen eigenen LED-Master-Clock mit Alarm bauen – aus 12 Metern Entfernung ablesbar
- Find Me: Smarter Gegenstands-Finder mit Arduino und Bluetooth
- Optimierte Stromversorgungslösungen für Arduino-Projekte
- Arduino Tic Tac Toe mit MAX7219 LED-Matrix und Karton-Gehäuse
- Intelligenten Arduino-Vierbeiner-Roboter bauen: Schritt-für-Schritt-Anleitung
- Bewährte Best Practices für die Inspektion von Handwaschstationen