ESP8266 - IR-Gabellichtschranke (Geschwindigkeitssensor)
Dieses Tutorial zeigt Ihnen, wie Sie den ESP8266 NodeMCU mit einer IR-Gabellichtschranke verwenden, damit das Board jedes Mal erkennt, wenn sich etwas durch den schmalen Spalt des Sensors bewegt. Mit diesem einen Signal kann der NodeMCU Dinge zählen oder messen, wie schnell sich ein Motor dreht. Im Detail lernen wir:
- Wie die Lichtschranke im Inneren des Sensors (auch als Opto-Interrupter oder Photo-Interrupter verkauft) ein HIGH- oder LOW-Signal liefert
- Wie man den Sensor mit dem 3,3-V-Pin und dem Pin D5 (GPIO14) des NodeMCU verdrahtet und welche Pins frei bleiben sollen
- Wie man ESP8266-Code schreibt, der jedes Objekt zählt, das den Schlitz blockiert
- Wie man ESP8266-Code schreibt, der die Motordrehzahl in RPM mit einer Encoderscheibe und einer mit IRAM_ATTR markierten Interrupt-Funktion misst
Wir empfehlen:
- Einen Drehencoder zu verwenden, wenn eine Person von Hand an einem Knopf dreht und der Code wissen muss, ob es nach links oder rechts geht.
- Einen Infrarot-Hindernissensor zu verwenden, wenn das gesuchte Objekt einige Zentimeter vor dem Sensor liegt und nicht durch einen kleinen Schlitz passt.

Erforderliche Hardware
Oder Sie können die folgenden Kits kaufen:
| 1 | × | DIYables Sensor-Kit (18 Sensoren/Displays) |
Über die IR-Gabellichtschranke
Stellen Sie sich einen kleinen Türrahmen aus schwarzem Kunststoff vor. Ein unsichtbarer Strahl geht quer durch den Rahmen. Wenn etwas Festes durch den Rahmen geht, wird der Strahl unterbrochen, und der Sensor meldet es sofort dem ESP8266. Mehr macht dieses Modul nicht, aber es macht es schnell und mit einem sehr sauberen Signal. Deshalb nutzen Bastler es als Geschwindigkeitssensor, Impulszähler und Endschalter.
Im Inneren des U-förmigen Gehäuses

Das Modul besteht aus drei Teilen:
- Einer Infrarot-LED in einem Arm. Sie sendet die ganze Zeit IR-Licht aus.
- Einem NPN-Fototransistor im anderen Arm. Er sitzt 5,9 mm entfernt und schaut zur LED.
- Einem Schmitt-Trigger auf der kleinen Platine. Er macht aus dem Signal des Fototransistors einen scharfen digitalen Pegel.
Der OUT-Pin folgt dem Strahl:
- Der Strahl erreicht den Fototransistor (der Schlitz ist leer): OUT ist HIGH.
- Der Strahl wird von einem festen Objekt unterbrochen (eine Karte, ein Finger, ein Zahn einer Encoderscheibe): OUT ist LOW.
Dank des Schmitt-Triggers haben die Flanken kein Jitter. Ihr ESP8266-Code kann den Wert direkt verwenden, ohne Entprellung.
Einige Tipps vor dem Test:
- Verwenden Sie etwas, durch das man nicht hindurchsehen kann. Klarer Kunststoff lässt eventuell IR-Licht durch, und der Sensor bemerkt ihn nicht.
- Einige Module anderer Hersteller haben die umgekehrte Logik (LOW, wenn leer). Tauschen Sie in diesem Fall LOW und HIGH im Zählcode. Der RPM-Code zählt eine Flanke pro Schlitz, daher liefert er trotzdem die richtige Drehzahl.
Technische Daten
| IR-Gabellichtschranke | |
|---|---|
| Sensortyp | Gabel-Lichtschranke (IR-LED + NPN-Fototransistor) |
| Schlitzbreite | 5,9 mm |
| Betriebsspannung | 3,3V bis 5V DC |
| Ausgang | Digital (TTL), LOW bei Unterbrechung, HIGH bei freiem Schlitz |
| Signalaufbereitung | Eingebauter Schmitt-Trigger |
| Montage | M3-Schraubenlöcher an beiden Enden |
| Pins | 3 (VCC, GND, OUT) |
Mit den zwei M3-Löchern können Sie das Modul an ein Roboterchassis oder einen Motorhalter schrauben, sodass es an derselben Stelle bleibt, während sich daneben eine Scheibe dreht. Typische Einsatzzwecke: ein Drehzahlmesser für einen kleinen Motor, Raddrehzahl-Rückmeldung für ein Roboterauto, ein Zähler für Gegenstände auf einem Förderband, ein Wegmesser, der Radumdrehungen zählt, und ein berührungsloser Endschalter oder Positionsschalter.
Die Pinbelegung der IR-Gabellichtschranke

- VCC-Pin: muss mit dem 3V3-Pin des NodeMCU verbunden werden (nicht mit 5V oder VIN)
- GND-Pin: muss mit einem G-Pin (GND) des NodeMCU verbunden werden (0V)
- OUT-Pin: der digitale Ausgang; er muss mit einem Eingangspin des NodeMCU verbunden werden (in diesem Tutorial D5)
※ Notiz:
Die Anordnung der Pins kann sich von Hersteller zu Hersteller unterscheiden, und auch zwei Chargen desselben Produkts können unterschiedlich sein. Orientieren Sie sich bei der Verwendung immer an den auf dem Modul aufgedruckten Beschriftungen. Schauen Sie genau hin!
Warum 3,3 V und nicht 5 V? Der OUT-Pin geht so hoch wie die Spannung an VCC. Der ESP8266 ist ein 3,3-V-Chip. Wenn der Sensor 5 V bekommt, würde OUT ebenfalls 5 V an einen NodeMCU-Pin geben. Kommt VCC vom 3V3-Pin, bleibt OUT zwischen 0 V und 3,3 V, was für das Board sicher ist.
Encoderscheibe: Von Impulsen zu RPM
Eine Encoderscheibe ist ein flaches Rad mit einem Ring aus Löchern nahe am Rand. Sie drücken sie auf die Motorwelle oder das Rad und platzieren den Sensor so, dass der Rand der Scheibe durch den Schlitz läuft. Während sich die Scheibe dreht, passieren Löcher und Zähne nacheinander den Strahl. Jeder Zahn lässt OUT einmal auf LOW gehen.
Die meisten TT-Getriebemotor-Sets haben eine Scheibe mit 20 Schlitzen. So macht der ESP8266 aus Impulsen eine Geschwindigkeit:
- Zählen Sie die Impulse 1 Sekunde lang.
- Multiplizieren Sie mit 60, um die Impulse pro Minute zu erhalten.
- Teilen Sie durch 20 (Impulse pro Umdrehung), um die Umdrehungen pro Minute zu erhalten, also U/min (RPM).
Verdrahtungsdiagramm
Verwenden Sie drei Jumper-Kabel: Sensor-VCC an den 3V3-Pin des NodeMCU, Sensor-GND an einen G-Pin und Sensor-OUT an D5, wie Sie im Bild unten sehen.

Dieses Bild wurde mit Fritzing erstellt. Klicken Sie, um das Bild zu vergrößern.
Weitere Informationen finden Sie unter ESP8266-Pinbelegung und wie man ESP8266 und andere Komponenten mit Strom versorgt.
D5-Beschriftung oder GPIO14?
Der Aufdruck auf dem NodeMCU zeigt Beschriftungen wie D1, D2 und D5. Der ESP8266-Chip selbst verwendet GPIO-Nummern, und die beiden stimmen nicht überein. D5 auf dem Board ist GPIO14 im Chip. Im Code schreiben wir D5, und der ESP8266-Core für die Arduino IDE wandelt es für uns in GPIO14 um. Wenn Sie nur 5 schreiben, verwendet der Code GPIO5, das ist der Pin D1. Das ist ein häufiger Fehler, lassen Sie daher im Code immer das "D" stehen.
Sie können den OUT-Draht an einen anderen Pin legen, wenn D5 belegt ist. Wählen Sie anhand dieser Liste:
| NodeMCU-Beschriftung | GPIO | Gut für diesen Sensor? |
|---|---|---|
| D1 | GPIO5 | Ja |
| D2 | GPIO4 | Ja |
| D5 | GPIO14 | Ja (in diesem Tutorial verwendet) |
| D6 | GPIO12 | Ja |
| D7 | GPIO13 | Ja |
| D3 | GPIO0 | Nein, Boot-Pin |
| D4 | GPIO2 | Nein, Boot-Pin |
| D8 | GPIO15 | Nein, Boot-Pin |
| D0 | GPIO16 | Keine Interrupt-Unterstützung, daher nicht für den RPM-Code |
Der Chip prüft D3, D4 und D8 beim Start. Der Sensor treibt OUT die ganze Zeit. Ist der Schlitz frei, ist OUT HIGH, und an D8 kann dieses HIGH das Booten des Boards verhindern. Steht zufällig ein Zahn der Scheibe im Schlitz, ist OUT LOW, und an D3 oder D4 kann dieses LOW ebenfalls einen normalen Start verhindern. Halten Sie den Sensor daher von diesen drei Pins fern.
Wie man die IR-Gabellichtschranke programmiert
Es muss keine Bibliothek installiert werden. Alles kommt aus dem ESP8266-Core, den Sie zur Arduino IDE hinzugefügt haben.
Schritte für den Zählcode
- Der erste Schritt ist, dem Pin, der mit OUT verbunden ist, einen Namen zu geben. Beachten Sie die "D"-Beschriftung:
- Als Nächstes wird der Pin in setup() als Eingang festgelegt. Der Sensor zieht die Leitung selbst auf HIGH oder LOW, daher ist kein Pull-up nötig:
- Dann liest der Code den Pin in jedem Durchlauf von loop(). LOW sagt dem ESP8266, dass der Strahl unterbrochen ist:
- Schließlich wird der neue Messwert mit dem vorherigen (lastState) verglichen. Der Zähler wird nur erhöht, wenn der Wert zu LOW gewechselt hat. Eine Karte, die fünf Sekunden im Schlitz bleibt, zählt also trotzdem nur einmal.
Schritte für den RPM-Code
- Der erste Schritt ist, den Impulszähler als volatile festzulegen. Die Interrupt-Funktion ändert ihn im Hintergrund, und das Schlüsselwort volatile sagt dem Compiler, immer den echten Wert zu lesen:
- Als Nächstes wird die Interrupt-Funktion geschrieben. Beim ESP8266 muss diese Funktion das Wort IRAM_ATTR vor sich haben. Dadurch liegt die Funktion im schnellen internen RAM des Chips. Ohne es kann der ESP8266 abstürzen und neu starten, wenn ein Impuls eintrifft:
- Dann wird die Funktion in setup() mit D5 verknüpft. FALLING bedeutet, dass sie läuft, wenn OUT von HIGH auf LOW fällt, also in dem Moment, in dem ein Zahn in den Schlitz eintritt:
- Danach kopiert der Code einmal pro Sekunde (geprüft mit millis()) den Zähler und setzt ihn auf null zurück. Der ESP8266 ist ein 32-Bit-Chip, daher liest er den 32-Bit-Zähler in einem Schritt. Deshalb braucht diese Version das Paar noInterrupts() und interrupts() nicht, das 8-Bit-Boards verwenden:
- Schließlich wird die Drehzahl mit der Formel aus dem Abschnitt über die Encoderscheibe berechnet:
ESP8266-NodeMCU-Code zum Zählen von Objekten im Schlitz
Dieser Code liest D5 ständig in loop(). Er addiert jedes Mal eins zum Zähler, wenn der Schlitz blockiert wird, und gibt nur eine Zeile aus, wenn sich der Zustand ändert. So füllt sich der Serial Monitor nicht mit derselben Meldung.
Schnelle Schritte
- Wenn Sie den ESP8266 zum ersten Mal verwenden, lesen Sie wie man die Umgebung für den ESP8266 in der Arduino IDE einrichtet.
- Verdrahten Sie die Bauteile wie im Diagramm gezeigt.
- Verbinden Sie das ESP8266-Board über ein USB-Kabel mit Ihrem Computer.
- Öffnen Sie die Arduino IDE auf Ihrem Computer.
- Wählen Sie das Board NodeMCU 1.0 (ESP-12E Module) und den COM-Port Ihres NodeMCU.
- Kopieren Sie den obigen Code und fügen Sie ihn in die Arduino IDE ein.
- Klicken Sie auf die Schaltfläche Upload und warten Sie, bis der Upload fertig ist.
- Öffnen Sie den Serial Monitor und stellen Sie 9600 Baud ein.
- Schieben Sie einen Kartonstreifen in den Schlitz und ziehen Sie ihn wieder heraus. Wiederholen Sie das dreimal.
- Sehen Sie sich das Ergebnis im Serial Monitor an.
Sagt die erste Zeile "blocked", obwohl nichts im Schlitz ist? Dann hat Ihr Modul die umgekehrte Logik. Ändern Sie LOW in der if-Anweisung zu HIGH und laden Sie den Code erneut hoch.
ESP8266-NodeMCU-Code zum Messen der Motordrehzahl (RPM)
Eine sich drehende 20-Schlitz-Scheibe kann Hunderte von Impulsen pro Sekunde erzeugen. Wenn loop() nur den Pin liest, gehen einige Impulse verloren, während der ESP8266 beschäftigt ist, zum Beispiel beim Ausgeben von Text. Ein Interrupt löst das. Der Chip hält kurz an, führt countPulse() aus und kehrt zu seiner Arbeit zurück, sodass jeder Zahn gezählt wird.
Einmal pro Sekunde gibt der Code die Impulszahl und die Drehzahl aus. Die Konstante SLOTS_PER_TURN ist 20. Wenn Ihre Scheibe eine andere Anzahl Löcher hat, zählen Sie sie und ändern Sie diese Zahl.
Schnelle Schritte
- Lassen Sie die Verdrahtung, wie sie ist. OUT bleibt an D5. Wenn Sie ihn verlegen, wählen Sie D1, D2, D6 oder D7 und ändern Sie SENSOR_PIN im Code.
- Drücken Sie die Encoderscheibe auf die Motorwelle oder das Rad. Stellen Sie die Höhe des Sensors so ein, dass die Zähne durch die Mitte des Schlitzes laufen und den Kunststoff nie berühren.
- Fügen Sie den RPM-Code in die Arduino IDE ein und klicken Sie auf Upload.
- Öffnen Sie den Serial Monitor mit 9600 Baud.
- Drehen Sie die Scheibe mit dem Finger oder lassen Sie den Motor laufen. Wie Sie den Motor mit dem NodeMCU betreiben, sehen Sie im Tutorial ESP8266 - Gleichstrommotor.
- Beobachten Sie die Drehzahl im Serial Monitor.
Der Motor in diesem Test dreht sich mit fast 300 RPM. Prüfen Sie die Zeile mit 101 Impulsen: 101 x 60 / 20 = 303 RPM. Die erste Zeile wurde ausgegeben, bevor der Motor gestartet war, und die letzte, nachdem er gestoppt hatte.
※ Notiz:
Wenn der NodeMCU ständig neu startet, sobald sich die Scheibe dreht, sehen Sie sich zuerst die Interrupt-Funktion an. Beim ESP8266 muss sie mit IRAM_ATTR markiert sein. Halten Sie sie außerdem sehr kurz: kein Serial.print(), kein delay(), nur der Zähler.
Zusätzliches Wissen
Häufig gestellte Fragen
Kann ich den Sensor über den VIN-Pin versorgen, damit er stärker wird?
Nein. VIN führt 5 V vom USB-Kabel, und OUT würde dann 5 V in einen 3,3-V-GPIO schicken. Das Modul arbeitet gut mit 3,3 V, daher ist der 3V3-Pin die richtige Wahl.
Warum ändern sich die RPM-Werte in Schritten von 3?
Der Code zählt ganze Impulse für eine Sekunde. Bei 20 Schlitzen ergibt ein zusätzlicher Impuls 60 / 20 = 3 RPM mehr. Eine Scheibe mit mehr Schlitzen gibt kleinere Schritte. Eine Scheibe mit weniger Schlitzen gibt größere Schritte. Welche Scheibe Sie auch verwenden, SLOTS_PER_TURN muss dazu passen.
Warum FALLING und nicht CHANGE?
FALLING führt die Funktion einmal pro Zahn aus, in dem Moment, in dem der Zahn in den Schlitz eintritt. CHANGE würde sie auch beim Verlassen des Zahns ausführen, sodass Sie zwei Zählungen pro Zahn und die doppelte echte Drehzahl erhalten würden.
Kann ein NodeMCU zwei Geschwindigkeitssensoren auslesen?
Ja. Legen Sie den zweiten Sensor an einen anderen sicheren Pin, zum Beispiel D6, und geben Sie ihm einen eigenen volatile-Zähler und eine eigene IRAM_ATTR-Funktion. Das ist praktisch für ein Roboterauto mit zwei angetriebenen Rädern.
Gabellichtschranke, Hindernissensor oder Drehencoder?
Die Gabellichtschranke braucht ein Ziel, das durch ihren 5,9-mm-Spalt geht, immer an derselben Stelle. Sie liefert einen sauberen Impuls pro Durchgang und ist das beste Werkzeug für Drehzahl und Zählen.
Der Hindernissensor schaut in den freien Raum. Er erfasst Licht, das von einer Wand, einer Hand oder einer Kiste vor ihm zurückgeworfen wird, sodass das Ziel nicht in einen Schlitz passen muss.
Der Drehencoder ist ein Drehknopf. Er hat zwei Signale (CLK und DT) plus einen Taster, sodass er auch die Drehrichtung erkennen kann.
Es ist offensichtlich, dass die Gabellichtschranke von den dreien die genaueste ist, um ein sich drehendes Teil zu messen, weil der Strahl bei jeder Umdrehung an derselben kleinen Stelle unterbrochen wird. Die Drehrichtung kann sie allerdings nicht erkennen. Wenn Sie das brauchen, ist der Drehencoder die richtige Wahl.
Von RPM zur Radgeschwindigkeit
Wenn die Scheibe auf einem Roboterrad sitzt, macht ein weiterer Schritt aus RPM die Geschwindigkeit des Roboters:
- Radumfang = π x Raddurchmesser
- Strecke in einer Sekunde = (RPM / 60) x Radumfang
Beispiel: Ein Rad mit 60 mm Durchmesser hat einen Umfang von etwa 188,5 mm. Bei 300 RPM macht es 5 Umdrehungen pro Sekunde, sodass der Roboter etwa 942 mm, also 0,94 Meter, pro Sekunde rollt.
Video Tutorial
Wir erwägen die Erstellung von Video-Tutorials. Wenn Sie Video-Tutorials für wichtig halten, abonnieren Sie bitte unseren YouTube-Kanal , um uns zu motivieren, die Videos zu erstellen.