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.
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.
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.
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.
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.
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.
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.
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.
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.
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
- Tabelle der IR-Frequenzen, als Open Dokument Datei, ods
- Schaltplan des Detektors, als gEDA Schaltplan, sch
- Schaltplan des Detektors, als PDF-Datei, pdf
- LM 393, Fritzing Steckbrett Image, Scalable Vector Grafics, svg
- LM 393, Fritzing Icon, Scalable Vector Grafics, svg
- LM 393, Fritzing Schaltplan Image, Scalable Vector Grafics, svg
- LM 393, Fritzing Bauelement", Fritzing Datei, fzpz
- 3 mm Infrarot Phototransistor, Fritzing Steckbrett Image, Scalable Vector Grafics, svg
- 3 mm Infrarot Phototransistor, Fritzing Icon, Scalable Vector Grafics, svg
- Phototransistor, Fritzing Schaltplan Image, Scalable Vector Grafics, svg
- 3mm Infrarot Phototransistor, Fritzing Bauelement, Fritzing Datei, fzpz
- Vollständige Fritzing Datei des IR-Detektors, Fritzing Datei, fzz
- IR-Detektor Quelltext, Arduino Sketch, ASCII Text, ino
Erstveröffentlichung: Mai 2013