Serielle Datenstring vom Computer im Adruino Mega einlesen und aufteilen

Na du bist mir ja einer...... :grinning:
Weil es schon wieder spät ist, antworte ich nur eben kurz auf Deine Fragen. Bitte nicht als abfällig werten.Hatte gestern schon mal probiert, aber da wollte mein Decoder plötzlich nicht mehr.....bis ich den Fehler gefunden habe war es 23:00 uhr :joy:
#define BENZINER ....er war's

Die Funktion hast Du geschrieben :wink:, wenn ich es richtig sehe sind das die Anzahl Zeichen für die obere LCD-Zeile beim eintritt in die Farbeinstellung.

War wohl ein Überbleibsel.....Überflüssig

Habe ich überarbeitet...
Anzeige, muss ich noch machen.....

Hinzugefügt habe ich noch

void clearBrightness()                            // Alle TM1637-Anzeigen auf eingestellten bzw. gespeicherten Wert zurücksetzen
{
  for (byte d = 0; d < 8; d++)
  {
    tmDisp[d].setBrightness(lumi);
  }
}

Diese Funktion wird bei Anzeigewechsel (ausser bei Runden-Anzeige) vorher durchgeführt.
Hatte sonst immer in den anderen Anzeigebilder eine Zeile heller.... :grin:

Aber nun mal im ganzen...

[code]
// Tower-Control auf MEGA 2560
const char ver[] = {" Tower-V1.25edit "}; // Stand 10.11.2021

//#define DEBUG
#define BENZINER

#ifdef DEBUG
  #define DEBUG_PRINT(x)    Serial.print (x)
  #define DEBUG_PRINTLN(x)  Serial.println (x)
#else
  #define DEBUG_PRINT(x)
  #define DEBUG_PRINTLN(x)
#endif

#include <Wire.h>
#include <EEPROM.h>                                        // Zum Abspeichern der Einstellungen

// Tower 7-Segmentanzeigen
#include <TM1637Display.h>                                 // Einbinden der Bibliothekt zum ansteuern des 7 Segment-Displays
const uint8_t clk[8] = {22, 24, 26, 28, 30, 32, 34, 36};   // CLK Pin´s der TM 1637
const uint8_t dio[8] = {6, 7, 8, 9, 10, 11, 12, 13};       // DIO Pin´s der TM 1637

uint8_t lumi = EEPROM.read(1);            // Helligkeit für alle 7-Segment Anzeigen
uint8_t lumiPole = 7;                     // Helligkeit für führenden Fahrer bzw. Spur bei der Rundenanzeige
uint8_t kanal = EEPROM.read(2);           // Kanal für NRF24 Empfänger
uint8_t id = EEPROM.read(3);              // Id für Fernsteuerung vom Converter
uint8_t SBild = EEPROM.read(4);           // Anzeigebild Turm nach dem Einschalten
uint8_t AnzahlSpuren = EEPROM.read(5);    // Anzahl der Fahrspuren
uint8_t Wsl = SBild;                      // Imaginärer Wahlschalter ;-)
uint8_t spuren = AnzahlSpuren;            // Anzahl der Bahnspuren !!!
uint8_t exitMenu = false;                 // Aufruf (true) im Hauptmenü = verlassen, wenn kein subMenu
uint8_t ExternAnz_state = 0;              // Anzeigestatus für Externabfrage
uint8_t ExternLich_state[3] = {0};        // Anzeigestatus für Externabfrage Licht

//erzeugen des Display 1 bis 8 Objektes mit den Parametern für die PINs
TM1637Display tmDisp[] = {  TM1637Display (clk[0], dio[0]),  // 1 Reihe von oben / - links
                            TM1637Display (clk[1], dio[1]),  // 1 Reihe von oben / - rechts
                            TM1637Display (clk[2], dio[2]),  // 2 Reihe von oben / - links
                            TM1637Display (clk[3], dio[3]),  // 2 Reihe von oben / - rechts
                            TM1637Display (clk[4], dio[4]),  // 3 Reihe von oben / - links
                            TM1637Display (clk[5], dio[5]),  // 3 Reihe von oben / - rechts
                            TM1637Display (clk[6], dio[6]),  // 4 Reihe von oben / - links
                            TM1637Display (clk[7], dio[7])   // 4 Reihe von oben / - rechts
                         };
// Array für ***Uhr***
const uint8_t Uhr[] = {0, SEG_F | SEG_E | SEG_D | SEG_C | SEG_B, SEG_F | SEG_E | SEG_G | SEG_C, SEG_E | SEG_G , };

// Array für ***Jahr***
const uint8_t Jahr[] = {SEG_B | SEG_C | SEG_D | SEG_E, SEG_G | SEG_C | SEG_D | SEG_E, SEG_F | SEG_E | SEG_G | SEG_C, SEG_E | SEG_G , };

// Array für ***Cal***
const uint8_t Cal[] = {0, SEG_A | SEG_F | SEG_E | SEG_D, SEG_G | SEG_C | SEG_D | SEG_E, SEG_E | SEG_F, };

// Array für ***C***
const uint8_t C[] = { SEG_A | SEG_E | SEG_F | SEG_D , };

// Array für ***Grad***
const uint8_t Grad[] = { SEG_A | SEG_F | SEG_E | SEG_D | SEG_C | SEG_G , SEG_E | SEG_G , SEG_G | SEG_C | SEG_D | SEG_G | SEG_E, SEG_E | SEG_D | SEG_C | SEG_B | SEG_G, };

// Array für ***U--***
const uint8_t U[] = {0, SEG_F | SEG_E | SEG_D | SEG_C | SEG_B , SEG_G,};

// Array für ***AL-***
const uint8_t AL[] = {SEG_E | SEG_F | SEG_A | SEG_B | SEG_C | SEG_G , SEG_F | SEG_E | SEG_D, SEG_G,};

// Array für ***SP-***
const uint8_t Sp[] = {SEG_A | SEG_F | SEG_G | SEG_C | SEG_D, SEG_E | SEG_F | SEG_A | SEG_B | SEG_G , SEG_G, SEG_G,};

// Array für ***,***
const uint8_t Komma[] = {SEG_E,};

// Array für ***1***
const uint8_t Eins[] = {SEG_B | SEG_C,};

// Array für ***2***
const uint8_t Zwei[] = {SEG_A | SEG_B | SEG_G | SEG_E | SEG_D,};

// Array für ***3***
const uint8_t Drei[] = {SEG_A | SEG_B | SEG_G | SEG_C | SEG_D,};

// Array für ******
const uint8_t Vier[] = {SEG_F | SEG_G | SEG_B | SEG_C,};

// Radio
#include <nRF24L01.h>
#include <RF24.h>
#include <printf.h>
RF24 radio(4, 5);                          // CE=4, CS=5, SCK=, MO=, MI=
const byte address[6] = "00001";           // Sender-Adresse

// Vorbereitung LCD-Menu Zeichenketten
constexpr unsigned menueStrLen {12};
constexpr unsigned hauptMenuePunkte {11};
constexpr unsigned turmAnzeigePunkte{5};
constexpr unsigned turmLichtPunkte{6};
using ConstStrPtr  = const char *;
using FlashStrPtr  = const __FlashStringHelper *;
using MenuePunkt   = const char[menueStrLen + 1];

// LCD
#include <LiquidCrystal_I2C.h>
const uint8_t lcdRow = 16;
const uint8_t lcdCol = 2;
LiquidCrystal_I2C lcd(0x27, lcdRow, lcdCol);

// Licht
#include <Adafruit_NeoPixel.h>            // Einbinden der Bibliothekt zum ansteuern der WS2812 LEDs
const uint8_t ledPin = 45;                // Pin für WS2812 LEDs
const uint16_t numPixel = 7;              // Anzahl der WS2812 LEDs
Adafruit_NeoPixel pixel(numPixel, ledPin, NEO_GRB + NEO_KHZ800);

// Verarbeitung
uint8_t temp = 10;                        // Einschalt-Temperatur vor dem Empfang des Converter's
const uint8_t maxSpuren = 8;              // Mögliche Anzahl der Spuren
uint16_t AR[maxSpuren + 1] = {0};         // Runden je Spur
uint16_t RZvk[maxSpuren + 1] = {0};       // Rundenzeit Vorkomma je Spur
uint16_t RZnk[maxSpuren + 1] = {0};       // Rundenzeit Nachkomma je Spur
uint16_t Voltage[maxSpuren + 1] = {0};    // Spannung für die Spur
uint8_t VoltVK[maxSpuren + 1] = {0};      // Bahnstrom Vorkomma je Spur
uint8_t VoltNK[maxSpuren + 1] = {0};      // Bahnstrom Vorkomma je Spur
const uint8_t charNum = 26;               // Anzahl Buchstaben -1 für Fahrernamen
char Fahrer[maxSpuren + 1][charNum] = {0};

// RGB Werte
byte rgbLicht[3][3] = {0};        // Auswahl RGB-Werte Beleuchtung Eingang,Erdgeschoss,Obergeschoss

// Uhr
#include <DS1307RTCB.h>           // auf die TimeLibB angepasste 1307 von Paul Stoffregen
#include <TimeLibB.h>             // auf deutsch umgeschriebene TimeLib von Paul Stoffregen
uint8_t minutealt = 61;           // Zwangsaktuallisierung Uhrzeit! - nur alle Minute neue Abfrage

// RotaryEncoder
#include <rotary.h>
#ifdef BENZINER
  Rotary r = Rotary(2, 3, 40);    // Rotary(Encoder Pin 1, Encoder Pin 2, Button Pin)
#else
  Rotary r = Rotary(5, 3, 23);    // Rotary(Encoder Pin 1, Encoder Pin 2, Button Pin) 5,3,23
#endif
const uint8_t bounce = 10;

// Extern-AbfragePin´s
// 23=Rundenzeiten Wsl-1,25=Runden Wsl-2,27= Uhr Wsl-3,29=Bahnstrom Wsl-4,31=Tagesrunden Wsl-5
// 33=Licht Eingang,35=Licht Erdgeschoss,37=Licht Obergeschoss,39=Frei,41=Licht Chaos Blinken
const uint8_t ExternPin[] = {23, 25, 27, 29, 31, 33, 35, 37, 39, 41};

// Gesamtzähler
uint16_t TagZahl[maxSpuren + 1] = {0};         // Tageszähler, zählt alle Runden pro Spur zusammen
uint16_t lastAR[maxSpuren + 1] = {0};          // Vergleicher, für Tageszähler
uint16_t lastTagesrunden[maxSpuren + 1] = {0}; // Vergleicher, für Tageszähler Anzeigetafel
uint16_t maxRunden;                            // Merker für größte Rundenzahl

void setup()
{
  Serial.begin(115200);
  DEBUG_PRINTLN(F("Start..."));
  lcd.init(); // Für Benziner
  //lcd.begin(); // Für XY Projekt
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print(ver);
  //Setzt die Helligkeit des Displays mögliche Werte sind 0 bis 7, 0 dunkel und 7 hell
  for (uint8_t i = 0; i < 8 ; i++)
  {
    tmDisp[i].setBrightness(lumi);
  }
  clearAll();
  // setzt die Farbwerte aus EEprom
  for (uint8_t i = 0; i < 3 ; i++)
  {
    rgbLicht[0][i] = //Farbe für Eingang
      EEPROM.read(i + 10);
    rgbLicht[1][i] = //Farbe für Erdgeschoss
      EEPROM.read(i + 20);
    rgbLicht[2][i] = //Farbe für Obergeschoss
      EEPROM.read(i + 30);
  }
  // Setup Radio
  radio.begin();
  radio.enableDynamicPayloads();        // wichtig! Es werden nur Nutzdaten übertragen!
  radio.setPALevel(RF24_PA_MAX);        // der Sender muss nicht hoch sein (MAX,HIGH,LOW,MIN)
  radio.setDataRate(RF24_1MBPS);        // je schneller desto...
  radio.setChannel(kanal);              // Für Benziner
  radio.setAutoAck(0);                  // NoACK - ein Sender multiple Empfänger
  radio.openReadingPipe(0, address);
  radio.startListening();               // Start des Empfängermodus
  pixel.begin();
  // Init ExternPin
  for (uint8_t i = 0; i < sizeof(ExternPin); i++)
  {
    pinMode(ExternPin[i], INPUT_PULLUP);
  }
}
// Ende Setup

void loop()
{
  if (!menue())        // fragt das menu ab
  {
    displayKalender(); // wenn kein menu dann Kalender
    
  }
  anzeige();           // Auswahl für Anzeigetafel
  leseEmpfang();       // Empfange NRF 24 und werte aus
  leseEingaenge();     // Abfrage der Extern-Eingänge
  merkeRunden();       // Zählt alle Runden je Spur zusammen"Tageszähler"
}

bool menue()           // gibt true zurück, wenn ein Menu aufgemacht - sonst false
{
  static uint8_t nextMenu = 0;
  if (!nextMenu && r.buttonPressedReleased(bounce)) // Kein Menu? aber auf Button gedrückt
  {
    DEBUG_PRINTLN(F("Button pressed Aufruf Hauptmenue"));
    nextMenu = Hauptmenue(0);                       // übergebe Startzeichen für Menu
  }
  else  if (nextMenu != 0)                          // wenn doch Menu
  {
    nextMenu = Hauptmenue(nextMenu);                // ... dann einmal durchs Menu
  }
  return nextMenu;                                  // gib Zustand zurück (0=false - alles andere ist true)
}

uint8_t getRotary(uint8_t rotaryWert, const uint8_t rotaryMin, const uint8_t rotaryMax)
{
  // *INDENT-OFF*
  //uint8_t lastRotary = rotaryWert;  // fuer debugausgabe
  uint8_t val = r.process();     // Check the encoder
  //DEBUG_PRINTLN(val);
  if (val == r.clockwise()) { rotaryWert ++; }
  else if (val == r.counterClockwise() && rotaryWert>0)
  { rotaryWert --; }
  if (rotaryWert > rotaryMax) { rotaryWert = rotaryMax; }
  else if (rotaryWert < rotaryMin) { rotaryWert = rotaryMin; }
  // if (lastRotary != rotaryWert) DEBUG_PRINTLN(rotaryWert); // debugausgabe
  return (rotaryWert);
  // *INDENT-ON*
}

MenuePunkt hauptMenu[] PROGMEM  // TAB Hauptmenu
{
  {"Hauptmenue"},
  {"Anzeigetafel"},
  {"Beleuchtung"},
  {"Helligkeit"},
  {"Farbe-Licht"},
  {"Fahrspuren"},
  {"Startanzeige"},
  {"IDNummer"},
  {"Funkkanal"},
  {"WerksWerte"},
  {"Verlassen"},
};

uint8_t Hauptmenue(uint8_t menuRotary)                                    // Auswahl Hauptmenue...
{
  const uint8_t rotaryMin = 1;                                            // erster Eintrag
  const uint8_t rotaryMax = sizeof(hauptMenu) / sizeof(hauptMenu[0]) - 1; // letzer Menueintrag -> Menu verlassen
  static uint8_t subMenu = 0;                                             // Merker auf switch/case
  static uint8_t nextMenu = 0;
  static bool lcdInitMerker = false;                                      // fuer erstmalige Anzeige des UnterMenu
  if (menuRotary == 0)                                                    // Initialisiert Variablen
  {
    lcdMenuLine(0, 0);
    subMenu = 0;
    nextMenu = 0;
    menuRotary++;
    Serial.println(rotaryMax);
  }
  if (!subMenu)                                                           // bisher kein SubMenu ausgewählt
  {
    uint8_t tikRotary = getRotary(nextMenu, rotaryMin, rotaryMax);        // Abfrage RotaryEncoder
    if (nextMenu != tikRotary)                                            // neuer Wert? dann zeige an
    {
      nextMenu = tikRotary;                                               // merke den aktuellen RotaryWert
      Serial.println(nextMenu);
      if (nextMenu <= rotaryMax)                                          // Untermenu geht nur bis vorletzten Eintrag
        lcdMenuLine(1, nextMenu);                                         // untere Zeile im lcd
    }
    if (r.buttonPressedReleased(bounce))                                  // EncoderButton ausgelöst?
    {
      if (nextMenu < rotaryMax)
        lcdMenuLine(0, nextMenu);                                         // schreibt erste Zeile mit nächstem Menupunkt
      subMenu = nextMenu;                                                 // übernimmt den Wert zur Weitergabe
      DEBUG_PRINT(F("switch Menu: "));
      DEBUG_PRINTLN(nextMenu);
    }
    if (exitMenu == true)
    {
      lcd.setCursor(0, 0);
      lcd.print(ver);
      minutealt = 61;
      subMenu = false;
      exitMenu = false;
      menuRotary = 0;
    }
  }
  if (subMenu)
    switch (nextMenu)
    {
      case rotaryMin:                   // Gehe zu Turmanzeige-Menue
        if (!lcdInitMerker)lcdSubTurmLineTwo(0);
        subMenu = turmAnzeige(subMenu);
        break;
      case 2:                           // Gehe zu Turmlicht-Menue
        if (!lcdInitMerker)turmLicht(false);
        subMenu = turmLicht(subMenu);
        break;
      case 3:                           // Gehe zu Helligkeit-Menue
        if (!lcdInitMerker) subMenu = Helligkeit(false);
        subMenu = Helligkeit(subMenu);
        break;
      case 4:                           // Gehe zu LEDFarben-Menue
        if (!lcdInitMerker)ledFarben(0);
        subMenu = ledFarben(subMenu);
        break;
      case 5:                           // Gehe zu Fahrspuren-Menue
        if (!lcdInitMerker)subMenu = Fahrspuren(false);
        subMenu = Fahrspuren(subMenu);
        break;
      case 6:                           // Gehe zu  Startanzeige-Menue
        if (!lcdInitMerker)subMenu = Startanzeige(false);
        subMenu = Startanzeige(subMenu);
        break;
      case 7:                           // Gehe zu  IDNummer-Menue
        if (!lcdInitMerker)subMenu = IDNummer(false);
        subMenu = IDNummer(subMenu);
        break;
      case 8:                           // Gehe zu  Funkkanal-Menue
        if (!lcdInitMerker)subMenu = Funkkanal(false);
        //if (!lcdInitMerker)Funkkanal(0);
        subMenu = Funkkanal(subMenu);
        break;
      case 9:                           // Gehe zu  WerksWerte-Menue
        if (!lcdInitMerker)WerksWerte(0);
        subMenu = WerksWerte(subMenu);
        break;
      case rotaryMax:                   // Hauptmenue verlassen
        //DEBUG_PRINTLN(F("Button pressed Abfrage ob speichern und Hauptmenue verlassen"));
        if (!lcdInitMerker)Speichern(0);
        subMenu = Speichern(subMenu);
        break;
    }
  if (subMenu) lcdInitMerker = true; else lcdInitMerker = false;
  return (menuRotary);
}

void lcdMenuLine(const uint8_t line, const uint8_t auswahl)  // Inhalt der ersten Zeile des LCD-Menu
{
  lcd.setCursor(0, line);
  if (line == 0)
  {
    lcd.print("*"); //DEBUG_PRINT("*");
    lcdLineZentriert(auswahl); //DEBUG_PRINT(auswahl);
    lcd.print("*"); //DEBUG_PRINTLN("*");
  }
  else if (line == 1)
  {
    if (auswahl > 1) lcd.print("<"); else lcd.print(" ");
    lcdLineZentriert(auswahl);
    if (auswahl < sizeof(hauptMenu) / sizeof(hauptMenu[0]) - 1) lcd.print(">"); else lcd.print(" ");
  }
}

void lcdLineZentriert(uint8_t ausgabe)
{
  const uint8_t gesamt = lcdRow - 2;
  uint8_t vor = 0;
  uint8_t nach = 0;
  vor = (gesamt - txtlaenge(ausgabe)) / 2;
  nach = gesamt - txtlaenge(ausgabe) - vor;
  for (; vor >= 1; vor--)
  {
    lcd.print(" "); //DEBUG_PRINT(" ");
  }
  lcd.print(lcdHauptMenu(ausgabe));
  // DEBUG_PRINT(lcdHauptMenu(ausgabe));
  for (; nach >= 1; nach--)
  {
    lcd.print(" ");// DEBUG_PRINT(" ");
  }
  //DEBUG_PRINTLN();
}

FlashStrPtr lcdHauptMenu(byte index)
{
  return FlashStrPtr(&hauptMenu[index]);
}

uint8_t txtlaenge(byte index)
{
  return strlen_P(ConstStrPtr(&hauptMenu[index]));
}

const uint8_t stripeLen[][2] = // Tab RGB - Stand 26.08.
{
  {0, 1},                       // Eingang: start, länge
  {1, 3},                       // Unten
  {4, 3},                       // Oben
};

uint8_t ledFarben(uint8_t menuRotary)
{
  // my_xy_Erinnerung: 3 WS RGB -> 2D Array!
  const uint8_t rotaryMin = 1;
  const uint8_t rotaryMax = sizeof(rgbLicht) / 3 + 1; // Wenn das mal erweitert wird...
  static uint8_t colorType = 0;    // 1=rt 2=gn 3=bl 4=Weiter/Ende
  static uint8_t ledType = 0;      // zaehlt die Einsatzorte durch
  uint8_t tempRotary = 0;          // temporäre Aufnahme RotaryWert
  static bool holdPixel = false;   // Merker für Zustand der Beleuchtung
  if (menuRotary == 0)             // erster Aufruf der Einstellung
  {
    colorType = 1;
    ledType = 0 ;
    holdPixel = pixel.getPixelColor(0); // Merkt sich den Zustand des Pixel
    pixelAnAus(0, 1);                   // Macht Stripe an
    lcd.clear();
    lcdSubLedOne(ledType);
    lcd.blink();
    lcd.setCursor(0, 1);
    lcdSubLedTwo(ledType, 0);      // 0 löst Init für LCD aus!
    menuRotary++;                  // setzt != 0 für Dauerschleife
    // DEBUG_PRINTLN(colorType);
    // DEBUG_PRINT(F("RGB-"));
    // DEBUG_PRINTLN(ledType);
  }
  switch (colorType)
  {
    case rotaryMin:
      tempRotary = getRotary(rgbLicht[ledType][0], 0, 255); // rot für WS Nummer: ledType Eingang
      if (rgbLicht[ledType][0] != tempRotary)
      {
        rgbLicht[ledType][0] = tempRotary;
        lcdSubLedTwo(ledType, colorType);
        pixelAnAus(ledType, 1);
      }
      break;
    case 2:
      tempRotary = getRotary(rgbLicht[ledType][1], 0, 255); // gruen für WS Nummer: ledType Erdgeschoss
      if (rgbLicht[ledType][1] != tempRotary)
      {
        rgbLicht[ledType][1] = tempRotary;
        lcdSubLedTwo(ledType, colorType);
        pixelAnAus(ledType, 1);
      }
      break;
    case 3:
      tempRotary = getRotary(rgbLicht[ledType][2], 0, 255); // blau für WS Nummer: ledType Obergeschoss
      if (rgbLicht[ledType][2] != tempRotary)
      {
        rgbLicht[ledType][2] = tempRotary;
        lcdSubLedTwo(ledType, colorType);
        pixelAnAus(ledType, 1);
      }
      break;
    case rotaryMax:
      {
        pixelAnAus(ledType, holdPixel);
        if (ledType < sizeof(rgbLicht) / 3 - 1) // noch nicht alle WS durch...
        {
          colorType = 1;  // fange an von vorn
          ledType++;     // naechste WS
          holdPixel = pixel.getPixelColor(stripeLen[ledType][0]);
          pixelAnAus(ledType, 1);
          lcdSubLedOne(ledType);
          lcdSubLedTwo(ledType, 0);
          DEBUG_PRINT(F("RGB-"));
          DEBUG_PRINTLN(ledType);
          DEBUG_PRINTLN(colorType);
        }
        else
        {
          colorType = 0;
          ledType = 0;
          menuRotary = 0;
          lcdMenuLine(0, 0);
          lcdMenuLine(1, 4);
        }
      }
      break;
  }
  if (r.buttonPressedReleased(bounce))
  {
    colorType++;
    lcdSubLedTwo(ledType, colorType);
  }
#ifdef DEBUG
  serialColor(ledType, rgbLicht[ledType][0], rgbLicht[ledType][1], rgbLicht[ledType][2]);
#endif
  if (!menuRotary)lcd.noBlink(); // wenn menuRotary wieder auf 0 gesetzt, ist Ende lcd und damit Ende blink
  return menuRotary;
}

void pixelAnAus(uint8_t stripeNum, bool anAus)
{
  Serial.print(F("Pixel "));
  if (anAus)
  {
    Serial.println(F("an"));
    pixel.fill(pixel.Color(rgbLicht[stripeNum][0],
                           rgbLicht[stripeNum][1],
                           rgbLicht[stripeNum][2]), stripeLen[stripeNum][0], stripeLen[stripeNum][1]);
  }
  else
  {
    Serial.println(F("aus"));
    pixel.fill(0, stripeLen[stripeNum][0], stripeLen[stripeNum][1]);
  }
  pixel.show();
}

void lcdSubLedOne(const uint8_t number)
{
  const uint8_t laenge = 5; // RGB-0
  uint8_t vor = 0;
  uint8_t nach = 0;
  vor = (lcdRow - laenge) / 2;
  nach = lcdRow - laenge - vor;
  for (; vor >= 1; vor--)
  {
    lcd.print(" "); DEBUG_PRINT(" ");
  }
  lcd.print(F("RGB- ")); DEBUG_PRINT(F("RGB- "));
  for (; nach >= 1; nach--)
  {
    lcd.print(" "); DEBUG_PRINT(" ");
  }
  lcd.setCursor(9, 0);
  lcd.print(number);
  DEBUG_PRINTLN();
}

void lcdSubLedTwo(const uint8_t farbenWert, const uint8_t farbenType) // lcd Zeile 2 fuer ledFarben
{
  const uint8_t row = 1;
  uint8_t col = 3;
  if (farbenType == 1) col = 3;
  if (farbenType == 2) col = 7;
  if (farbenType == 3) col = 11;
  if (farbenType == 0 || farbenType == 1) // alle oder rot
  {
    lcd.setCursor(0, row);
    lcd.print(" ");
    if (rgbLicht[farbenWert][0] < 100) lcd.print(" ");
    if (rgbLicht[farbenWert][0] < 10 ) lcd.print(" ");
    lcd.print(rgbLicht[farbenWert][0]);
  }
  if (farbenType == 0 || farbenType == 2) // alle oder gruen
  {
    lcd.setCursor(4, row);
    lcd.print(" ");
    if (rgbLicht[farbenWert][1] < 100) lcd.print(" ");
    if (rgbLicht[farbenWert][1] < 10 ) lcd.print(" ");
    lcd.print(rgbLicht[farbenWert][1]);
  }
  if (farbenType == 0 || farbenType == 3) // alle oder blau
  {
    lcd.setCursor(8, row);
    lcd.print(" ");
    if (rgbLicht[farbenWert][2] < 100) lcd.print(" ");
    if (rgbLicht[farbenWert][2] < 10 ) lcd.print(" ");
    lcd.print(rgbLicht[farbenWert][2]);
  }
  lcd.setCursor(col, row);
}

void serialColor(const uint8_t t, const uint8_t r, const uint8_t g, const uint8_t b)
{
  static uint32_t oldColor = {0};
  uint32_t myColor = pixel.Color(r, g, b);
  if (oldColor != myColor)
  {
    oldColor = myColor;
    DEBUG_PRINT(F("RGB: "));
    for (uint8_t i = 0; i < 3; i++)
    {
      DEBUG_PRINT(rgbLicht[t][i]);
      DEBUG_PRINT("\t");
    }
    DEBUG_PRINTLN();
  }
}

uint8_t Helligkeit(uint8_t menuRotary) // TAB SubMenu Helligkeit
{
  const uint8_t rotaryMin = 1;
  const uint8_t rotaryMax = 7;
  if (menuRotary == 0)
  {
    lcd.blink();
    menuRotary = lumi;
    lcdSubHelligLineTwo(menuRotary);
  }
  uint8_t tikRotary = getRotary(menuRotary, rotaryMin, rotaryMax);
  if (menuRotary != tikRotary)
  {
    menuRotary = tikRotary;
    lcdSubHelligLineTwo(tikRotary);             // untere Zeile im lcd
  }
  if (r.buttonPressedReleased(bounce))
  {
    DEBUG_PRINTLN(F("Button pressed Helligkeit -> Werte übernehmen und zurück ins Hauptmenu"));
    lcdMenuLine(0, 0);
    lcdMenuLine(1, 3);
    lumi = tikRotary;
    for (uint8_t i = 0; i < 8 ; i++)
    {
      tmDisp[i].setBrightness(tikRotary);
    }
    if (Wsl == 2)spurAnzeigeLinks();
    if (Wsl == 3)
    {
      uhrAnzeigeLinks();
    }
    lcd.noBlink();
    menuRotary = 0;
  }
  return menuRotary;
}

uint8_t Fahrspuren(uint8_t menuRotary) // TAB SubMenu Fahrspuren
{
  const uint8_t rotaryMin = 2;
  const uint8_t rotaryMax = 8;
  if (menuRotary == 0)
  {
    lcd.blink();
    menuRotary = AnzahlSpuren;
    lcdSubSpurenLineTwo(menuRotary);
  }
  uint8_t tikRotary = getRotary(menuRotary, rotaryMin, rotaryMax);
  if (menuRotary != tikRotary)
  {
    menuRotary = tikRotary;
    lcdSubSpurenLineTwo(tikRotary);             // untere Zeile im lcd
  }
  if (r.buttonPressedReleased(bounce))
  {
    DEBUG_PRINTLN(F("Button pressed Fahrspuren -> Werte übernehmen und zurück ins Hauptmenu"));
    lcdMenuLine(0, 0);
    lcdMenuLine(1, 5);
    AnzahlSpuren = tikRotary;
    lcd.noBlink();
    menuRotary = 0;
    return false;
  }
  return menuRotary;
}

uint8_t Startanzeige(uint8_t menuRotary)
{
  const uint8_t rotaryMin = 1;
  const uint8_t rotaryMax = 5;
  if (menuRotary == 0)
  {
    lcd.blink();
    menuRotary = SBild;
    lcdSubStartanzeigeLineTwo(menuRotary);
  }
  uint8_t tikRotary = getRotary(menuRotary, rotaryMin, rotaryMax);
  if (menuRotary != tikRotary)
  {
    menuRotary = tikRotary;
    lcdSubStartanzeigeLineTwo(tikRotary);             // untere Zeile im lcd
  }
  if (r.buttonPressedReleased(bounce))
  {
    DEBUG_PRINTLN(F("Button pressed Startanzeige -> zurück ins Hauptmenu"));
    lcdMenuLine(0, 0);
    lcdMenuLine(1, 6);
    SBild = tikRotary;
    menuRotary = 0;
    lcd.noBlink();
    return false;
  }
  return menuRotary;
}

uint8_t IDNummer(uint8_t menuRotary)
{
  const uint8_t rotaryMin = 1;
  const uint8_t rotaryMax = 50;
  if (menuRotary == 0)
  {
    lcd.blink();
    menuRotary = id;
    lcdSubIDNummerLineTwo(menuRotary);
  }
  uint8_t tikRotary = getRotary(menuRotary, rotaryMin, rotaryMax);
  if (menuRotary != tikRotary)
  {
    menuRotary = tikRotary;
    lcdSubIDNummerLineTwo(tikRotary);             // untere Zeile im lcd
  }
  if (r.buttonPressedReleased(bounce))
  {
    DEBUG_PRINTLN(F("Button pressed IDNummer -> zurück ins Hauptmenu"));
    lcdMenuLine(0, 0);
    lcdMenuLine(1, 7);
    id = tikRotary;
    menuRotary = 0;
    lcd.noBlink();
    return false;
  }
  return menuRotary;
}

uint8_t Funkkanal(uint8_t menuRotary)
{
  const uint8_t rotaryMin = 1;
  const uint8_t rotaryMax = 127;
  if (menuRotary == 0)
  {
    lcd.blink();
    menuRotary = kanal;
    lcdSubkanalLineTwo(menuRotary);
  }
  uint8_t tikRotary = getRotary(menuRotary, rotaryMin, rotaryMax);
  if (menuRotary != tikRotary)
  {
    menuRotary = tikRotary;
    lcdSubkanalLineTwo(tikRotary);             // untere Zeile im lcd
  }
  if (r.buttonPressedReleased(bounce))
  {
    DEBUG_PRINTLN(F("Button pressed FunkKanal -> zurück ins Hauptmenu"));
    lcdMenuLine(0, 0);
    lcdMenuLine(1, 8);
    radio.setChannel(kanal);
    kanal = tikRotary;
    menuRotary = 0;
    lcd.noBlink();
    return false;
  }
  return menuRotary;
}

uint8_t WerksWerte(uint8_t menuRotary)
{
  const uint8_t rotaryMin = 1;
  const uint8_t rotaryMax = 2;
  if (menuRotary == 0)
  {
    lcd.blink();
  }
  uint8_t tikRotary = getRotary(menuRotary, rotaryMin, rotaryMax);
  if (menuRotary != tikRotary)
  {
    menuRotary = tikRotary;
    lcdSubWerksWerteLineTwo(tikRotary);             // untere Zeile im lcd
  }
  if (r.buttonPressedReleased(bounce))
  {
    DEBUG_PRINTLN(F("Button pressed WerksWerte -> zurück ins Hauptmenu"));
    lcdMenuLine(0, 0);
    lcdMenuLine(1, 10);
    if (tikRotary == 1)
    {
      Werkseinstellung();
      DEBUG_PRINTLN("Es werden Daten wiederhergestellt");
    }
    if (tikRotary == 2)
    {
      DEBUG_PRINTLN("Es wurden keine Daten wiederhergestellt");
    }
    exitMenu = true;
    return false;
  }
  return menuRotary;
}

uint8_t Speichern(uint8_t menuRotary)
{
  const uint8_t rotaryMin = 1;
  const uint8_t rotaryMax = 2;
  if (menuRotary == 0)
  {
    lcd.blink();
  }
  uint8_t tikRotary = getRotary(menuRotary, rotaryMin, rotaryMax);
  if (menuRotary != tikRotary)
  {
    menuRotary = tikRotary;
    lcdSubSpeichernLineTwo(tikRotary);             // untere Zeile im lcd
  }
  if (r.buttonPressedReleased(bounce))
  {
    DEBUG_PRINTLN(F("Button pressed Speichern -> zurück ins Hauptmenu"));
    lcdMenuLine(0, 0);
    lcdMenuLine(1, 10);
    if (tikRotary == 1)
    {
      Datensicherung();
      DEBUG_PRINTLN("Es wurden Daten gesichert");
    }
    if (tikRotary == 2)
    {
      DEBUG_PRINTLN("Es wurden keine Daten gesichert");
    }
    exitMenu = true;
    return false;
  }
  return menuRotary;
}

uint8_t turmAnzeige(uint8_t menuRotary)// TAB Turmanzeige menue "Was soll Turm anzeigen werden: Rundenzeit / Rundenanzahl / Uhr_Datum / Extern "
{
  const uint8_t rotaryMin = 1;
  const uint8_t rotaryMax = 6;
  uint8_t tikRotary = getRotary(menuRotary, rotaryMin, rotaryMax);
  if (menuRotary != tikRotary)
  {
    menuRotary = tikRotary;
    lcdSubTurmLineTwo(tikRotary - 1);             // untere Zeile im lcd
  }
  if (r.buttonPressedReleased(bounce))
  {
    DEBUG_PRINT(F("Button pressed Turmanzeige -> Wert: "));
    DEBUG_PRINTLN(tikRotary);
    switch (menuRotary)
    {
      case rotaryMin:   // Turmanzeige  "Rundenzeit"
        DEBUG_PRINT(F("Rundenzeit"));
        Wsl = 1;
        break;
      case 2:   // Turmanzeige  "Rundenanzahl"
        DEBUG_PRINT(F("Rundenanzahl"));
        Wsl = 2;
        break;
      case 3:   // Turmanzeige "Datum / Uhrzeit"
        DEBUG_PRINT(F("Datum / Uhrzeit"));
        Wsl = 3;
        break;
      case 4:   // Turmanzeige "Extern-Auswahl"
        DEBUG_PRINT(F("Bahnstrom-Auswahl"));
        Wsl = 4;
        for (uint8_t i = 1; i <= spuren; i++)
        {
          Voltage[i] = 0;
        }
        break;
      case 5:   // Turmanzeige "Extern-Auswahl"
        DEBUG_PRINT(F("Gesamtrunden-Auswahl"));
        Wsl = 5;
        break;
      case rotaryMax:   // Turmanzeige gehe zurück zu Hauptmenue
        DEBUG_PRINT(F("-> ins Hauptmenu"));
        break;
    }
    DEBUG_PRINTLN(F(" ausgewaehlt"));
    DEBUG_PRINTLN();
    lcdMenuLine(0, 0);
    lcdMenuLine(1, 1);
    return 0;
  }
  return menuRotary;
}

void lcdSubTurmLineTwo(const uint8_t auswahl) // Inhalt der zweiten Zeile des Lcd-Menu im Turmmenu
{
  static uint8_t oldAuswahl = 0;
  lcd.setCursor(0, 1);
  const char *line2[] = {" Zeiten-Anzeige>" , "<Runden-Anzeige>" , "<  Uhr/Datum   >" , "<   Bahnstrom  >" ,  "< Gesamtrunden >" , "<    Zurueck    "}; // Tab Turmlich - Stand 19.09.
  lcd.print(line2[auswahl]);
  if (oldAuswahl != auswahl)
  {
    oldAuswahl = auswahl;
    DEBUG_PRINT(F("SubMenu Tumranzeige: "));
    DEBUG_PRINTLN(line2[auswahl]);
  }
}
/*   my_xy_Erinnerung: 3 WS RGB -> 2D Array!
  byte rgbLicht[3][3] =
  {
  {55, 20, 0}, // Eingang ab Pixel 0
  {0, 50, 0},  // Unten ab Pixel 1
  {0, 0, 50}   // Oben ab Pixel 3
  };
*/
MenuePunkt turmLichtMenu[] PROGMEM
{
  {"Eingang"},
  {"Licht EG"},
  {"Licht OG"},
  {"zurueck"},
};

uint8_t turmLicht(bool menuRotary) // Turmleuchten.....
{
  const uint8_t rotaryMin = 0;            // erster Menupunkt turmLichtMenu[] ist auf 0!
  const uint8_t rotaryMax =
    sizeof(turmLichtMenu) /
    sizeof(turmLichtMenu[0]) - 1;         // letzter Menuepunkt aus Anzahl der Eintraege
  static bool subMenu = false;            // Merker fuer lcd vs. switch/case
  static uint8_t tempRotary = 0;          // temporäre Aufnahme RotaryWert
  if (!menuRotary)                        // beim ersten Aufruf der Funktion: Grundeinstellung
  {
    subMenu = false;
    tempRotary = 0;
    menuRotary = true;
    lcd.clear();
    lcdMenuLine(0, 2);                    // schreibt "Turmlicht" in obere Zeile
    lcd.blink();                          // wenn kein weiteres Menu, kann das entfallen
    lcdSubLichtLine(1, tempRotary);       // schreibt ersten Menupunkt in untere Zeile
  }
  if (!subMenu)                           // noch kein Menu ausgewaehlt
  {
    uint8_t tikRotary = getRotary(tempRotary, rotaryMin, rotaryMax);
    if (tempRotary != tikRotary)
    {
      tempRotary = tikRotary;
      lcdSubLichtLine(1, tikRotary);      // untere Zeile im lcd
    }
    if (r.buttonPressedReleased(bounce))
    {
      DEBUG_PRINT(F("Button pressed Turmlicht -> Wert: "));
      DEBUG_PRINTLN(tikRotary);
      subMenu = true;                     // Ende der Auswahl - gehe zur Auswertung
    }
  }
  if (subMenu)                            // Fange mit der Auswertung an
  {
    DEBUG_PRINT(F("Licht "));
    switch (tempRotary)                   // gehe zum ausgewaehlten
    {
      case rotaryMin:                     // Turmlicht Eingang
        DEBUG_PRINT(F("Eingang"));
        // fragt den ersten Pixel ab und schaltet den Stripe um
        pixelAnAus(0, !pixel.getPixelColor(0));
        subMenu = false;                  // zetze Merker zurueck
        break;
      case (rotaryMin+1):                 // Turmlicht "EG"
        DEBUG_PRINTLN(F("EG"));
        pixelAnAus(1, !pixel.getPixelColor(1));
        subMenu = false;                  // setze Merker zurück
        break;
      case (rotaryMin+2):                 // Turmlicht "OG"
        DEBUG_PRINTLN(F("OG"));
        pixelAnAus(2, !pixel.getPixelColor(4));
        subMenu = false;
        break;
      case rotaryMax:                     // zurück zum Hauptmenue
        DEBUG_PRINT(F("-> ins Hauptmenu"));
        subMenu = false;
        menuRotary = 0;
        break;
    }
    if (!subMenu)                         // Wenn hier der Merker gelöscht...
    {
      pixel.show();                       // Aktuallisiere Stripe
      lcdMenuLine(0, 0);                  // Anzeige letztes Menu
      lcdMenuLine(1, 2);
      menuRotary = false;                 // sorgt für Ende des Aufrufs dieser Funktion
    }
  }
  return (menuRotary);
}

void lcdSubLichtLine(const uint8_t line, const uint8_t auswahl) // Inhalt der zweiten Zeile des Lcd-Menu im Lichtmenu
{
  lcd.setCursor(0, line);
  if (line == 0)
  {
    lcd.print("*"); DEBUG_PRINT("*");
    lcdTurmLichtZentriert(auswahl); DEBUG_PRINT(auswahl);
    lcd.print("*"); DEBUG_PRINTLN("*");
  }
  else if (line == 1)
  {
    lcdTurmLichtZentriert(auswahl);
  }
}

void lcdTurmLichtZentriert(uint8_t ausgabe)
{
  Serial.println(ausgabe);
  const uint8_t gesamt = lcdRow - 2;
  uint8_t vor = 0;
  uint8_t nach = 0;
  vor = (gesamt - strlen_P(ConstStrPtr(&turmLichtMenu[ausgabe]))) / 2;
  nach = gesamt - strlen_P(ConstStrPtr(&turmLichtMenu[ausgabe])) - vor;
  for (; vor >= 1; vor--)
  {
    lcd.print(" "); DEBUG_PRINT(" ");
  }
  lcd.print(FlashStrPtr(&turmLichtMenu[ausgabe])); DEBUG_PRINT(FlashStrPtr(&turmLichtMenu[ausgabe]));
  for (; nach >= 1; nach--)
  {
    lcd.print(" "); DEBUG_PRINT(" ");
  }
  DEBUG_PRINTLN();
}

void lcdSubHelligLineTwo(uint8_t menuRotary)
{
  lcd.setCursor(0, 1);
  lcd.print(F(" Ist="));     // 5 Stellen merken
  lcd.print(lumi);           // Anzahl Stellen wird errechnet
  lcd.print(F("   Soll="));  // 8 Stellen merken
  lcd.print(menuRotary);     // Stellen wird auch errecnet
  uint8_t curPos = 13;       // "Ist = " + " Soll = "!!! gemerkt ;)
  if (lumi > 99) curPos++;   // Jede Stelle gibt einen weiteren +Punkt
  if (lumi > 9) curPos++;
  curPos++;
  if (menuRotary > 99) curPos++;
  if (menuRotary > 9) curPos++;
  curPos++;
  // Bis zum Ende der Zeile löschen:
  for (uint8_t i = curPos; i < lcdRow; i++) lcd.print(" "); // Bis zum ende der Zeile Leerzeichen setzen!
  lcd.setCursor(curPos - 1, 1); // Ach schau es blinkt!
}

void lcdSubStartanzeigeLineTwo(uint8_t menuRotary)
{
  lcd.setCursor(0, 1);
  lcd.print(F(" Ist="));     // 5 Stellen merken
  lcd.print(SBild);          // Anzahl Stellen wird errechnet
  lcd.print(F("   Soll="));  // 8 Stellen merken
  lcd.print(menuRotary);     // Stellen wird auch errecnet
  uint8_t curPos = 13;       // "Ist = " + " Soll = "!!! gemerkt ;)
  if (SBild > 99) curPos++;  // Jede Stelle gibt einen weiteren +Punkt
  if (SBild > 9) curPos++;
  curPos++;
  if (menuRotary > 99) curPos++;
  if (menuRotary > 9) curPos++;
  curPos++;
  // Bis zum Ende der Zeile löschen:
  for (uint8_t i = curPos; i < lcdRow; i++) lcd.print(" "); // Bis zum ende der Zeile Leerzeichen setzen!
  lcd.setCursor(curPos - 1, 1); // Ach schau es blinkt!
}

void lcdSubSpurenLineTwo(uint8_t menuRotary)
{
  lcd.setCursor(0, 1);
  lcd.print(F(" Ist="));     // 5 Stellen merken
  lcd.print(AnzahlSpuren);   // Anzahl Stellen wird errechnet
  lcd.print(F("   Soll="));  // 8 Stellen merken
  lcd.print(menuRotary);     // Stellen wird auch errecnet
  uint8_t curPos = 13;       // "Ist = " + " Soll = "!!! gemerkt ;)
  if (AnzahlSpuren > 99) curPos++;   // Jede Stelle gibt einen weiteren +Punkt
  if (AnzahlSpuren > 9) curPos++;
  curPos++;
  if (menuRotary > 99) curPos++;
  if (menuRotary > 9) curPos++;
  curPos++;
  // Bis zum Ende der Zeile löschen:
  for (uint8_t i = curPos; i < lcdRow; i++) lcd.print(" "); // Bis zum ende der Zeile Leerzeichen setzen!
  lcd.setCursor(curPos - 1, 1); // Ach schau es blinkt!
}

void lcdSubIDNummerLineTwo(uint8_t menuRotary)
{
  lcd.setCursor(0, 1);
  lcd.print(F("Ist="));     // 4 Stellen merken
  lcd.print(id);            // Anzahl Stellen wird errechnet
  lcd.print(F("   Soll=")); // 7 Stellen merken
  lcd.print(menuRotary);    // Stellen wird auch errecnet
  uint8_t curPos = 12;      // "Ist = " + " Soll = "!!! gemerkt ;)
  if (id > 99) curPos++;    // Jede Stelle gibt einen weiteren +Punkt
  if (id > 9) curPos++;
  curPos++;
  if (menuRotary > 99) curPos++;
  if (menuRotary > 9) curPos++;
  curPos++;
  // Bis zum Ende der Zeile löschen:
  for (uint8_t i = curPos; i < lcdRow; i++) lcd.print(" "); // Bis zum ende der Zeile Leerzeichen setzen!
  lcd.setCursor(curPos - 1, 1); // Ach schau es blinkt!
}

void lcdSubkanalLineTwo(uint8_t menuRotary)
{
  lcd.setCursor(0, 1);
  lcd.print(F("Ist="));      // 4 Stellen merken
  lcd.print(kanal);          // Anzahl Stellen wird errechnet
  lcd.print(F(" Soll="));    // 6 Stellen merken
  lcd.print(menuRotary);     // Stellen wird auch errecnet
  uint8_t curPos = 11;       // "Ist = " + " Soll = "!!! gemerkt ;)
  if (id > 99) curPos++;     // Jede Stelle gibt einen weiteren +Punkt
  if (id > 9) curPos++;
  curPos++;
  if (menuRotary > 99) curPos++;
  if (menuRotary > 9) curPos++;
  curPos++;
  // Bis zum Ende der Zeile löschen:
  for (uint8_t i = curPos; i < lcdRow + 1; i++) lcd.print(" "); // Bis zum ende der Zeile Leerzeichen setzen!
  lcd.setCursor(curPos - 1 , 1); // Ach schau es blinkt!
}

void lcdSubSpeichernLineTwo(uint8_t menuRotary)
{
  for (uint8_t i = 0; i < 16; i++) lcd.print(" "); // Bis zum ende der Zeile Leerzeichen setzen!
  lcd.setCursor(0, 1);
  lcd.print(F("  Speichern J/N"));     // 15 Stellen merken
  uint8_t curPos = 15;                 // "Ist = " + " Soll = "!!! gemerkt ;)
  if (menuRotary == 1) curPos = curPos - 3; // Jede Stelle gibt einen weiteren +Punkt
  if (menuRotary == 2) curPos = curPos - 1;
  lcd.setCursor(curPos , 1); // Nu schau es blinkt an verschiedenen Stellen!
}

void lcdSubWerksWerteLineTwo(uint8_t menuRotary)
{
  for (uint8_t i = 0; i < 16; i++) lcd.print(" "); // Bis zum ende der unteren Zeile Leerzeichen setzen!
  lcd.setCursor(0, 1);                 // Untere Zeile
  lcd.print(F("Werkeinstell J/N"));    // 16 Stellen
  uint8_t curPos = 16;                 // "J = -3  N = -1)
  if (menuRotary == 1) curPos = curPos - 3;
  if (menuRotary == 2) curPos = curPos - 1;
  lcd.setCursor(curPos , 1); // Nu schau es blinkt an verschiedenen Stellen!
}
// ********** ab hier Renndaten / Display - Verarbeitung *********

void displayKalender()                            // LCD Start Anzeige und nicht Menü
{
  if (minute() != minutealt)
  {
    minutealt = minute();
    char zeileAnzeige[16] = {0};
    memset(zeileAnzeige, 0, sizeof(zeileAnzeige - 1));
    sprintf(zeileAnzeige, "%s %02u.%02u.  %02u:%02u", dayShortStr(weekday()), day(), month(), hour(), minute());
    lcd.setCursor(0, 0);
    lcd.print(ver);
    lcd.setCursor(0, 1);
    lcd.print(zeileAnzeige);
    DEBUG_PRINTLN(zeileAnzeige);
  }
}// Ende Start-Tab

void leseEmpfang()                                // Lese NFR24 und werte aus
{
  if (radio.available())
  {
    char text[32] = {0};
    radio.read(&text, radio.getDynamicPayloadSize());
    char *c;                                      // Teilstring
    uint8_t zahl = 0;
    //Serial.println(text);
    //tik();
    c = strtok(text, " ");                        // Lese bis erstes Leerzeichen
    if (isDigit(c[0]))
    {
      uint8_t spur = (c[0] - '0');
      switch (c[1])
      {
        case 'R':                                 // Runde für die Spur
          AR[spur] = atoi(strtok(NULL, " "));
          break;
        case 'Z':                                 // Zeit für die Spur
          RZvk[spur] = atoi(strtok(NULL, " "));
          RZnk[spur] = atoi(strtok(NULL, " "));
          break;
        case 'V':                                 // Spannung für die Spur
          Voltage[spur] = atoi(strtok(NULL, " "));
          break;
        case 'F':                                 // Fahrername für die Spur
          //          strcpy(Fahrer[spur], strtok(NULL, " "));
          //          strcat(Fahrer[spur], " ");
          //          strcat(Fahrer[spur], strtok(NULL, " "));
          break;
      }
    }
    else                                        // Ab hier nur zeigen Fernkonfiguration
    {
      switch (c[0])
      {
        case 'T':                               // T Zeit für RTC
          setTime(atol(strtok(NULL, " ")));     // übernimmt den Zeitstempel
          RTC.set(now());                       // setzt die RTC
          break;
        case 'C':                               // C für Celsius Vorkomma
          temp = atol(strtok(NULL, " "));       // übernimmt die Temperatur
          break;
        case 'i':
          zahl = atoi(strtok(NULL, " "));
          break;
        case 'r':                               // r setzt die Anzeige auf Rundenzeiten
          zahl = atoi(strtok(NULL, " "));
          if (zahl == id)
          {
            lcd.clear();                        // Lösche gesamte LCD-Display
            Wsl = 1;                            // Anzeige Rundenzeiten
          }
          break;
        case 'l':                               // l setzt die Anzeige auf Runden
          zahl = atoi(strtok(NULL, " "));
          if (zahl == id)
          {
            lcd.clear();                        // Lösche gesamte LCD-Display
            Wsl = 2;                            // Anzeige Runden
          }
          break;
        case 'u':                               // u setzt das Display auf Uhrzeit / Datum / Temperatur
          zahl = atoi(strtok(NULL, " "));
          if (zahl == id)                       // Entspricht empfangende Zahl der Empfänger-ID
          {
            lcd.clear();                        // Lösche gesamte LCD-Display
            Wsl = 3;                            // Anzeige Uhrzeit / Datum / Temperatur
          }
          break;
        case 'b':                               // b setzt das Display auf Bahnstrom
          zahl = atoi(strtok(NULL, " "));
          if (zahl == id)                       // Entspricht empfangende Zahl der Empfänger-ID
          {
            lcd.clear();                        // Lösche gesamte LCD-Display
            Wsl = 4;                            // Anzeige Bahnstrom
          }
          break;
        case 'f':                               // f setzt die Anzeige auf Fahrernamen "BEIM TURM NICHT MÖGLICH"
          break;
      }
    }
  }
}

void anzeige()                                    // TAB TM Auswahl Anzeigetafel
{
    // *INDENT-OFF*
    static uint8_t anzeigeType = 1;
    static bool merker = false;
    // Auswahl, was angezeigt werden soll mit Wahlschalter links
    // Zeiten,Runden,Uhrzeit,Bahnstrom
    if (anzeigeType !=Wsl)
    {
     anzeigeType = Wsl;
     merker = false;
    }
    switch (anzeigeType)
    {
    case 1:
      static uint16_t lastTime[8] = {0};
      if (!merker)
      {
        Serial.println(F("Rundenzeiten"));
        lcd.setCursor(0, 1);
        lcd.print(F(" Runden-Zeiten  "));
        clearRight();
        clearBrightness();
        for (uint8_t i = 1; i < spuren; i++)
        {
          zeitenAnzeige(i);
        }
        merker = true;
      }
      else
      {
        if ((lastTime[0] != RZvk[1]) || (lastTime[1] != RZnk[1]))
        {  zeitenAnzeige(1); lastTime[0] = RZvk[1]; lastTime[1] = RZnk[1]; }
        if ((lastTime[2] != RZvk[2]) || (lastTime[3] != RZnk[2]))
        {  zeitenAnzeige(2); lastTime[2] = RZvk[2]; lastTime[3] = RZnk[2]; }
        if ((lastTime[4] != RZvk[3]) || (lastTime[5] != RZnk[3]))
        {  zeitenAnzeige(3); lastTime[4] = RZvk[3]; lastTime[5] = RZnk[3]; }
        if ((lastTime[6] != RZvk[4]) || (lastTime[7] != RZnk[4]))
        {  zeitenAnzeige(4); lastTime[6] = RZvk[4]; lastTime[7] = RZnk[4]; }
      }
      break;
    case 2:
      static uint16_t lastSpuren[maxSpuren + 1] = {0};
      if (!merker)
      {
        Serial.println(F("Rundenanzeige"));
        lcd.setCursor(0, 1);
        lcd.print(F("  Runden-Anzeige "));
        clearLeft();
        //spurAnzeigeLinks();
        for (uint8_t i = 1; i <= spuren; i++)
        {
          spurAnzeigeRechts(i);
          lastSpuren[i] = AR[i];
        }
        merker = true;
      }
      else
      {
        for (uint8_t i = 1; i <= spuren; i++)
        {
          if (lastSpuren[i] != AR[i])
          {
            spurAnzeigeRechts(i); 
            lastSpuren[i] = AR[i];
          }
        }
      }
      break;
    case 3:
      {
        const uint32_t dotTime = 500;
        static uint32_t lastMillis = 0;
        static int16_t lYear = 0;
        static uint8_t lDay, lMonth = 61;
        static int8_t ltemp = 0;
        static uint8_t lastDot = 2; // Start Merker mit dot AUS
        if (!merker)
        {
          Serial.println(F("Uhranzeige"));
          lcd.setCursor(0, 1);
          lcd.print(F("Uhrzeit-Anzeige "));
          clearRight();
          clearBrightness();
          uhrAnzeigeLinks();
          for (uint8_t i = 1; i < 7; i++)  // Init der case 1-7 in uhrAnzeigeRechts // 
          {
            uhrAnzeigeRechts(i);
          }
          merker = true;
        }
        else
        {
          // Begin Erzeugung Dot blinken
          if (millis() - lastMillis <= dotTime)                        // Zeit nicht abgelaufen?
              {if (lastDot == 2) { lastDot = uhrAnzeigeRechts(1); }}   // DotMerker ist AUS -> dann 
          else if (lastDot == 1) { lastDot = uhrAnzeigeRechts(2); }    // Zeit abgelaufen UND DotMerker ist EIN -> dann
          if (millis() - lastMillis >= 1000) { lastMillis = millis(); }// Zeitmerker zurücksetzen
          // Ende Erzeugung Dot blinken
          if (lDay   != day())    { lDay = uhrAnzeigeRechts(3);    }   // Kalenderdaten aktuallisieren
          if (lMonth != month())  { lMonth = uhrAnzeigeRechts(4);  }
          if (lYear  != year())   { lYear = uhrAnzeigeRechts(5);   }
          if (ltemp  != temp)     { ltemp = uhrAnzeigeRechts(6);   }   // Temperatur...
        }
      }
      break;
    case 4:
    static uint16_t lastVoltage[maxSpuren + 1] = {0};
      if (!merker)
      {
        Serial.println(F("Spannungsanzeige"));
        lcd.setCursor(0, 1);
        lcd.print("   Bahnstrom    ");
        clearRight();
        clearBrightness();
        StromAnzeigeLinks();
        for (uint8_t i = 1; i <= spuren; i++)
         {
         VoltageAnzeigeRechts(i);
         lastVoltage[i] = Voltage[i];
        }
        merker = true;
      }
      else
      {
        for (uint8_t i = 1; i <= spuren; i++)
        {
          if (lastVoltage[i] != Voltage[i])
          {
        VoltVK[i] = (Voltage[i]) / 10;
        VoltNK[i] = (Voltage[i]) - (VoltVK[i] * 10);
        if ((VoltNK[i]) < 3) (VoltNK[i]) = 0;
        if ((VoltNK[i]) > 2 && (VoltNK[i]) < 8 )(VoltNK[i]) = 5;
        if ((VoltNK[i]) > 7)
        {
          (VoltNK[i]) = 0;
          (VoltVK[i])= (VoltVK[i])+ 1;
        }
         VoltageAnzeigeRechts(i);
         lastVoltage[i] = Voltage[i];
          }
        }
      }
      break;
      case 5:
      if (!merker)
      {
        Serial.println(F("Tages-Rundenanzeige"));
        lcd.setCursor(0, 1);
        lcd.print("  Gesamtrunden  ");
        clearAll();
        clearBrightness();
        Serial.println("case 5");
        TagesAnzeigeLinks();
        for (uint8_t i = 1; i <= spuren; i++)
        {
          spurTagesRundenRechts(i);          
        }      
        merker = true;
      }
      else
       {
        for (uint8_t i = 1; i <= spuren; i++)
        { 
          if (lastTagesrunden[i] != TagZahl[i]){      
          spurTagesRundenRechts(i);
          lastTagesrunden[i] = TagZahl[i];
          }
      } 
    }     
      break;
    default:
      anzeigeType = 1;
      break;
    }
    // *INDENT-ON*
}

void zeitenAnzeige(const uint8_t spur)            // Anzeigetafel links/rechts für Rundenzeiten
{
  tmDisp[(spur - 1) * 2].showNumberDec(RZvk[spur]);
  tmDisp[(spur - 1) * 2 + 1].showNumberDec(RZnk[spur], true, 3, 0);
}

void uhrAnzeigeLinks()                            // Anzeigetafel links für Uhr/Datum Anzeige
{
  tmDisp[0].setSegments(Uhr);
  tmDisp[2].setSegments(Cal);
  tmDisp[4].setSegments(Jahr);
  tmDisp[6].setSegments(Grad);
}

uint16_t uhrAnzeigeRechts(const uint8_t type)     // Anzeigetafel rechts für Uhr/Datum Anzeige
{
  // *INDENT-OFF*
  uint16_t rueckgabe = 0;
  switch (type)
  {
    case 1: tmDisp[1].showNumberDecEx((hour() * 100) + minute(), 0b01000000, true); rueckgabe = 1; break;
    case 2: tmDisp[1].showNumberDecEx((hour() * 100) + minute(), true); rueckgabe = 2; break;
    case 3: tmDisp[3].showNumberDec(day(), DEC, 2, 0); rueckgabe = day(); break;
    case 4: tmDisp[3].showNumberDec(month(), DEC, 2, 2); rueckgabe = month(); break;
    case 5: tmDisp[5].showNumberDec(year()); rueckgabe = year(); break;
    case 6: tmDisp[7].showNumberDec(temp, false, 2, 0); tmDisp[7].setSegments(C, 1, 3); rueckgabe = temp; break;
  }
  return rueckgabe;
  // *INDENT-ON*
}

void spurAnzeigeLinks()            // Anzeigetafel links für Rundenanzeige
{
  tmDisp[0].setSegments(Sp);
  tmDisp[2].setSegments(Sp);
  tmDisp[4].setSegments(Sp);
  tmDisp[6].setSegments(Sp);
  teil2AnzeigeLinks();
}

void TagesAnzeigeLinks()            // Anzeigetafel links für Gesamtrunden
{
  tmDisp[0].setSegments(AL);
  tmDisp[2].setSegments(AL);
  tmDisp[4].setSegments(AL);
  tmDisp[6].setSegments(AL);
  teil2AnzeigeLinks();
}

void StromAnzeigeLinks()            // Anzeigetafel links für Bahnstrom
{
  tmDisp[0].setSegments(U);
  tmDisp[2].setSegments(U);
  tmDisp[4].setSegments(U);
  tmDisp[6].setSegments(U);
  teil2AnzeigeLinks();
}

void teil2AnzeigeLinks()
{
  tmDisp[0].setSegments(Eins, 1, 3);
  tmDisp[2].setSegments(Zwei, 1, 3);
  tmDisp[4].setSegments(Drei, 1, 3);
  tmDisp[6].setSegments(Vier, 1, 3);
}


void spurTagesRundenRechts(const uint8_t spur)    // Anzeigetafel rechts für Gesamtrunden
{
  // *INDENT-OFF*
    switch (spur)
    {
    case 1: tmDisp[1].showNumberDec(TagZahl[spur]); break;
    case 2: tmDisp[3].showNumberDec(TagZahl[spur]); break;
    case 3: tmDisp[5].showNumberDec(TagZahl[spur]); break;
    case 4: tmDisp[7].showNumberDec(TagZahl[spur]); break;
    }
    // *INDENT-ON*
}

void spurAnzeigeRechts(const uint8_t spur)        // Anzeigetafel rechts für Rundenanzeige
{
  switch (spur)
  {
    case 1: tmDisp[0].setSegments(Sp, 3, 0);
      tmDisp[0].setSegments(Eins, 1, 3);
      tmDisp[1].showNumberDec(AR[spur]);
      break;
    case 2: tmDisp[2].setSegments(Sp, 3, 0);
      tmDisp[2].setSegments(Zwei, 1, 3);
      tmDisp[3].showNumberDec(AR[spur]); break;
    case 3: tmDisp[4].setSegments(Sp, 3, 0);
      tmDisp[4].setSegments(Drei, 1, 3);
      tmDisp[5].showNumberDec(AR[spur]); break;
    case 4: tmDisp[6].setSegments(Sp, 3, 0);
      tmDisp[6].setSegments(Vier, 1, 3);
      tmDisp[7].showNumberDec(AR[spur]); break;
  }
}

void VoltageAnzeigeRechts(const uint8_t spur)     // Anzeigetafel rechts für Bahnstrom
{
  switch (spur)
  {
    case 1:
      tmDisp[1].showNumberDec(VoltVK[spur], false, 2, 0);
      tmDisp[1].setSegments(Komma, 1, 2);
      tmDisp[1].showNumberDec(VoltNK[spur], false, 1, 3); break;
    case 2:
      tmDisp[3].showNumberDec(VoltVK[spur], false, 2, 0);
      tmDisp[3].setSegments(Komma, 1, 2);
      tmDisp[3].showNumberDec(VoltNK[spur], false, 1, 3); break;
    case 3:
      tmDisp[5].showNumberDec(VoltVK[spur], false, 2, 0);
      tmDisp[5].setSegments(Komma, 1, 2);
      tmDisp[5].showNumberDec(VoltNK[spur], false, 1, 3); break;
    case 4:
      tmDisp[7].showNumberDec(VoltVK[spur], false, 2, 0);
      tmDisp[7].setSegments(Komma, 1, 2);
      tmDisp[7].showNumberDec(VoltNK[spur], false, 1, 3); break;
  }
}

void clearAll()                                   // Anzeigetafel komplett löschen
{
  clearLeft();
  clearRight();
}

void clearLeft()                                  // Anzeigetafel Links löschen
{
  for (uint8_t i = 0; i <= 6; i += 2)
  {
    tmDisp[i].clear();
  }
}

void clearRight()                                 // Anzeigetafel Rechts löschen
{
  for (uint8_t i = 1; i <= 7; i += 2)
  {
    tmDisp[i].clear();
  }
}

void Datensicherung()                             // Prüfen ob Wert sich verändert hat, wenn ja neuen Wert ins EEprom schreiben
{
  EEPROM.update(1, lumi);
  EEPROM.update(2, kanal);
  EEPROM.update(3, id);
  EEPROM.update(4, SBild);
  EEPROM.update(5, AnzahlSpuren);
  for (uint8_t i = 0; i < 3 ; i++)
  {
    EEPROM.update(i + 10, rgbLicht[0][i]); //Farbe für Eingang
    EEPROM.update(i + 20, rgbLicht[1][i]); //Farbe für Erdgeschoss
    EEPROM.update(i + 30, rgbLicht[2][i]); //Farbe für Obergeschoss
  }
  DEBUG_PRINT(F("Ich war bei der Datensicherung"));
}

void Werkseinstellung()                           // Setzt alle Werte zurück auf Standard
{
  // Es werden die Voreinstellungen abgespeichert und neu gestartet!!!
  EEPROM.update(1, 2);           // Speicheradresse ,Helligkeit (Werte 1 bis 7)  Werkseinstellung=2
  EEPROM.update(2, 127);         // Speicheradresse ,Funkkanal  (Werte 1 bis 127)Werkseinstellung=127
  EEPROM.update(3, 10);          // Speicheradresse ,ID         (Werte 1 bis 50) Werkseinstellung=10
  EEPROM.update(4, 2);           // Speicheradresse ,Startbild  (Werte 1 bis 4)  Werkseinstellung=2
  EEPROM.update(10, 55);         // Speicheradresse ,Farbe Rot für Eingang
  EEPROM.update(11, 20);         // Speicheradresse ,Farbe Grün für Eingang
  EEPROM.update(12, 0);          // Speichersdresse ,Farbe Blau für Eingang
  EEPROM.update(20, 20);         // Speichersdresse ,Farbe Rot für Erdgeschoss
  EEPROM.update(21, 20);         // Speichersdresse ,Farbe Grün Erdgeschoss
  EEPROM.update(22, 20);         // Speichersdresse ,Farbe Blau für Erdgeschoss
  EEPROM.update(30, 25);         // Speichersdresse ,Farbe Rot für Obergeschoss
  EEPROM.update(31, 25);         // Speichersdresse ,Farbe Grün für Obergeschoss
  EEPROM.update(32, 25);         // Speichersdresse ,Farbe Blau für Obergeschoss
  DEBUG_PRINT(F("Werkseinstellungen wurden geladen"));
  {
    asm volatile ("  jmp 0");                               // Software-Reset
  }
}

void leseEingaenge()                              // Abfrage Extern für Anzeigetafel und Licht
{
  uint32_t jetzt = millis();
  static uint32_t vorhin = 0;
  const uint32_t intervall = 500;
  //uint8_t Wsl_old;                                         // soll aktuelle Wsl vor Chaos merken und dort zurückschalten nach wenn kein Chaos "BAUSTELLE"
  
  // Abfrage der Externeingänge für Turmanzeige
  if ((digitalRead(ExternPin[0])) && (ExternAnz_state == 0)) // Extern EingangPin X=Low und kein anderes Extern EingangsSignal für Anzeigetafel
  {
    ExternAnz_state = 1;                                     // Setze EingangsSignal
    Wsl = 1;                                                 // Wechsel die Turmanzeige zu Wsl=1 Rundenzeiten
    Serial.println(ExternAnz_state);
  }
  if ((digitalRead(ExternPin[1])) && (ExternAnz_state == 0)) // Extern EingangPin X=Low und kein anderes Extern EingangsSignal für Anzeigetafel
  {
    ExternAnz_state = 1;                                     // Setze EingangsSignal
    Wsl = 2;                                                 // Wechsel die Turmanzeige zu Wsl=2 Anzahl Runden
    Serial.println("WSL 2");                                
    Serial.println(ExternAnz_state);
  }
  if ((digitalRead(ExternPin[2])) && (ExternAnz_state == 0)) // extern EingangPin X=Low und kein anderes Extern EingangsSignal für Anzeigetafel
  {
    ExternAnz_state = 1;                                     // Setze EingangsSignal
    Wsl = 3;                                                 // Wechsel die Turmanzeige zu Wsl=3 Datum/Uhrzeit
    Serial.println(ExternAnz_state);
  }
  if ((digitalRead(ExternPin[3])) && (ExternAnz_state == 0)) // extern EingangPin X=Low und kein anderes Extern EingangsSignal für Anzeigetafel
  {
    ExternAnz_state = 1;                                     // Setze EingangsSignal
    Serial.println("WSL 4");                                 
    Serial.println(ExternAnz_state);                         // Wechsel die Turmanzeige zu Wsl=4 Bahnstrom
    Wsl = 4;
    for (uint8_t i = 1; i <= spuren; i++)
    {
      Voltage[i] = 0;                                        // Setze Anfangswert bis zum ersten Empfang der Daten
    }
  }
  if ((digitalRead(ExternPin[4])) && (ExternAnz_state == 0)) // extern EingangPin X=Low und kein anderes Extern EingangsSignal für Anzeigetafel
  {
    ExternAnz_state = 1;                                     // Setze EingangsSignal
    Serial.println("WSL 5");                                 
    Serial.println(ExternAnz_state);
    Wsl = 5;                                                 // Wechsel die Turmanzeige zu Wsl=5 Tagesrunden
  }
  if ((!digitalRead(ExternPin[0])) &&                       // Rücksetzen des EingangsSignal
      (!digitalRead(ExternPin[1])) &&                       // Erst wenn alle 5 Eingänge HIGH sind wird zurückgesetzt  
      (!digitalRead(ExternPin[2])) &&
      (!digitalRead(ExternPin[3])) &&
      (!digitalRead(ExternPin[4])))
  {
    ExternAnz_state = 0;                                             // EingangsSignal zurückgesetzt 
  }

  
  // Ab hier Externlicht Abfrage
  if ((digitalRead(ExternPin[5])) && ((ExternLich_state[0]) == 0))   // extern EingangPin X=Low und Merker ob Schalter / Taster nicht gedrückt ist
  {
    pixelAnAus(0, 1);                                                // Schalte Licht Eingang ein
    ExternLich_state[0] = 1;                                         // Merker Licht Eingang Schalter / Taster ist gedrückt
  }
  if ((!digitalRead(ExternPin[5])) && ((ExternLich_state[0]) == 1))  // Abfrage Externeingänge für Turmlicht Eingang Aus
  {
    pixelAnAus(0, 0);                                                // Schalte Licht Eingang aus                                               
    ExternLich_state[0] = 0;                                         // Merker Schalter / Taster nicht mehr gedrückt
  }
  if ((digitalRead(ExternPin[6])) && ((ExternLich_state[1]) == 0))   // extern EingangPin X=Low und Merker ob Schalter / Taster nicht gedrückt ist
  {
    pixelAnAus(1, 1);                                                // Schalte Licht Erdgeschoss ein
    ExternLich_state[1] = 1;                                         // Merker Licht Erdgeschoss Schalter / Taster ist gedrückt
  }
  if ((!digitalRead(ExternPin[6])) && ((ExternLich_state[1]) == 1))  // Abfrage Externeingänge für Turmlicht Erdgeschoss Aus
  {
    pixelAnAus(1, 0);                                                // Schalte Licht Erdgeschoss aus 
    ExternLich_state[1] = 0;                                         // Merker Schalter / Taster nicht mehr gedrückt
  }
  if ((digitalRead(ExternPin[7])) && ((ExternLich_state[2]) == 0))   // extern EingangPin X=Low und Merker ob Schalter / Taster nicht gedrückt ist
  {
    pixelAnAus(2, 1);                                                // Schalte Licht Obergeschoss ein
    ExternLich_state[2] = 1;                                         // Merker Licht Obergeschoss Schalter / Taster ist gedrückt
  }
  if ((!digitalRead(ExternPin[7])) && ((ExternLich_state[2]) == 1))  // Abfrage Externeingänge für Turmlicht Obergeschoss Aus
  {
    pixelAnAus(2, 0);                                                // Schalte Licht Obergeschoss aus
    ExternLich_state[2] = 0;                                         // Merker Schalter / Taster nicht mehr gedrückt
  }
  if  (digitalRead(ExternPin[9]))                                    // extern EingangPin X=Low 
  {                                                                  // Chaos Licht, Alle LED's blinken
    Wsl = 3;                                                         // Zeige Uhrzeit während Chaostste betätigt ist....später vielleicht eine Chaos Anzeigetafel                                           
    ExternLich_state[3] = 1;                                         // Merker Schalter / Taster ist gedrückt                            
    if (jetzt - vorhin >= intervall)
    {
      vorhin = jetzt;
      if (pixel.getPixelColor(1) > 0)                                // 
      {
        pixel.fill(0, 0);                                            // Alle Pixel ausschalten
      }
      else
      {
        pixel.fill(pixel.Color(110, 40, 0), 0, 7);                   // Pixel Orange setzen - Farbe, ab LED 0, für 7 LED
      }
      pixel.show();                                                  // Zeige alle Pixel in Orange
    }
  }
  if ((!digitalRead(ExternPin[9])) && ((ExternLich_state[3]) == 1 ))  //Abfrage Externeingänge für Turmlicht Chaos blinken = LOW und Merker ob Schalter / Taster gedrückt ist
  {
    pixel.fill(pixel.Color(0, 0, 0), 0, 7);                           // Setze alle LED's auf Aus
    pixel.show();
    ExternLich_state[3] = 0;                                          // Merker Schalter / Taster nicht mehr gedrückt
    for (uint8_t i = 0; i < 3; i++)
    {
      if ((ExternLich_state[i]) == 1)                                 // Prüfen welcher Schalter / Taster gedrückt
      {
        pixelAnAus(i, 1);                                             // Schalte entsprechende LED's wieder ein
      }
    }                                          
    Wsl = SBild;                                                      // Wechsel wieder zu SBild.....Baustelle soll zu Old_Wsl wechseln
  }
}

void merkeRunden()                                // Zählt alle Runden pro Spur zusammen
{
  for (uint8_t i = 1; i <= spuren; i++)
  {
    if ((AR[i] > maxRunden) && (Wsl == 2))        // hat AR[i] mehr Runden gefahren als maxRunden
    {
      maxRunden = AR[i];                          // dann hat AR[i] die meist gefahrenden Runden
      poleZeile(i);                               // Lass entsprechende Zeile heller leuchten
    }
    if (AR[i] > lastAR[i])
    {
      TagZahl[i] = TagZahl[i] + AR[i] - lastAR[i];
      lastAR[i] = AR[i];
    }
    else
    {
      bool neustart = true;
      for (byte b = 1; b <= spuren; b++)
      {
        if (AR[b] >= 1) neustart = false;
      }
      if (neustart)
      {
        lastAR[i] = 0;
        maxRunden = 0;
      }
    }
  }
}

void poleZeile(const uint8_t pole)              // Anzeigetafel rechts für Pole
{
  for (byte b = 0; b < sizeof(tmDisp) / sizeof(tmDisp[0]); b++)
  {
    tmDisp[b].setBrightness(lumi);
  }
  tmDisp[ (pole - 1) * 2 ].setBrightness(lumiPole);
  tmDisp[ ((pole - 1) * 2) + 1 ].setBrightness(lumiPole);
}
void clearBrightness()                            // Alle TM1637-Anzeigen auf eingestellten bzw. gespeicherten Wert zurücksetzen
{
  for (byte d = 0; d < 8; d++)
  {
    tmDisp[d].setBrightness(lumi);
  }
}
[/code]
1 Like