Modellbahn

Die folgende Software ist noch im Alphastadium vom Alphastadium. Sie tut nur das Allernötigste: Anzeigen der Lok auf dem Display. Hierzu wird die CV1-Adresse auf Lokbezeichnungen gemappt - siehe switch-Anweisung im Code weiter unten.  In den jeweiligen Loks muss natürlich Railcom für Channel 1 aktiviert werden. Es sind kaum Algorithmen für Fehlerkorrekturen vorhanden. Ausserdem sind die Lokbezeichnungen im Sketch hard-coded. 

Achtung: die Adressen werden nicht im ASCII-Code übertragen, sondern sind 4/8-el codiert. Zum Durchführen der Zuordnung die Lok auf das Gleis stellen, den angezeigten Binärcode in der Switch-Anweisung hinterlegen und eine Lokbezeichnung zuweisen. Sketch kompilieren und auf Arduino laden.

An Pin 8 - 13 hängen LED's. Diese haben nur Debugzwecke und werden nicht benötigt.

/*
 * Railcom detection and display
 * Version: 20161023
 * ©2012,Thomas Hörndlein
 */

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

byte receivedByte     = B00000000;
byte locoAddressByte1 = B00000000;
byte locoAddressByte2 = B00000000;
String loco = "hmm...?";


void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // initialize the serial communications:
  Serial.begin(250000);

  // DDRB/PORTB ist hier gemappt auf Pin 8-13
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  // All LED's off:
  PORTB = B00000000;
}

void loop() {
  // when characters arrive over the serial port...
  if (Serial.available()) {
    // wait a bit for the entire message to arrive. 100ms ~ 11 Cutouts
    delay(100);

   // According to spec channel1 1 is used for sending the loco address.
   // ESU decoders send additional information in channel 1
    while (Serial.available() > 0) {
      receivedByte = Serial.read();
      // Filter to ensure we really received a loco address:
      if (receivedByte == B10011001) {
        locoAddressByte1 = receivedByte;
        locoAddressByte2 = Serial.read();
        // clear serial buffer...
        while (Serial.read() > 0);
      }
    }

    switch(locoAddressByte2) {
      case B10010101:
        loco = "BR218";
        break;
      case B10100110:
        loco = "GFN1309";
        break;
      case B10010110:
        loco = "BR39";
        break;
      case B10110010:
        loco = "ICE";
        break;
      case B10100101:
        loco = "R250";
        break;   
      case B10011010:
        loco = "E103A";
        break;
      case B10011100:
        loco = "E103B";
        break;
      default:
        loco = "unbek.";
        break;
    }

    PORTB = B00000001;
        
    // clear the screen
    lcd.clear();
    // display each character to the LCD
    lcd.setCursor(0, 0);
    lcd.print("Lok:");
    lcd.setCursor(8, 0);
    lcd.print(locoAddressByte1, BIN);
    lcd.setCursor(0, 1);
    lcd.print(loco);
    lcd.setCursor(8, 1);
    lcd.print(locoAddressByte2, BIN);

    //show last six bits of locoAddressByte2 on LED's:
    // auskommentiert. verursacht takten des displays
    //PORTB = locoAddressByte2;
      PORTB = B00000010;
      delay(100); // nur damit LED 2 leuchtet
  }

  PORTB = B00000100;
  // There is no loco on the rails if we don't receive data
  // within on second (serial buffer is empty)
  delay(1000);
  if (Serial.available() == 0) {
      PORTB = B00001000;
      locoAddressByte1 = B00000000;
      locoAddressByte2 = B00000000;
      loco = "hmm...? ";
      // clear the screen
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Lok:");
      lcd.setCursor(0, 1);
      lcd.print(loco);
  }
 
}