[Elektronik] Prototyp Geschwindigkeitsmessung

Hier dreht sich alles um die Modellbahn
Herbert

[Elektronik] Prototyp Geschwindigkeitsmessung

Beitrag von Herbert »

Hi, liebe N-Bahner,

nachdem in den letzten Tagen endlich meine Arduino-Module bei mir eingelangt sind, habe ich mich aufgemacht, meine Idee einer Geschwindigkeitmess-Station zu bauen. Im Moment ist es noch ein Prototyp, aber soweit scheint es zufriedenstellend zu funktionieren.

Zum Nachbau meines Prototypen benötigt man folgende Komponenten:

- Steckbrett
- 2 LEDs (in meinem Fall grün)
- 2 Widerstände 1kOhm
- 2 IR-Näherungssensoren
- 1 Arduino Uno R3 (es geht wohl auch ein Arduino Nano)
- Jumperkabeln in ausreichender Länge und Menge

Ein paar Worte zum IR-Näherungssensor: Dieses besteht im Wesentlichen aus einer IR-LED und einem IR-Empfänger. Es gibt 3 Anschlüsse: +5V, GND, DataOUT. Über das integrierte Poti kann man die Empfindlichkeit einstellen. Funktionieren tut es so, dass auf DataOUT ein HIGH-Signal anliegt, so lange kein Hindernis erkannt wird. Sobald ein Hindernis erkannt wird, wird DataOUT auf LOW gesetzt. Hier der Schaltplan von so einem IR-Näherungssensor:
Bild

Mein Aufbauplan sieht so aus:
Bild

Und zuletzt fehlt noch der zugehörige Sketch:

Code: Alles auswählen

// **************************************************
// Definition der Ports
//     liinp = Links Input
//     reinp = Rechts Input
//     liout = Links Output
//     reout = Rechts Output
// **************************************************
int liinp=8;
int reinp=9;
int liout=10;
int reout=11;

// **************************************************
// Status des Programmablaufs
//      0 = Warten auf Messbeginn
//      1 = Messung läuft; warte auf 2.Messung
//      2 = Messung abgeschlossen; Berechnung+Ausgabe
// **************************************************
int Status=0;

// **************************************************
// Richtung, in der die Lok fährt
//     1 = Lok fährt von links nach rechts
//     2 = Lok fährt von rechts nach links
// **************************************************
int Richtung;

// **************************************************
// Zwischenspeicher der beiden Werte vom IR-Modul
// **************************************************
int links;
int rechts;

// **************************************************
// Zeitstempel der beiden Messpunkte
//     TSb = Zeitstempel Beginn
//     TSe = Zeitstempel Ende
// **************************************************
long TSb;
long TSe;

// **************************************************
// Messstrecke = Länge der Strecke in Milimeter
// Massstab    = Maßstab der Spurweite
// **************************************************
long Messstrecke=300;
int Massstab=160;

// **************************************************
// diverse interne Zwischenspeicher zum Berechnen der
// umgerechneten Vorbild-Geschwindigkeit
// **************************************************
float Fahrdauer;
long Tempo;

void setup() {
// Öffnen der Console
  Serial.begin(9600);
  
// Definition der verwendeten Digitalpins
  pinMode(liout,OUTPUT);
  pinMode(reout,OUTPUT);
  pinMode(liinp,INPUT_PULLUP);
  pinMode(reinp,INPUT_PULLUP);

// Start-Meldung auf die Console
  Serial.println("Warte auf Messbeginn ...");
}

void loop() {
// Lesen der Werte der beiden IR-Module
  links=digitalRead(liinp);
  rechts=digitalRead(reinp);

// **************************************************
// Phase 0
//     Wenn eines der beiden IR-Module auf LOW steht:
//       TSb setzen
//       Fahrtrichtung merken
//       Hinweis auf Console ausgeben
//       zugehörige LED ausschalten
//       Status auf Phase 1 setzen
// **************************************************
  if (Status==0) {
    digitalWrite(liout,links);
    digitalWrite(reout,rechts);
    if (links==0) {
      TSb = millis();
      Richtung = 1;
      Serial.println("Start: Zug von links ...");
      Status=1;
    }
    if (rechts==0) {
      TSb = millis();
      Richtung = 2;
      Serial.println("Start: Zug von rechts ...");
      Status=1;
    }
  }

// **************************************************
// Phase 1
//     Wenn das zweite IR-Modul auf LOW steht:
//       TSe setzen
//       Status auf Phase 2 setzen
//       Hinweis auf Console ausgeben
// **************************************************
  if (Status==1) {
    if (Richtung==2) {
      if (links==0) {
        TSe = millis();
        Serial.println("Ende: hier die Auswertung ...");
        Status=2;
      }
    }
    if (Richtung==1) {
      if (rechts==0) {
        TSe = millis();
        Richtung = 2;
        Serial.println("Ende: hier die Auswertung ...");
        Status=2;
      }
    }
  }

// **************************************************
// Phase 2
//     Berechnung Vorbildgeschwindigkeit
//     Ausgabe auf Console
//     Warte 5 Sekunden
//     Status auf Phase 0 setzen
//     Startmeldung ausgeben
// **************************************************
  if (Status==2) {
    Fahrdauer=(TSe - TSb);
    Tempo=(Messstrecke*Massstab) / Fahrdauer * 3.6;
    Serial.print("Geschwindigkeit: ");
    Serial.println(Tempo);
    delay(5000);
    Status=0;
    Serial.println("Warte auf Messbeginn ...");
  }
}
Da die Auswertung auf die serielle Console vom Arduino ausgegeben wird, muss zum Zeitpunkt der Messung der Mikrokontroller am Computer angeschlossen sein. Die Messung geht natürlich auch ohne diesem, aber man sieht dann das Ergebnis nirgendwo. Eine Variante mit einem 2-zeiligen LCD-Display folgt, sobald ich den Sketch entsprechend adaptiert habe.

Das Projekt kann sowohl für analoge als auch digitale Anlagen verwendet werden und ist nicht nur für die Spur N geeignet; man muss dann allerdings den Maßstab auf seine Spur ändern (steht derzeit auf 160 für Spur N). Die Genauigkeit der Messung steigt mit der Distanz der beiden Messpunkte. Allerdings dauert die Messung dann entsprechend lange, falls eine niedrige Geschwindigkeit gemessen werden soll. Auf jeden Fall ist die Distanz möglichst exakt einzugeben. Ich empfehle, vor der tatsächlichen Messung die jeweilige Stelle, an der die Messung greift, mit einem Wagen auszuloten und zu markieren. Das geht sehr einfach, weil das IR-Modul eine eigene LED hat, die anzeigt, ob ein Hindernis erkannt wird oder nicht. Genau dort, wo diese LED umspringt, sollte man eine Markierung setzen an beiden Modulen. Und die Entfernung ist dann im Sketch einzutragen (steht bei mir derzeit auf 300 = 30cm).

Hinweis: Natürlich kann man damit keine exakte Geschwindigkeit ermitteln, da das Erkennen der herannahenden Lok von deren Reflexionsverhalten abhängig ist. Helle Objekte werden in der Regel besser erkannt als dunkle, und je nach Fahrtrichtung kann es ebenfalls zu Unterschieden kommen. Trotzdem kann dieser Aufbau zu aufschlussreichen Ergebnissen führen.

Was das Zeug kostet: Ich habe die Bauteile in China bestellt. Ein Arduino Nano inkl Terminal-Adapter-Board schlug mit € 3,03 zu Buche, ein IR-Modul kostete € 0,27; dazu kommen noch die beiden LEDs samt Vorwiderstände (kann man auch weglassen; ich verwende sie, um visuell zu sehen, ob der Sketch arbeitet) sowie die Jumperkabel; insgesamt kommen die Bauteile auf nicht mal € 4,00.
Helmut
Site Admin
Beiträge: 1504
Registriert: 14 Jan 2019, 19:29

Re: [Elektronik] Prototyp Geschwindigkeitsmessung

Beitrag von Helmut »

Hallo Herbert,
das liest sich sehr interessant. Ich könnte mir sowas für meinen Testkringel gut vorstellen, um die Höchstgeschwindigkeit der Loks einzustellen. Macht es Sinn, den Näherungssensor senkrecht zum Gleis als Reflexlichtschranke zu nutzen. Die Reflexionseigenschaften der Lok dürften da kaum noch eine Rolle spielen.

Gruß aus KerpeN
Helmut
Herbert

Re: [Elektronik] Prototyp Geschwindigkeitsmessung

Beitrag von Herbert »

Hi Helmut,

grundsätzlich ist es egal, ob die Messung waagrecht oder senkrecht erfolgt. Ich bin gerade dabei, mir eine Lösung einfallen zu lassen, wo ich diese Messstation fix in meine Anlage integrieren kann. Möglicherweise im Zuge eines Programmiergleises. Muss dann halt lang genug sein, um die Loks auf Höchstgeschwindigkeit zu bringen, denn die Messstrecke sollte in gleichbeibendem Tempo durchfahren werden. Und wenn ich es fix mache, dann auch unterhalb des Gleises zwischen den Schienen.

Der Umbau mit dem LCD-Display ist auch schon fertig und der Sketch ist ebenfalls schon fast fertig, sodass ich den Aufbau bereits mobil habe und den PC nicht mehr brauche. Allerdings sind zwei Mal 16 Zeichen nicht besonders viel, aber für diese Zwecke sollte es ausreichend sein. Jetzt muss ich das nur noch zeichnerisch dokumentieren, was bei der Menge an Strippen sehr unübersichtlich werden wird. Aber sobald ich das habe, werde ich die Lösung hier präsentieren.

Übrigens: Die IR-Näherungssensoren habe ich eigentlich dafür gekauft, um im SBf die Züge punktgenau stoppen zu lassen. Meine Abstellgleise sind ja möglichst kurz gehalten, sodass hier ein Unterschied von 1 bis 2 cm bedeuten kann, dass die Lok oder der letzte Wagon im Bereich einer Weiche zum Stehen kommt. Bei den üblichen Stromfühlern kann es ja durchaus passieren, dass Räder oder Gleise verschmutzt sind und deswegen die Lok zu spät erkannt wird, wodurch sie dann deutlich weiter fährt als mir lieb ist. Mit so einem Näherungssensor sollte das nicht passieren.
Herbert

Re: [Elektronik] Prototyp Geschwindigkeitsmessung

Beitrag von Herbert »

So, ich möchte jetzt die stand-alone Version meiner Geschwindigkeitsmessstation vorstellen:

Was man benötigt:

- Steckbrett
- 2 IR-Näherungssensoren
- 1 Arduino nano R3
- 1 LCD 1602 Display Module
- 1 10k Potentiometer
- Jumperkabeln in ausreichender Länge und Menge

Den IR-Näherungssensor werde ich an dieser Stelle nicht beschreiben und über das LCD-Display möchte ich auch keine Worte verlieren; wer mehr Informationen darüber benötigt, findet im Internet sicher alles, was interessant ist. Daher geht es hier mit meinem Aufbauplan los:
Bild

Über das Potentiometer wird der Kontrast des Displays eingestellt - wenn man nach der Einstellung des Potis den Wert misst, geht es mit Sicherheit auch mit einem einfachen Widerstand (habs aber noch nicht ausprobiert).

Grundsätzlich ist der Aufbau ident zum vorherigen Prototyp, nur dass die Ausgabe diesmal am LCD-Display erfolgt. Was im obigen Plan nicht eingezeichnet ist, ist die Spannungsversorgung. Diese erfolgt entweder über den USB-Port am Arduino oder man speist die 5V über den VIN-Pin (rechts unten im Bild) und GND ein. Der Ablauf des Sketches ist im Wesentlichen gleich zum obigen Prototypen, nur dass hier die visuelle Anzeige über die beiden LEDs wegfällt.

Achja, hier der Sketch:

Code: Alles auswählen

// ##################################################
// Dieser Sketch misst die Dauer, die eine Modell-
// bahnlok für eine definierte Strecke benötigt und
// errechnet daraus deren Vorbildgeschwindigkeit.
// Zum Einsatz kommen IR-Näherungssensoren, wie sie
// für die Robotik benötigt werden.
// Parameter für diesen Sketch:
//   5 Ports für das LCD Display
//   2 Ports für die beiden IR-Sensoren
//   Maßstabsangabe der verwendeten MoBa
//   Distanz der beiden IR-Sensoren in mm
// ##################################################

// **************************************************
// Library für das LCD Display
// **************************************************
#include <LiquidCrystal.h>

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Hier sind die notwendigen Änderungen vorzunehmen !
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

// **************************************************
// Definition der Ports
//     liinp = Links Input
//     reinp = Rechts Input
// **************************************************
int liinp=2;
int reinp=3;

// **************************************************
// LiquidCrystal lcd = Ports für das LCD Display
// Messstrecke       = Länge der Strecke in Milimeter
// Massstab          = Maßstab der Spurweite
// **************************************************
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
long Messstrecke=300;
int Massstab=160;



// **************************************************
// Nur zur internen Verwendung des Sketches
// **************************************************
// **************************************************
// Status des Programmablaufs
//      0 = Warten auf Messbeginn
//      1 = Messung läuft; warte auf 2.Messung
//      2 = Messung abgeschlossen; Berechnung+Ausgabe
// **************************************************
int Status=0;

// **************************************************
// Richtung, in der die Lok fährt
//     1 = Lok fährt von links nach rechts
//     2 = Lok fährt von rechts nach links
// **************************************************
int Richtung;

// **************************************************
// Zwischenspeicher der beiden Werte vom IR-Modul
// **************************************************
int links;
int rechts;

// **************************************************
// Zeitstempel der beiden Messpunkte
//     TSb = Zeitstempel Beginn
//     TSe = Zeitstempel Ende
// **************************************************
long TSb;
long TSe;

// **************************************************
// diverse interne Zwischenspeicher zum Berechnen der
// umgerechneten Vorbild-Geschwindigkeit
// **************************************************
float Fahrdauer;
long Tempo;

void setup() {
// Öffnen LCD Display
  lcd.begin(16, 2);

// Definition der verwendeten Digitalpins IR-Module
  pinMode(liinp,INPUT_PULLUP);
  pinMode(reinp,INPUT_PULLUP);

// Ausgabe Startmeldung
  lcd.setCursor(0,0);
  lcd.print("  WARTE AUF LOK ");
}

void loop() {
// Lesen der Werte der beiden IR-Module
  links=digitalRead(liinp);
  rechts=digitalRead(reinp);

// **************************************************
// Phase 0
//     Wenn eines der beiden IR-Module auf LOW steht:
//       TSb setzen
//       Fahrtrichtung merken
//       Hinweis auf Console ausgeben
//       zugehörige LED ausschalten
//       Status auf Phase 1 setzen
// **************************************************
  if (Status==0) {
    if (links==0) {
      TSb = millis();
      Richtung = 1;
      lcd.setCursor(0,1);
      lcd.print("== RICHTUNG ==>>");
      Status=1;
    }
    if (rechts==0) {
      TSb = millis();
      Richtung = 2;
      lcd.setCursor(0,1);
      lcd.print("<<== RICHTUNG ==");
      Status=1;
    }
  }

// **************************************************
// Phase 1
//     Wenn das zweite IR-Modul auf LOW steht:
//       TSe setzen
//       Status auf Phase 2 setzen
//       Hinweis auf Console ausgeben
// **************************************************
  if (Status==1) {
    if (Richtung==2) {
      if (links==0) {
        TSe = millis();
        Status=2;
      }
    }
    if (Richtung==1) {
      if (rechts==0) {
        TSe = millis();
        Richtung = 2;
        Status=2;
      }
    }
  }

// **************************************************
// Phase 2
//     Berechnung Vorbildgeschwindigkeit
//     Ausgabe auf Console
//     Warte 5 Sekunden
//     Status auf Phase 0 setzen
//     Startmeldung ausgeben
// **************************************************
  if (Status==2) {
    Fahrdauer=(TSe - TSb);
    Tempo=(Messstrecke*Massstab) / Fahrdauer * 3.6;
    lcd.setCursor(0,0);
    lcd.print("GESCHWINDIGKEIT:");
    lcd.setCursor(0,1);
    lcd.print("                ");
    lcd.setCursor(0,1);
    lcd.print(String(Tempo));
    lcd.print(" km/h");
    delay(5000);
    Status=0;
    lcd.setCursor(0,0);
    lcd.print("  WARTE AUF LOK ");
    lcd.setCursor(0,1);
    lcd.print("                ");
  }
}
Falls das jemand nachbaut, würde ich mich über Feedback freuen ...

Nachtrag: Das LCD Modul habe ich bei den einschlägigen China-Händlern bereits für unter € 1,70 gesehen, inkl Versand nach Österreich! Ich bin echt begeistert davon, für wie wenig Geld man solche Helferleins zusammen schrauben kann; und dazu ist noch nicht mal allzu viel Elektronik-Wissen notwendig.
Antworten