Carrera Arduino Infrarot Wagenerkennung
Erkennung der Infrarot Wagenkennung für Weichensteuerung, Zeitmessung und sonstiges...


Ein letzter und wichtiger Grundbaustein des Carrera Hackings ist die sichere Erkennung der Wagen bei Überfahrt der Sensoren. Ich benötige diese Erkennung beispielsweise für den Bau einer intelligenten Arduino Weiche, zur Zeit- und Geschwindigkeitsmessung und zum Auslösen von Ereignissen. Diesen Hacking-Grundlagenbaustein habe ich mir als letzten für die Winterbastelsaison 2012/2013 aufgehoben. Ich dachte, dass die Erkennung keine besondere Herausforderung sein würde.

IR-Transistor in der Sart-Ziel-Geraden Abbildung 1
Ein Infrarot Transistor erfasst die Signale der Wagen bei der Überfahrt, jedes Fahrzeug hat seine eigene Blinkfrequenz


In der Theorie war alles ganz einfach. Die Wagen senden über eine IR-Diode dauerhaft ein Ein-Aus Signal mit einer festen Frequenz, die Frequenz hängt dabei von der Fahrzeugnummer, respektive der Reglernummer ab. Ich wollte einfach einen passenden Fototransistor an einen digitalen Eingang des Arduino hängen und mit dem Arduino Processing Befehl pulseIn() die Zeitdauer der einlaufenden Signale messen. So einfach, wie ich mir das anfänglich ausgedacht hatte, war es dann leider doch nicht.

Infrarot Erkennungsschaltung Emitterschaltung Abbildung 2
Erste Beschaltung des IR-Transistors zur Erkennung der Carrera Wagenkennung mit dem Arduino (Emitterschaltung)

Für die ersten Tests habe ich einen passenden Fototransistor beim Elektronikhändler meines Vertrauens gekauft und über einen Widerstand eine einfache Emitterschaltung gebaut. Als Fototransistor kommt ein OSRAM SFH309FA zum Einsatz, wichtig ist der Zusatz FA, der die Tageslichtfilterung kennzeichnet. Diese Transistortypen sind an dem charakteristischen, schwarzen Gehäuse zu erkennen. An die oben abgebildete Schaltung habe ich zunächst ein Oszilloskop anstelle des Arduinos angeschlossen, das Ergebnis war leider ernüchternd.

Sensorsignale bei Überfahrt Abbildung 3
Messung der Signale bei Überfahrt der Fahrzeuge mit maximaler Geschwindigkeit, Fahrzeuge 0,1,3,5 von o.l nach u.r.

Bei maximaler Geschwindigkeit der Fahrzeuge bleiben dem Fototransistor gerade mal 3 Millisekunden um brauchbare Signale zu empfangen. Bei dem Fahrzeug mit der ID 5, Regler Nr. 6 (Abbildung 2 unten rechts) liegt die Blinkfrequenz bei 2,6 kHz. In dem kurzen Zeitschlitz der Sensorüberfahrt kommen gerade mal 5 saubere Pulse an. Am anderen Ende der Fahnenstange sieht es auch nicht viel besser aus. Bei Fahrzeug ID 0, Regler Nr. 1 blinkt die IR-Diode mit 15,6 kHz. Die Detektorschaltung empfängt so viele Impulse, dass sie sich in den Pausen nicht vollständig erholen kann und die Spannung nicht mehr auf HIGH-Level kommt. Die Kapazitäten und Widerstände von Zuleitung und Transistor bewirken eine deutliche Signaldämpfung. Bei den unteren beiden Messungen mit den Fahrzeug ID's vier und sechs kann man die Dämpfung beim Übergang von LOW zu HIGH sehr schön erkennen.

Frequenzen der IR-Dioden Abbildung 4
Frequenzen und Periodenzeiten der IR-Dioden je nach Fahrzeug ID, bzw. Regler

Eine Verringerung des Widerstands R1 hat zwar eine kürzere Zeitkonstante zur Folge, die Spannung kann sich nach Abschalten des IR-Lichtes also schneller regenerieren. Allerdings geht das nur auf Kosten des Flankenwechsels von HIGH nach LOW. Egal wie ich es drehe und wende, die Signale eignen sich nicht für eine Auswertung durch den Arduino. Die Auswertung durch die analogen Eingänge habe ich erst gar nicht weiter in Betracht gezogen. Die internen A/D-Wandler des Atmega sind zu langsam, um einzelne Pulse von 15 kHz sauber auflösen zu können. "It takes about 100 microseconds (0.0001 s) to read an analog input, so the maximum reading rate is about 10,000 times a second." Arduino Reference analogRead(). Das kürzeste Intervall der Carrera Wagen liegt mit 64 Mikrosekunden schon deutlich unter dem minimal möglichen Zeitfenster von 100 Mikrosekunden des A/D-Wandlers.

Infrarot Erkennungsschaltung Komparatorschaltung Abbildung 5
Aufbereitung der Carrera IR-Transistorsignale mit Hilfe eines Komparators

Um die Signale sicher auswerten zu können, müssen sie durch weitere Elektronik aufbereitet werden. Hierzu bieten sich die aus der Analogtechnik bekannten Komparatoren, beispielsweise dem LM393 an. Diese Technik widerspricht zwar meiner Carrera Hacking Philosophie, wonach die externe Hardware so minimal wie möglich gehalten werden soll. Ich sehe momentan aber keine praktikable Alternative, zumal die einfache Technik spätestens dann an ihre Grenzen gestoßen wäre, wenn die Sensoren in größerem Abstand zum Arduino platziert werden. Die Leitungskapazitäten würden eine Erkennung der Signale mit an Sicherheit grenzender Wahrscheinlichkeit unmöglich machen.

Fritzing Sketch des IR-Detektors Abbildung 6
Testaufbau der Detektorschaltung mit Komparator und Hysterese auf dem Steckbrett.

In der Komparatorschaltung wird der Fototransistor in Kollektorschaltung betrieben, R1 ist dabei mit 1 kΩ deutlich geringer als in der ersten Schaltung. Die Signalspannung hinter dem Transistor sinkt damit deutlich unter 5V, das Signal selber ist aber dafür aber um so stabiler und der Komparator hebt die Spannung am Ausgang sowieso wieder auf digital taugliche Level. Über R2 und R3 wird der Arbeitspunkt des Komparators eingestellt, die Spannung am invertierenden Eingang beträgt in der vorliegenden Beschaltung ca. 0,8 V.

Die Signalflanken am nicht invertierenden Eingang des Komparators sind nur noch verhältnismäßig flach, insbesondere der Übergang in den HIGH Zustand ist auf Grund der Transistor Kapazitäten relativ sanft. Das Restrauschen auf dem Signal würde zusammen mit den sanften Flanken unweigerlich zu Schwingungen des Komparators an den Schaltpunkten führen. Ein Auswertung wäre zwar prinzipiell noch möglich, würde aber regelmäßig zu Fehlmessungen führen. Um die Schwingungen zu unterdrücken, wird ein Teil der Ausgangsspannung über R5 zurück gekoppelt, was eine Schalthysterese zur Folge hat.

Wagen 1 und 6 am Komparator Abbildung 7
Wagen mit ID 0 und ID 5 überfahren mit maximaler Geschwindigkeit die Sensoren an der Komparatorschaltung.

Mit der Rückkopplung sind die Signalverläufe absolut sauber wie in Abbildung 7 sehr schön zu sehen ist. Der fliegende Testaufbau auf dem Steckbrett ist in der Abbildung 6 abgebildet. Der Infrarotsensor sollte für die weiteren Tests am Besten in eine Schiene eingebaut werden. Während meiner diversen Test hatte ich den Sensor in einer geraden Schiene direkt hinter die Start/Zielgerade der CU gebaut. So konnte ich die Ergebnisse der Arduino-IR-Erkennung direkt mit denen der CU vergleichen.

Infrarot Sensor in der Start-/Zielschiene Abbildung 8
Infrarottransistor in der Start-/Ziel-Schiene der CU

Die Software zur Erkennung ist mal wieder recht überschaubar. Die Hauptschleife besteht aus 3 Zeilen, und wartet hauptsächlich auf erkannte Wagen, deren ID einen Wert kleiner als 8 hat. Sobald eine ID zwischen 0 und 7 vorliegt, wird sie auf der seriellen Schnittstelle ausgegeben. Anschließend wird die ID wieder auf einen ungültigen Wert gesetzt und die Hauptschleife wartet erneut. Die eigentliche Erkennung erledigt eine Interrupt Routine.
int carID = 99;                                         // save current car ID
boolean identified = false;                             // indicates that car has already been indentified
unsigned long previousMicros = 0;                       // last runtime of interrupt call
unsigned long currentMicros = 0;                        // current runtime 
unsigned long interval = 0;                             // time interval between last and current interrupt call

void setup() {                                          ////// 
  Serial.begin( 115200 );                               // initialize serial bus 
  attachInterrupt(0, infraredDetect, FALLING);          // whenever level on Pin 2 falls, start detection routine
}                                                       //////

void loop() {                                           //////
  if ( carID < 8 ){                                     // real car ID's are always smaler then 8
    Serial.println( carID, DEC );                       // print ID to serial
    carID = 99;}                                        // set ID to unreal level
}                                                       //////
  
void infraredDetect(){                                  //////
  currentMicros = micros();                             // save current runtime
  interval = currentMicros - previousMicros;            // interval to last interrupt call
  if ( interval > 30000 ){                              // minimal time gap between two cars
    identified = false;                                 // a new car has to be detected
    previousMicros = currentMicros;                     // save runtime for next interrupt call
    return;}                                            //
  if ( identified ) return;                             // if car already detected, skip interrupt
  if ( interval < 60 ) {                                // must be an error
    previousMicros = currentMicros;                     // save runtime for a new try
    return;}                                            //
  carID = (interval / 64) - 1;                          // at this point interval is valid, calculate car ID
  identified = true;                                    // indicate that we have already identified the car
  previousMicros = currentMicros;                       // save runtime for next interrupt call
}                                                       //////                                             
Die Interrupt Routine misst hauptsächlich die Zeit zwischen zwei Aufrufen. Fahren zwei Wagen mit Vollgas direkt hintereinander über den Sensor, beträgt die Pausenzeit zwischen den Signalen zwischen 50 und 60 Millisekunden (siehe Abbildung 9). Ab einer Signalpause von etwa der Hälfte dieser Pausenzeit, also bei über 30 Millisekunden, etwa dem 10-fachen der Plusedauer bei Sensorüberfahrt, können wir absolut sicher sein, dass ein neuer Wagen den Sensor überfährt. In diesem Fall muss eine neue Erkennung beginnen, was über die boolsche Variable "identified" geregelt wird. Wenn die Variable auf "true" gesetzt ist, wurde der Wagen bereits erkannt und der Interrupt kann verlassen werden.

Zwei Wagen fahren direkt hintereinander Abbildung 9
Zwei Wagen mit der ID 4 fahren bei maximaler Geschwindigkeit Stoßstange an Stoßstange über den Sensor.

Ansonsten wurde der Erkennungsroutine noch eine Abfrage zur Fehlerkorrektur hinzugefügt. Bei Zeitfenstern, die sicher unter der minimalen Intervallzeit von 64 Mikrosekunden liegen, muss ein Fehler vorliegen, die Messung wird im nächsten Intervall wiederholt. Läuft alles richtig, kann die ID am Ende der Routine über eine einfache Division durch die minimal Periodenzeit von 64 µs berechnet werden.

Während meinen Tests im vergangenen Winter 2012/2013 waren die Erkennungsraten der Arduino Testschaltung gefühlt besser als die der CU. Zur Bestätigung meiner Ergebnisse würde ich mich über Erfahrungsberichte von Nachbauern freuen. Ansonsten wünsche ich viel Spaß beim Nachbauen.

Experimentierkasten
Alle Dateien für eigene Experimente zum Download auf einen Blick

  1. Tabelle der IR-Frequenzen, als Open Dokument Datei, ods
  2. Schaltplan des Detektors, als gEDA Schaltplan, sch
  3. Schaltplan des Detektors, als PDF-Datei, pdf
  4. LM 393, Fritzing Steckbrett Image, Scalable Vector Grafics, svg
  5. LM 393, Fritzing Icon, Scalable Vector Grafics, svg
  6. LM 393, Fritzing Schaltplan Image, Scalable Vector Grafics, svg
  7. LM 393, Fritzing Bauelement", Fritzing Datei, fzpz
  8. 3 mm Infrarot Phototransistor, Fritzing Steckbrett Image, Scalable Vector Grafics, svg
  9. 3 mm Infrarot Phototransistor, Fritzing Icon, Scalable Vector Grafics, svg
  10. Phototransistor, Fritzing Schaltplan Image, Scalable Vector Grafics, svg
  11. 3mm Infrarot Phototransistor, Fritzing Bauelement, Fritzing Datei, fzpz
  12. Vollständige Fritzing Datei des IR-Detektors, Fritzing Datei, fzz
  13. IR-Detektor Quelltext, Arduino Sketch, ASCII Text, ino


Erstveröffentlichung: Mai 2013

Home / Carrera-Hacks   -   CC BY-NC-SA   -   Impressum   -   Kontakt
Powered by: bluefisch, Arduino, Fritzing, LibreOffice, gEDA and the gimp