Das hier beschriebene Infrarot-Lichtschrankenmodul kann man z.B. unter den Bezeichnungen
"GR-YM-226", "HC-020k" oder "MH-Sensor-Series" erhalten.
Damit sollen z.B. Impulsmessungen von bis zu 100kHz möglich sein (z.B. Umdrehungsmessung von Motoren)
Das Modul besitzt ein Paar von IR-Diode und Empfänger, welche in U-Form verbaut sind. Durch einem LM393
Komparator werden die Signale verstärkt/digitalisiert und liegen dann an dem Ausgang D0
des
Moduls an. (A0
hat -wie auch im unteren Schaltplan zu sehen ist- keine Verwendung und muss
auch nicht verdrahtet werden)
Das Modul kann mit 3,3V und mit 5V betrieben werden und ist somit vom Arduino über den ESP32/ESP8266 als auch für den Raspberry Pi geeignet. Die beiden grünen Indikator-LEDs leuchten recht kräftig und können u.U. entfernt werden, falls sie in der entsprechenden Anwendung stören sollten.
Für den Ausgang D0
des Moduls kann jeder digitale Pin am Arduino verwendet werden (hier #7).
Soll jedoch ein Interrupt benutzt werden, dann muss entweder #2 oder #3 angeschlossen werden.
Um die Unterbrechungen der IR-Lichtschranke zu messen und anzuzeigen ist der folgende Sketch geeignet. Hier wird nach jeder Messung noch ein kleine Pause von 1ms eingelegt, damit die seriellen Konsole nicht zu sehr "geflutet" wird.
#define PIN_DOUT 7
void setup()
{
Serial.begin(9600);
pinMode(PIN_DOUT, INPUT);
}
void loop()
{
Serial.println(digitalRead(PIN_DOUT));
delay(1);
}
Man kann statt der seriellen Konsole auch den seriellen Plotter der Arduino-IDE verwenden und sieht dann jede Unterbrechung der Lichtschranke als vertikalen Ausschlag der Linie:
Für Motoren, Räder, Ventilatoren etc. kann mit diesem IR-Modul leicht ein einfacher Umdrehungsmesser
programmiert werden. Dazu muss die Anzahl der gemessenen Unterbrechungen der IR-Lichtschranke nur durch
die vergangene Zeit geteilt und dann auf eine Minute hochgerechnet werden. Schon erhält man die Umdrehungszahl
pro Minute in rpm
.
In dem folgenden Sketch wird statt der normalen Messung über digitalRead()
ein Interrupt des
Arduinos verwendet. Dazu kann Pin 2 (wie hier) oder auch Pin 3 verwendet werden.
#define PIN_DOUT 2
#define CUSTOM_DELAY 5000
#define lmillis() ((long)millis())
long lastAction;
volatile int count = 0;
void isrCount()
{
count++;
}
void setup()
{
Serial.begin(9600);
pinMode(PIN_DOUT, INPUT);
lastAction = lmillis() + CUSTOM_DELAY;
attachInterrupt(digitalPinToInterrupt(PIN_DOUT), isrCount, RISING);
}
void loop()
{
if (lmillis() - lastAction >= 0) {
detachInterrupt(digitalPinToInterrupt(PIN_DOUT));
lastAction = lmillis() + CUSTOM_DELAY;
int rpm = count * 60 / (CUSTOM_DELAY / 1000);
Serial.println("RPM: " + String(rpm));
count = 0;
attachInterrupt(digitalPinToInterrupt(PIN_DOUT), isrCount, RISING);
}
}
So sollte die Ausgabe aussehen, wenn einige verschiedene Messungen durchgeführt wurden:
In diesem Aufbau wird ein Gleichstrommotor so betrieben, dass die Umdrehungszahl mit der IR-Lichtschranke gemessen und dann mit dem Arduino auf eine bestimmte Zahl gedrosselt wird.
Der Gleichstrommotor wird vom Arduino durch eine einfache Transistorschaltung mit PWM betrieben, so dass die Geschwindigkeit geregelt werden kann (Freilaufdiode 1N400x nicht vergessen!). Als externe Stromquelle für den Motor verwende ich hierbei den 5V-Anschluss eines 18650 Batterie-Boards.
Falls ein anderer Transistor (oder MOSFET) verwendet wird, hierbei auf die Anschlüsse achten!
Zum Abgreifen der Umdrehungen habe ich auf dem 3D-Drucker eine spezielle Lochmaske zum Aufstecken auf den Motorschaft gedruckt.
Je nach verwendetem Motor muss der Innen- und Außendurchmesser angepasst werden.
wheel.scad
In dem folgenden Sketch sind die beiden konstanten Werte CHECK_DELAY
und RPM_SET
wichtig:
CHECK_DELAY
gibt den Zeitraum in Millisekunden an, in dem das Programm die Umdrehungszahl
des Motors überprüft und dann entsprechend nachregelt.
RPM_SET
gibt dabei die gewünschte Umdrehungszahl an, die eingeregelt werden soll.
#define PIN_IR 2
#define PIN_MOTOR 9
#define CHECK_DELAY 1000
#define RPM_SET 2500
#define lmillis() ((long)millis())
int motorValue = 0;
long nextCheck = 0;
volatile int count = 0;
void isrCount()
{
count++;
}
void setup()
{
Serial.begin(9600);
pinMode(PIN_IR, INPUT);
pinMode(PIN_MOTOR, OUTPUT);
analogWrite(PIN_MOTOR, motorValue);
attachInterrupt(digitalPinToInterrupt(PIN_IR), isrCount, RISING);
}
void loop()
{
if (lmillis() - nextCheck >= 0) {
detachInterrupt(digitalPinToInterrupt(PIN_IR));
int rpm = count * 60 / (CHECK_DELAY / 1000);
Serial.println("RPM: " + String(rpm));
count = 0;
if (rpm < RPM_SET) {
motorValue++;
} else if (rpm > RPM_SET) {
motorValue--;
}
analogWrite(PIN_MOTOR, motorValue);
nextCheck = lmillis() + CHECK_DELAY;
attachInterrupt(digitalPinToInterrupt(PIN_IR), isrCount, RISING);
}
}
Um die Umdrehungszahlen leichter überprüfen zu können, werden diese in jedem Prüf-Durchgang auf der seriellen Konsole ausgegeben:
Hinweis: Will man die WIRKLICHEN Umdrehungszahlen eines Motors einregeln, so darf natürlich nur EINE Unterbrechung pro Umdrehung des Motors gezählt werden und nicht acht, wie in meinem Beispiel.
zurück