Uno mit Groove LCD Shield spinnt

Hallo zusammen,

am Uno ist auf SDA + SDC ein Groove LCD Display angeschlossen, per Interrupt Pin 2 + 3 ein Drehwertgeber (rotary encoder 600 AB).

Display arbeitet ganz normal bis zu dem Bereich wo eine Schleife arbeitet und das Display ständig aktualisiert. Die Impulse des Drehwertgeber werden ausgelesen und bei über 30717 ein COUNTER erhöht und der Drehwertgeber wieder auf 0 gesetzt.

  while (COUNTER < LAUFZEIT) {
    char key = keypad.getKey(); 
    IMPULS = myEnc.read();
    if (30717 < IMPULS) {
    COUNTER++;
    myEnc.write(0);
    LAUFLAENGE++;
    lcd.setCursor(0,1);
    lcd.print(COUNTER);
    lcd.print("/");
    lcd.print(LAUFZEIT);
    }
  }

Das ganze läuft ca. 1 - 3 Min und plötzlich fängt das Display an zu spinnen und zeigt verschiedene komische Symbole an die sich ständig ändern. Die Symbole und Zeit sind zufällig. Lasse ich den Arduino trotzdem weiterlaufen, stürzt er dann nach ca. 1 Minute ab.

Klammere ich aber alle lcd. Befehle aus oder lasse diese auf Serial anzeigen, klappt alles ohne Probleme.

Gibt es irgendwie ein Verbindung mit sda + sdc und Interrupt ? Gegeneinander Störung oder so ? A4 und A5 ist nicht belegt.

Danke.
Gruß
Matthias

Was für einen Drehgeber? Einen mechanischen Drehgeber macht an den InteruptPins nur wenig sinn, da das Teil einfach zu stark prellt. Wie kann dein Display angeschlossen sein, wenn A4+5 nicht belegt sind`?

Hallo sschultewolter,

mit dem Drehgeber messe ich die Umdrehungen wobei eine Umdrehung 600 Impulse sind das ganze klappt auch ohne Probleme.

Am Uno habe ich Pin SDA und SDC wo das LCD aber auch direkt an A4 und A5 angeschlossen werden kann (intern gebrückt ?). Aber ob SDA und SDC oder A4 und A5, dass Problem tritt bei beiden auf.

Das ganze läuft ca. 1 - 3 Min und plötzlich fängt das Display an zu spinnen und zeigt verschiedene komische Symbole an die sich ständig ändern. Die Symbole und Zeit sind zufällig. Lasse ich den Arduino trotzdem weiterlaufen, stürzt er dann nach ca. 1 Minute ab.

Speicherprobleme....
Ein Array Index, welcher aus dem Ruder läuft.
Stacküberlauf
Rekursion
Dynamische Speicherverwaltung,

dass Problem tritt bei beiden auf.

I2C dürfte unschuldig sein!
Auch wenn sich da der Fehler zuerst zeigt.
Es werden korrupte Daten zum LCD geschoben.
Diese werden angezeigt.
Mehr nicht.

Matthino:
Display arbeitet ganz normal bis zu dem Bereich wo eine Schleife arbeitet und das Display ständig aktualisiert. Die Impulse des Drehwertgeber werden ausgelesen und bei über 30717 ein COUNTER erhöht und der Drehwertgeber wieder auf 0 gesetzt.

Ich sehe da zwei Möglichkeiten, um nach Hilfe zu fragen:

  1. Entweder postest Du DEN VOLLSTÄNDIGEN CODE und bei Verwendung externer Drittanbieter-Libraries auch die Links auf ALLE VERWENDETEN DRITTANBIETER-Libraries.

  2. Oder Du fragst mal in einem Forum für HELLSEHER nach, ob man Dir dort weiterhelfen kann.

Das gesendete winzige Codefragment hat im Zusammenhang mit Deiner Fragestellung exakt NULL AUSSAGEKRAFT.

Bei so einer Problembeschreibung ist aber - rein hellseherisch - ein Buffer-Overflow Problem zu vermuten, so wie sich auch combie bereits geäußert hat.

Ich frage mich ob ich als Moderator nicht anfangen soll, einfach Post's zu löschen, wenn auch bei wiederholter Nachfrage nicht die notwendigen Infos nicht geliefert werden.
Grüße Uwe

Wo bin ich hier gelandet ? Was ist das für ein Moderator ?

@jurs:
Meine Frage war auf ein Bereich bezogen, nämlich I2C und Interrupt. Dieses hat combie mit seinem Post beantwortet und netterweise noch eine hellseherische Vermutung aufgrund der dürftigen Angaben angemerkt. Dein Post ist daher völlig unnütz und den vollen Code zu posten, was nicht zur Fragestellung gehört finde ich unnötig. Ich verlange von keinem hier, den kompletten Code zu analysieren. Dann würde ich schon darum bitten und logischerweise auch den ganzen Code posten.

@uwefed:
Was soll das mit wiederholter Nachfrage und Infos in Bezug auf mein Posting ? combie hat die Frage beantwortet und das reicht doch auch. Oder wird jetzt kritisiert das ich von 11:43 bis 12:54 Uhr nicht reagiert habe ?

Mir fehlen echt die Worte für die zwei letzten Posts.

Ein Danke an combie und sschultewolter.

Sowas ist mir in 15 Jahren nicht ein einziges Mal im linuxforen passiert.

Matthino:
Wo bin ich hier gelandet ? Was ist das für ein Moderator ?

Einem der 25,714 posts geschrieben hat und dem es leid ist, immer nach Infos nachfragen zu müssen.
:wink: :wink: :wink: :wink:

den vollen Code zu posten, was nicht zur Fragestellung gehört finde ich unnötig.

Der Punkt ist der Fragesteller (nicht nur du sondern viele andere) glauben zu wissen, wo der Fehler ist (in den 10 Zeilen die sie geben) aber wissen nicht welcher Fehler es ist.

Aus deinem Minimalinformationen erkennt man nicht ob die Pisn A4 und A5 für etwas verwendet werden, ob ein Indexoverflow eines Arrays auftritt, ob mehr RAM verwendet wird als der Arduino hat (Nichtverwendung von F() Makro bei .print(), welche Bibliotheken verwender werden (einige beißen sich gegenseitig) Fehler bei Verwendung von Pointern ecc.

Sowas ist mir in 15 Jahren nicht ein einziges Mal im linuxforen passiert.

Uns leider viel zu oft, daß die für die Diagnose bzw Problemanalyse notwendigen Infos uns vorenthalten werden, weil der User ja weiß wo der Fehler steckt. Ich wette, daß Dir einige der oben genannten Gründe für das Blockieren des Sketches nicht bekannt waren

Grüße Uwe

Natürlich musst du nicht innerhalb eines halben Tags antworten, und bis Uwe jemanden rausschmeisst dauert es --wenn überhaupt-- bisher auch länger. Ausserdem war jurs, wie es manchmal vorkommt, überdeutlich, so dass Uwe eigentlich nichts hätte obendraufsetzen müssen. Finde ich.

Ansonsten: mach unsern Uwe nicht an, bitte :wink:

Im Gegensatz zur allgemeinen Auffassung hier, mag ich auch keinen "ganzen code"
(die geflügelte Antwort unseres Support Team wenn die Frage nach den Versionnummern keine Hilfestellung gibt: "Please send me all your log files" )

Aber dein Schnipsel kompiliert nicht, und selbst wenn man daraus was irgendwie laufendes raten und basteln würde, bin ich ziemlich sicher dass dein Fehler nicht nach 1 bis 3 Minuten auftritt. (und durch Austausch der I2C-LCD mit Serial behoben würde).

Bzw. der Unterschied liegt darin, dass Serial deinen Unsinn-Code etwas bremst, sobald der Ausgabepuffer voll ist. Kannst ja auch mal statt des lcd den enc rausnehmen ( was immer du da für eine library verwendest. )

Das einzige was deinem Schnipsel anzusehehen ist, ist ein böses while, mit dem du leicht deinen Sketch töten kannst, musst nur die falschen Variablentypen für COUNTER und LAUFZEIT nehmen.

@uwefed

Für mich hat ein Forum eine unterstützende Hilfestellung. Ein Copy & Paste von allem und irgendeiner wird sich schon die Mühe machen ist nicht meine Art und will ich auch nicht kostenlos.

Genau aus diesem Grund habe ich die Frage komprimiert und bezog sich lediglich auf I2C und Interrupt und nicht sucht den Fehler.

Gibt es irgendwie ein Verbindung mit sda + sdc und Interrupt ? Gegeneinander Störung oder so ?

Das ist die eigentliche Frage, nicht mehr und nicht weniger. Da der Fehler nicht auftritt, wenn ich die lcd.* Befehle ausklammere und erst auftritt seit dem ich Interrupt für die Messung nutze bezog sich die Frage nur dadrauf.

Die gezielte Antwort habe ich von combie erhalten und weiß nun, dass dies nicht der Fehler sein kann um dann SELBER andere Fehlerquellen zu prüfen.

@michael_x

Im Gegensatz zur allgemeinen Auffassung hier, mag ich auch keinen “ganzen code”

Genau so sehe ich das auch, auch wenn ich mir selber keinen Gefallen damit tue.

Ich poste jetzt den ganzen Code, vielleicht hat jemand Lust mal drüber zu schauen und kann mir ein Tipp geben wo der Fehler sein könnte. Wie gesagt, klammere ich die lcd Befehle in der Schleife aus, läuft das ganze ohne Probleme. Alle Komponenten wurden getauscht, so das kein Hardwarefehler vorliegen kann.

Am Arduino ist ein Relay was zwei Motoren über ext. Stromquelle schaltet. Der Drehwertgeber hat 1 Meter bei 30717 Impulse und stoppt bei erreichter Länge die vorher per Keypad eingegeben wird.

// Seilwickler
// 26.08.2015

// Library
#include <Wire.h>         // Display
#include <rgb_lcd.h>      // Display
#include <Keypad.h>       // Keypad
#include <Encoder.h>      // Encoder
#include <SoftReset.h>    // Softreset

// Komponente   Arduino Pin                 Komponenten Pin         
// Motorrelay   Digital 7,8                 Pin IN1,IN2 (Motor 1 und Motor 2)
// Display      Analog SDA, SCL             Pin SDA,SCL identisch
// Keypad       Digital 0,10,11,13,5,6,9    Pin 5,4,6,2,8,7,3 (Keypad umdrehen, Pins nach oben, links ist der unbenutze 1, rechts 8)
// Speaker      Digital AO                  Pin beliebig, der andere auf GND
// Encoder      Digital 2,3                 weiß, grün (Rot +5V, Schwarz GND)

// Display
rgb_lcd lcd;

// Keypad
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {0, 10, 9, 13}; 
byte colPins[COLS] = {5, 6, 11}; 
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
int currentPosition = 0;
int METER[5];
int i = 0;

// Sensor
int COUNTER = 0;
int UMDREHUNG = 0;

// Encoder
Encoder myEnc(2, 3);
long IMPULS  = 0;
long STOPIMPULS = 0;

// Speaker
int Speaker = 14;

// Motorrelay
int MOTOR = 7;

// Allgemein
int LAUFLAENGE = 0;
int LAUFZEIT = 0;

// Speaker
  int tones[] = {261, 277, 294, 311, 330, 349, 370, 392, 415, 440};
  //            mid C  C#   D    D#   E    F    F#   G    G#   A
  int keya[] = {1336, 1209, 1336, 1477, 1209, 1336, 1477, 1209, 1336, 1477, 1209, 1336, 1477};
  int keyb[] = {941, 697, 697, 697, 770, 770, 770, 852, 852}; 
  int TON = 0;

void setup() {
  Serial.begin(9600);

  // Display
  lcd.begin(16, 2);           // Zeilen und Höhe definieren             
  lcd.setRGB(100, 149, 237);  // RGB Farben Hintergrundbeleuchtung

  // Motorrelay
  pinMode(7, OUTPUT);
  digitalWrite(7, HIGH);
  pinMode(8, OUTPUT);
  digitalWrite(8, HIGH);

  // Ton
  pinMode(Speaker, OUTPUT);

  // Display
  lcd.print(" Seilwickler");
  lcd.setCursor(0,1);
  lcd.print("1=klein  2=gross    ");
  char key = keypad.waitForKey();
  tone(Speaker, 941, 100);
  if (key == '2') {
        MOTOR = 8;
  }
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("0 Meter");
 
  // Keypad
  keypad.addEventListener(keypadEvent); // Callback definieren
  displayEingabeMeter();
}

void loop() {
  char key = keypad.getKey();  
  }
  
void keypadEvent(KeypadEvent key){  
  switch (keypad.getState()){
    
    case PRESSED:
        if (currentPosition == 9) {
              digitalWrite(MOTOR, HIGH);
              tone(Speaker, 221, 2000);
              lcd.clear();
              lcd.print("Abbruch");
              LAUFZEIT = COUNTER;
              STOPIMPULS = 0;
              delay(5000);
              currentPosition = 0;
              displayEingabeMeter();
              break;
              }
        if (key == '*') {
          tone(Speaker, 221, 100);
          lcd.setCursor(6,1);
          lcd.print("     ");
          lcd.setCursor(6,1);
          if (currentPosition == 0 ) {
            LAUFLAENGE = 0;
          }
          currentPosition = 0;
          displayEingabeMeter();
          break;
        }
        if (key == '#') {
          STARTMOTOR();
          break;
        }
        if (currentPosition == 0) {
          if (key == '0') {
              tone(Speaker, 221, 100);
              lcd.setCursor(6,1);
              lcd.print("     ");
              lcd.setCursor(6,1);
              currentPosition = 0;
              break;
              }
          
          METER[0] = (key)-48;                 
          lcd.print(key);
          lcd.setCursor(7,1);
          currentPosition++;
          tone(Speaker, 941, 100); 
          break;         
         }
        if (currentPosition == 1) {
          METER[1] = (key)-48;
          lcd.print(key);
          lcd.setCursor(8,1);
          currentPosition++;
          tone(Speaker, 941, 100);
          break;         
        }
        if (currentPosition == 2) {
          METER[2] = (key)-48;
          lcd.print(key);
          lcd.setCursor(9,1);
          currentPosition++;
          tone(Speaker, 941, 100);
          break;
        }
        if (currentPosition == 3) {
          METER[3] = (key)-48;
          lcd.print(key);
          lcd.setCursor(10,1);
          currentPosition++;
          tone(Speaker, 941, 100);
          break;
        }        
  }     
}

void STARTMOTOR()
 {
  lcd.noBlink();
  STOPIMPULS = 0;
  IMPULS = 0;
  myEnc.write(0);
  LAUFZEIT = 0;
  COUNTER = 0;
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("               ");
  lcd.setCursor(0,0);
  int z;
  z = 0;
  while(z<currentPosition) {
    LAUFZEIT = 10*LAUFZEIT+METER[z];  
    z++;
  }
  if (LAUFZEIT == 9999){
            lcd.print("Neustart...");
            tone(Speaker, 1041, 1000);
            delay(1000);
            soft_restart();
          }
  lcd.print(LAUFZEIT);
  lcd.print(" Meter werden");
  lcd.setCursor(0,1);
  lcd.print("gestartet...");
  delay(100);
  tone(Speaker, 941, 100);
  delay(500);
  tone(Speaker, 941, 100);
  delay(500);
  tone(Speaker, 941, 100);
  delay(500);
  tone(Speaker, 1041, 400);
  delay(1000); 
  currentPosition = 0;
  lcd.setCursor(0,0);
  lcd.print("                ");
  lcd.setCursor(0,0);
  lcd.print(LAUFLAENGE);
  lcd.print(" Meter");
  lcd.setCursor(0,1);
  lcd.print("            ");
  lcd.setCursor(0,1);
  lcd.print("0/");
  lcd.print(LAUFZEIT);
  lcd.print(" Meter");
  lcd.setCursor(0,1);
  int COUNTERALT = 0;
  currentPosition = 9;
  STOPIMPULS = LAUFZEIT * 30717L;
  digitalWrite(MOTOR, LOW);
  while (COUNTER < LAUFZEIT) {
    char key = keypad.getKey(); 
    IMPULS = myEnc.read();
    if (30717 < IMPULS) {
      Serial.print("COUNTER: ");
      Serial.println(COUNTER);
    COUNTER++;
    myEnc.write(0);
    lcd.setCursor(0,0);
    LAUFLAENGE++;
    Serial.print("LAUFLAENGE: ");
    Serial.println(LAUFLAENGE);
    lcd.print(LAUFLAENGE);
    lcd.print(" Meter");
    lcd.setCursor(0,1);
    lcd.print(COUNTER);
    lcd.print("/");
    lcd.print(LAUFZEIT);
  lcd.print(" Meter");
    Serial.print("LAUFZEIT: ");
      Serial.println(LAUFZEIT);
    }
  }
  digitalWrite(MOTOR, HIGH);
  tone(Speaker, 1041, 200);
  delay(400);
  tone(Speaker, 1041, 200);
  delay(400);
  tone(Speaker, 1041, 200);
  delay(400);
  COUNTER = 0;
  currentPosition = 0;
  displayEingabeMeter();
 }

void displayEingabeMeter()
  {
    COUNTER = LAUFZEIT;
    lcd.setCursor(0,0);
    lcd.print("               ");
    lcd.setCursor(0,0);
    lcd.print(LAUFLAENGE);
    lcd.print(" Meter");
    lcd.setCursor(0,1);
    lcd.print("               ");
    lcd.setCursor(0,1);
    lcd.print("Meter:");
    lcd.blink();
  }

Matthino:
Am Arduino ist ein Relay was zwei Motoren über ext. Stromquelle schaltet.

Das Schalten von induktiven Lasten (wie z.B. "Motoren") mittels Relais ist eine problematische Angelegenheit, abhängig von dem, was da geschaltet wird und wie die konkrete Schaltung aussieht:

  • was für ein Motor?
  • was für ein Relais?
  • wird Gleichstrom oder Wechselstrom geschaltet?
  • welche Entstörmaßnahmen in der Schaltung?

Treten die Probleme vielleicht stets nur beim Schalten von Relais/Motor auf?

In Deinem Code fällt mir so auf Anhieb zunächst mal auf, dass Du Pin-0 offenbar doppelt verwendest:

byte rowPins[ROWS] = {0, 10, 9, 13}; 
...
  Serial.begin(9600);

Auf dem UNO-Board ist Pin-0 einerseits für die serielle Schnittstelle als RX (Receive) Pin in Verwendung.
Gleichzeitig verwendest Du offenbar denselben Pin nochmal für Dein Keypad.

Das mit der Doppelverwendung desselben Pins funktioniert so nicht.

Soweit ich das übersehe, hast Du die Analogpins A1, A2 und A3 nocht nicht in Verwendung. Wenn Du mit digitalen Pins knapp wirst, kannst Du auch die UNO-Analogpins wie digitale Pins verwenden. Aber das weißt Du ja wohl bereits, weil Du das mit "int Speaker = 14;" bzw. A0 schon so machst.

Hallo jurs,

danke erst Mal für Deine Antwort.

Auch auf die Gefahr hin, aber das Relais kann ich ausschließen. Ich habe das Relais komplett abgeklemmt, die Software zum Zählen gestartet und den Motor über ein Labornetzteil versorgt, also komplett getrennt vom Arduino und der Fehler tritt ebenfalls auf.

Ich starte das Programm und gib 50 Meter ein, der Motor startet und der Encoder zählt die Meter und sendet diese bei jedem Meter an das LCD. Sind 50 erreicht stoppt der Motor.

Nach einiger Zeit schreibt das Display versetzt, dann Symbole und dann friert der Arduino ein.
Klemme ich aber sda und sdc vom Display ab und lass statt lcd.print auf serial schreiben, läuft das ganze durch (bis 2000 Meter getestet) ohne jeglichen Fehler. Bei allem was ich getestet habe war bei Fehlern das Display angeschlossen und ohne Fehler abgeklemmt.

combie sagte das es da kein Zusammenhang gibt, deswegen versuche ich gerade irgendwie die Software zu debuggen und beschäftige mit der Installation mit Atmel Studio mit VisualMicro um einmal den Fehler zu finden und den Code zu optimieren.

  • Um Ram zu sparen verwende die F() Makro:
    für alle Texte die mit print oder println ausgegeben werden egal ob serial oder lcd:

statt lcd.print(" Meter");
besser lcd.print(F(" Meter")); das spart RAM weil der Text nict zuerst ins RAM kopiert wird und dann ausgegeben wird sondern direkt vom Flash genommen wird.

  • funktionert zwar ist aber eine etwas sehr eigenwillige Verwendung von switch case
void keypadEvent(KeypadEvent key){ 
  switch (keypad.getState()){   
    case PRESSED:
        if (currentPosition == 9) { ....; break;}
        if (key == '*') {...; break;}
        if (key == '#') {...; break;}
        if (currentPosition == 0) {if (key == '0') {...;}...; break;}
        if (currentPosition == 1) {...;break;}
        if (currentPosition == 2) {...;break;}
        if (currentPosition == 3) {...;break;}       
  }     
}

Grüße Uwe

Matthino:
Bei allem was ich getestet habe war bei Fehlern das Display angeschlossen und ohne Fehler abgeklemmt.

Welches LCD-Display genau? Link? Datenblatt?

Wenn es ein Display auf Shield zum Stecken ist: An welchem Pin ist die Hintergrundbeleuchtung des Displays angeschlossen? Bei vielen Text-LCDs hängt die Hintergrundbeleuchtung des Displays an Pin-10.

Wenn das bei Deinem LCD-Shield der Fall sein sollte, hast Du außer einer Doppelbelegung von Pin-0 zusätzlich noch eine Doppelbelegung von Pin-10: Einmal wieder bei den rowPins für Dein Keypad und nochmal für die Hintergrundbeleuchtung des LCD-Shields.

Beseitige alle doppelten Pinbelegungen durch Änderung der Schaltung, so dass jeder Pin stets nur einmal verwendet wird! Und wenn keine Pins mehr doppelt verwendet werden, dann nochmal testen.

@uwefed
Das mit dem Ram teste ich gleich direkt. Zum Code, naja, ich bin da nicht so der Crack und hatte den Arduino eigentlich für die Gartenbewässerung gekauft. Habe das dann aber in Bash umgesetzt weil ich damit seit 20 Jahren alles programmiere. Mit dem Seilwickler dem Encoder und 600 Impulse pro Sekunde erschien mir der Arduino die bessere Wahl bzw. Möglichkeiten und habe mich eingearbeitet, daher der Code nicht so super optimal gmpf

@jurs
Es ist ein Grove-LCD RGB Backlight V2.0 mit den Libs von der Webseite. Kein Shield.
http://www.seeedstudio.com/wiki/Grove_-_LCD_RGB_Backlight
Plus, Minus, SDA und SDC am UNO ebenfalls bei SDA und SDC.

Ich habe gerade nochmal einiges getestet. Es ist definitiv so, dass wenn das LCD Display angeklemmt ist, der Fehler auftritt. Klemme ich sda und sdc ab und bediene "blind", funktioniert es ohne Probleme dauerhaft.

Pin0 vom Keyboard habe ich auf Analog geändert.

LCD habe ich zwei Stück hier, beide das selbe Problem. Arduino habe ich hier 4 Stück (cc org Kopie etc.), bei allen tritt der selbe Fehler auf.

Echt unglaublich. Dann kann es ja eigentlich nur ein Softwareproblem sein wenn ich alles andere ausgetestet habe.

Es kann auch sein, daß die Hintergrundbeleuchtung zuviel Strom zieht und darum die Spannung zusammenbricht.

Wie versorgst Du den Arduino mit Strom? über die Netzteilbuchse? Funktioniert es mit USB?

Laut Datenblatt zieht das Display max 60mA und damit müßte der Arduino klarkommen.

Versuch mal die Hintergrundbeleuchtung abzuschalten und zu schauen ob da Arduino immernoch blockiert

Grüße Uwe

Der Arduino ist über USB versorgt, habe aber das Display mit dem Labornetzteil extra versorgt, ohne Veränderung vom Fehler. Daher schließe ich Strom bei Display auch aus.

Ich habe aber eine Veränderung festgestellt.

Einmal habe ich das mit dem F bei print gemacht wodurch der Fehler zwar kam, aber relativ spät erst (mehrere Testläufe).
Da ich im Code auch Serial.Print habe, leuchtet wohl immer kurz die TX Lampe auf dem Uno. Bei Fehlern im Display blinkt die erst normal weiter, beim einfrieren leuchtet diese dann ständig.

Ich habe die while schleife jetzt verkürzt.

while (COUNTER < LAUFZEIT) {
    char key = keypad.getKey(); 
    IMPULS = myEnc.read();
    if (30717 < IMPULS) {
    COUNTER++;
    myEnc.write(0);
    // lcd.setCursor(0,0);
    LAUFLAENGE++;
    // lcd.print(LAUFLAENGE);
    // lcd.print(F(" Meter"));
    // lcd.setCursor(0,1);
    lcd.print(COUNTER);
    // lcd.print(F("/"));
    // lcd.print(LAUFZEIT);
    // lcd.print(F(" Meter"));
    //  Serial.println(LAUFZEIT);
    }
  }

Zwar ist die Anzeige auf dem Display nicht optimal, aber er läuft komplett durch und das Display ist angeschlossen. Ich habe gerade 2 x 2000m ohne ein einzige Fehler durchlaufen lassen können.

Ich würde behaupten, dass es zu viele lcd. Befehle hintereinander sind, die zuerst den i2c ins stottern bringen und somit das Display spinnt und dann später den Arduino einfriert.

Update:
Problem leider noch nicht gelöst. Mit einem einzigen lcd.print kommen jetzt keine zufällige Zeichen mehr, aber der Arduino stürzt nach 5000 Metern ab. Vorher schon bei 50 - 100 Meter. Nutze ich wieder alle lcd.print kommen schon nach 5 Metern wieder die Symbole und das Display spinnt. Echt komisch das ganze grummel

Ein delay zwischen den lcd. Befehlen verändert auch nichts.

Ich habe ein kleines Sketch geschrieben als loop wo das Display als Counter hochzählt ohne Delay. Geht super schnell und ohne Fehler. Dann kann es ja auch nicht am Display selber liegen wenn es die Daten ohne Fehler verarbeitet was 1000 mal schneller ist als in meinem eigentlichen Sketch.

Ich habe nun mehrere Stunden probiert und nun ein anderes Display bestellt.

Lasse ich den Code wie erst ist und klammer nur in der while Schleife die LCD Befehle aus und nehme dafür ein Serial.print, läuft alles sauber. Das Display wird für Eingabe etc. trotzdem genutzt. Sobald ein LCD Befehl in der Schleife ist, tritt das Problem auf, bei nur einem LCD.Print Befehl dauert es sehr lange bis das Display spinnt, umso mehr LCD Befehle in der Schleife sind, umso eher tritt der Fehler auf und der Uno friert ein.

Fazit: Es kann nur das Display oder die zugehörigen Libs sein, daher ein anderes Display mit anderen Libs.
Danke für die Mühe und Fehlersuche wodurch ich hier und da was dazugelernt habe.

Wenn ich das dann getestet habe, poste ich hier das Resultat.

Also wenn die lcd Befehle drin sind und das Display nicht angeschlossen ist, stürzt der Arduino auch ab?

Hast du dir schon das freie RAM beim debuggen mit ausgeben lassen?

Hast du Pullups am I2C ?