Serieller Monitor unterbricht ausgaben & gibt wirres zeug aus

Hallo Zusammen,

bei meinem Programm habe ich wie bei so vielen den Seriellen Monitor verwendet um das Programm zu Debuggen und einfach zu sehen was das Programm macht.

Bei diesem Programm habe ich allerdings das Problem das der Serielle Monitor die Ausgabe mitten drin unterbricht und mit einer ander Ausgabe weiter macht.
Es kommen auch zwischen durch wirres Zeug dabei raus.

Die Baudrate habe ich auf 9600 im Programm wie auch im Seriellen Monitor eingestellt. Das sollte also denke ich nicht das Problem sein.

Die Arduino IDE die ich nutze ist die 1.8.13 auf Winsows 10.
Mit der 1.8.5 hatte ich das selbe Problem.

Beispiel Serieller Monitor:

Hier auch der Programm Code:


#include <FastLED.h>
#include <EEPROM.h>



////////////////////////Allgemeine Werte////////////////////////

boolean DebugMode = true;


////////////////////////Werte für die LED's////////////////////////

//Pins an denen die LED Streifen angeschlossen sind
#define Pin_Strip_1     6
#define Pin_Strip_2     7
#define Pin_Strip_3     8
#define Pin_Strip_4     9

// Variablen für die Länge der LED Streifen
uint8_t Strip_1 = 130;
uint8_t Strip_2 = 130;
uint8_t Strip_3 = 130;
uint8_t Strip_4 = 130;





void setup() {

  Serial.begin(9600);
  Serial.println("Starte das Programm");

  
  
  EEPromSetup();
  
  EEPromLoad();

  LEDSetup();
 
  
}

void loop() {
  //Serielle Schnittstelle überprüfen
  chkSer();
  delay(1000);

}



////////////////////////////////////////////LED Funktionen////////////////////////////////////////////

void LEDSetup(){
  CRGB leds[Strip_1 + Strip_2 + Strip_3 + Strip_4];
  
  FastLED.addLeds<NEOPIXEL, Pin_Strip_1>(leds, 0, Strip_1);
  FastLED.addLeds<NEOPIXEL, Pin_Strip_2>(leds, Strip_1, Strip_2);
  FastLED.addLeds<NEOPIXEL, Pin_Strip_3>(leds, Strip_1 + Strip_2, Strip_3);
  FastLED.addLeds<NEOPIXEL, Pin_Strip_4>(leds, Strip_1 + Strip_2 + Strip_3, Strip_4);
}




////////////////////////EEProm Werte////////////////////////

//Standart länge der LED Strip_1 bis Strip_4
#define E_Strip_1    132      
#define E_Strip_2    130
#define E_Strip_3    119 
#define E_Strip_4    118

//DebugMode ist Standart mäßig aktiviert
#define E_DebugMode  true



////////////////////////////////////////////EEProm Funktionen////////////////////////////////////////////

#define KontrollByte    0xBB

void EEPromSetup(){
  //Überprüfen, ob unsere Daten bereits gespeichert sind anhand des Kontrollbytes
  //Falls nicht werden die Standartwerte gespeichert
  if(EEPROM.read(0) != KontrollByte){
    //Serielle Ausgabe im DebugMode
    if(DebugMode == true){
      Serial.println("Falsches Kontrollbyte -> Reset des EEProms wird durchgefuehrt");
    }
    EEPromFactoryReset();
  }
  
}

void EEPromFactoryReset(){
  EEPROM.write(0, KontrollByte);            //Konrtoll Byte
    
  EEPROM.write(1, E_Strip_1);               //Anzahl an LEDs an Strip_1 bis Strip_4
  EEPROM.write(2, E_Strip_2);     
  EEPROM.write(3, E_Strip_3);
  EEPROM.write(4, E_Strip_4);

  EEPROM.write(5, E_DebugMode);             //DebugMode aktiviert die Serielle Ausgabe
}


void EEPromLoad(){
  //Serielle Ausgabe im DebugMode
  if(DebugMode == true){
    Serial.println("Lade die im EEProm gespeicherten Werte in das Programm.");
  }
    
  Strip_1 = EEPROM.read(1);
  Strip_2 = EEPROM.read(2);
  Strip_3 = EEPROM.read(3);
  Strip_4 = EEPROM.read(4);

  DebugMode = EEPROM.read(5);
}




////////////////////////////////////////////Serielle Eingabe////////////////////////////////////////////

void chkSer() { 
  String Buffer;

  Serial.println("chkSer");

  if(!Serial.available()) return;

  Buffer = Serial.readStringUntil(' ');
  if(DebugMode == true){
        Serial.println("Buffer:\t" + String(Buffer));
        Serial.println(Buffer);
      }

  if(Buffer == "Strip_1"){
    Strip_1 = Serial.readString().toInt();
   
      //Serielle Ausgabe im DebugMode
      if(DebugMode == true){
        Serial.println("Strip_1 wurde auf " + String(Strip_1) + " LEDs aktualisiert");
        Serial.println("Strip_1 aktualisiert");
      }
      //Führt den LED Setup noch einmal durch um die LED anzahl auf den Streifen zu aktualisieren
      LEDSetup();
  }
  else if(Buffer == "Strip_2"){
    Strip_2 = Serial.readString().toInt();
      //Serielle Ausgabe im DebugMode
      if(DebugMode == true){
        Serial.println("Strip_2 wurde auf" + String(Strip_2) + "LEDs aktualisiert");
      }
      //Führt den LED Setup noch einmal durch um die LED anzahl auf den Streifen zu aktualisieren
      LEDSetup();
  }
  else if(Buffer == "Strip_3"){
    Strip_3 = Serial.readString().toInt();
      //Serielle Ausgabe im DebugMode
      if(DebugMode == true){
        Serial.println("Strip_3 wurde auf" + String(Strip_3) + "LEDs aktualisiert");
      }
      //Führt den LED Setup noch einmal durch um die LED anzahl auf den Streifen zu aktualisieren
      LEDSetup();
  }
  else if(Buffer == "Strip_4"){
    Strip_4 = Serial.readString().toInt();
      //Serielle Ausgabe im DebugMode
      if(DebugMode == true){
        Serial.println("Strip_4 wurde auf" + String(Strip_4) + "LEDs aktualisiert");
      }
      //Führt den LED Setup noch einmal durch um die LED anzahl auf den Streifen zu aktualisieren
      LEDSetup();
  }
  
}

Man kann einen EEPROM nicht unbegrenztz oft beschreiben.
mach 100.000 mal ist Schluss. manchmal auch schon nach 10.000

Ich würde in die Funktion die einen Faktoriy-reset macht nicht automatisch erneut aufrufen sondern nur wenn ein IO-pin einen bestimmten Zustand hat. Der herühmte Hardware-reset-knopf.

Wenn dein Programm nicht richtig funktioniert und die Überprüfung des Kontrolbytes nicht funktioniert hat dann kannst du dir in einer Viertelstunde den EEPROM kaputt-nudeln
weil das Programm ständig noch einmal deinen factory-reset macht. Kontrollbyte stimmt wieder nicht also gleich nochmal usw. usw. usf.

Wenn auf einmal so komische Zeichen ausgegeben werden ist das meistens ein Hinweis darauf das ein Array außerhalb seiner Grenzen beschrieben wird.
vgs

you need to identify what is generating the unexpected serial output. seems that EEPromLoad() was OK and problems occurred when LEDSetup() is invoked.

suggest not call LEDSetup() or putting a return at the beginning of the function to nul it out

Der Fehler ist immer da, wo die Information geheim gehalten wird.

Welcher Information ist geheim?

Der Arduino Type!

Also ist der auch das Problem.

Ich behaupte:
Zu wenig RAM

Dann:

Hier wird Speicher lokal auf dem Stack reserviert, dann an die Instanz weiter gegeben.
Dann wird der Speicher wieder frei gegeben.

Die Instanz arbeitet ab dann mit ungültigen Speichern.
Es ist also kein Wunder, dass Bereiche überschrieben werden.

Als Arduino habe ich einen Uno verwendet, da der einfach gerade da war.
Ich habs jetzt mal auf einen Mega aufgespielt und dort funktioniert das Programm. Also liegt es wohl am Fehlenden RAM

Dort wo ich dann das Programm für die Steuerung für die Neopixel LEDs verwenden möchte ist ein Arduino Nano verbaut wegen seiner Größe.
Der hat ja den Gleichen Microkontroller wie der Uno. Gibt es jetzt einen Weg, dass ich da nicht so viel RAM brauche?

Das der EEPROM nur begrenst beschreibbar ist, ist mir bewust.
Sah es jetzt allerdings nicht als ein Problem an, da das Kontrollbyte sich ja nicht ändern kann sobald das Programm kompiliert wurde.
So sollte der EEPROM "eigentlich" nur einmal neu beschrieben werden durch den Factoty-reset.
Ich werde es aber wahrscheinlich dennoch nicht mehr automatisch durchführen lassen sondern nur eine Wahrnung ausgeben wenn das Kontrollbyte nicht passt.

Hallo
nimm eine Suchmaschine deiner Wahl und suche nach "F-Macro +arduino"

Das ist ein Punkt!
Der zweite, die falsche Speicherreservierung.

diese "eigentlich"-Überlegungen sind zu 80% der Grund warum ein Programm nicht funktioniert und der Newcomer stunden-, und tagelang sucht ohne den Fehler zu finden.
Nix is besser als jedes Detail zu überprüfen.
vgs

Das ist wirklich ein nützliches Macro um den RAM frei zu halten

Aber wie kann ich das verbessern?
Habe nur recht wenig Erfahrung mit dem Speicher managment eines Microkontrollers.

Statisch und oder global reservieren.
Alternativ, wenn es dynamisch sein muss: malloc() oder seine Brüder, z.B. new.

Unterscheidet sich nicht von anderen Platformen. Nur eben, dass weniger Speicher da ist, und man darum auch eher Probleme mit Fragmentierungen bekommt.


Auch dieses ist ein starkes Indiz dafür, dass hier eine Problemstelle ihren Raum gefunden hat:

E:\Programme\arduino\portable\sketchbook\sketch_jun19c\sketch_jun19c.ino:57:8: warning: ISO C++ forbids variable length array 'leds' [-Wvla]
   57 |   CRGB leds[Strip_1 + Strip_2 + Strip_3 + Strip_4];
      |        ^~~~

OK, das kommt bei dir nicht wirklich zum tragen, da der Gcc solcher Art Variablen erzeugen kann. Aber da sie lokal ist/sind, auch sofort wieder vergisst.

Also wenn ich das richtig verstehe ist malloc() eine funktion, mit der der benötigte Speicherplatz für ein Array reserviert werden kann. Also dieser Speicherplatz dann für das restliche Programm gespert ist und nur von dem Array benutzt werden kann.
Dann kann es auch nicht mehr vorkommen das dieser Speicherplatz von etwas anderm überschrieben wird?

Dafür ist in C/C++ allein der Programmierer verantwortlich. Der Compiler prüft da nichts.

Gruß Tommy

Nein, das ist kein absoluter Schutz gegen jede Dummheit..
Aber es ist eine Vereinbarung, an die man sich halten kann und darf.

Ok Danke :smiley:

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.