I²C LiquidCrystal mit noBacklight

Was kann hier stören?

Mega 2560 mit folgenden Lib´s

Einbindung
#define MAX8BUTTONS     // MobaTools: maximal acht Taster
#include <MobaTools.h>
#include <AVR_PWM.h>
#include <Wire.h>
#include <NoiascaEncoder.h>        // download library from http://werner.rothschopf.net/microcontroller/202202_noiasca_encoder_en.htm
#include <NoiascaLiquidCrystal.h>  // download library from https://werner.rothschopf.net/202009_arduino_liquid_crystal_intro.htm 
//#include <NoiascaHW/lcd_4bit.h>    // parallel interface, 4bit
#include <NoiascaHW/lcd_PCF8574_fast.h>// include the proper IO interface   *** Nur für Simm Martin ****
//LiquidCrystal_4bit LCD(rs, en, d4, d5, d6, d7, bl, cols, rows);
LiquidCrystal_PCF8574_fast LCD(0x27, 16, 2);   //                             *** Nur für Simm Martin ****
//#define PCF1 0x20 
#include "PCF8574.h"

Folgendes Problem
wird das LCD Display mit LCD.noBacklight angesprochen dann wird der I²C Bus traktiert.


Chanel 3 ist EN des LCD und Chanel 2 ist hier D6 LCD den Rest habe ich nicht angeschlossen, dient ja auch nur zur Kontrolle.
ist LCD backlight aktiv

und nach Datenübertragung Ruhe auf dem I²C Bus.

ist das Verhalten des I²C Busses normal.
Mit der LiquidCrystal ( noiasca ) und LCD noBacklight.
dann sieht das Ganze so aus

Vergrößert:


es wird EN am LCD Display gesetzt.
Die große Frage ist jetzt: Welche der eingebundenen Lib verursacht dieses Verhalten?
Die LCD Libs egal welche für sich allein sind in der Funktion richtig.
ein noBacklight wird gesetzt und I²C ist in Ruhestellung.
die NoiascaEncoder.h hatte ich zum Testen auch mal entfernt das verhalten ist geblieben.
Vielleicht hat da ja einer ne Idee welche Lib dieses Verhalten verursacht.
AVR_PWM.h ist auf uint32_t PWM_Pins[] = { 46, 6 }; // A Timer 5 und 4
MobaTools.h wird mit Button / Servo und Timer Funktion angesprochen.
Da ja ein Mega2560 in gebrauch ist gehe ich davon aus dass Timer 3 dafür verwendung findet.

Ausschnitt MobaTools

2.1.1 ATmega328P, ATMega2560, ATmega32u4, ATtiny
Boards: UNO Rev3, Nano classic, Mega2560, Leonardo, Micro u.ä
Die MobaTools verwenden intensiv den Timer1 des Arduino (AVR). D.h. Alle anderen Libraries oder Funktionen, die ebenfalls den Timer1 verwenden, können nicht gleichzeitig genutzt werden. Dies betrifft z.B. die Standard-ServoLib und analogWrite an den Pins 9+10. Ist der Timer 3 vorhanden, so wird er anstelle des Timer 1 verwendet. Das betrifft z.B. Arduino Leonardo, Micro und Mega.

NoiascaEncoder nutzt keine Interrupts und keine Timer. Sie nutzt zwar Portzugriffe - aber ausschließlich über Arduino interne Funktionen
digitalPinToBitMask()
digitalPinToPort()
portInputRegister()

die NoiascaHW/lcd_PFC8574_fast ... setzt bei noBacklight eigentlich nur ein internes Flag

noBacklight() --> setBacklight(0)
setBacklight() --> command(0)
command() -> send()
send() ruft dann zweimal write4bits()
write4bits() macht dann am AVR und für den ESP8266 eine I2C Datenübertragung (mit gesetztem / gelöschtem BL Pin) .
Jede Übertragung besteht aus zwei Bytes - und ja - zunächst mit aktiviertem EN. Und dann ein zweites wo nur mehr der BL Pin drinnen sein soll (bzw. bei noBacklight eben 0).

Meine Anname - du könntest auf einem Mega zwei I2C Packete sehen beim noBacklight.
Wenn du das auch siehst - dann "Works as designed".

Wenn nicht - dann beschreibe bitte was genau bei dir zu einem Fehler führt.

Mach doch mal ein MRE und lass das BL im Sekundenryhtmus blinken (without delay).
Und dann ergänze eine weitere Library nach der anderen.

noBacklight :joy: was im Prog nach 10 Sekunden nichts tun aktiviert wird.


Das wird wohl den Unterschied zur
LCDI2C_Multilingual.h Lib erklären. Die ist hier im ersten Bild im einsatz.
Mit einem 2 ten PCF 0x20 (nur zum Test. In Bild 4 sieht ma dann, das der gesammte I²C Bus 0x27 0x20 ausgegeben wird bis noBacklight Inaktiv ist.(backlight aktiv).

Richtig ! wird so ja auch in Dauerschleife ausgegeben.
erst 0x27
dann
En
static const uint8_t enPin = 0b00000100; // the enable pin
und
uint8_t backlightState = 0;
Und ja ich werde der Sache mit Versuch und Irtum auf dem Grund gehen
Kleines Prog mit Blink Intervall 5 Sec auf Backlight und nach und nach die anderen Libs einbinden.
Werde das Ergebniss dann berichten.

Tja, Nobody is perfect

kleiner Test

/**************************LCD *****************************************************
   Variants of German umlauts Ä Ö Ü
   LCD in parallel 4 bit Mode

   open tasks:
   - ISO 8583 Latin 1 - 4  Characters on LCD with SPI connector

   Hardware:
   LCD should be wired as follows:

   LCD          UNO
   --------------------------
   VSS    GND   GND
   VDD    5V    Vin
   V0           -       contrast - connect a poti to GND
   RS           P0 RS
   RW     GND   -       Read/Write not used in this library - Pulldown to GND     
   E            P2 EN
   DB0          -
   DB1          -
   DB2          -
   DB3          -
   D4           P4 DB4
   D5           P5 DB5
   D6           P6 DB6
   D7           P7 DB7
   LEDA   5V
   LEDK   GND   P10 Backlight circuitry (HIGH signal enables backlight using a simple NPN transistor)

   by noiasca
   2021-05-16
   2020-09-01 base 4bit 2928/296 
   
 ******************************************************************************
 */

const byte cols = 16;                  // columns/characters per row
const byte rows = 2;                   // how many rows
const byte rs = 34;
const byte en = 32;
const byte d4 = 31;
const byte d5 = 33;
const byte d6 = 35;
const byte d7 = 37;
const byte bl = 36;                    // set to 255 if not used

//#define CLICK_NO_SHORT  // MobaTools: das ‚shortPress‘ Ereignis wird gelöscht, wenn beim Aufruf von ‚clicked‘ ein Einfach- oder Doppel-Klick erkannt wurde.
#define MAX8BUTTONS     // MobaTools: maximal acht Taster
#include <MobaTools.h>
#include <AVR_PWM.h>
#include <Wire.h>
#include <NoiascaEncoder.h>        // download library from http://werner.rothschopf.net/microcontroller/202202_noiasca_encoder_en.htm
#include <NoiascaLiquidCrystal.h>  // download library from https://werner.rothschopf.net/202009_arduino_liquid_crystal_intro.htm 
//#include <NoiascaHW/lcd_4bit.h>    // parallel interface, 4bit
#include <NoiascaHW/lcd_PCF8574_fast.h>// include the proper IO interface   *** Nur für Simm Martin ****
//LiquidCrystal_4bit LCD(rs, en, d4, d5, d6, d7, bl, cols, rows);
LiquidCrystal_PCF8574_fast LCD(0x27, 16, 2);   //                             *** Nur für Simm Martin ****
button_t getHW( void );  // macht den Compiler hinsichtlich Reihenfolge glücklich
MoToButtons taster( getHW, 20, 2000 );  // 50ms Entprellzeit, 2000ms für den Unterschied kurz/lang gedrückt.
enum tasterNr { TASTER_S, TASTER_O, TASTER_U, TASTER_D , Button1, Button2, Button3};  // Index für die MobaTools
Encoder myEnc(28, 24);//   Interruptpin wählen   // (DT grau  und CLK grün)

const byte DrehTast = 26; // Taster Drehencoder                 *gelb     
const byte tasterS = 4;   // Taster Stopp
const byte tasterU = 3;   // Taster Unten / vorne runter
const byte tasterO = 2;   // Taster Oben  / vorne rauf
const byte Butt_1 = 30;   // Handtaster rechts / vorne rauf     *blau
const byte Butt_2 = 27;   // Handtaster links / vorne runter    *pink
const byte Butt_3 = 25;   // Handtaster Stopp                   *violett

button_t getHW( void )    // Einlesen der Tasterstatus (Plural lt. Duden)
{
  button_t tasterTemp = 0;
  bitWrite( tasterTemp, 0, !digitalRead(tasterS) );  // 0
  bitWrite( tasterTemp, 1, !digitalRead(tasterO) );  // 1
  bitWrite( tasterTemp, 2, !digitalRead(tasterU) );  // 2
  bitWrite( tasterTemp, 3, !digitalRead(DrehTast) ); // 3
  bitWrite( tasterTemp, 4, !digitalRead(Butt_1) );   // 4
  bitWrite( tasterTemp, 5, !digitalRead(Butt_2) );   // 5
  bitWrite( tasterTemp, 6, !digitalRead(Butt_3) );   // 6
  
  return tasterTemp;
}
const byte Poti = A0;     // Potischleifer an Pin  Poti ca. 10-50 K Ohm als Spannungsteiler mit C = 10 uF Schleifer / GND

MoToServo DornServo;
// *************** PWM Motor  ***********//
uint32_t PWM_Pins[]       = { 46, 6 };  // A Timer 5 und 4
//uint32_t PWM_Pins[]       = { 7, 45 }; // B Timer   45 RichtungA 7 RichtungB 
//uint32_t PWM_Pins[]       = { 8, 44 }; // C Timer   44 Richtung C für Lok B
#define NUM_OF_PINS       ( sizeof(PWM_Pins) / sizeof(uint32_t) )
float dutyCycle[]  = { 0.0f, 0.0f };
float freq[] = {20000.0f , 20000.0f}; // 1. Paternosterantrieb  , 2. für Lok
AVR_PWM* PWM_Instance[NUM_OF_PINS];
const byte RichtungA = 45;  // Drehrichtung H-Brücke 1  * Paternoster *
const byte RichtungB =  7;  // Drehrichtung H-Brücke 2  * Lok 1 *
const byte RichtungC =  44; // Drehrichtung H-Brücke 3  * Lok 2 * Nur wenn Paternoster frei
const byte LokB =  47;      // Wechsel auf Lok B  **  SETUP für LokB:   RichtungA = LOW ; LokB = HIGH ***
const byte Enabel = 8;      // H-Bruecke Ein / Aus 
const byte Enabel2 = 5;     // H-Bruecke für Lok 1 Ein / Aus  
// ******************  Sensoren  ******************* // 
const byte TCRT = A4;       //  Pin Sensor TCRT  Gondel Postition
const byte SlowO = A2;      //  Pin Sensoren Langsamfahrt 
const byte SlowU = A3;      //  Pin Sensoren Langsamfahrt
const byte TCRTG = A1;      //  Pin Sensor TCRT für Gondel Lesen Strichcode
const byte BGondel = A5;    //  Pin Belgtmeldung Gondel Abfrage
const byte Haltepunkt = 37; //  Wert Haltepunkt Gondel für Sensor TCRT5000  
// ******************  Sonstiges  ******************* // 
const byte R1Gondel = 38;   //  Relais 1 Gondel Belegtmeldung
const byte R2Gondel = 39;   //  Relais 2 Gondel Belegtmeldung
const byte Dorn = 22;       // PIN Erkennung Dornlage  Dorn Hinten?
const byte Panel = 29;      // PIN Erkennung Handpanel Tasten / Drehgeber Gesteckt    orange
const byte LED = 13;        //  LED  Arduino Board
const byte Servo = 12;      // Servo an PIN 
// ******************  Gondel / Gondelfahrt  ******************* // 
uint16_t Setzzeit[3];       // verrechnungszeiten Gondel Lesen
uint16_t Lesezeit[7];       // verrechnungszeiten Gondel Lesen
const byte Teiler= 10;      // Teiler 10 aus 10 mm breite der obersten und untersten Balken der Strichcodes
const byte Tolleranz = 4;   // Tolleranzwert Genauigkeit Lesen Strichcode 
uint8_t gondel,gondelAlt,GondelSetz; // Vari für Gondelfahrt
byte Richtung;                      // Fahrtrichtung
enum Richtung {Halt,Oben,Unten,Stop,Vor,Ruek};
byte Status,GStatus,GFehler,GLesen; // Vari für Paternosterfahrt Nr. Lesen
enum Status {Aus,Anfahren,Bremsen,SlowOben,SlowUnten,ASlowUnten};


//                   Start PWM Richtung Oben    ***********  
//                   |  Max PWM Richtung Oben
//                   |  |    Slow PWM Richtung Oben
//                   |  |    |   Start PWM Richtung Unten
//                   |  |    |   |   Max PWM Richtung Unten
//                   |  |    |   |   |   Slow PWM Richtung Unten
uint8_t Rampe[] = { 10, 50, 20, 10, 50, 20};  //  ****   Anfang  PWM /Beschleunigung / Slow Fahrt
//  Rampe auf neue PWM angepasst da 0 bis 100%  gegeben sind.  Werte sind durch Versuche zu ermitteln

// **********  Motorzeiten / Zeiten *******************  //
MoToTimer pause;
const uint8_t intervall = 80;       // Intervall Zeit Poti einlesen
const uint8_t Gintervall = 2;      // Intervall Zeit GondelPositions Abfrage
const uint8_t Motorintervall = 10;  // Intervall Zeit Beschleunigung  **** 10 nur für Simm
const uint8_t Bremsintervall = 8;   // Intervall Zeit Bremsen         ****  8 nur für Simm
const uint8_t StopIntervall = 5;   // Intervall Zeit Bremsen bei Slow Fahrt
const uint8_t Pulswelle = 5;        // PWM % +/- im Interwall
uint32_t zeitAlt, Time1, Time2, Time3, Time4;
const uint8_t warteLCD =5;          // Zeit in Sec. für No Backlight LCD

uint16_t speed,speedAlt;            // PWM Geschwindigkeiten Potieinstellung
uint8_t pwb,pw,pwh;                 // PWM Übergabevaiable pwh für Handpanel
uint8_t pwLok1,pwLok2;              // PWM Lock 1 und Lok 2
const byte PWMax=99;                // Maximale PWM
const byte Servospeed = 50;         // Servogeschwindigkeit 
const byte Servolage[] {50,155,95}; // Servoendlagen   !! Wert muss erst ermittelt werden Werte nur zur Simmulation
enum Servolage{Frei,Geklemmt,Mitte};
const uint16_t S_fahrzeit =1500;    // verfahrzeit für Servo
const uint16_t Kontakt=100;         // Gemessender Wert wenn Dorn geklemmt !! Muss noch ermittelt werden!!
uint8_t val,valOld;                 // Vari für Servoeinstellung  

uint8_t SWE = 0;   //   
uint8_t SW, SW1, SW2, SW3, SW4, SW5, SER, KON, Fehler, Belegt, Lok_1, Lok_2 ; // *******  Allgemeine Laufschalter ****** //
int wert;
char zeichen = 0;
//  *****************  Drehgeber ************************ //
long newPosition = 42;              // the current value to be used in your sketch
long oldPosition = 42;              // internal used previous value 

void setup() 
{
  Wire.begin();
  LCD.begin();Time4=millis(); LCD.backlight();   
  ALCD(1,0,3,0,0);ALCD(0,1,1,1,0);
  pinMode(DrehTast, INPUT_PULLUP);
  pinMode(tasterS, INPUT_PULLUP);
  pinMode(tasterO, INPUT_PULLUP);
  pinMode(tasterU, INPUT_PULLUP); 
  pinMode(Butt_1, INPUT_PULLUP);
  pinMode(Butt_2, INPUT_PULLUP);
  pinMode(Butt_3, INPUT_PULLUP);
  pinMode(Enabel, OUTPUT);
  pinMode(Enabel2, OUTPUT);
  pinMode(TCRT, INPUT);
  pinMode(TCRTG, INPUT_PULLUP);
  pinMode(LED, OUTPUT);  
  // pinMode(R1Gondel, OUTPUT); 
  // pinMode(R2Gondel, OUTPUT);
  pinMode(BGondel,INPUT);
  pinMode(SlowO, INPUT_PULLUP);
  pinMode(SlowU, INPUT_PULLUP);
  pinMode(Panel, INPUT_PULLUP);
  pinMode(RichtungA, OUTPUT);
  pinMode(RichtungB, OUTPUT);
  pinMode(RichtungC, OUTPUT);
  pinMode(LokB, OUTPUT);
  pinMode(Dorn, INPUT_PULLUP);  /*  Dorn Pin 22 ist mit Brücke auf 5V */
  
  digitalWrite(Enabel,0);digitalWrite(Enabel2,0);
  for (uint8_t index = 0; index < NUM_OF_PINS; index++)
    {
      PWM_Instance[index] = new AVR_PWM(PWM_Pins[index], freq[index], dutyCycle[index]);
      analogWrite(PWM_Pins[index],0);    
    } 

  Serial.begin(115200);
  Serial1.begin(38400);   // Pin 18 TX  Pin 19 RX  auf Bluetooth HC-05
  myEnc.begin(); 
  delay(500);

  char buf[150];
  snprintf( buf, sizeof(buf), "\nSketchname: %s\nBuild: %s\t\tIDE: %d.%d.%d\n\n", __FILE__, __TIMESTAMP__, ARDUINO / 10000, ARDUINO % 10000 / 100, ARDUINO % 100 / 10 ? ARDUINO % 100 : ARDUINO % 10);
  Serial.print(buf);   // Ausgabe des Sketchnamens
  DornServo.attach(Servo); //Servo an Pin 12
  DornServo.setSpeed( Servospeed );    // Verfahrgeschwindigkeit einstellen  
  
  if(!digitalRead(Panel)){// Ist Panel beim Start eingesteckt wird gleich zum Handpanel gestellt //
    LCD.backlight();
    Serial.println("Handpanel angeschlossen");
    ALCD(1,0,3,0,1);
    }else{ 
      PRINTStart();
  } 
  SERVO(Frei) ;
  
  if(digitalRead(Dorn)) {
    Fehler=1;}
  else{
  
  ALCD(1,0,3,0,0);ALCD(0,1,5,1,8);} // LCD Ausgabe ** Paternoster Bereit ** 
  gondelAlt=5;gondel=5; // Zu Testzwecken solange keine Gondel ins EEProm vermekt wird Start mit Gondel 5//
  pwLok1=50;pwLok2=80; // Nur zu Testzwecke ****************

}
void loop()
{
  delay(1000);
  LCD.noBacklight();
  delay(5000);
  LCD.backlight();
 
}
void SERVO( byte stell) {  
  switch (stell){
    case Frei: 
      Serial.println("Frei klappt");SW=0;
      DornServo.write(Servolage[Frei]);
      delay(S_fahrzeit);
      if(digitalRead(Dorn)){
        for(byte i=0;i<6;i++){
        DornServo.write(Servolage[Mitte]);
        delay(S_fahrzeit/2);
        DornServo.write(Servolage[Frei]);SW++;
        delay(S_fahrzeit);
        if(!digitalRead(Dorn)) {stell=7;break;} 
        }
        if(SW >= 5 ) {
          Serial.println("Fehler Servo");
           ALCD(1,0,2,1,4);ALCD(0,0,8,1,9);
          DornServo.write(Servolage[Mitte]);
          delay(S_fahrzeit);
          DornServo.detach(); digitalWrite(Enabel,0); Fehler=1;GStatus=0;           
          }
      }
      break;        
    case Geklemmt: 
      Serial.println("Geklemmt klappt");SW=0;
      DornServo.write(Servolage[Geklemmt]); 
      delay(S_fahrzeit);
      val=map(analogRead(BGondel),0,1023,0,255);
      if(val < Kontakt) {
        for(byte i=0;i<6;i++){
        DornServo.write(Servolage[Mitte]);
        delay(S_fahrzeit/2);
        DornServo.write(Servolage[Geklemmt]);SW++;
        delay(S_fahrzeit);
        val=map(analogRead(BGondel),0,1023,0,255);
        if(val >= Kontakt) {stell=7;break;} 
        }
        if(SW >= 5 ) {
          Serial.println("Fehler Servo");
           ALCD(1,0,2,1,4);ALCD(0,0,8,1,9);
          DornServo.write(Servolage[Mitte]);
          delay(S_fahrzeit);
          DornServo.detach(); digitalWrite(Enabel,0); Fehler=1;GStatus=0;
        }
      }
       break;
    case 4: ALCD(1,0,2,1,4);ALCD(0,0,8,1,9);     
      
      Fehler++;
            if(!digitalRead(Dorn)) {
              Fehler=0;ALCD(1,0,3,0,0);ALCD(0,1,1,1,8);
              digitalWrite(Enabel,1);break;
              }
              GStatus=0;
            break;
    
    
    case 7: break;
    
  }
  
}
void PRINTStart(){ // Startausgabe Serial Monitor
  Serial.println("e       H-Brueke  EIN / AUS"); Serial.println("");
  Serial.println("Wahl    Drehrichtung Motor");
  Serial.println("r       Rechts  Gondelfahrt nach Oben");
  Serial.println("l       Links   Gondelfahrt nach Unten");
  Serial.println("Space   Gondel Stop");Serial.println(" ");
  Serial.print("t       Auto Stop bei Halt  ");Serial.print(Haltepunkt);Serial.println("  am TCRT erreicht ");
  Serial.println("g       Gondel lesen Ein/Aus");Serial.println(" ");
  Serial.println("a       Beschleunigungsfahrt ");//Serial.println(" ");
  Serial.println("b       Bremsen ");Serial.println(" ");
}



void LCDPWM(uint8_t pw){ // LCD Ausgabe PWM
  Time4=millis();LCD.backlight();
  ALCD(4,1,8,0,5);LCD.setCursor(12, 1); LCD.print(pw); LCD.setCursor(14, 1); LCD.print('%');
}
const byte maxT0 = sizeof("Paternoster");  // anpassen! 
const char T0[14][maxT0] PROGMEM = {"Paternoster","Handpanel","Menue","Start","Stop","PWM  ","Gondel","Richtung ","OBEN ","UNTEN","Bremsen","Anfahren","Neu","Pos." };
const char * const T0_table[] PROGMEM = {T0[0], T0[1], T0[2], T0[3], T0[4], T0[5], T0[6], T0[7],T0[8], T0[9], T0[10], T0[11], T0[12], T0[13], T0[14]};
const byte maxT1 = sizeof("Initialisierung");
const char T1[11][maxT1] PROGMEM = { "Initialisierung", "Störung", "Zeit", "Dorn", "Servo", "NOT AUS", "POTI Stellung", "Position","Bereit", "Fehler", "Kontakt" };
const char * const T1_table[] PROGMEM = {T1[0], T1[1], T1[2], T1[3], T1[4], T1[5], T1[6], T1[7], T1[8], T1[9], T1[10], T1[11]};
void ALCD(byte loesch, uint8_t zeile, uint8_t spalte, uint8_t Tx, uint8_t text) {
  byte maxT = max(maxT, maxT0);
  maxT = max(maxT, maxT1);  // längster Text
  char buf[maxT]; // Der Buffer zum Lesen der Daten muss so lang sein wie der längste Text!
  switch (loesch) {
    case 1: LCD.clear(); break;
    case 2:
      LCD.setCursor(0, zeile);
      LCD.print("                ");
      break;
    case 3:
      LCD.setCursor(0, zeile);
      LCD.print("        ");
      break;
    case 4:
      LCD.setCursor(8, zeile);
      LCD.print("        ");
      break;
      //resume : break;
  }
  LCD.setCursor(spalte, zeile);
  switch (Tx) {
    case 0:
      strncpy_P(buf, (char*)pgm_read_word(&(T0_table[text])), sizeof(buf));
      LCD.print(buf);
      break;
    case 1:
      strncpy_P(buf, (char*)pgm_read_word(&(T1_table[text])), sizeof(buf));
      LCD.print(buf);
      break;
  }
}

Alle Libs nach und nach eingebunden
als letztes dann Dekla und Setup komplett übernommen nur die Loop nicht.
alles so wie es sein sollte.
Da muss mal der Benutzer getauscht werden :joy:
Problem liegt also zwischen meinen Ohren und ich habe in der Loop irgendwo eine Speicher überschreitung eingepflanzt die dieses Verhalten auslöst.

Aua Aus Aua :slightly_smiling_face:
wenn man

if(millis()- Time4 > warteLCD*1000) {LCD.noBacklight();}

selbst sich ein Ei legt

if(millis()- Time4 > warteLCD*1000) {LCD.noBacklight();Time4=millis();}

Auch noch nicht gut aber Fehler erkannt.
Ich denke da schau ich mal @my_xy_projekt über die Schulten
aus Christbaum.

Ausschnitt
enum class CHRISTLIGHT {off, day, all};
CHRISTLIGHT lastChristLight = CHRISTLIGHT::off;
.
.
.
if (CHRISTLIGHT::off != lastChristLight)
      {
        makeAllChristWindowOff();
        lastChristLight = CHRISTLIGHT::off;
        strip.show();player.stop();
      }

ich denke du solltest für Fixtexte stärker mit dem F-Makro arbeiten und SRAM sparen!

Serial.println(F("Geklemmt klappt"));

aber auch an vielen anderen Stellen.

Oh ja, da ist noch viel viel mehr zu machen.
Das ist ja ein Prog was gewachsen ist um Einstellungen zu tätigen und um einzelne Baustufen zu Prüfen.
Mittlerweile sind bei dem Paternoster vom (schandel) die vielen Hardwareprobleme behoben, so das es denn weitergehen kann.
Und der ganze Teil SERVO muss ja noch überarbeitet werden. In dieser Zeit ist noch wegen den delays keine Tastaturabfrage möglich.
Das hier war : Ich habe jetzt nen Mega mir mal endlich zugelegt und den Logik Analyser.
Ja und dann Testet man halt. Vorher auf dem Simm ist mir das kleine lämpchen nicht aufgefallen, zumal das Simmulieren dauert ja die 10 fache Zeit. Tja und da ist mir der Fehler durchgeruscht.
Und durch "Ich mache ja keine Fehler" sucht man dann gleich den nächsten Schuldigen. :slight_smile:
Böse Zungen würden jetzt sagen lerne erstmal aus Büchern.
Nur, ich bin Maschinenbauer Richtung Zerspannung.
Da legt man die Hand auf das Werkstück, fühlt wie es sich verhält in der Bearbeitung
und reagiert entsprechend mit Schnittgeschwindigkeit und Vorschub mit dem Rattenschwanz Werzeugschneidengeometrie und Schneidwerkstoff.
Uns da ist ein geschriebenes CNC Prog nur Hilfsmittel. Bücher (Tabellen) nur wenn man was spezielles sucht.
So schaue ich dann lieber hier im Forum, da ist die Lernkurve kleiner aber ist ja auch nur Hobby.
Und, Werkstatt wäre mir lieber. :frowning: Der Adrenalin Kick beim Prog anfahren ist unbeschreiblich. :star_struck: Das hat schon was wenn da ein par Tonnen auf dem Tisch sind und der Werkstattboden vibriert.

Oh ja.... von 33% auf 15% runter :flexed_biceps: