MOBA Wechsel-/Pendelsteuerung

Moin Zusammen
Beim Programmieren einer Wechselsteuerung mit einem Arduino Mega 2560 und den milis() habe ich nun Timing Probleme (Mehrzahl). Beim Review meines Codes, ist mir aufgefallen, dass vorallem bei der HW per I2C einlesen viel Abgearbeitet werden muss.

Aktuelle Probleme sind:,

  • Er erkennt den Reedsensor beim drüber Fahren, aber er hält nicht an oder / und schaltet die Weiche nicht.
  • Er erkennt den Reedsensor nicht, Z.B. bei der Haltesstelle bahnhof2 trotz eigestecktem Jumper und überprüfen des Wertes per Serial.println()
  • Wenn der Zug mit seinen magnetkupplungen auf dem Abstellgeleise auf dem Sensor anhält, bringts die Logik durcheinander. (Fährt bei der Haltestelle Bahnhof1 kurz an und hält an oder/und schaltet die weiche und er Zug fährt zu schnell los.

Am 10.1.24 an der Ausstellung sollte die Steuerung Ihre Dienste tun.

Was habe ich getan bevor ich hier schreibe und meinen Spagethicode zeige :wink:

  • Gleiche variablen zu einem Array zusammengefasst.
  • Millis versucht zusammen zu fassen, habe festgestellt wenn eine millis() in Millis() mit längerer Laufzeit sich befunde, dass es dann eher besser oder schlechter läuft.
  • Lesen der 170 Beiträge von combie, agmue und noiasca: Millis Befehl, Steuerung Schattenbahnof. - #18 by kgbrus
  • Einlesen in allen gängigen Foren
  • Einlesen betr. Tasksteuerung, sehe dies eher fürs nächste Projekt resp. nach der Ausstellung
  • Einiges statisches in das Setup() verfrachtet

Was funktioniert?

  • manuel Fahren
  • manuell Weichenmotoren schalten
  • Reed sensoren werden von den Zugsmagneten detektiert

Der Code ist 2079 Zeilen lang. Soll ich Ihn in Ettappen posten oder gibts eine Funktion zum Code anhängen? habe schon lange nichts gepostet :wink:
Gruss TrainControl

Hallo train_control

Herzlich Willkommen im besten Arduinoforum der Welt.

Das hört sich in der nullten Näherung nach der Verwendung der delay() Funktion an, da das Programm die Erkennung des Reedsensors "verpennt".

Hallo paulpaulson
Habe keine Delays in der Loop() verwendet, und nur da ein Serial.print() wo ich was wissen wollte, ansonsten nur millis() und if () {} else {} und noch eine lcd Anzeige die ich aktualisiere mit niedriger Zeit, hohen millis()

Der Code ist 100K lang ;-( könnte Ihn in 11x Beiträge splitten ;.(, aber dies ist ja dann nicht händelbar....

Auch kein WHILE(), die kleine Schwester von der delay() Funktion?

1 Like

vereinfacht gesagt, sind deine Loks so schnarch langsam, dass I2C Sensoren kein Problem damit haben sollen.

Irgendwas ist an deinem Sketch faul.

An deiner Stelle würde ich zunächst einen ganz einfachen Sketch schreiben.
Nur die Pendelzugstrecke von A nach B und die zwei Reed Kontakte zum Umschalten auslesen.
Das wird bis zum 10.1. fertig.

Da sollte man mal wissen, was da alles angeschlossen ist. Ein Schaltbild wäre sehr hilfreich.

Woher weist Du, dass er den Reedsensor erkennt, wenn er nicht drauf reagiert?

Was ist das für ein Jumper? Wieder fehlt ein Schaltbild. Bedenke: wir wissen nur das was Du uns erzählst - wir können dir nicht über die Schulter schauen.

Bei so einem umfangreichen Programm kann die loop() Durchlaufzeit auch ohne delay() rel. lang werden. So ein Reed-impuls beim Drüberfahren kann recht kurz sein ...

Ohne die Schaltung und den Sketch kann man kaum etwas sagen und alles sind nur Vermutungen.

1 Like

Nein keine While() , ev. in einer der beiden Librarys, werde die mal heute Abend abschalten zum testen.

Ja etwas am Sketch muss sein. Es ist eine Wechselsteuerung mit 2 Weichen (Keine Pendelsteuerung im eigentlichen Sinn.

Wie kann ich hier 100K *.ino einbinden? Es sind 3 Platinen 100mm x 100mm und eine mit 160mm x 100mm und 4x eine A3 KiCAD Datei dazu...

vermutlich gar nicht.
Zippen und wo hochladen. Link hier reinstellen.

Zeig mal ein Blockschaltbild.
Wie viele Eingänge, Wie viele Ausgänge ... was wird wann geschalten. Das kann ja nicht wirklich eine Raketenwissenschaft sein...

Der Jumper wenn gesteckt wird als 1 interpretiert für die 2 haltestelle die es diesmal nicht benötigt.
-> Als neuer benutzer kann man keine Dateien hochladen kam eben beim drufziehen des Sketches auf diese Maske

  • Ja der Fehler liegt im Sketch_Code / Timing. Ich suche mal noch einem Transfer service für die Schematas und den Code
  • Der Reedsensor wird erkannt beim überfahren, weil da die rote Led angeht und bleibt. Sie wird gelöscht beim erkennen des nächsten Blockes

Zip kann man doch direkt hier einbinden.

Leider nein, das jpg ging ;-( Ev. kann das ja ein Admin freischalten

OK, :roll_eyes:

Hier mal der Sketch: WeTransfer - Send Large Files & Share Photos Online - Up to 2GB Free

ich poste das zip mal ...

jetzt bräuchte es halt noch ein Blockschaltbild damit man weis was was ist ...

#include <LiquidCrystal.h>

/*
  Wechsel Steuerung für eine MOBA Anlage
  (C) 2023 by Train Control
*/

const char ver[] = "Ver 0.B";

#define frei 1
#define besetzt 0

#define IODIRA 0x00                      // Eine 1 im Register = Input, eine 0 = Output
#define IODIRB 0x01
#define GPIOA  0x12
#define GPIOB  0x13
#define GPIO_INPUT  0b01111111           // Nach dem Start sind alles Ports als Input konfiguriert (MSB .. LSB), ausser der Pin 7 = Ausgang
#define GPIO_OUTPUT 0x00                 // 8 Bit Output  = 0
// const byte GPIO_INPUT = 0b10000000;   // Nach dem Start sind alles Ports als Input konfiguriert (MSB .. LSB), ausser der Pin 7 = Ausgang
// const byte GPIO_OUTPUT = 0xFF;        // 8 Bit Output  = 0

// I2C Wire Library
#include <Wire.h>

// LCD I2C Library
#include <LiquidCrystal_PCF8574.h>

// F-RAM Library
// benötigt noch eine Adafruit IO Library
#include "Adafruit_FRAM_I2C.h"


//--------------------------------------------------------------------
// Variablen FRAM Baustein 32KB
Adafruit_FRAM_I2C fram = Adafruit_FRAM_I2C();


// --------------------------------------------------------------
// Variablen pro Modul
// Steuerpult
//
// const byte max_reed_unbounce_count = 5;  // fest verdrahtet
// const byte min_reed_unbounce_count = 0;  // fest verdrahtet
// const byte max_reed_sensor = 7;

// const byte max_taster = 8;

const byte i2c_mcp1_adr = 0x23;    // U1 Platine 2, Led Output, Konfig Jumper Input
const byte i2c_mcp2_adr = 0x24;    // U2 Platine 2, Relais Output, Led Output Status Weichen
const byte i2c_mcp3_adr = 0x25;    // U3 Platine 3, J18, GPA Led Out Reed + GPB Led Out Weiche + Run, Stop, Stopping Led
const byte i2c_mcp4_adr = 0x26;    // U4 Platine 3, J17, GPA Weichen + GPB Weichen + Run, Stop, Stopping - Taster
const byte i2c_pca8574_adr = 0x27; // Standard Adresse des LCD I2C Kontrollers
const byte i2c_fram_adr = 0x50;    // Fram RAM 32KByte zum Speichern der Poitionen

// I2C Scanner Funktion
// #define delay2000 2000
const byte i2cStartAdresse = 0x07;
const byte i2cEndAdresse = 0x77;
byte i2cTransmissionResultat = 0;

// definition und starten einer lcd Instanz
LiquidCrystal_PCF8574 lcd(i2c_pca8574_adr); // Address of most PCF8574 modules are on 0x27


// Allgemein:
// Port Byte einlesen in der Funktion und per BitRead(x,i) gleich in die "Bit" Variablen speichern
// GPIO U1 Port A - Output
byte GPIO_U1_PortA_raw = 0;
byte GPIO_U1_PortB_raw = 0;
byte GPIO_U2_PortA_raw = 0;
byte GPIO_U2_PortB_raw = 0;
byte GPIO_U3_PortA_raw = 0;
byte GPIO_U3_PortB_raw = 0;
byte GPIO_U4_PortA_raw = 0;
byte GPIO_U4_PortB_raw = 0;


// GPIO U1 Port B - Input
byte GPIO_U1_Abstellgeleise = 0;        // 1x Abstellgeleis = 0, 2x Abstellgeleise = 1 per Jumper J11/1
byte GPIO_U1_Bahnhof2 = 0;              // 1x Bahnhof Reed Sensor = 0, 2x Bahnhof Reed Sensor = 1 per Jumper J11/2
byte GPIO_U1_Fahrspannung_Reverse = 0;  // Fahrspannung auf Reverse schalten per Jumper J11/3
byte GPIO_U1_Weiche1_Reverse = 0;       //  Weiche 1 auf Reverse schalten per Jumper J11/4
byte GPIO_U1_Weiche2_Reverse = 0;       //  Weiche 2 auf Reverse schalten per Jumper J11/5
byte GPIO_U1_Weiche3_Reverse = 0;       //  Weiche 3 auf Reverse schalten per Jumper J11/6
byte GPIO_U1_Weiche4_Reverse = 0;       //  Weiche 4 auf Reverse schalten per Jumper J11/7


// Achtung alten MCP23017 Chip nehmen da GPA7 und GPB7 nur Output können ab 2020!!

// GPIO U2 Port A - Output
byte GPIO_U2_Relais1 = 1;  // 1 = Aus
byte GPIO_U2_Relais2 = 1;
byte GPIO_U2_Relais3 = 1;
byte GPIO_U2_Relais4 = 1;
byte GPIO_U2_Relais5 = 1;
byte GPIO_U2_Relais6 = 1;
byte GPIO_U2_Relais7 = 1;
byte GPIO_U2_Relais8 = 1;


// GPIO U2 Port B - Output
// <tbd>
byte GPIO_U2_Led_weiche1_gerade_blau = 0;
byte GPIO_U2_Led_weiche1_abgebogen_orange = 0;
byte GPIO_U2_Led_weiche2_gerade_blau = 0;
byte GPIO_U2_Led_weiche2_abgebogen_orange = 0;
byte GPIO_U2_Led_weiche3_gerade_blau = 0;
byte GPIO_U2_Led_weiche3_abgebogen_orange = 0;
byte GPIO_U2_Led_weiche4_gerade_blau = 0;
byte GPIO_U2_Led_weiche4_abgebogen_orange = 0;


// GPIO U3 Port B - Output
byte GPIO_U3_Led1_run = 0;              // Led grün
byte GPIO_U3_Led2_stop = 0;             // Led rot
byte GPIO_U3_Led3_stopping = 0;         // Led gelb
byte GPIO_U3_Led4_weiche1_orange = 0;   // Led orange, abgebogen
byte GPIO_U3_Led5_weiche1_blau = 0;     // Led blau, gerade aus
byte GPIO_U3_Led6_weiche2_orange = 0;   // Led orange, abgebogen
byte GPIO_U3_Led7_weiche2_blau = 0;     // Led blau, gerade aus
byte GPIO_U3_Led8_weiche3_orange = 0;   // Led orange, abgebogen

// GPIO U3 Port A - Output
byte GPIO_U3_Led9_weiche3_blau = 0;     // Led blau, gerade aus
byte GPIO_U3_Led10_weiche4_orange = 0;  // Led orange, abgebogen
byte GPIO_U3_Led11_weiche4_blau = 0;    // Led blau, gerade aus
byte GPIO_U3_Led12_Reed1 = 0;           // Led rot Fahrt langsam beschleunigen
byte GPIO_U3_Led13_Reed2 = 0;           // Led rot hauptgleis
byte GPIO_U3_Led14_Reed3 = 0;           // Led rot 1. Abstellgleis
byte GPIO_U3_Led15_Reed4 = 0;           // Led rot 2. Abstellgleis
byte GPIO_U3_Led16_Reed5 = 0;           // Led rot Fahrt verlangsamen

// GPIO U4 Port B - Output Bit 7
byte GPIO_U4_Led17_Reed6 = 0;           // Led rot Haltestelle Bahnhof 1

// GPIO U4 Port A - Output Bit 7
byte GPIO_U4_Led18_Reed7 = 0;           // Led rot Haltestelle Bahnhof 2


// GPIO U4 Port B - Input Bit 0..6
byte GPIO_U4_taster_start_entprellt = 0;                // Run Taster
byte GPIO_U4_taster_stop_entprellt = 0;                 // Stop Taster
byte GPIO_U4_taster_stopping_entprellt = 0;             // Anhalten Taster
byte GPIO_U4_weiche1_L_taster_gerade_entprellt = 0;     // Taster Weiche 1 Links gerade
byte GPIO_U4_weiche1_L_taster_abgebogen_entprellt = 0;  // Taster Weiche 1 Links abgebogen
byte GPIO_U4_weiche2_L_taster_gerade_entprellt = 0;     // Taster Weiche Links 2 gerade
byte GPIO_U4_weiche2_L_taster_abgebogen_entprellt = 0;  // Taster Weiche Links 2 abgebogen

byte GPIO_U4_taster_start_raw = 0;                  // Run Taster
byte GPIO_U4_taster_stop_raw = 0;                   // Stop Taster
byte GPIO_U4_taster_stopping_raw = 0;               // Anhalten Taster
byte GPIO_U4_weiche1_L_taster_gerade_raw = 0;       // Taster Weiche 1 Links gerade
byte GPIO_U4_weiche1_L_taster_abgebogen_raw = 0;    // Taster Weiche 1 Links abgebogen
byte GPIO_U4_weiche2_L_taster_gerade_raw = 0;       // Taster Weiche Links 2 gerade
byte GPIO_U4_weiche2_L_taster_abgebogen_raw = 0;    // Taster Weiche Links 2 abgebogen

byte GPIO_U4_taster_start_merker = 0;                // Run Taster
byte GPIO_U4_taster_stop_merker = 0;                 //  Stop Taster
byte GPIO_U4_taster_stopping_merker = 0;             // Anhalten Taster
byte GPIO_U4_weiche1_L_taster_gerade_merker = 0;     // Taster Weiche 1 Links gerade
byte GPIO_U4_weiche1_L_taster_abgebogen_merker = 0;  // Taster Weiche 1 Links abgebogen
byte GPIO_U4_weiche2_L_taster_gerade_merker = 0;     // Taster Weiche Links 2 gerade
byte GPIO_U4_weiche2_L_taster_abgebogen_merker = 0;  // Taster Weiche Links 2 abgebogen

// GPIO U4 Port A - Input Bit 0..6
byte GPIO_U4_weiche3_R_taster_gerade_entprellt = 0;     // Taster Weiche 3 Links gerade
byte GPIO_U4_weiche3_R_taster_abgebogen_entprellt = 0;  // Taster Weiche 3 Links abgebogen
byte GPIO_U4_weiche4_R_taster_gerade_entprellt = 0;     // Taster Weiche 4 Links gerade
byte GPIO_U4_weiche4_R_taster_abgebogen_entprellt = 0;  // Taster Weiche 4 Links abgebogen
// byte GPIO_U4_
// byte GPIO_U4_
// byte GPIO_U4_

// GPIO U4 Port A - Input Bit 0..6
byte GPIO_U4_weiche3_R_taster_gerade_raw = 0;     // Taster Weiche 3 Links gerade
byte GPIO_U4_weiche3_R_taster_abgebogen_raw = 0;  // Taster Weiche 3 Links abgebogen
byte GPIO_U4_weiche4_R_taster_gerade_raw = 0;     // Taster Weiche 4 Links gerade
byte GPIO_U4_weiche4_R_taster_abgebogen_raw = 0;  // Taster Weiche 4 Links abgebogen
// byte GPIO_U4_
// byte GPIO_U4_
// byte GPIO_U4_

// GPIO U4 Port A - Input Bit 0..6
byte GPIO_U4_weiche3_R_taster_gerade_merker = 0;     // Taster Weiche 3 Links gerade
byte GPIO_U4_weiche3_R_taster_abgebogen_merker = 0;  // Taster Weiche 3 Links abgebogen
byte GPIO_U4_weiche4_R_taster_gerade_merker = 0;     // Taster Weiche 4 Links gerade
byte GPIO_U4_weiche4_R_taster_abgebogen_merker = 0;  // Taster Weiche 4 Links abgebogen
// byte GPIO_U4_
// byte GPIO_U4_
// byte GPIO_U4_

// Weichenposition in Fram speichern
byte weichen_pos[] = {0, 0, 0, 0};  // = > fram-Adressen: 0x00 - 0x03
byte max_weichen_pos = (sizeof(weichen_pos) / sizeof(weichen_pos[0]));  // Alle Elemente / Wert eines einzelnen Elemenstes = Anzahl Elemente

byte auto_manuell_schalter = 0;    // Eingang mcp23017 GPA0 - Steuerung automatisch = 1 / manuell = 0
byte vor_rueckwaerts_schalter = 1; // Eingang mcp23017 GPA1 - Vorwärts = 1 / rückwärts = 0

byte steuerung_stop_taster = 0;    // Eingang mcp23017 GPA6 - Stop = 1
byte steuerung_start_taster = 0;   // Eingang mcp23017 GPA7 - Start = 1


unsigned int analog_poti = 0;      // Fahrregler für den manuellen Betrieb
unsigned int analog_trimmer = 0;   // Vorgabewert für die maximale Fahrspannung

// unsigned int analog_poti_1 = 0; // reserve Platine 1
//
// unsigned int analog_poti_7 = 0; // reserve Platine 1

const byte max_mittelwerte = 8;    // Glättung der Poti werte / Analogsignale

unsigned int analog_poti_Fahrspannung = 0;       //
unsigned analog_poti_Fahrspannung_mapped = 0;
unsigned int analog_trimmer_Fahrspannung = 0;    //
unsigned analog_trimmer_Fahrspannung_mapped = 0; //

byte Auto_Manuel_Led;
byte Stop_led;
byte Betriebs_Led;
byte fahrtrichtung_vorwaerts_raw = 0;         // direkt via Schalter geführt
byte fahrtrichtung_rueckwaerts_raw = 0;       // direkt via Schalter geführt
byte auto_automatisch_raw = 0;                // automatischer Ablauf
byte auto_manuell_raw = 0;                    // manuelles fahren

byte fahrtrichtung_vorwaerts_merker = 0;      // direkt via Schalter geführt
byte fahrtrichtung_rueckwaerts_merker = 0;    // direkt via Schalter geführt
byte auto_automatisch_merker = 0;             // automatischer Ablauf
byte auto_manuell_merker = 0;                 // manuelles fahren

byte fahrtrichtung_vorwaerts_entprellt = 0;   // direkt via Schalter geführt
byte fahrtrichtung_rueckwaerts_entprellt = 0; // direkt via Schalter geführt
byte auto_automatisch_entprellt = 0;          // automatischer Ablauf
byte auto_manuell_entprellt = 0;              // manuelles fahren


// State Machine, Deklarationen
unsigned long currentTime;
unsigned long init1Time = 0;
unsigned long init2Time = 0;
unsigned long init3Time = 0;
unsigned long init4Time = 0;
unsigned long init5aTime = 0;
unsigned long init5bTime = 0;
unsigned long init5cTime = 0;
unsigned long init5dTime = 0;
unsigned long init6aTime = 0;
unsigned long init6bTime = 0;
unsigned long init7Time = 0;
unsigned long init8Time = 0;
unsigned long init91Time = 0;
unsigned long init92Time = 0;
unsigned long init93Time = 0;

// Init 1
const unsigned long periode1_Reed = 25; // Abfrage alle 20ms des Reed Sensors
// Init 2
const unsigned long periode1_Taster = 35; // Ausgabe der Led alle 50ms
// Init 3
const unsigned long periode1_Steuerung = 50; // Steuerung der Blöcke alle 100ms
// Init 4
const unsigned long periode1_Merker = 950; // Merker Löschen alle 6s
// Init 5
const unsigned long max_weichen_stell_zeit_rechts = 1150; // mS
// const unsigned long max_weichen_stell_zeit_links = 1950; // mS
// Init7 + 8
const unsigned long max_Bahnhof1_Wartezeit = 10000; // 10sec
const unsigned long max_Bahnhof2_Wartezeit = 12000; // 12sec
// Init9
const unsigned long max_Weichen_Anfahrwartezeit = 5000; // 5sec


const byte max_weichen_stellspannung = 90; // 0..255 = 0 .. 9V -> z.B. Wert von 200 entspricht 9V/255 * 200 ~ 7V

const unsigned long Fahrregler_Anfahrzeit = 210; // mS
const unsigned long Fahrregler_Anhalten = 70;    // mS
const byte Fahrregler_PWM_Anfangs_Anfahrwert = 50;        // 0..255 PWM Frequenz entspricht 0..9V -> PWM Zahl = u[V] * 255 / 9V -> zB. 2V * 255 / 9V = 57
const byte Fahrregler_PWM_Schritte = 5;                  // Die Fahrgeschwindigkeit wird vom Anfangswert um Schritte bis auf das max trimmer wert erhöht/verringert
const byte Fahrregler_PWM_Rangiergeschwindigkeit = 105;   // 0..255 PWM Frequenz entspricht 0..9V -> PWM Zahl = u[V] * 255 / 9V -> zB. 4V * 255 / 9V = 115
byte fahrregler_PWM_auto = 0;                             // aktuelle Fahrgeschwindigkeit in PWM 0..255 im auto Modus
byte fahrregler_Schritte_zaehler = 0;                     // aktueller Zählstand der erhöhten/verringerten Fahrspannung
byte fahrregler_auto_Status = 0;                          // aktueller Status des Fahrbetriebes 0 = Aus, 1 = verlangsamen, 2 = beschleunigen
byte fahrregler_auto_Modus = 0;                           // 0 = Angehalten, 1 = Anfahren bis Rangierfahrt, 2 = Rangierfahrt bis max analog_trimmer_Fahrspannung_mapped
//                                                        // 3 = Rangierfahrt bis 0, 4 = max analog_trimmer_Fahrspannung_mapped  bis Rangierfahrt
byte bahnhof1_stop = 0;                                   // 0 = Wartezeit beendet / 1 = Wartezeit = aktiv
byte bahnhof2_stop = 0;                                   // 0 = Wartezeit beendet / 1 = Wartezeit = aktiv


// Reed Sensor direkt dem uC anschliessen via J tbd
byte reed_sensor_Pin[] = {A8, A9, A10, A11, A12, A13, A14, A15};  // Reed Sensor Unentprellt
byte max_reed_sensor_Pin = (sizeof(reed_sensor_Pin) / sizeof(reed_sensor_Pin[0]));
/* Beschreibung der uC Pin's
  byte reed_sensor1_Pin = A8;  // Scheichfahrt aus,
  byte reed_sensor2_Pin = A9;  // Hauptgleis,
  byte reed_sensor3_Pin = A10; // Abstellgeleise 1,
  byte reed_sensor4_Pin = A11; // Abstellgeleise 2,
  byte reed_sensor5_Pin = A12; // Schleichfahrt ein,
  byte reed_sensor6_Pin = A13; // Bahnhof 1,
  byte reed_sensor7_Pin = A14; // Bahnhof 2,
  byte reed_sensor8_Pin = A15; // res.
*/

// Fahrpult
unsigned int analog_poti_Pin = A0;  // Fahrregler für den manuellen Betrieb Pin
unsigned int analog_trimmer_Pin = A1; // Vorgabewert für die maximale Fahrspannung Pin

byte fahrmodus_auto_Pin = 22;    // Pendel Automat ein, Digital Pin  vom Arduino D22
byte fahrmodus_manuell_Pin = 24; // manuelle Steuerung
byte fahrmodus_reverse_Pin = 26; // Rückwärts fahren
byte fahrmodus_forward_Pin = 28; // Forwärts fahren


// res. Potis auf der Platine 1
// unsigned int analog_poti1_Pin = A2;
// unsigned int analog_poti2_Pin = A3;
// unsigned int analog_poti3_Pin = A4;
// unsigned int analog_poti4_Pin = A5;
// unsigned int analog_poti5_Pin = A6;
// unsigned int analog_poti6_Pin = A7;


// ------------------------------------------------------------
// Eingänge ab uC
// Variablen / Merker
// Einlesen der werte roh alle 20 mS
byte reed_sensor_raw[] = {0, 0, 0, 0, 0, 0, 0, 0};  // Reed Sensor Unentprellt
byte max_reed_sensor_raw = (sizeof(reed_sensor_raw) / sizeof(reed_sensor_raw[0]));

// Entprellzwischenstand Werte alle 20 mS
byte reed_sensor_merker[] = {0, 0, 0, 0, 0, 0, 0, 0};  // Reed Sensor Merker
// byte max_reed_sensor_merker = (sizeof(reed_sensor_merker) / sizeof(reed_sensor_merker[0]));

// Entprellte Werte speichern / Zugriff der Schaltung auf diese Werte
byte reed_sensor_entprellt[] = {0, 0, 0, 0, 0, 0, 0, 0};  // Reed Sensor Merker
// byte max_reed_sensor_entprellt = (sizeof(reed_sensor_entprellt) / sizeof(reed_sensor_entprellt[0]));

// Block sperren wenn Aktionen aktiv sind
byte block[] = {0, 0, 0, 0, 0, 0, 0};
byte max_blocks = (sizeof(block) / sizeof(block[0]));  // Alle Elemente / Wert eines einzelnen Elemenstes = Anzahl Elemente

// res. Rohe analoge Werte der Poti auf der Platine 1
// unsigned int analog_poti1_raw; // Eingang poti 1
// unsigned int analog_poti2_raw; // Eingang poti 2
// unsigned int analog_poti3_raw; // Eingang poti 3
// unsigned int analog_poti4_raw; // Eingang poti 4
// unsigned int analog_poti5_raw; // Eingang poti 5
// unsigned int analog_poti6_raw; // Eingang poti 6

// byte besetzt[] = {2, 2, 2};  // Losschnappen auf den Abstellgeleise verhinden. 0 = frei, 1 = , 2 = besetzt

// ------------------------------------------------------------
// Ausgänge ab uC
// H-Brücke L298 (max. 2A)
// Weiche 1 Motor A
byte Weiche1_ENA_Pin = 46; // Pin zuordnung , Array 0..3, 0..3 {PWM, rück, vor, 1=180° gedreht }, Weichen_Motor_Ein, Weichen_Motor_Aus, Richtung
byte Weiche1_IN1_Pin = 49;
byte Weiche1_IN2_Pin = 47;
byte Weiche1_reverse = 0; // 180°(0 = Weiche vorne, 1 = Weiche hinten um 180° montiert)
byte Weiche1_motor_status = 0; // Weichen Motor Ein = 1, Aus = 0;
byte Weiche1_stellung = 0; // Weichen Motor Richtung garade = 0, abgebogen = 1;
byte Weiche1_stellen = 0;  // Taster für die Weichenstellung wurde gedrückt: 0 = nichts tun, 1 = abbiegen, 2 = gerade

// Weiche 2 Motor B
byte Weiche2_ENB_Pin = 45;
byte Weiche2_IN3_Pin = 41;
byte Weiche2_IN4_Pin = 43;
byte Weiche2_reverse = 0; // 180°(0 = Weiche vorne, 1 = Weiche hinten um 180° montiert)
byte Weiche2_motor_status = 0; // Weichen Motor Ein = 1, Aus = 0;
byte Weiche2_stellung = 0; // Weichen Motor Richtung garade = 0, abgebogen = 1;
byte Weiche2_stellen = 0;  // Taster für die Weichenstellung wurde gedrückt: 0 = nichts tun, 1 = abbiegen, 2 = gerade


// Weiche 3 Motor A
byte Weiche3_ENA_Pin = 6; // Pin zuordnung , {PWM, rück, vor, 1=180° gedreht }, Weichen_Motor_Ein, Weichen_Motor_Aus, Richtung
byte Weiche3_IN1_Pin = 34;
byte Weiche3_IN2_Pin = 36;
byte Weiche3_reverse = 0; // 180°(0 = Weiche vorne, 1 = Weiche hinten um 180° montiert)
byte Weiche3_motor_status = 0; // Weichen Motor Ein = 1, Aus = 0;
byte Weiche3_stellung = 0; // Weichen Motor Richtung garade = 0, abgebogen = 1;
byte Weiche3_stellen = 0;  // Taster für die Weichenstellung wurde gedrückt: 0 = nichts tun, 1 = abbiegen, 2 = gerade


// Weiche 4 Motor B
byte Weiche4_ENB_Pin = 44;
byte Weiche4_IN3_Pin = 48;
byte Weiche4_IN4_Pin = 42;
byte Weiche4_reverse = 0; // 180°(0 = Weiche vorne, 1 = Weiche hinten um 180° montiert)
byte Weiche4_motor_status = 0; // Weichen Motor Ein = 1, Aus = 0;
byte Weiche4_stellung = 0; // Weichen Motor Richtung garade = 0, abgebogen = 1;
byte Weiche4_stellen = 0;  // Taster für die Weichenstellung wurde gedrückt: 0 = nichts tun, 1 = abbiegen, 2 = gerade


// Fahrspannung H-Brücke BTS 7960 (max. 43A)
byte fahrspannung1_BTS_L_PWM_Pin = 7; // BTS7960 L_PWM, Turn left, PWM Speed
byte fahrspannung1_BTS_R_PWM_Pin = 8; // BTS7960 R_PWM, Turn right, PWM Speed,
byte fahrspannung1_BTS_L_EN_Pin = 30; // BTS7960 L_EN, left 0 = Disable, 1 = Enable -> beide EN miteinander 0 oder 1 schalten
byte fahrspannung1_BTS_R_EN_Pin = 32; // BTS7960 R_EN, right 0 = Disable, 1 = Enable

// =====================================================================================
void setup() {

  Wire.begin(); // Erwecken des I2C Busses
  delay(200);

  if (fram.begin(i2c_fram_adr)) {  // you can stick the new i2c addr in here, e.g. begin(0x51);
    Serial.println("Found I2C FRAM");
  } else {
    Serial.println("I2C FRAM not identified ... check your connections?\r\n");
    Serial.println("Will continue in case this processor doesn't support repeated start\r\n");
    while (1);
  }



  // For Arduino Mega1280, Mega2560, MegaADK, Spider or any other board using ATmega1280 or ATmega2560
  //---------------------------------------------- Set PWM frequency for D4 & D13 ------------------------------
  // Standard lassen, nicht fuer PWM verwendbar wenn nicht 976.56 Hz da fuer Timer 0 -> millis() gebraucht wird
  //TCCR0B = TCCR0B & B11111000 | B00000001;    // set timer 0 divisor to     1 for PWM frequency of 62500.00 Hz
  //TCCR0B = TCCR0B & B11111000 | B00000010;    // set timer 0 divisor to     8 for PWM frequency of  7812.50 Hz
  TCCR0B = TCCR0B & B11111000 | B00000011;    // set timer 0 divisor to    64 for PWM frequency of   976.56 Hz
  //TCCR0B = TCCR0B & B11111000 | B00000100;    // set timer 0 divisor to   256 for PWM frequency of   244.14 Hz
  //TCCR0B = TCCR0B & B11111000 | B00000101;    // set timer 0 divisor to  1024 for PWM frequency of    61.04 Hz
  //---------------------------------------------- Set PWM frequency for D11 & D12 -----------------------------
  // TCCR1B = TCCR1B & B11111000 | B00000001;    // set timer 1 divisor to     1 for PWM frequency of 31372.55 Hz
  //TCCR1B = TCCR1B & B11111000 | B00000010;    // set timer 1 divisor to     8 for PWM frequency of  3921.16 Hz
  // TCCR1B = TCCR1B & B11111000 | B00000011;    // set timer 1 divisor to    64 for PWM frequency of   490.20 Hz
  //TCCR1B = TCCR1B & B11111000 | B00000100;    // set timer 1 divisor to   256 for PWM frequency of   122.55 Hz
  //TCCR1B = TCCR1B & B11111000 | B00000101;    // set timer 1 divisor to  1024 for PWM frequency of    30.64 Hz
  // ---------------------------------------------- Set PWM frequency for D9 & D10 ------------------------------
  TCCR2B = TCCR2B & B11111000 | B00000001;    // set timer 2 divisor to     1 for PWM frequency of 31372.55 Hz
  //TCCR2B = TCCR2B & B11111000 | B00000010;    // set timer 2 divisor to     8 for PWM frequency of  3921.16 Hz
  //TCCR2B = TCCR2B & B11111000 | B00000011;    // set timer 2 divisor to    32 for PWM frequency of   980.39 Hz
  //TCCR2B = TCCR2B & B11111000 | B00000100;    // set timer 2 divisor to    64 for PWM frequency of   490.20 Hz
  //TCCR2B = TCCR2B & B11111000 | B00000101;    // set timer 2 divisor to   128 for PWM frequency of   245.10 Hz
  //TCCR2B = TCCR2B & B11111000 | B00000110;    // set timer 2 divisor to   256 for PWM frequency of   122.55 Hz
  //TCCR2B = TCCR2B & B11111000 | B00000111;    // set timer 2 divisor to  1024 for PWM frequency of    30.64 Hz
  // ---------------------------------------------- Set PWM frequency for D2, D3 & D5 ---------------------------
  TCCR3B = TCCR3B & B11111000 | B00000001;    // set timer 3 divisor to     1 for PWM frequency of 31372.55 Hz
  // TCCR3B = TCCR3B & B11111000 | B00000010;    // set timer 3 divisor to     8 for PWM frequency of  3921.16 Hz
  //TCCR3B = TCCR3B & B11111000 | B00000011;    // set timer 3 divisor to    64 for PWM frequency of   490.20 Hz
  //TCCR3B = TCCR3B & B11111000 | B00000100;    // set timer 3 divisor to   256 for PWM frequency of   122.55 Hz
  //TCCR3B = TCCR3B & B11111000 | B00000101;    // set timer 3 divisor to  1024 for PWM frequency of    30.64 Hz
  //---------------------------------------------- Set PWM frequency for D6, D7 & D8 ---------------------------
  TCCR4B = TCCR4B & B11111000 | B00000001;    // set timer 4 divisor to     1 for PWM frequency of 31372.55 Hz
  // TCCR4B = TCCR4B & B11111000 | B00000010;    // set timer 4 divisor to     8 for PWM frequency of  3921.16 Hz
  // TCCR4B = TCCR4B & B11111000 | B00000011;    // set timer 4 divisor to    64 for PWM frequency of   490.20 Hz
  //TCCR4B = TCCR4B & B11111000 | B00000100;    // set timer 4 divisor to   256 for PWM frequency of   122.55 Hz
  //TCCR4B = TCCR4B & B11111000 | B00000101;    // set timer 4 divisor to  1024 for PWM frequency of    30.64 Hz
  //---------------------------------------------- Set PWM frequency for D44, D45 & D46 ------------------------
  TCCR5B = TCCR5B & B11111000 | B00000001;    // set timer 5 divisor to     1 for PWM frequency of 31372.55 Hz
  // TCCR5B = TCCR5B & B11111000 | B00000010;    // set timer 5 divisor to     8 for PWM frequency of  3921.16 Hz
  // TCCR5B = TCCR5B & B11111000 | B00000011;    // set timer 5 divisor to    64 for PWM frequency of   490.20 Hz
  // TCCR5B = TCCR5B & B11111000 | B00000100;    // set timer 5 divisor to   256 for PWM frequency of   122.55 Hz
  // TCCR5B = TCCR5B & B11111000 | B00000101;    // set timer 5 divisor to  1024 for PWM frequency of    30.64 Hz


  // Zuweisung Port Pin's als Output / Input
  // Weiche 1 Motor A
  pinMode(Weiche1_ENA_Pin, OUTPUT);
  pinMode(Weiche1_IN1_Pin, OUTPUT);
  pinMode(Weiche1_IN2_Pin, OUTPUT);

  // Weiche 2 Motor B
  pinMode(Weiche2_ENB_Pin, OUTPUT);
  pinMode(Weiche2_IN3_Pin, OUTPUT);
  pinMode(Weiche2_IN4_Pin, OUTPUT);

  // Weiche 3 Motor A
  pinMode(Weiche3_ENA_Pin, OUTPUT);
  pinMode(Weiche3_IN1_Pin, OUTPUT);
  pinMode(Weiche3_IN2_Pin, OUTPUT);

  // Weiche 4 Motor B
  pinMode(Weiche4_ENB_Pin, OUTPUT);
  pinMode(Weiche4_IN3_Pin, OUTPUT);
  pinMode(Weiche4_IN4_Pin, OUTPUT);


  // Konfiguration des Fahrspannungs H-Brücken Modul von Siemens BTS 7960 43A
  pinMode(fahrspannung1_BTS_L_PWM_Pin, OUTPUT); // BTS7960 L_PWM, Turn left, PWM Speed
  pinMode(fahrspannung1_BTS_R_PWM_Pin, OUTPUT); // BTS7960 R_PWM, Turn right, PWM Speed,
  pinMode(fahrspannung1_BTS_L_EN_Pin, OUTPUT); // BTS7960 L_EN, left 0 = Disable, 1 = Enable -> beide EN miteinander 0 oder 1 schalten
  pinMode(fahrspannung1_BTS_R_EN_Pin, OUTPUT);// BTS7960 R_EN, right 0 = Disable, 1 = Enable -> beide EN miteinander 0 oder 1 schalten


  // Fahrregler Poti
  pinMode(analog_poti_Pin, INPUT);  // Fahrregler für den manuellen Betrieb analog Pin A0
  pinMode(analog_trimmer_Pin, INPUT);  // Vorgabewert für die maximale Fahrspannung analog Pin A1


  // Fahrregler Steuerung automatisch / manuell
  pinMode(fahrmodus_auto_Pin, INPUT);    // Pendel Automat ein, Pin D22
  pinMode(fahrmodus_manuell_Pin, INPUT); // manuelle Steuerung, Pin D24
  pinMode(fahrmodus_reverse_Pin, INPUT); // Rückwärts fahren, Pin D26
  pinMode(fahrmodus_forward_Pin, INPUT);  // Vorwärts fahren, Pin D28


  // Reed Kontakt Eingänge direct am uC
  // Eingänge
  for (int i = 0; i < max_reed_sensor_Pin; i++) {
    pinMode(reed_sensor_Pin[i], INPUT);     // sets the analog A8 - A15 as input
  }


  // res. Poti auf der Platine 1
  // pinMode(analog_poti1_Pin, INPUT);     // Analog Poti 1 res. Platine 1
  // pinMode(analog_poti2_Pin, INPUT);     // Analog Poti 1 res. Platine 1
  // pinMode(analog_poti3_Pin, INPUT);     // Analog Poti 1 res. Platine 1
  // pinMode(analog_poti4_Pin, INPUT);     // Analog Poti 1 res. Platine 1
  // pinMode(analog_poti5_Pin, INPUT);     // Analog Poti 1 res. Platine 1
  // pinMode(analog_poti6_Pin, INPUT);     // Analog Poti 1 res. Platine 1


  // Ausgänge

  // Zeitsteuerung starten
  init1Time = millis();  //initial start time Reed
  init2Time = millis();  //initial start time Taster
  init3Time = millis();  //initial start time Steuerung
  init4Time = millis();  //initial start time Merker löschen
  init5aTime = millis();  //initial start time Weichen Motoren rechts Aus
  init5bTime = millis();  //initial start time Weichen Motoren rechts Aus
  init5cTime = millis();  //initial start time Weichen Motoren rechts Aus
  init5dTime = millis();  //initial start time Weichen Motoren rechts Aus
  init6aTime = millis();  //initial start time Anfahrtszeit
  init6bTime = millis();  //initial start time Anhaltezeit
  init7Time = millis();  //initial start time Bahnhof 1 wartezeit
  init8Time = millis();  //initial start time Bahnhof 2 wartezeit
  init91Time = millis();  //initial start time Weichenstellwartezeit
  init92Time = millis();  //initial start time Weichenstellwartezeit
  init93Time = millis();  //initial start time Weichenstellwartezeit


  // Konfigurieren der MCP23017
  // Label mmmm
  // U1 - Platine 2
  GPIO_Set_PortA_Output(i2c_mcp1_adr);  //  Led Out Signalistation J23
  delay(100);
  GPIO_Write_PortA(i2c_mcp1_adr, 0b00000000);  // alle Led aus, Led 8 .... Led 1
  delay(100);
  GPIO_Set_PortA_Input(i2c_mcp1_adr);  // Konfig Jumper J11, Achtung die neueren MCP23017 haben auf den GBA7 und GPB7 nur noch Output mögl.
  // U2 - Platine 2
  delay(100);
  // GPIO_Set_PortA_Output(i2c_mcp2_adr);  // Relais Aus = 1, Ein = 0, J58
  // delay(100);
  // GPIO_Write_PortA(i2c_mcp2_adr, 0xFF);  // alle Relais Aus
  // delay(100);
  GPIO_Set_PortB_Output(i2c_mcp2_adr);  // Led "rot", Weichenstatus or, bl, J6, J8, J16, J19 je Pin 1 + 2 und Pin 7 + 8
  delay(100);
  // U3 - Platine 3
  delay(100);
  GPIO_Set_PortA_Output(i2c_mcp3_adr);  // Als Output
  delay(100);
  GPIO_Set_PortB_Output(i2c_mcp3_adr);  // Als Output
  delay(100);
  // U4 - Platine 3
  GPIO_Set_PortA_Input(i2c_mcp4_adr);  // Als Input, GPA7 + GPA7 = Outputs
  delay(100);
  GPIO_Set_PortB_Input(i2c_mcp4_adr);  // Als Input, GPA7 + GPA7 = Outputs
  delay(100);


  // serielle Schnittstelle für den Monitor
  Serial.begin(115200);
  Serial.println("Begin Debug");

  lcd.begin(20, 4);
  delay(100);
  lcd.setBacklight(245);
  lcd.home();
  lcd.clear();
  lcd.cursor();
  lcd.setCursor(0, 0);  // Zeile 1
  lcd.print("Moba Control (C)2022 ");
  lcd.setCursor(0, 1);  // Zeile 2
  lcd.print("MoBa Control ");
  delay (3000);
  lcd.setCursor(0, 1);  // Zeile 2
  lcd.print("Wechselsteuerung ");
  lcd.print(ver);
  delay (3000);

  // Initialisierung der Anlage:
  // Starteinstellung:
  // Einlesen Konfig Taster/Jumper via I2C
  // Einlesen via I2C das Byte im Port B - > Aus Loop genommen
  GPIO_U1_PortB_raw = GPIO_Read_PortB(i2c_mcp1_adr); // U1 PortB
  GPIO_U1_Abstellgeleise = bitRead(GPIO_U1_PortB_raw, 0); // Anzahl Abstellgeleise 1 => Wert = 0 oder Abstellgeleise 2 => Wert = 1
  GPIO_U1_Bahnhof2 = bitRead(GPIO_U1_PortB_raw, 1); // Anzahl Reed Sensoren Bahnhof 1 = (0) / Bahnhof 2=(1)
  GPIO_U1_Fahrspannung_Reverse = bitRead(GPIO_U1_PortB_raw, 2); // J11 Inp03
  GPIO_U1_Weiche1_Reverse = bitRead(GPIO_U1_PortB_raw, 3); // J11 Inp04
  GPIO_U1_Weiche2_Reverse = bitRead(GPIO_U1_PortB_raw, 4); // J11 Inp05
  GPIO_U1_Weiche3_Reverse = bitRead(GPIO_U1_PortB_raw, 5); // J11 Inp06
  GPIO_U1_Weiche4_Reverse = bitRead(GPIO_U1_PortB_raw, 6); // J11 Inp07

  delay(100);
  // Stellung auf stop (Automat)
  GPIO_U3_Led2_stop = 1;  // Automat auf Stop

  // Weiche Gerade aus, wenn nicht schon: Werte aus FRAM lesen
  for (int i = 0; i < max_weichen_pos; i++) {
    // weichen_pos[i] = fram.write(i, 7);
    weichen_pos[i] = fram.read(i);  // Einlesen Fram Adresse 0x00 - 0x03
    Serial.print("weichen_pos[");
    Serial.print(i);
    Serial.print("] : ");
    Serial.println(weichen_pos[i]);
  }
  // Setzen der Variablen die die Werte via I2C ausgibt
  // Einlesen Fram. Wenn schon Gerade aus, nichts tun, ansonsten Gerade aus

  // Weichen Stellung vom letzten Betrieb aus Fram auslesen und die Led dementsprechend einschalten
  // Weiche 1 und 3 gereade ausstellen wenn nicht schon -> Einlesen FRAM via i2C -> Später
  if (weichen_pos[0x00] == 1) {        // Weiche 1 abgebogen
    GPIO_U3_Led4_weiche1_orange = 1;
    GPIO_U3_Led5_weiche1_blau = 0;
  } else {                             // Weiche 1 gerade
    GPIO_U3_Led4_weiche1_orange = 0;
    GPIO_U3_Led5_weiche1_blau = 1;
  }
  if (weichen_pos[0x02] == 1) {        // Weiche 3 abgebogen
    GPIO_U3_Led8_weiche3_orange = 1;
    GPIO_U3_Led9_weiche3_blau = 0;
  } else {                             // Weiche 3 gerade
    GPIO_U3_Led8_weiche3_orange = 0;
    GPIO_U3_Led9_weiche3_blau = 1;
  }
  bitWrite(GPIO_U3_PortB_raw, 3, GPIO_U3_Led4_weiche1_orange);   // Led orange, abgebogen
  bitWrite(GPIO_U3_PortB_raw, 4, GPIO_U3_Led5_weiche1_blau);     // Led blau, gerade aus
  bitWrite(GPIO_U3_PortA_raw, 2, GPIO_U3_Led9_weiche3_blau);      // Led blau, gerade aus
  bitWrite(GPIO_U3_PortB_raw, 7, GPIO_U3_Led8_weiche3_orange);   // Led orange, abgebogen
  if (GPIO_U1_Abstellgeleise == 1) {  // Abstellgleis 2 -> In Betrieb
    // Weiche 2 und 4 gereade ausstellen wenn nicht schon -> Einlesen FRAM via i2C -> Später
    if (weichen_pos[0x01] == 1) {       // Weiche 2 abgebogen
      GPIO_U3_Led6_weiche2_orange = 1;
      GPIO_U3_Led7_weiche2_blau = 0;
    } else {                            // Weiche 2 gerade
      GPIO_U3_Led6_weiche2_orange = 0;
      GPIO_U3_Led7_weiche2_blau = 1;
    }
    if (weichen_pos[0x03] == 1) {       // Weiche 4 abgebogen
      GPIO_U3_Led10_weiche4_orange = 1;
      GPIO_U3_Led11_weiche4_blau = 0;
    } else {                            // Weiche 4 gerade
      GPIO_U3_Led11_weiche4_blau = 1;
      GPIO_U3_Led10_weiche4_orange = 0;
    }
    bitWrite(GPIO_U3_PortB_raw, 5, GPIO_U3_Led6_weiche2_orange);    // Led orange, abgebogen
    bitWrite(GPIO_U3_PortB_raw, 6, GPIO_U3_Led7_weiche2_blau);      // Led blau, gerade aus
    bitWrite(GPIO_U3_PortA_raw, 0, GPIO_U3_Led11_weiche4_blau);     // Led blau, gerade aus
    bitWrite(GPIO_U3_PortA_raw, 1, GPIO_U3_Led10_weiche4_orange);   // Led orange, abgebogen
  }
  // Speichern im I2C Baustein
  GPIO_Write_PortB(i2c_mcp3_adr, GPIO_U3_PortB_raw);
  delay(100);
  GPIO_Write_PortA(i2c_mcp3_adr, GPIO_U3_PortA_raw);
  delay(100);
  // Nur zum debuggen
  // I2CScan();


  // Ende Setup-Teil
}


// =====================================================================================
// Haupt Routine State Machine
void loop() {
  // put your main code here, to run repeatedly:
  // Abfrage aktuelle "Zeit"
  currentTime = millis();
  // ------------------------------------------------------------------------------
  // Abfrage Reed Sensoren
  // ------------------------------------------------------------------------------
  if (currentTime - init1Time >= periode1_Reed) //test whether the period has elapsed
  {
    // softe Entprellong
    // Lesen des Pin Wertes 0 oder 1
    // Mit for Schleife ersetzen:
    for (int i = 0; i < max_reed_sensor_raw; i++) {
      reed_sensor_raw[i] = digitalRead(reed_sensor_Pin[i]);
      if ( reed_sensor_raw[i] == reed_sensor_merker[i]) {
        reed_sensor_entprellt[i] = reed_sensor_merker[i];
      } else {
        reed_sensor_merker[i] = reed_sensor_raw[i];
      }
    }
    init1Time = currentTime;
  }


  // ------------------------------------------------------------------------------
  // Abfrage Taster und Poti und in Variablen speichern
  // ------------------------------------------------------------------------------
  if (currentTime - init2Time >= periode1_Taster)   //test whether the period has elapsed
  {
    // Abfrage der Taster am mC
    // softe Entprellung
    fahrtrichtung_vorwaerts_raw = digitalRead(fahrmodus_forward_Pin);
    if ( fahrtrichtung_vorwaerts_raw == fahrtrichtung_vorwaerts_merker) {
      fahrtrichtung_vorwaerts_entprellt = fahrtrichtung_vorwaerts_merker;
    } else {
      fahrtrichtung_vorwaerts_merker = fahrtrichtung_vorwaerts_raw;
    }
    fahrtrichtung_rueckwaerts_raw = digitalRead(fahrmodus_reverse_Pin);
    if ( fahrtrichtung_rueckwaerts_raw == fahrtrichtung_rueckwaerts_merker) {
      fahrtrichtung_rueckwaerts_entprellt = fahrtrichtung_rueckwaerts_merker;
    } else {
      fahrtrichtung_rueckwaerts_merker = fahrtrichtung_rueckwaerts_raw;
    }
    auto_automatisch_raw = digitalRead(fahrmodus_auto_Pin);
    if ( auto_automatisch_raw == auto_automatisch_merker) {
      auto_automatisch_entprellt = auto_automatisch_merker;
    } else {
      auto_automatisch_merker = auto_automatisch_raw;
    }
    auto_manuell_raw = digitalRead(fahrmodus_manuell_Pin);
    if ( auto_manuell_raw == auto_manuell_merker) {
      auto_manuell_entprellt = auto_manuell_merker;
    } else {
      auto_manuell_merker = auto_manuell_raw;
    }


    // ------------------------------------------------------------------------------
    // Abfragw Poti am mC für den manuellen Betrieb mit dem Poti
    // ------------------------------------------------------------------------------
    analog_poti_Fahrspannung = analogRead(analog_poti_Pin);  // Abfragen Poti
    analog_poti_Fahrspannung_mapped = map(analog_poti_Fahrspannung, 1023, 0, 0, 255); // Drehen der Skala 1023 nach 0 und auf 0..255 mappen
    // Abfrage Trimmer für die Fahrspannung des automatischen Pendelbetriebes
    analog_trimmer_Fahrspannung = analogRead(analog_trimmer_Pin);
    analog_trimmer_Fahrspannung_mapped = map(analog_trimmer_Fahrspannung, 1023, 0, 0, 255); // Drehen der Skala 1023 nach 0 und auf 0..255 mappen
    //  res. poti auf der Platine 1
    //  analog_poti1_raw = analogRead(analog_poti1_Pin);
    //  analog_poti2_raw = analogRead(analog_poti2_Pin);
    //  analog_poti3_raw = analogRead(analog_poti3_Pin);
    //  analog_poti4_raw = analogRead(analog_poti4_Pin);
    //  analog_poti5_raw = analogRead(analog_poti5_Pin);
    //  analog_poti6_raw = analogRead(analog_poti6_Pin);

    //
    GPIO_U4_PortB_raw = GPIO_Read_PortB(i2c_mcp4_adr); // U4 Port B
    // Speichern der Bit Werte vom Port B Byte
    GPIO_U4_taster_start_raw = bitRead(GPIO_U4_PortB_raw, 0);
    if ( GPIO_U4_taster_start_raw == GPIO_U4_taster_start_merker) {
      GPIO_U4_taster_start_entprellt = GPIO_U4_taster_start_merker;
    } else {
      GPIO_U4_taster_start_merker = GPIO_U4_taster_start_raw;
    }
    GPIO_U4_taster_stop_raw = bitRead(GPIO_U4_PortB_raw, 1);
    if ( GPIO_U4_taster_stop_raw == GPIO_U4_taster_stop_merker) {
      GPIO_U4_taster_stop_entprellt = GPIO_U4_taster_stop_merker;
    } else {
      GPIO_U4_taster_stop_merker = GPIO_U4_taster_stop_raw;
    }
    GPIO_U4_taster_stopping_raw = bitRead(GPIO_U4_PortB_raw, 2);
    if ( GPIO_U4_taster_stopping_raw == GPIO_U4_taster_stopping_merker) {
      GPIO_U4_taster_stopping_entprellt = GPIO_U4_taster_stopping_merker;
    } else {
      GPIO_U4_taster_stopping_merker = GPIO_U4_taster_stopping_raw;
    }
    // Weichen Taster U4 Port B
    GPIO_U4_weiche1_L_taster_gerade_raw = bitRead(GPIO_U4_PortB_raw, 3);
    if ( GPIO_U4_weiche1_L_taster_gerade_raw == GPIO_U4_weiche1_L_taster_gerade_merker) {
      GPIO_U4_weiche1_L_taster_gerade_entprellt = GPIO_U4_weiche1_L_taster_gerade_merker;
    } else {
      GPIO_U4_weiche1_L_taster_gerade_merker = GPIO_U4_weiche1_L_taster_gerade_raw;
    }
    GPIO_U4_weiche1_L_taster_abgebogen_raw = bitRead(GPIO_U4_PortB_raw, 4);
    if ( GPIO_U4_weiche1_L_taster_abgebogen_raw == GPIO_U4_weiche1_L_taster_abgebogen_merker) {
      GPIO_U4_weiche1_L_taster_abgebogen_entprellt = GPIO_U4_weiche1_L_taster_abgebogen_merker;
    } else {
      GPIO_U4_weiche1_L_taster_abgebogen_merker = GPIO_U4_weiche1_L_taster_abgebogen_raw;
    }
    GPIO_U4_weiche2_L_taster_gerade_raw = bitRead(GPIO_U4_PortB_raw, 5);
    if ( GPIO_U4_weiche2_L_taster_gerade_raw == GPIO_U4_weiche2_L_taster_gerade_merker) {
      GPIO_U4_weiche2_L_taster_gerade_entprellt = GPIO_U4_weiche2_L_taster_gerade_merker;
    } else {
      GPIO_U4_weiche2_L_taster_gerade_merker = GPIO_U4_weiche2_L_taster_gerade_raw;
    }
    GPIO_U4_weiche2_L_taster_abgebogen_raw = bitRead(GPIO_U4_PortB_raw, 6); // -> Nur noch Output Pin ??
    if ( GPIO_U4_weiche2_L_taster_abgebogen_raw == GPIO_U4_weiche2_L_taster_abgebogen_merker) {
      GPIO_U4_weiche2_L_taster_abgebogen_entprellt = GPIO_U4_weiche2_L_taster_abgebogen_merker;
    } else {
      GPIO_U4_weiche2_L_taster_abgebogen_merker = GPIO_U4_weiche2_L_taster_abgebogen_raw;
    }
    // Einlesen via I2C das Byte im Port A
    GPIO_U4_PortA_raw = GPIO_Read_PortA(i2c_mcp4_adr); // U4
    // Weichen Taster U4 Port A
    GPIO_U4_weiche3_R_taster_gerade_raw = bitRead(GPIO_U4_PortA_raw, 0);
    if ( GPIO_U4_weiche3_R_taster_gerade_raw == GPIO_U4_weiche3_R_taster_gerade_merker) {
      GPIO_U4_weiche3_R_taster_gerade_entprellt = GPIO_U4_weiche3_R_taster_gerade_merker;
    } else {
      GPIO_U4_weiche3_R_taster_gerade_merker = GPIO_U4_weiche3_R_taster_gerade_raw;
    }
    GPIO_U4_weiche3_R_taster_abgebogen_raw = bitRead(GPIO_U4_PortA_raw, 1); //
    if ( GPIO_U4_weiche3_R_taster_abgebogen_raw == GPIO_U4_weiche3_R_taster_abgebogen_merker) {
      GPIO_U4_weiche3_R_taster_abgebogen_entprellt = GPIO_U4_weiche3_R_taster_abgebogen_merker;
    } else {
      GPIO_U4_weiche3_R_taster_abgebogen_merker = GPIO_U4_weiche3_R_taster_abgebogen_raw;
    }
    GPIO_U4_weiche4_R_taster_gerade_raw = bitRead(GPIO_U4_PortA_raw, 2);
    if ( GPIO_U4_weiche4_R_taster_gerade_raw == GPIO_U4_weiche4_R_taster_gerade_merker) {
      GPIO_U4_weiche4_R_taster_gerade_entprellt = GPIO_U4_weiche4_R_taster_gerade_merker;
    } else {
      GPIO_U4_weiche4_R_taster_gerade_merker = GPIO_U4_weiche4_R_taster_gerade_raw;
    }
    GPIO_U4_weiche4_R_taster_abgebogen_raw = bitRead(GPIO_U4_PortA_raw, 3); // -> Nur noch Output Pin ??
    if ( GPIO_U4_weiche4_R_taster_abgebogen_raw == GPIO_U4_weiche4_R_taster_abgebogen_merker) {
      GPIO_U4_weiche4_R_taster_abgebogen_entprellt = GPIO_U4_weiche4_R_taster_abgebogen_merker;
    } else {
      GPIO_U4_weiche4_R_taster_abgebogen_merker = GPIO_U4_weiche4_R_taster_abgebogen_raw;
    }
    // res. = bitRead(GPIO_U4_PortA_raw,4);
    // res. = bitRead(GPIO_U4_PortA_raw,5);
    // res. = bitRead(GPIO_U4_PortA_raw,6);
    init2Time = currentTime;

  }

  // ------------------------------------------------------------------------------
  // Steuerungs Funktionen / Ausgänge
  // ------------------------------------------------------------------------------
  if (currentTime - init3Time >= periode1_Steuerung)//test whether the period has elapsed
  {
    // ------------------------------------------------------------------------------------------------------
    // Steuerung manuell, auto, vorwärts rückwärts
    // Sektion manueller Betrieb
    if (auto_manuell_entprellt == 1) {
      auto_automatisch_entprellt = 0;  // Automat stoppen
      // Vor Rückwärts
      if ((fahrtrichtung_vorwaerts_entprellt == 1) && (fahrtrichtung_rueckwaerts_entprellt == 0)) {
        // Funktion für vor- und rückwärts -> Rücksetzen der Rückwärtsfahrt
        // Prüfen vor der Umschaltung der Fahrspannung
        Fahrspannung_Vorwaerts(analog_poti_Fahrspannung_mapped);
      }
      if ((fahrtrichtung_rueckwaerts_entprellt == 1) && (fahrtrichtung_vorwaerts_entprellt == 0)) {
        // Funktion für vor- und rückwärts -> Rücksetzen der Vorwärtsfahrt
        // Prüfen vor der Umschaltung der Fahrspannung
        Fahrspannung_Rueckwaerts(analog_poti_Fahrspannung_mapped);
      }
      // Beim umstellen des Fahhrichtungsschalters, wird die Fahtrspannung weggenommen
      if ((fahrtrichtung_vorwaerts_entprellt == 0)  && (fahrtrichtung_rueckwaerts_entprellt == 0)) {
        Fahrregler_Stop();  // Fahrspannung ausschalten
        // tbd ev. Verriegelung wenn Poti nicht unter 10 ist
        // lcd.setCursor(16,1);
        // lcd.print("Stop");
      }
      // Ende manueller Betrieb
    }

    // ------------------------------------------------------------------
    // Steuerung Run, Stop, Stopping
    if (GPIO_U4_taster_start_entprellt == 1 && auto_manuell_entprellt == 0) {  // Anstelle Taster die Led abfragen -> Automat starten nur wenn der Schalter in  der Pos. Auto istt
      GPIO_U3_Led1_run = 1;  // Led Run (grün) einschalten
      GPIO_U3_Led2_stop = 0; // Led Stop (rot) ausschalten
      GPIO_U3_Led3_stopping = 0; // Led Stopping (orange) ausschalten
      // Starten des automatischen Betriebes -> Alle Weichen müssen auf Gerade aus sein
      // Beim ersten Start/nach dem Aufstarten sin ddie Reed sensoren nicht aktiv -> Starten ab den Hauptgleis (ignorieren der Reed2 Led / Sensor)
      // Weitere Dinge
      block[1] = 90;   // Freigeben Block 1, 2 oder 3
      block[2] = 90;   // Freigeben Block 1, 2 oder 3
      block[3] = 90;   // Freigeben Block 1, 2 oder 3
      // Anfahren der Lok egal wo sie steht
      Fahrspannung_anfahren();
    }

    if (GPIO_U4_taster_stop_entprellt == 1) {  // -> Nothalt, anhalten
      GPIO_U3_Led1_run = 0;  // Led Run (grün) ausschalten
      GPIO_U3_Led2_stop = 1; // Led Stop (rot) einschalten
      GPIO_U3_Led3_stopping = 0; // Led Stopping (orange) ausschalten
      // Löschen der Reed Led's
      GPIO_U3_Led12_Reed1 = 0;
      GPIO_U3_Led13_Reed2 = 0;
      GPIO_U3_Led14_Reed3 = 0;
      GPIO_U3_Led15_Reed4 = 0;
      GPIO_U3_Led16_Reed5 = 0;
      GPIO_U4_Led17_Reed6 = 0;
      GPIO_U4_Led18_Reed7 = 0;
      // Weitere Dinge
      fahrregler_PWM_auto = 0;
      fahrregler_auto_Status = 0; // Anhalten / Stop
      fahrregler_auto_Modus = 0;
      Fahrregler_Stop();
      // block[1] = 0;   // Freigeben Block 1, 2 oder 3
      // block[2] = 0;   // Freigeben Block 1, 2 oder 3
      // block[3] = 0;   // Freigeben Block 1, 2 oder 3
    }

    if (GPIO_U4_taster_stopping_entprellt == 1) {  // -> Weiter fahren ins Depot und da anhalten
      GPIO_U3_Led1_run = 0;  // Led Run (grün) ausschalten
      GPIO_U3_Led2_stop = 0; // Led Stop (rot) einschalten
      GPIO_U3_Led3_stopping = 1; // Led Stopping (orange) ausschalten
      // Weitere dinge
      block[1] = 98;   // Anhalten beim Block 1, 2 oder 3
      block[2] = 98;   // Anhalten beim Block 1, 2 oder 3
      block[3] = 98;   // Anhalten beim Block 1, 2 oder 3
    }
    // Reed Kontakte anzeigen mit Led
    if (reed_sensor_entprellt[0] == 1) {
      GPIO_U3_Led12_Reed1 = 1;           // Led rot Fahrt langsam beschleunigen (Ausfaht aus den Weichen auf die Strecke)
      GPIO_U3_Led13_Reed2 = 0;           // Led rot Hauptgleis
      GPIO_U3_Led14_Reed3 = 0;           // Led rot 1. Abstellgleis
      GPIO_U3_Led15_Reed4 = 0;           // Led rot 2. Abstellgleis
    }
    if (reed_sensor_entprellt[1] == 1) {  // Nur bei Gerade aus dedektieren
      // && weichen_pos[0] == 2  && weichen_pos[2] == 2  && weichen_pos[1] == 2 && weichen_pos[3] == 2 && block[1] == 0)
      GPIO_U3_Led13_Reed2 = 1;           // Led rot Hauptgleis
      GPIO_U3_Led16_Reed5 = 0;           // Led rot Fahrt verlangsamen
    }
    if (reed_sensor_entprellt[2] == 1) { // Abstellgleis 1 (rechts)        // Test mit verriegeln, das Lok nicht davon schiesst nach dem Weichenstellen, nun mit Block[x] = 90 gelöst      // && weichen_pos[0] == 1 && weichen_pos[2] == 1 && block[2] == 0
      GPIO_U3_Led14_Reed3 = 1;           // Led rot 1. Abstellgleis
      GPIO_U3_Led16_Reed5 = 0;           // Led rot Fahrt verlangsamen
    }
    if (reed_sensor_entprellt[3] == 1) {  // Abstellgleis 2 (links)
      // && weichen_pos[1] == 1 && weichen_pos[3] == 1 && block[3] == 0  // Test mit verriegeln, das Lok nicht davon schiesst nach dem Weichenstellen, nun mit Block[x] = 90 gelöst
      GPIO_U3_Led15_Reed4 = 1;           // Led rot 2. Abstellgleis
      GPIO_U3_Led16_Reed5 = 0;           // Led rot Fahrt verlangsamen
    }
    if (reed_sensor_entprellt[4] == 1) {   // Fahrt verlangsamen (Einfahrt auf die Weichen)
      GPIO_U3_Led16_Reed5 = 1;           // Led rot Fahrt verlangsamen
      GPIO_U4_Led17_Reed6 = 0;           // Led rot Haltestelle Bahnhof 1
    }
    if ((reed_sensor_entprellt[5] == 1) && (GPIO_U1_Bahnhof2 == 1)) {  // Bahnhof 2, nur wenn Jumper 2 J11 gesetzt
      // GPIO U4 Port A - Output Bit 7
      GPIO_U4_Led18_Reed7 = 1;           // Led rot Haltestelle Bahnhof 2
      GPIO_U3_Led12_Reed1 = 0;           // Led rot Fahrt langsam beschleunigen aus
    }
    // von Microchip verschwurbelte nur Ausgaänge GPA7 unf GPB7
    if (reed_sensor_entprellt[6] == 1) {  // Bahnhof 1 gibt es immer
      // GPIO U4 Port B - Output Bit 7
      GPIO_U4_Led17_Reed6 = 1;           // Led rot Haltestelle Bahnhof 1
      // Jumper abfragen Bhf 2 ja / Nein
      if (GPIO_U1_Bahnhof2 == 0) {
        GPIO_U4_Led18_Reed7 = 0;           // Led rot Haltestelle Bahnhof 2 falls es mal leuchten sollte
        GPIO_U3_Led12_Reed1 = 0;           // Led rot Fahrt langsam beschleunigen löschen
      } else {
        GPIO_U4_Led18_Reed7 = 0;           // Led rot Haltestelle Bahnhof 2
      }
    }

    // Ende Reed Einlesen und auf rote Led ausgeben



    // -----------------------------------------------------------------------------------------------------
    // Automatischer Betrieb (Wechselsteuerung)
    if ((auto_automatisch_entprellt == 1) && (GPIO_U3_Led2_stop == 1)) {  // Automatische Stellung und Taste/Led noch auf Stop
      Fahrregler_Stop();
    }

    if ((auto_automatisch_entprellt == 1) && (GPIO_U3_Led1_run == 1 || GPIO_U3_Led3_stopping == 1)) {       // Schalter auf der Stellung Automatischer Betrieb + Start des Automaten Tasters mit Run
      // Umschalten zwischen manuellem und automatischem Pendel Fahrbetrieb
      // Prüfen zurücksetzen der fahrspannung
      // Prüfen zurücksetzen des automatischen Fahrbetriebes
      //
      auto_manuell_entprellt = 0;                // Zurücksetzen des manuellen Fahrbetriebes

      // -------------------------------------------------------
      // Reed Sensor 1 - Beschleunigen
      if (GPIO_U3_Led12_Reed1 == 1 && block[0] == 0) {  // Beschleunigungs Reed Kontakt -> Led Reed 1 abfragen, block darf nicht gespertt sein
        // Block 1 resp. 0 sperren
        block[0] = 1;
        Fahrspannung_schneller();                       // beschleunigen von Rangierfahrt bis max Trimmer Geschwindigkeit
        // vorherigen Block[] frei geben: Hauptgeleis, Abstellgeleis 1 und 2
        block[1] = 0;
        block[2] = 0;
        block[3] = 0;
      }

      // ====================================================
      // Reed Sensor 7 - Bahnhof 2 anhalten
      if (GPIO_U4_Led18_Reed7 == 1 && block[6] == 0  && bahnhof2_stop == 0 && GPIO_U1_Bahnhof2 == 1) { // Bahnhof 2 anhalten aber nur wenn Sensor 7 in Betrieb
        // Block 7 resp. 6 sperren
        block[6] = 1;
        bahnhof2_stop = 1;
        Fahrspannung_anhalten();  // Verlangsamen und anhalten
        // Serial.priintln("Bahnhof 2 ein");
        init8Time = currentTime;  // Wartezeit Bahnhof 2
        Serial.println("bahnhof 2.1, Anhalten, Warten");
      }

      if (GPIO_U4_Led18_Reed7 == 1 && block[6] == 2  && bahnhof2_stop == 2 && GPIO_U1_Bahnhof2 == 1) { // Bahnhof 2 anfahren aber nur wenn Sensor 7 in Betrieb
        block[6] = 3;
        // Startwert in Warteschlaufe mitgegeben, da Fahrspannung_Anfahren(); übergangen wird
        Fahrspannung_anfahren(); // anfahren
        Serial.println("bahnhof 2.2, anfahren");
      }

      if (GPIO_U4_Led18_Reed7 == 1 && block[6] == 3 && bahnhof2_stop == 2 && (fahrregler_PWM_auto >= 110) && GPIO_U1_Bahnhof2 == 1) { // Bahnhof 2 anfahren aber nur wenn Sensor 7 in Betrieb
        block[6] = 4;
        bahnhof2_stop = 4;
        Fahrspannung_schneller();              // weiter fahren Rangierspannung bis max Trimmer Geschwindigkeit
        // vorherigen Block[0] frei geben
        block[0] = 0;
        Serial.println("bahnhof 2.3, Schneller");
      }

      // -------------------------------------------------------
      // Reed Sensor 6 - Bahnhof 1 anhalten
      if (GPIO_U4_Led17_Reed6 == 1 && block[5] == 0 && bahnhof1_stop == 0) {  // Bahnhof 1 anhalten
        // Block 6 resp. [5] sperren
        block[5] = 1;
        bahnhof1_stop = 1;
        Fahrspannung_anhalten();            // Verlangsamen und anhalten
        init7Time = currentTime;            // Wartezeit Bahnhof 1
        Serial.println("bahnhof 1.1 Anhalten, warten");

      }

      if (GPIO_U4_Led17_Reed6 == 1 && block[5] == 2 && bahnhof1_stop == 2) {  // Bahnhof 1 anfahren
        block[5] = 3;
        bahnhof1_stop = 3;
        // Startwert in Warteschlaufe mitgegeben, da Fahrspannung_Anfahren(); übergangen wird
        Fahrspannung_anfahren();  // Bis Rangierfahrt Geschwindigkeit
        Serial.println("bahnhof 1.2 Anfahren");

      }

      if (GPIO_U4_Led17_Reed6 == 1 && block[5] == 3 && bahnhof1_stop == 3 && fahrregler_PWM_auto >= 100) {  // Bahnhof 1 bescheunigen
        block[5] = 4;
        bahnhof1_stop = 4;
        Fahrspannung_schneller();              // weiter fahren Rangierspannung bis max Trimmer Geschwindigkeit
        // vorherigen Block[] frei geben
        block[6] = 0;
        bahnhof2_stop = 0;
        Serial.println("bahnhof 1.3, Schneller");
        if (GPIO_U1_Bahnhof2 == 0) { // Wenn keine Haltestelle an Bahnhof 2, dann vorhereigen Block [0] zurücksetzen
          Serial.println("bahnhof 2.x BFH 2");
          block[0] = 0;
        }
      }

      // -------------------------------------------------------
      // Reed Sensor 5 - Fahrt verlangsamen bei der Einfahrt auf die Weichen mit Rangierfahrt
      if (GPIO_U3_Led16_Reed5 == 1 && block[4] == 0) {      //
        // Block 5 resp. [4] sperren
        block[4] = 1;
        Fahrspannung_langsamer();
        // vorherigen Block[] frei geben
        block[5] = 0;
        bahnhof1_stop = 0;
        bahnhof2_stop = 0;
        // Serial.println(" Sensor 5 - Fahr verlangsamen");
      }

      // ----------------Hauptgleis 1---------------------------------------
      // Reed Sensor 2 - Rangierfahrt anhalten auf dem Hauptgleis
      if ((GPIO_U3_Led13_Reed2 == 1 && block[0] == 0) && (block[1] == 0 || block[1] == 98)) {      // Hauptgleis, anhalten, Block 1 sperren wegen Mehrfacheintritt
        // Block 2 resp. [1] sperren
        if (block[1] == 0) {
          block[1] = 1;
        } else {
          block[1] = 97; // für Anhalten
        }
        Fahrspannung_anhalten();
        // Serial.println("Hauptgleis 1 - 1");
      }

      if ((GPIO_U3_Led13_Reed2 == 1 && fahrregler_PWM_auto <= 19 && block[0] == 0) && (block[1] == 1 || block[1] == 97)) {
        if (block[1] == 1)  {
          block[1] = 2;
        } else {
          // Block[1] auf 96 stellen, nicht mehr weiterfahren
          block[1] = 96;
          fahrregler_PWM_auto = 0;
          fahrregler_auto_Status = 0; // Anhalten / Stop
          fahrregler_auto_Modus = 0;
        }
        Fahrregler_Stop();
        // wenn der Zug angehalten hat, prüfen des Motorstatuses des Fahrreglers
        // Serial.println("Hauptgleis 1 - 2");
      }

      if (GPIO_U3_Led13_Reed2 == 1 && block[1] == 2 && block[0] == 0 && fahrregler_auto_Status == 0 && fahrregler_auto_Modus == 0) {
        block[1] = 3;
        // besetzt[1] = 2;  // Besetzen des anderen Geleises
        // Weiche erst stellen, wenn Motorstatus und fahrregler_auto_Modus = 0 sind
        // Weiche stellen auf das Abstellgleis 1
        Weiche1_stellen = 1; // Abbiegen
        GPIO_U3_Led4_weiche1_orange = 1;    // Led orange ein
        GPIO_U3_Led5_weiche1_blau = 0;      // Led blau aus
        Weiche3_stellen = 1; // Abbiegen
        GPIO_U3_Led9_weiche3_blau = 0;      // Led blau aus
        GPIO_U3_Led8_weiche3_orange = 1;     // Led orange ein
        // Serial.println("Hauptgleis 1 - nach Weiche stellen 3");
        // Wartezeit Weichenstellzeit abwarten
        init91Time = currentTime;
      }

      if (GPIO_U3_Led13_Reed2 == 1 && block[1] == 4 && block[0] == 0 && Weiche1_motor_status == 0 && Weiche3_motor_status == 0) {
        block[1] = 5;
        block[2] = 99;  // Block Abstellgleis 1 präventiv sperren
        block[3] = 99;  // Block Abstellgleis 1 präventiv sperren
        // Wenn Weiche fertig gestellt ist, dann darf der Zug abfahren
        // Fahrspannung anfahren anderes Gleis
        Fahrspannung_anfahren(); // Ab Abstellgleis 1
        // vorherigen Block[] frei geben
        block[4] = 0;
        // Serial.println("Hauptgleis 1 - 4");
      }

      // -------------------------------------------------------
      // Reed Sensor 3 - Rangierfahrt anhalten auf dem Abstellgleis 1
      if ((GPIO_U3_Led14_Reed3 == 1 && block[0] == 0) && (block[2] == 0 || block[2] == 98)) {      // Abstellgleis 1 (rechts)
        // Block 3 resp. [2] sperren
        if (block[2] == 0) {
          block[2] = 1;
        } else {
          block[2] = 97;
        }
        Fahrspannung_anhalten();
      }

      if ((GPIO_U3_Led14_Reed3 == 1 && fahrregler_PWM_auto <= 19 && block[0] == 0) && (block[2] == 1 || block[2] == 97)) {     // Anhalten bstellgleis 1 (rechts)
        // wenn der Zug angehalten hat, prüfen des Motorstatuses des Fahrreglers
        if (block[2] == 1) {
          block[2] = 2;
        } else {
          // Block[2] auf 96 stellen
          block[2] = 96;
          fahrregler_PWM_auto = 0;
          fahrregler_auto_Status = 0; // Anhalten / Stop
          fahrregler_auto_Modus = 0;
        }
        Fahrregler_Stop();
      }

      if (GPIO_U3_Led14_Reed3 == 1 && block[2] == 2 && block[0] == 0 && fahrregler_auto_Status == 0 && fahrregler_auto_Modus == 0) {
        block[2] = 3;
        // Weiche erst stellen, wenn Motorstatus und fahrregler_auto_Modus = 0 sind
        // Weiche stellen auf das Abstellgleis 1
        Weiche1_stellen = 2; // Gerade aus
        GPIO_U3_Led4_weiche1_orange = 0;    // Led orange aus
        GPIO_U3_Led5_weiche1_blau = 1;      // Led blau ein
        Weiche3_stellen = 2; // Gerade aus
        GPIO_U3_Led9_weiche3_blau = 1;      // Led blau ein
        GPIO_U3_Led8_weiche3_orange = 0;    // Led orange aus
        if (GPIO_U1_Abstellgeleise == 1) {
          // Weichen 2 und 4 sollten auch noch gestellt werden für das AbstellGeleise 2 zu befahren, wenn vorhanden
          Weiche2_stellen = 1; // abbiegen
          GPIO_U3_Led6_weiche2_orange = 1;    // Led orange ein
          GPIO_U3_Led7_weiche2_blau = 0;      // Led blau aus
          Weiche4_stellen = 1; // abbiegen
          GPIO_U3_Led10_weiche4_orange = 1;      // Led orange ein
          GPIO_U3_Led11_weiche4_blau = 0;    // Led blau aus
        }
        // Wartezeit Weichenstellzeit abwarten
        // besetzt[] = x
        init92Time = currentTime;
      }

      if (GPIO_U3_Led14_Reed3 == 1 && block[2] == 4 && block[0] == 0 && Weiche1_motor_status == 0 && Weiche3_motor_status == 0) {
        block[1] = 99;  // Block Abstellgleis 1 präventiv sperren
        block[2] = 5;
        block[3] = 99;  // Block Abstellgleis 1 präventiv sperren

        // Wenn Weiche fertig gestellt ist, dann darf der Zug abfahren
        // Fahrspannung anfahren anderes Gleis
        Fahrspannung_anfahren(); // Ab Abstellgleis 1
        // vorherigen Block[] frei geben
        block[4] = 0;
      }


      // -------------------------------------------------------
      // Reed Sensor 4 - Rangierfahrt anhalten auf dem Abstellgleis 2
      if ((GPIO_U3_Led15_Reed4 == 1 && block[0] == 0) && (block[3] == 0 || block[3] == 98)) {      // Abstellgleis 2 (links)
        // Block 4 resp. [3] sperren
        if (block[3] == 0) {
          block[3] = 1;
        } else {
          block[3] = 97;
        }
        Fahrspannung_anhalten();
      }

      if ((GPIO_U3_Led15_Reed4 == 1 && fahrregler_PWM_auto <= 19 && block[0] == 0) && (block[3] == 1 || block[3] == 97)) {      // Abstellgleis 2 (links)
        // wenn der Zug angehalten hat, prüfen des Motorstatuses des Fahrreglers
        if (block[3] == 1) {
          block[3] = 2;
        } else {
          // Block[3] auf 96 stellen, nicht mehr weiterfahren
          block[3] = 96;
          fahrregler_PWM_auto = 0;
          fahrregler_auto_Status = 0; // Anhalten / Stop
          fahrregler_auto_Modus = 0;
        }
        Fahrregler_Stop();
      }

      if (GPIO_U3_Led15_Reed4 == 1 && block[3] == 2 && block[0] == 0 &&  fahrregler_auto_Status == 0 && fahrregler_auto_Modus == 0) {
        block[3] = 3;
        // Weiche stellen auf das Abstellgleis 2
        Weiche2_stellen = 2; // gerade aus
        GPIO_U3_Led6_weiche2_orange = 0;    // Led orange ein
        GPIO_U3_Led7_weiche2_blau = 1;      // Led blau aus
        Weiche4_stellen = 2; // gerade aus
        GPIO_U3_Led10_weiche4_orange = 1;      // Led blau ein
        GPIO_U3_Led11_weiche4_blau = 0;    // Led orange aus
        // Wartezeit Weichenstellzeit abwarten
        init93Time = currentTime;
      }

      if (GPIO_U3_Led15_Reed4 == 1 && block[3] == 4 && block[0] == 0 && Weiche1_motor_status == 0 && Weiche3_motor_status == 0) {
        block[1] = 99;  // Block Abstellgleis 1 präventiv sperren
        block[2] = 99;  // Block Abstellgleis 1 präventiv sperren
        block[3] = 5;
        // Wenn Weiche fertig gestellt ist, dann darf der Zug abfahren
        // Fahrspannung anfahren anderes Gleis
        Fahrspannung_anfahren(); // Ab Abstellgleis 1
        // vorherigen Block[] frei geben
        block[4] = 0;
      }
      // Ende automatisches fahren
    }



    // Funktionieren immer
    // Weichen Stelltaster an U4 Port B
    if (GPIO_U4_weiche1_L_taster_abgebogen_entprellt == 1) {
      GPIO_U3_Led4_weiche1_orange = 1;    // Led orange ein
      GPIO_U3_Led5_weiche1_blau = 0;      // Led blau aus
      Weiche1_stellen = 1; // Befehl für abbiegen
    }
    if (GPIO_U4_weiche1_L_taster_gerade_entprellt == 1) {
      GPIO_U3_Led5_weiche1_blau = 1;      // Led blau ein
      GPIO_U3_Led4_weiche1_orange = 0;    // Led orange aus
      Weiche1_stellen = 2; // Befehl für geadeaus
    }
    if ((GPIO_U4_weiche2_L_taster_abgebogen_entprellt == 1) && (GPIO_U1_Abstellgeleise == 0)) {
      GPIO_U3_Led6_weiche2_orange = 1;    // Led orange ein
      GPIO_U3_Led7_weiche2_blau = 0;      // Led blau aus
      Weiche2_stellen = 1; // Befehl für abbiegen
    }
    if ((GPIO_U4_weiche2_L_taster_gerade_entprellt == 1) && (GPIO_U1_Abstellgeleise == 0)) {
      GPIO_U3_Led7_weiche2_blau = 1;      // Led blau ein
      GPIO_U3_Led6_weiche2_orange = 0;    // Led orange aus
      Weiche2_stellen = 2; // Befehl für geadeaus
    }
    if (GPIO_U4_weiche3_R_taster_abgebogen_entprellt == 1) {
      GPIO_U3_Led8_weiche3_orange = 1;    // Led orange ein
      GPIO_U3_Led9_weiche3_blau = 0;      // Led blau aus
      Weiche3_stellen = 1; // Befehl für abbiegen
    }
    // Weichen Stelltaster an U4 Port A
    if (GPIO_U4_weiche3_R_taster_gerade_entprellt == 1) {
      GPIO_U3_Led9_weiche3_blau = 1;      // Led blau ein
      GPIO_U3_Led8_weiche3_orange = 0;    // Led orange aus
      Weiche3_stellen = 2; // Befehl für geadeaus
    }
    if ((GPIO_U4_weiche4_R_taster_abgebogen_entprellt == 1) && (GPIO_U1_Abstellgeleise == 0)) {
      GPIO_U3_Led10_weiche4_orange = 1;   // Led orange ein
      GPIO_U3_Led11_weiche4_blau = 0;     // Led blau aus
      Weiche4_stellen = 1; // Befehl für abbiegen
    }
    if ((GPIO_U4_weiche4_R_taster_gerade_entprellt == 1) && (GPIO_U1_Abstellgeleise == 0)) {
      GPIO_U3_Led11_weiche4_blau = 1;     // Led blau ein
      GPIO_U3_Led10_weiche4_orange = 0;   // Led orange aus
      Weiche4_stellen = 2; // Befehl für geadeaus
    }



    // Ausgabe Led bits in Byte zum übertragen an den MCP23017 Port A oder B
    // Bit zu Byte zusammen setzen
    bitWrite(GPIO_U3_PortB_raw, 0, GPIO_U3_Led1_run);              // Led grün
    bitWrite(GPIO_U3_PortB_raw, 1, GPIO_U3_Led2_stop);             // Led rot
    bitWrite(GPIO_U3_PortB_raw, 2, GPIO_U3_Led3_stopping);         // Led gelb
    bitWrite(GPIO_U3_PortB_raw, 3, GPIO_U3_Led4_weiche1_orange);   // Led orange, abgebogen
    bitWrite(GPIO_U3_PortB_raw, 4, GPIO_U3_Led5_weiche1_blau);     // Led blau, gerade aus
    bitWrite(GPIO_U3_PortB_raw, 5, GPIO_U3_Led6_weiche2_orange);   // Led orange, abgebogen
    bitWrite(GPIO_U3_PortB_raw, 6, GPIO_U3_Led7_weiche2_blau);     // Led blau, gerade aus
    bitWrite(GPIO_U3_PortB_raw, 7, GPIO_U3_Led8_weiche3_orange);   // Led orange, abgebogen
    // Byte übertragen auf I2C
    GPIO_Write_PortB(i2c_mcp3_adr, GPIO_U3_PortB_raw);
    // Bit zu Byte zusammen setzen
    bitWrite(GPIO_U3_PortA_raw, 2, GPIO_U3_Led9_weiche3_blau);      // Led blau, gerade aus   // Layout Korr
    bitWrite(GPIO_U3_PortA_raw, 1, GPIO_U3_Led10_weiche4_orange);   // Led orange, abgebogen
    bitWrite(GPIO_U3_PortA_raw, 0, GPIO_U3_Led11_weiche4_blau);     // Led blau, gerade aus   // Layout korr
    // Reed ausgeben auf Led 1..3
    bitWrite(GPIO_U3_PortA_raw, 3, GPIO_U3_Led12_Reed1);   // Led rot, Fahrt langsam beschleunigen
    bitWrite(GPIO_U3_PortA_raw, 4, GPIO_U3_Led13_Reed2);   // Led rot, Hauptgleis
    bitWrite(GPIO_U3_PortA_raw, 5, GPIO_U3_Led14_Reed3);   // Led rot, 1. Abstellgleis
    bitWrite(GPIO_U3_PortA_raw, 6, GPIO_U3_Led15_Reed4);   // Led rot, 2. Abstellgleis
    bitWrite(GPIO_U3_PortA_raw, 7, GPIO_U3_Led16_Reed5);   // Led rot, Fahrt verlangsamen
    // Byte übertragen auf I2C
    GPIO_Write_PortA(i2c_mcp3_adr, GPIO_U3_PortA_raw);
    // lesen der Werte U4 Port B
    GPIO_U4_PortB_raw = GPIO_Read_PortB(i2c_mcp4_adr);
    // Hinzufügen des Bit 7
    bitWrite(GPIO_U4_PortB_raw, 7, GPIO_U4_Led17_Reed6);   // Led rot, Haltestelle Bahnhof 1
    // Zurückschreiben der Bit Werte
    GPIO_Write_PortB(i2c_mcp4_adr, GPIO_U4_PortB_raw);
    // lesen der Werte U4 Port A
    GPIO_U4_PortA_raw = GPIO_Read_PortA(i2c_mcp4_adr);
    // Hinzufügen des Bit 7
    bitWrite(GPIO_U4_PortA_raw, 7, GPIO_U4_Led18_Reed7);   // Led rot, Haltestelle Bahnhof 2
    // Zurückschreiben der Bit Werte
    GPIO_Write_PortA(i2c_mcp4_adr, GPIO_U4_PortA_raw);

    //----------------------------------------------------------------------------------
    // Steuerung der Weichen
    // Abfrage der Weichen Informationen
    // WeicheX_motor_status = 0; // Weichen Motor Ein = 1, Aus = 0;
    // WeicheX_stellung = 0; // Weichen Motor Richtung garade = 0, abgebogen = 1;
    // WeicheX_stellen = 0;  // Taster für die Weichenstellung wurde gedrückt: 0 = nichts tun, 1 = abbiegen, 2 = gerade

    // Nichts tun, wenn der Motor schon WeicheX_motor_status = 1 ist
    // Nichts tun, wenn die WeicheX_stellung = 1 und  WeicheX_stellen = 1 (abbiegen) resp. WeicheX_stellung = 0 und  WeicheX_stellen = 2 (gerade ist)
    // WeicheX_motor_status = 1 (Ein) setzen

    if (Weiche1_motor_status == 0) {
      if ((Weiche1_stellen == 1) && (Weiche1_stellung == 0)) {  // Abbiegen: 1, 1 nur wenn Gerade aus
        Weiche_Abbiegen(1);
        Weiche1_motor_status = 1;  // Weichenmotor aktiv
        Weiche1_stellung = 1;      // abgebogen das nächste Mal
        Weiche1_stellen = 0;       // Stellbefehl zurücksetzen
      }
      if  ((Weiche1_stellen == 2) && (Weiche1_stellung == 1)) {  // gerade aus: 2, 0
        Weiche_Gerade(1);
        Weiche1_motor_status = 1;  // Weichenmotor aktiv
        Weiche1_stellung = 0;      // gerade aus beim nächsten Mal
        Weiche1_stellen = 0;       // Stellbefehl zurücksetzen
      }
      init5aTime = currentTime;  // Weichen Motorstellzeit läuft
    }
    if (Weiche2_motor_status == 0) {
      if ((Weiche2_stellen == 1) && (Weiche2_stellung == 0)) {
        Weiche_Abbiegen(2);
        Weiche2_motor_status = 1;  // Weichenmotor aktiv
        Weiche2_stellung = 1;      // Abgebogen
        Weiche2_stellen = 0;       // Stellbefehl zurücksetzen
      }
      if  ((Weiche2_stellen == 2) && (Weiche2_stellung == 1)) {
        Weiche_Gerade(2);
        Weiche2_motor_status = 1;  // Weichenmotor aktiv
        Weiche2_stellung = 0;      // Gerade aus
        Weiche2_stellen = 0;       // Stellbefehl zurücksetzen
      }
      init5bTime = currentTime;  // Weichen Motorstellzeit läuft
    }
    if (Weiche3_motor_status == 0) {                            // Erst stellen wenn Motor nicht schon aktiv ist
      if (GPIO_U4_weiche3_R_taster_gerade_entprellt == 1 || GPIO_U4_weiche3_R_taster_abgebogen_entprellt == 1) {
        // Serial.println("-----------------------------------------------------");
      }
      if ((Weiche3_stellen == 1) && (Weiche3_stellung == 0)) {  // Erst stellen wenn gerade und abbiegen ist gewählt, sonst lassen
        Weiche_Abbiegen(3);
        Weiche3_motor_status = 1;  // Weichenmotor aktiv
        Weiche3_stellung = 1;      // Abgebogen
        Weiche3_stellen = 0;       // Stellbefehl zurücksetzen
        // Serial.println("Weiche 3, abgebogen 1");
      }
      if  ((Weiche3_stellen == 2) && (Weiche3_stellung == 1)) {  // Gerade wenn abgebogen ist
        Weiche_Gerade(3);
        Weiche3_motor_status = 1;  // Weichenmotor aktiv
        Weiche3_stellung = 0;      // Gerade aus -> Status
        Weiche3_stellen = 0;       // Stellbefehl zurücksetzen
        // Serial.println("Weiche 3, gerade 1");
      }
      init5cTime = currentTime;  // Weichen Motorstellzeit läuft
    }
    if (Weiche4_motor_status == 0) {
      if ((Weiche4_stellen == 1) && (Weiche4_stellung == 0)) {
        Weiche_Abbiegen(4);
        Weiche4_motor_status = 1;  // Weichenmotor aktiv
        Weiche4_stellung = 1;      // Abgebogen
        Weiche4_stellen = 0;       // Stellbefehl zurücksetzen
      }
      if  ((Weiche4_stellen == 2) && (Weiche4_stellung == 1)) {
        Weiche_Gerade(4);
        Weiche4_motor_status = 1;  // Weichenmotor aktiv
        Weiche4_stellung = 0;      // Gerade aus
        Weiche4_stellen = 0;       // Stellbefehl zurücksetzen
      }
      init5dTime = currentTime;  // Weichen Motorstellzeit läuft
    }

    init3Time = currentTime;
  }


  // ------------------------------------------------------------------------------
  // Zurücksetzen der Merker nur Debug
  // ------------------------------------------------------------------------------
  if (currentTime - init4Time >= periode1_Merker)//test whether the period has elapsed
  {
    /*
      merker1 = 0;
      merker2 = 0;
      merker3 = 0;
      Serial.print(" - Reset: ");
      Serial.println(block3);
    */
    // LCD für Debug
    // lcd.clear();
    // delay(5);
    // lcd.home();
    // debug Anzeige der Reed Sensoren auf dem Display
    /*
      lcd.setCursor(0, 2);
      char str10 = reed_sensor_entprellt[0];
      lcd.print(str10, DEC);
      lcd.setCursor(2, 2);
      char str11 = reed_sensor_entprellt[1];
      lcd.print(str11, DEC);
      lcd.setCursor(4, 2);
      char str12 = reed_sensor_entprellt[2];
      lcd.print(str12, DEC);
      lcd.setCursor(6, 2);
      char str13 = reed_sensor_entprellt[3];
      lcd.print(str13, DEC);
      lcd.setCursor(8, 2);
      char str14 = reed_sensor_entprellt[4];
      lcd.print(str14, DEC);
      lcd.setCursor(10, 2);
      char str15 = reed_sensor_entprellt[5];
      lcd.print(str15, DEC);
      lcd.setCursor(12, 2);
      char str16 = reed_sensor_entprellt[6];
      lcd.print(str16, DEC);
      lcd.setCursor(14, 2);
      char str17 = reed_sensor_entprellt[7];
      lcd.print(str17, DEC);
      // lcd.setCursor(16, 2);
      // char str18 = reed_sensor_entprellt[i];
      // lcd.print(str18, DEC);
    */

    // Poti
    lcd.setCursor(0, 2);
    // char str2 = 'Poti:';
    lcd.print("P:");
    lcd.setCursor(2, 2);
    float str6 = (float(map(analog_poti_Fahrspannung, 1023, 0, 0, 1023)) * 9.0 / 1023);
    lcd.print(str6 , 1);
    lcd.setCursor(5, 2);
    lcd.print("V T:");
    float str5 = ( float(map(analog_trimmer_Fahrspannung, 1023, 0, 0, 1023) * 9.0 / 1023));
    lcd.setCursor(9, 2);
    lcd.print(str5, 1);
    lcd.setCursor(12, 2);
    lcd.print("V A:");
    // Trimmer
    lcd.setCursor(16, 2);
    // float str4 = float(map(fahrregler_PWM_auto, 1023, 0, 1023, 0) * 9.0 / 1023);  // 0 bis 9V
    // float str4 = float(fahrregler_PWM_auto * 1.0);  // 0 bis 255
    float str4 = float(map(fahrregler_PWM_auto, 255, 0, 255, 0) * 9.0 / 255);  // 0 bis 9V
    lcd.print(str4, 1);
    lcd.setCursor(19, 2);
    lcd.print("V");
    // Serial.println(GPIO_U4_PortB_raw, BIN);
    // Serial.println(GPIO_U4_PortA_raw, BIN);
    // manuelle Fahrt

    lcd.setCursor(0, 3);
    if ((fahrtrichtung_vorwaerts_entprellt == 1) && (auto_manuell_entprellt == 1)) {
      lcd.print("Manuell Vorw");
      lcd.print('\xE1');
      lcd.print("rts.  ");
      // Quelle, Sonderzeichen: https://forum.arduino.cc/t/lcd-ausgabe-von-umlauten/140471/5
    }
    if ((fahrtrichtung_rueckwaerts_entprellt == 1) && (auto_manuell_entprellt == 1)) {
      lcd.print("Manuel R");
      lcd.print('\xF5');  // ü auf UTF 8 umgewandelt
      lcd.print("ckw");
      lcd.print('\xE1');  // ä auf UTF 8 umgewandelt
      lcd.print("rts.  ");
      // Quelle, Sonderzeichen: https://forum.arduino.cc/t/lcd-ausgabe-von-umlauten/140471/5
    }
    // automatische Fahrt
    if (((fahrregler_auto_Status == 1) || (fahrregler_auto_Status == 2)) && (auto_automatisch_entprellt == 1)) {
      lcd.print("Automatisches fahren");
    }
    init4Time = currentTime;
  }

  // ------------------------------------------------------------------------------
  // Weichenmotoren 1 - 4 Timer Aus nach Ablauf der Stellzeit (rechts)
  // ------------------------------------------------------------------------------
  if ((currentTime - init5aTime >= max_weichen_stell_zeit_rechts) && (Weiche1_motor_status == 1))   //test whether the period has elapsed
  {
    // Weichenmotor nach der max_Weichenmotor Zeit ausschalten
    // Abfragen der Variablen betr. Ein,  aus -> vergleichen der variablen
    // Ausschalten des Weichenmotors
    // Setzen der Variablem Motor Status = 1
    Weiche_Stop(1);
    Weiche1_motor_status = 0;  // Zurücksetzen des Motor Status
    Weiche1_stellen = 0;       // Weiche Stellbefehl zurücksetzen da die Weiche je erst gestellt wurde -> Optional
    // Weiche1_stellung = 0;    // Status nicht verstellen
    init5aTime = currentTime;
  }

  if ((currentTime - init5bTime >= max_weichen_stell_zeit_rechts) && (Weiche2_motor_status == 1))   //test whether the period has elapsed
  {
    Weiche_Stop(2);
    Weiche2_motor_status = 0;  // Zurücksetzen des Motor Status
    Weiche2_stellen = 0;       // Weiche Stellbefehl zurücksetzen da die Weiche je erst gestellt wurde -> Optional
    init5bTime = currentTime;
  }

  if ((currentTime - init5cTime >= max_weichen_stell_zeit_rechts) && (Weiche3_motor_status == 1))   //test whether the period has elapsed
  {
    Weiche_Stop(3);
    Weiche3_motor_status = 0;  // Zurücksetzen des Motor Status
    Weiche3_stellen = 0;       // Weiche Stellbefehl zurücksetzen da die Weiche je erst gestellt wurde -> Optional
    // Serial.println("Weiche 3, timer funktion stop");
    init5cTime = currentTime;
  }

  if ((currentTime - init5dTime >= max_weichen_stell_zeit_rechts) && (Weiche4_motor_status == 1))   //test whether the period has elapsed
  {
    Weiche_Stop(4);
    Weiche4_motor_status = 0;  // Zurücksetzen des Motor Status
    Weiche4_stellen = 0;       // Weiche Stellbefehl zurücksetzen da die Weiche je erst gestellt wurde -> Optional
    init5aTime = currentTime;
  }


  // ------------------------------------------------------------------------------
  // Fahrmodus Automatisch Zähler vor- / rückwärts Timer Ein / Aus
  // ------------------------------------------------------------------------------
  if ((currentTime - init6aTime >= Fahrregler_Anfahrzeit) && auto_manuell_entprellt == 0)   //Anfahren, schneller
  {
    // ---------------------------------------------
    if (fahrregler_PWM_auto > analog_trimmer_Fahrspannung_mapped) {
      fahrregler_PWM_auto = analog_trimmer_Fahrspannung_mapped; // maximal mit der Trimmerspannung fahren
    }
    // ---------------------------------------------
    // beschleunigen der Fahrgeschwindigkeit min/0 auf max_Rangiergeschwindigleit
    if ((fahrregler_auto_Status == 2) && (fahrregler_auto_Modus == 1)) {
      // beschleunigen von minimum bis Rangierfahrts Geschwindigkeit
      if (fahrregler_PWM_auto <= Fahrregler_PWM_Rangiergeschwindigkeit) {
        fahrregler_PWM_auto = fahrregler_PWM_auto + Fahrregler_PWM_Schritte;  // Nur hoch zählen, wenn kleiner als Rangiergeschwindigkeit
        // oben -> fahrregler_PWM_auto = Fahrregler_PWM_Anfangs_Anfahrwert;  // Aktuelle Fahrspannung im Automodus
        if (fahrregler_PWM_auto > Fahrregler_PWM_Rangiergeschwindigkeit) {
          fahrregler_PWM_auto = Fahrregler_PWM_Rangiergeschwindigkeit; // maximal mit der Rangiergeschwindigkeit fahren
        }
        Fahrspannung_Vorwaerts(fahrregler_PWM_auto);
      }
    }
    // ---------------------------------------------
    // beschleunigen von der Rangierfahrt bis zur max_fahrgeschwindigkeit analog_trimmer_Fahrspannung_mapped
    if ((fahrregler_auto_Status == 2) && (fahrregler_auto_Modus == 2)) {
      // beschleunigen von der Rangierfahrt bis zur max_fahrgeschwindigkeit analog_trimmer_Fahrspannung_mapped
      if (fahrregler_PWM_auto <= analog_trimmer_Fahrspannung_mapped) {
        fahrregler_PWM_auto = fahrregler_PWM_auto + Fahrregler_PWM_Schritte;  // Nur hoch zählen, wenn kleiner als max Geschwindigkeit analog_trimmer_Fahrspannung_mapped
        // oben -> fahrregler_PWM_auto = Fahrregler_PWM_Anfangs_Anfahrwert;   // Aktuelle Fahrspannung im Automodus
        if (fahrregler_PWM_auto > analog_trimmer_Fahrspannung_mapped) {
          fahrregler_PWM_auto = analog_trimmer_Fahrspannung_mapped; // maximal mit der Trimmer Spannung fahren
        }
        Fahrspannung_Vorwaerts(fahrregler_PWM_auto);
      }
    }

    init6aTime = currentTime;
  }


  if ((currentTime - init6bTime >= Fahrregler_Anhalten) && auto_manuell_entprellt == 0)   // langsamer, anhalten, Stop
  {
    // ---------------------------------------------
    if (fahrregler_PWM_auto > analog_trimmer_Fahrspannung_mapped) {
      fahrregler_PWM_auto = analog_trimmer_Fahrspannung_mapped; // maximal mit der Trimmerspannung fahren
    }
    // verlangsamen der Fahrgeschwindigkeit auf max_Rangiergeschwindigleit (Trimmer) analog_trimmer_Fahrspannung_mapped
    if ((fahrregler_auto_Status == 1) && (fahrregler_auto_Modus == 3)) {
      // verlangsamen von max_fahrgeschwindigkeit analog_trimmer_Fahrspannung_mapped bis zur Rangiergeschwindigkeit
      if (fahrregler_PWM_auto >= Fahrregler_PWM_Rangiergeschwindigkeit) {
        fahrregler_PWM_auto = fahrregler_PWM_auto - Fahrregler_PWM_Schritte;  // Nur runter zählen, wenn kleiner als max Geschwindigkeit analog_trimmer_Fahrspannung_mapped
        // oben -> fahrregler_PWM_auto = analog_trimmer_Fahrspannung_mapped;   // Aktuelle Fahrspannung im Automodus
        Fahrspannung_Vorwaerts(fahrregler_PWM_auto);  // Er fährt mit der Rangiergeschwindigkeit
        // Keine Statusänderung
      }
    }
    // ---------------------------------------------
    // verlangsamen von Rangierfahrts Geschwindigkeit auf 0
    if ((fahrregler_auto_Status == 1) && (fahrregler_auto_Modus == 4)) {
      // verlangsamen von Rangierfahrts Geschwindigkeit auf 0
      if (fahrregler_PWM_auto > Fahrregler_PWM_Rangiergeschwindigkeit) {
        fahrregler_PWM_auto = Fahrregler_PWM_Rangiergeschwindigkeit; // maximal mit der Rangiergeschwindigkeit fahren
      }
      if (fahrregler_PWM_auto >= 0) {
        fahrregler_PWM_auto = fahrregler_PWM_auto - Fahrregler_PWM_Schritte;  // Nur runter zählen, wenn kleiner als Rangiergeschwindigkeit
        // oben -> fahrregler_PWM_auto = Fahrregler_PWM_Anfangs_Anfahrwert;  // Aktuelle Fahrspannung im Automodus
        if (fahrregler_PWM_auto <= 50) { // Anhalten wenn Wert kleiner als 50 ist
          fahrregler_auto_Status = 0; // Anhalten / Stop
          fahrregler_auto_Modus = 0;  // Anhalten / Stop
          fahrregler_PWM_auto = 0;  // Fahrgeschwindigkeit auf 0
        }
        Fahrspannung_Vorwaerts(fahrregler_PWM_auto);
      }
    }
    // ---------------------------------------------
    // Anhalten, stoppen
    if ((fahrregler_auto_Status == 0) && (fahrregler_auto_Modus == 0)) {
      fahrregler_PWM_auto = 0;
      Fahrregler_Stop();
    }
    init6bTime = currentTime;
  }

  // -------------------------------------------------------------------------------------------------
  // Bahnhof 1 Wartezeit
  if ((currentTime - init7Time >= max_Bahnhof1_Wartezeit) && bahnhof1_stop == 1 && block[5] == 1)   //test whether the period has elapsed
  {
    // Wartezeit beenden
    bahnhof1_stop = 2;
    block[5] = 2;  // Block für Weiterfahrt freigeben
    // Anfangsfahrgeschwindigkeit
    // fahrregler_PWM_auto = Fahrregler_PWM_Anfangs_Anfahrwert;
    init7Time = currentTime;
  }


  // -------------------------------------------------------------------------------------------------
  // Bahnhof 2 Wartezeit
  if ((currentTime - init8Time >= max_Bahnhof2_Wartezeit) && (bahnhof2_stop == 1))   //test whether the period has elapsed
  {
    // Wartezeit beenden
    bahnhof2_stop = 2;
    block[6] = 2;  // Block für Weiterfahrt freigeben
    // Anfangsfahrgeschwindigkeit
    // fahrregler_PWM_auto = Fahrregler_PWM_Anfangs_Anfahrwert;
    init8Time = currentTime;
  }


  // Weichenmotoren 1 - 4 Timer Stell-Wartezeit bis Lok wieder anfahren darf
  // nach Ablauf der Stellzeit darf die Lok anfahren
  // Hauptgleis
  // ------------------------------------------------------------------------------
  if ((currentTime - init91Time >= max_Weichen_Anfahrwartezeit) && (block[1] == 3))   //test whether the period has elapsed
  {
    block[1] = 4;  // Block sperren
    // Nach Ablauf der Weichenstellwartezeit, die Abfolge weiterführen
    // Serial.println("Weiche 3, timer 91");
    init91Time = currentTime;
  }

  // Abtellgleis 1
  if ((currentTime - init92Time >= max_Weichen_Anfahrwartezeit) && (block[2] == 3))   //test whether the period has elapsed
  {
    block[2] = 4;  // Block sperren
    // Nach Ablauf der Weichenstellwartezeit, die Abfolge weiterführen
    init92Time = currentTime;
  }

  // Abtellgleis 2
  if ((currentTime - init93Time >= max_Weichen_Anfahrwartezeit) && (block[3] == 3))   //test whether the period has elapsed
  {
    block[3] = 4;  // Block sperren
    // Nach Ablauf der Weichenstellwartezeit, die Abfolge weiterführen
    init93Time = currentTime;
  }

}  // Ende Loop




// ==================================================================================================================
// Funktionen
// ----------------------------------------------------------------------------------------------------------------------


// Fahrregler Funktionen

// H-Bridge Funktionen Fahrspannungen
// Stop
void Fahrregler_Stop() {
  // Stoppen der Fahrspannung
  analogWrite(fahrspannung1_BTS_L_PWM_Pin, 0);     // Wert 0 schreiben für stoppen, BTS7960 L_PWM, Turn left, PWM Speed
  analogWrite(fahrspannung1_BTS_R_PWM_Pin, 0);     // Wert 0 schreiben für stoppen, BTS7960 R_PWM, Turn right, PWM Speed
  // Stoppen beider Enable Pin's
  digitalWrite(fahrspannung1_BTS_L_EN_Pin, 0);     // BTS7960 L_EN, left 0 = Disable, 1 = Enable -> beide EN miteinander 0 oder 1 schalten
  digitalWrite(fahrspannung1_BTS_R_EN_Pin, 0);     // BTS7960 R_EN, right 0 = Disable, 1 = Enable -> beide EN miteinander 0 oder 1 schalten
}


//----------------------------------------------------------------------------------
// Fahrregler Funktionen manuelles fahren vorwärts (R) / Rückwärts (L)
// Fahrregler Poti Einlesen mit der millis() Funktion (oben)

void Fahrspannung_Vorwaerts(unsigned int Speed) {
  // Ausgabe der eingelesenen und mit Mittelwert behandelten Poti Werte auf die H-Brücke BTS7960
  digitalWrite(fahrspannung1_BTS_L_EN_Pin, 1);     // BTS7960 L_EN, left 0 = Disable, 1 = Enable -> beide EN miteinander 0 oder 1 schalten
  digitalWrite(fahrspannung1_BTS_R_EN_Pin, 1);     // BTS7960 R_EN, right 0 = Disable, 1 = Enable -> beide EN miteinander 0 oder 1 schalten
  if (GPIO_U1_Fahrspannung_Reverse == 0) {         // Per Jumper J11 / 3 Wechsekl der Drehrichtung
    analogWrite(fahrspannung1_BTS_R_PWM_Pin , Speed);     // BTS7960 R_PWM, Turn right, PWM Speed,
  } else {
    analogWrite(fahrspannung1_BTS_L_PWM_Pin , Speed);     // BTS7960 L_PWM, Turn left, PWM Speed,
  }
}


void Fahrspannung_Rueckwaerts(unsigned int Speed) {
  // Ausgabe der eingelesenen und mit Mittelwert behandelten Poti Werte auf die H-Brücke BTS7960
  digitalWrite(fahrspannung1_BTS_R_EN_Pin, 1);     // BTS7960 L_EN, left 0 = Disable, 1 = Enable -> beide EN miteinander 0 oder 1 schalten
  digitalWrite(fahrspannung1_BTS_L_EN_Pin, 1);     // BTS7960 R_EN, right 0 = Disable, 1 = Enable -> beide EN miteinander 0 oder 1 schalten
  if (GPIO_U1_Fahrspannung_Reverse == 0) {         // Per Jumper J11 / 3 Wechsekl der Drehrichtung
    analogWrite(fahrspannung1_BTS_L_PWM_Pin , Speed);     // BTS7960 L_PWM, Turn left, PWM Speed,
  } else {
    analogWrite(fahrspannung1_BTS_R_PWM_Pin , Speed);     // BTS7960 R_PWM, Turn right, PWM Speed,
  }
}


// --------------------------------------------------------------------- zzzz
// Fahrregler Funktionen automatisches fahren
// Beschläunigen vom Minimum in Schritten bis zur Rangiergeschwindigkeit
void Fahrspannung_anfahren()  // anfahren bis Rangierfahrt Geschwindigkeit
{
  // Alles mal Aus -> Zum Starten
  fahrregler_auto_Status = 0;  // Stop
  fahrregler_auto_Modus = 0;   // Angehalten
  fahrregler_PWM_auto = Fahrregler_PWM_Anfangs_Anfahrwert; // Startwert vorgeben
  fahrregler_auto_Status = 2;  // Beschleunigen
  fahrregler_auto_Modus = 1;   // Bis Rangierfahrtsgeschwindigkeit
  // Fahrspannungsfunktion in Rampen-/Zählfunktion
}

// Beschleunigen von der Rangiergeschwindigkeit zur max. Geschwindigkeit die im Trimmer eingestellt wird.
void Fahrspannung_schneller()  // beschläunigen bis Trimmereinstellung max Fahrt
{
  // Fahrspannung_Vorwaerts(unsigned int Speed)
  fahrregler_PWM_auto = Fahrregler_PWM_Rangiergeschwindigkeit; // ev. nicht nötig wenn Anfahrt schon auf Rangiergeschwindigkeit ist
  fahrregler_auto_Status = 2;  // Beschleunigen
  fahrregler_auto_Modus = 2;   // Rangierfahrtsgeschwindigkeit bis max trimmer
  // Fahrspannungsfunktion in Rampen-/Zählfunktion
}

// Verlangsamen von der eingestellten trimmer Geschwindigkeit auf Rangiergeschweindigkeit
void Fahrspannung_langsamer() // Fahrt verlangsamen auf Rangiefahrt Geschwindigkeit
{
  // Fahrspannung_Vorwaerts(unsigned int Speed)
  // fahrregler_PWM_auto = analog_trimmer_Fahrspannung_mapped; // ev. nicht nötig wenn Fahrt schon auf analog_trimmer_Fahrspannung_mapped ist
  fahrregler_auto_Status = 1;  // Verlangsamen
  fahrregler_auto_Modus = 3;   // analog_trimmer_Fahrspannung_mapped bis Rangierfahrtsgeschwindigkeit verlangsamen
  // Fahrspannungsfunktion in Rampen-/Zählfunktion
}

// verlangsamen von der Rangiergeschwindigkeit in Schritten bis 0 (nicht minimum)
void Fahrspannung_anhalten()  // anhalten von Rangierfahrt Geschwindigkeit
{
  // Fahrspannung_Vorwaerts(unsigned int Speed)
  // fahrregler_PWM_auto = analog_trimmer_Fahrspannung_mapped; // ev. nicht nötig wenn Fahrt schon auf analog_trimmer_Fahrspannung_mapped ist
  fahrregler_auto_Status = 1;  // Verlangsamen
  fahrregler_auto_Modus = 4;   // Rangierfahrtsgeschwindigkeit Bis anhalten
  // Fahrspannungsfunktion in Rampen-/Zählfunktion
  // fahrregler_auto_Status = 0; // in Zähl-/Rampenfunktion
  // fahrregler_auto_Modus = 0;  // in Zähl-/Rampenfunktion

}






//=============================================================
// H- Bridge Weichen Funktione
// Stop Weiche nr n= 1..4
void Weiche_Stop(byte nr) {
  switch (nr) {
    case 1:
      { // Weiche 1
        digitalWrite(Weiche1_ENA_Pin, LOW);  // Alles auf 0 setzen
        digitalWrite(Weiche1_IN1_Pin, LOW);
        digitalWrite(Weiche1_IN2_Pin, LOW);
      }
    case 2:
      { // Weiche 4
        digitalWrite(Weiche2_ENB_Pin, LOW);  // Alles auf 0 setzen
        digitalWrite(Weiche2_IN3_Pin, LOW);
        digitalWrite(Weiche2_IN4_Pin, LOW);
      }
    case 3:
      { // Weiche 4
        digitalWrite(Weiche3_ENA_Pin, LOW);  // Alles auf 0 setzen
        digitalWrite(Weiche3_IN1_Pin, LOW);
        digitalWrite(Weiche3_IN2_Pin, LOW);
      }
    case 4:
      { // Weiche 4
        digitalWrite(Weiche4_ENB_Pin, LOW);  // Alles auf 0 setzen
        digitalWrite(Weiche4_IN3_Pin, LOW);
        digitalWrite(Weiche4_IN4_Pin, LOW);
      }
  }
}

// -------------------------------------------------------------------
// Weiche Gerade Aus
void Weiche_Gerade(byte nr) {
  // Weiche_Stop(nr);
  switch (nr) {
    case 1:
      {
        // 180° montiertre gegen-Weiche
        if (GPIO_U1_Weiche1_Reverse == 0) {  // Abfrage des Jumpers auf der Pfostenleiste J11 Inp03
          digitalWrite(Weiche1_IN1_Pin, HIGH);
          digitalWrite(Weiche1_IN2_Pin, LOW);
        } else {
          digitalWrite(Weiche1_IN1_Pin, LOW);
          digitalWrite(Weiche1_IN2_Pin, HIGH);
        }
        analogWrite(Weiche1_ENA_Pin, max_weichen_stellspannung);
        // Weichenstellung in Fram speichern; 0 = Nix, 1 = abgebogen, 2 = gerade aus
        weichen_pos[0x00] = 2;
        fram.write(0x00, weichen_pos[0x00]); // 2 für Gerade aus, Weiche 1
        break;
      }
    case 2:
      {
        // 180° montiertre gegen-Weiche
        if (GPIO_U1_Weiche2_Reverse == 0) {  // Abfrage des Jumpers auf der Pfostenleiste J11 Inp04
          digitalWrite(Weiche2_IN3_Pin, HIGH);
          digitalWrite(Weiche2_IN4_Pin, LOW);
        } else {
          digitalWrite(Weiche2_IN3_Pin, LOW);
          digitalWrite(Weiche2_IN4_Pin, HIGH);
        }
        analogWrite(Weiche2_ENB_Pin, max_weichen_stellspannung);
        // Weichenstellung in Fram speichern; 0 = Nix, 1 = abgebogen, 2 = gerade aus
        weichen_pos[0x01] = 2;
        fram.write(0x01, weichen_pos[0x01]);        // 2 für Gerade aus , Weiche 2
        break;
      }
    case 3:
      {
        // 180° montiertre gegen-Weiche
        if (GPIO_U1_Weiche3_Reverse == 0) {  // Abfrage des Jumpers auf der Pfostenleiste J11 Inp05
          digitalWrite(Weiche3_IN1_Pin, HIGH);
          digitalWrite(Weiche3_IN2_Pin, LOW);
        } else {
          digitalWrite(Weiche3_IN1_Pin, LOW);
          digitalWrite(Weiche3_IN2_Pin, HIGH);
        }
        analogWrite(Weiche3_ENA_Pin, max_weichen_stellspannung);
        // Weichenstellung in Fram speichern; 0 = Nix, 1 = abgebogen, 2 = gerade aus
        weichen_pos[0x02] = 2;
        fram.write(0x02, weichen_pos[0x02]); // 2 für Gerade aus, Weiche 3
        // delay(10);
        // Serial.print("Weiche Gerade - GPIO_U1_Weiche3_Reverse: ");
        // Serial.println(GPIO_U1_Weiche3_Reverse);

        break;
      }
    case 4:
      {
        // 180° montiertre gegen-Weiche
        if (GPIO_U1_Weiche4_Reverse == 0) {  // Abfrage des Jumpers auf der Pfostenleiste J11 Inp06
          digitalWrite(Weiche4_IN3_Pin, HIGH);
          digitalWrite(Weiche4_IN4_Pin, LOW);
        } else {
          digitalWrite(Weiche4_IN3_Pin, LOW);
          digitalWrite(Weiche4_IN4_Pin, HIGH);
        }
        analogWrite(Weiche4_ENB_Pin, max_weichen_stellspannung);
        // Weichenstellung in Fram speichern; 0 = Nix, 1 = abgebogen, 2 = gerade aus
        weichen_pos[0x03] = 2;
        fram.write(0x03, weichen_pos[0x03]); // 2 für Gerade aus, Weiche 4
        break;
      }
    default:
      // nix
      break;
  }
}


// -----------------------------------------------------------------
// Weiche abgebogen
void Weiche_Abbiegen(byte nr) {
  // Weiche_Stop(nr);
  switch (nr) {
    case 1:
      {
        // 180° montiertre gegen-Weiche
        if (GPIO_U1_Weiche1_Reverse == 0) {
          digitalWrite(Weiche1_IN1_Pin, LOW);
          digitalWrite(Weiche1_IN2_Pin, HIGH);
        } else {
          digitalWrite(Weiche1_IN1_Pin, HIGH);
          digitalWrite(Weiche1_IN2_Pin, LOW);
        }
        analogWrite(Weiche1_ENA_Pin, max_weichen_stellspannung);
        // Weichenstellung in Fram speichern; 0 = Nix, 1 = abgebogen, 2 = gerade aus
        weichen_pos[0x00] = 1;
        fram.write(0x00, weichen_pos[0x00]); // 1 für Abgebogen, Weiche 1

        break;
      }
    case 2:
      {
        // 180° montiertre gegen-Weiche
        if (GPIO_U1_Weiche2_Reverse == 0) {
          digitalWrite(Weiche2_IN3_Pin, LOW);
          digitalWrite(Weiche2_IN4_Pin, HIGH);
        } else {
          digitalWrite(Weiche2_IN3_Pin, HIGH);
          digitalWrite(Weiche2_IN4_Pin, LOW);
        }
        analogWrite(Weiche2_ENB_Pin, max_weichen_stellspannung);
        // Weichenstellung in Fram speichern; 0 = Nix, 1 = abgebogen, 2 = gerade aus
        weichen_pos[0x01] = 1;
        fram.write(0x01, weichen_pos[0x01]); // 1 für Abgebogen, Weiche 2

        break;
      }
    case 3:
      {
        // 180° montiertre gegen-Weiche
        if (GPIO_U1_Weiche3_Reverse == 0) {
          digitalWrite(Weiche3_IN1_Pin, LOW);
          digitalWrite(Weiche3_IN2_Pin, HIGH);
        } else {
          digitalWrite(Weiche3_IN1_Pin, HIGH);
          digitalWrite(Weiche3_IN2_Pin, LOW);
        }
        analogWrite(Weiche3_ENA_Pin, max_weichen_stellspannung);
        // Weichenstellung in Fram speichern; 0 = Nix, 1 = abgebogen, 2 = gerade aus
        weichen_pos[0x02] = 1;
        fram.write(0x02, weichen_pos[0x02]); // 1 für Abgebogen, Weiche 3
        // delay(10);
        // Serial.print("Weiche Abgebogen - GPIO_U1_Weiche3_Reverse:  ");
        Serial.println(GPIO_U1_Weiche3_Reverse);
        break;
      }
    case 4:
      {
        // 180° montiertre gegen-Weiche
        if (GPIO_U1_Weiche4_Reverse == 0) {
          digitalWrite(Weiche4_IN3_Pin, LOW);
          digitalWrite(Weiche4_IN4_Pin, HIGH);
        } else {
          digitalWrite(Weiche4_IN3_Pin, HIGH);
          digitalWrite(Weiche4_IN4_Pin, LOW);
        }
        analogWrite(Weiche4_ENB_Pin, max_weichen_stellspannung);
        // Weichenstellung in Fram speichern; 0 = Nix, 1 = abgebogen, 2 = gerade aus
        weichen_pos[0x03] = 1;
        fram.write(0x03, weichen_pos[0x03]); // 1 für Abgebogen, Weiche 4
        break;
      }
    default:
      // nix
      break;
  }
}



// ----------------------------------------------------------------------
// Weichenmotor ein / aus
// Muss Zeitgesteuiert mit milis() gestartet und gestoppt werden
// void Weichen_Motor_ein(byte nr, unsigned int Weichen_Speed) {
// analogWrite(Weichen_Pin[nr][0], map(Weichen_Speed, 0, 1023, 0, 255);
// }


// ======================================================================
// GPO Funktionen
// Konfigurieren des GPIO zum Output Port

void GPIO_Set_PortA_Output(byte i2c_adr) {
  Wire.beginTransmission(i2c_adr);
  Wire.write(IODIRA);      // IODIRA register
  Wire.write(GPIO_OUTPUT); // set all of port A to outputs
  Wire.endTransmission();
  delay(20);
}

void GPIO_Set_PortB_Output(byte i2c_adr) {
  Wire.beginTransmission(i2c_adr);
  Wire.write(IODIRB);      // IODIRB register
  Wire.write(GPIO_OUTPUT); // set all of port A to outputs
  Wire.endTransmission();
  delay(20);
}

// Konfigurieren des GPIO zum Input Port
void GPIO_Set_PortA_Input(byte i2c_adr) {
  Wire.beginTransmission(i2c_adr);
  Wire.write(IODIRA); // IODIRA register
  Wire.write(GPIO_INPUT); // set all of port A to inputs, excl. GPA7 = Output
  // Wire.write(0xff);
  Wire.endTransmission();
  delay(20);
}

void GPIO_Set_PortB_Input(byte i2c_adr) {
  Wire.beginTransmission(i2c_adr);
  Wire.write(IODIRB); // IODIRB register
  Wire.write(GPIO_INPUT); // set all of port A to inputs, excl. GPB7 = Output
  // Wire.write(0xff);
  Wire.endTransmission();
  delay(20);
}

// Label zzz
// Empfangen eines Bytes zum GPIO
byte GPIO_Read_PortA(byte i2c_adr) {
  Wire.beginTransmission(i2c_adr);
  Wire.write(GPIOA);  // read the inputs off PORT A
  Wire.endTransmission();
  Wire.requestFrom(i2c_adr, 1); // ask for 1 byte
  return Wire.read(); // read it
}

byte GPIO_Read_PortB(byte i2c_adr) {
  Wire.beginTransmission(i2c_adr);
  Wire.write(GPIOB);  // read the inputs off PORT B
  Wire.endTransmission();
  Wire.requestFrom(i2c_adr, 1); // ask for 1 byte
  return Wire.read(); // read it
}

// Senden eines Bytes zum GPIO
void GPIO_Write_PortA(byte i2c_adr, byte GPIO_Wert) {
  Wire.beginTransmission(i2c_adr);
  Wire.write(GPIOA);  // chose PORT A
  Wire.write(GPIO_Wert); // write one byte to PORT A
  Wire.endTransmission();
}

void GPIO_Write_PortB(byte i2c_adr, byte GPIO_Wert) {
  Wire.beginTransmission(i2c_adr);
  Wire.write(GPIOB);  // chose PORT B
  Wire.write(GPIO_Wert); // write one byte to PORT B
  Wire.endTransmission();
}

void I2CScan() {
  Serial.println("I2C Scan Start");
  boolean i2cfound = false;
  for (byte scanAdr = i2cStartAdresse; scanAdr <= i2cEndAdresse; scanAdr++) {
    Wire.beginTransmission(scanAdr);
    i2cTransmissionResultat =  Wire.endTransmission();
    if (i2cTransmissionResultat == 0) {
      i2cfound = true;
      Serial.println("--------------------------");
      String msg = "I2C gefunden an der Adresse 0x";
      if (scanAdr < 16) msg += "0";
      Serial.print(msg);
      Serial.println(scanAdr, HEX);
    } else {
      if (i2cfound == true) {
        Serial.println("--------------------------");
      }
      i2cfound = false;
      String msg = "kein I2C gefunden an der Adresse 0x";
      if (scanAdr < 16) msg += "0";
      Serial.print(msg);
      Serial.println(scanAdr, HEX);
      // Serial.println("--------------------------");
    }
    delay(2000);
  }
}

und by the way ...
im code sind 27 delays, 54 for schleifen, ein while ...

--> Schaltplan posten
--> erste Problemstellung mit dem Code genau erläutern!
Er erkennt den Reedsensor beim drüber Fahren, aber er hält nicht an oder / und schaltet die Weiche nicht.

Hallo

Trage hier mal die Pins für die Reedsensoren ein:

byte reed_sensor_raw[] = {0, 0, 0, 0, 0, 0, 0, 0};  // Reed Sensor Unentprellt

Nicht erforderlich. Die stehen in reed_sensor_Pin.

Danke Dir fürs reinstellen,

  • die delays() sollten nur in der setup() Routine sein oder ich habe da was übersehen :roll_eyes:, - die while suche ich noch
  • Die Schemas werde ich heute Abend noch nach der Arbeit nachliefern obwohl die HW Bedienung manuell ja funktioniert.
  • Der Fehler liegt im automatischen Modus (im manuellen Modus funktioniert die Weichenstellung) den Timeschlaufen: init3Time und auch init5aTime - init5dTime
  • Der Automat startet mit: if (GPIO_U4_taster_start_entprellt == 1 && ....
    Gruss

Brille aufsetz :slight_smile:

Hier die 4 Platinen: WeTransfer - Send Large Files & Share Photos Online - Up to 2GB Free, besten Dank mal schon im Voraus für die Hilfe.

  • Aktuell läuft es instabil, dass er "Funktionen" übergeht: Weichen 1 und Weiche 3 stellen, anhalten beim Bahnhof1 erst etwa nach 3-7 Runden
  • Wenn der Zug mit dem Magneten auf dem Redsensor 3 steht, auf dem Abstellgleis, ruckelt der Halt am Bahnhof1. Er haltet an -> i.O., fährt kurz an -> i.O., haltet dann nochmals an -> n.i.O. -> fährt dann an und weiter.

-> Manuell läufts mit den Sensorenerkennung und dem manuellen Fahren, manuellen weichen stellen. Sie denke ich, dass das Schema funktioniert :wink:

.