Optischer Zähler und Linienerkennung mit dem KY-033 Modul und dem Multi Function Shield
Das Multi Function Shield, das ich ja bereits vorgestellt habe und das mittlerweile ja auch um einen Drehgeber erweitert wurde, bietet mit der Möglichkeit zur einfachen Anzeige von Daten auf seinem 4-fach-7-Segment-Display und den freien Anschlusspins eine gute Grundlage, Sensoren ausprobieren.Heute wird ein weiteres Bauteil meiner 37-in-one-Sensoren-Bulk-Bestellung behandelt. Es ist das Tracking Sensor Modul KY-033.
Hardware: Modul KY-033
Auch diesmal galt es wieder, das Modul zu identifizieren, denn eine Bezeichnung fehlte mal wieder. Aber der Vergleich mit Fotos aus dem Internet ergab, dass es sich um ein KY-033 handelt, einem Modul zur Hindernis-Erkennung.
Das KY-033 ähnelt von den Komponenten und der Funktion sehr dem KY-032 Hinderniserkennungsmodul, allerdings sind die Infrarot-LED und der Fototransistor anders auf der Platine angebracht, nämlich eher so, dass die Sensoren zu einer Unterseite, denn zur Seite, zeigen.
Das Funktionsprinzip ist aber das selbe: Ein IR-Lichtstrahl wird von der LED ausgesendet. Trifft der Strahl auf ein Objekt, so wird die Infrarotstrahlung von diesem reflektiert. Ein Teil wird zurück in die Richtung des Moduls geworfen und trifft dort auf den Fototransistor. Das heißt: jedesmal, wenn ein reflektierendes Hindernis in der Nähe befindet, wird ein Signal geliefert, weil der Fototransistor IR-Strahlung registiert. Diese muss im Übrigen nicht vom Modul selbst stammen, man kann auch eine einfache Infrarot-Fernbedienung benutzen, um es zu täuschen.
Außerdem ist der Sensor anders abgestimmt, so dass er besser reflektierende und nicht reflektierende Flächen unterscheiden kann, oder anders gesagt: es kann zwischen hell und dunkel bzw. weiß und schwarz unterscheiden.
Mit dem Potentiometer kann man einstellen, ab welcher Lichtstärke empfangener IR-Strahlung das Modul Alarm schlagen soll, sprich die Data-Leitung auf HIGH setzt. Beim Einstellen hilft eine LED, die immer dann leuchtet, wenn der HIGH-Zustand (hell) erreicht wurde und erlischt, sobald die Leitung auf LOW (dunkel) geht. So lässt sich der Kontrast einstellen, am wann eine Fläche erkannt werden soll, also die Empfindlichkeit.
Das der Lichtstrahl Infrarotlicht benutzt, hat den Vorteil, dass nur dieses erkannt wird und normales Tageslicht, das einfällt, die Messung nicht stört. So kann außerdem mit sehr viel geringeren Lichtstärken gearbeitet werden, was den Stromverbrauch reduziert.
Zwischen Sende- und Empfangseinheit ist eine kleine Wand, damit die LED nicht direkt einstrahlt. Trotzdem sind die beiden Elemente dicht nebeneinander angeordnet, was genaue, regional begrenzte Messungen ermöglicht.
Die Anschlusspins des KY-033-Moduls sind schnell erklärt, von oben nach unten sind dies (Vorderseite oben, Pins rechts):
- S (Data / Signal): liefert HIGH oder LOW, je nachdem, ob IR-Strahlung eintrifft oder nicht
- V+ (+5V): Stromversorgung
- G (GND): Masse
Anwendungsgebiete
Das KY-033 kann man genau wie das KY-032 als Stückzähler einsetzen, die Software für den Arduino ist dabei die selbe. Nur reicht der KY-033-Sensor nicht ganz so weit wie der KY-032-Sensor.Vorgesehen ist das Modul zum Tracking, das heißt, es soll einem Roboter helfen, einem durch dunkle Farbe markiertem Track zu folgen. Das kann zum Beispiel eine schwarze Linie auf einem weißen Stück Papier sein. Erkennt der Roboter, dass er den Track verlassen hat, so kann er gegensteuern, um wieder auf den Track zu kommen. Am besten verbaut man 2 Module nebeneinander, dann ist auch klar, auf welcher Seite man den Track verlasen hat und in welche Richtung man steuern muss, um wieder hinauf zu kommen.
Man könnte das Modul auch missbrauchen, um einfach nur Infrarotstrahlung zu detektieren. Damit könnte man einen ganz einfachen Infrarot-Empfänger basteln, der etwas tut, wenn eine IR-Fernbedienung auf das Modul gerichtet wird und ein Knopf gedrückt wird. Und dann etwas auslösen, ganz gleich, was für eine Fernbedienung benutzt wurde, oder welcher Knopf gedrückt wurde.
Oder man positioniert das Modul innen vor die Tür in einem Kasten und reagiert, wenn kein Hindernis mehr erkannt wird, denn dann wurde die Tür geöffnet. Zum Beispiel, wenn man protokollieren möchte, wann ein Zugriff erfolgte.
Das Modul wird folgendermaßen an des Multi Function Shield angeschlossen:
Modul KY-033 Kabelfarbe MFS/Arduino
S (DATA) grün 5 (3x4 Header)
V+ (+5V) rot +5V (3x4 Header)
G (GND) schwarz GND (3x4 Header)
Da ein Stückzähler ja schon beim KY-032 realisiert wurde, habe ich zur Veranschaulichung einen optischen Taster programmiert, der den selben Source-Code wie der KY-032 benutzt und Berührungen mit dem Finger mitzählt, wie folgendes Video zeigt:Software
Kommen wir aber zu einem neuen Programm. Dazu wird das Modul an die Unterseite des Arduino geklebt und die Position des Fototransistors markiert, so dass man diese auch von oberhalb erahnen kann.Die Programm ist dem Spiel "Der heiße Draht" nachempfunden: Man muss auf der schwarzen Linie bleiben und möglichts ohne Fehler vom Start zum Ziel die Linie entlang fahren. Bei jeder Abweichung von der Linie gibt es einen Strafpunkt (wird mitgezählt), und das Gerät piept so lange, bis es wieder auf der Linie ist. Wer am wenigsten Fehlerpunkte hat, gewinnt.
Folgendes, kurzes Video vermag dies zu veranschaulichen:
Source-Code
Und hier noch der Source-Code für das gezeigte Programm:////////////////////////////////////////////////////////
// (C) 2018 by Oliver Kuhlemann //
// Bei Verwendung freue ich mich über Namensnennung, //
// Quellenangabe und Verlinkung //
// Quelle: http://cool-web.de/arduino/ //
////////////////////////////////////////////////////////
#include <TimerOne.h> // für Timings und Interrupts
#include <MultiFuncShield.h> // API für das Multi Function Shield
#define PinData 5 // wo ist Data angeschlossen?
#define DurPause 100 // Pause in ms zwischen den Messungen
void setup() {
Timer1.initialize();
MFS.initialize(&Timer1); // initialize multi-function shield library
pinMode (PinData, INPUT);
}
void loop() {
int za=0;
int wert=0;
int wertBefore=-1;
boolean silence=false;
int btn=0;
long last=millis();
MFS.beep(1, 5, 2); // bereit
MFS.write(za);
while (1) {
btn=MFS.getButton();
if (btn == BUTTON_1_PRESSED) {
silence = !silence;
if (silence) {
MFS.write ("ton-");
} else {
MFS.write ("ton+");
}
}
if (btn == BUTTON_2_PRESSED) {
MFS.write ("null");
za=0;
}
wert = digitalRead(PinData);
if (wert == 0 && !silence) MFS.beep(1);
if (wert != wertBefore) {
if (wert == 0) {
MFS.writeLeds(LED_1, ON);
MFS.writeLeds(LED_2, OFF);
} else {
MFS.writeLeds(LED_1, OFF);
MFS.writeLeds(LED_2, ON);
if (millis() - last > 50) { // ungenaues Zählen durch Kanten vermeiden
last = millis();
za++;
if (za > 9999) za=0;
MFS.write(za);
}
}
wertBefore = wert;
}
delay(DurPause);
}
}