Seltsamer Programmabruch

Hi Ich habe ein kleines programm geschrieben und bin dabei auf einen sehr verwirrenden Fehler gestoßen, der denke ich nicht direkt auf mangelnde Programmierkenntnisse zurückzuführen ist :fearful:
Also Ich habe eine Funktion die die Sensordaten über als Seriellen Output ausgibt, diese Funktion liefert den Sensornamen den gemessenen Wert und die Einheit in der gemessen wird.

Nun habe ich acht Sensoren und viele Ausgaben...

Nun passiert es, wenn ich die Einheiten ausschreibe das nach einer Zeile abgebrochen wird.

//... einige Andere Ausgaben
Serial.println(" :met:;"); //funktioniert noch die darauf folgenden Zeilen werden ausgeführt
//oder
   Serial.println(" :mete:;");//dannach geht nichts mehr ?!die darauf folgenden Zeilen werden nicht ausgeführt
//... einige Andere Ausgaben und Funktionsaufrufe

Für sich genommen gehen die Ausgaben, aber zusammen stürzt das System immer wieder ab, was also mache ich falsch? Gibt es vielleicht eine maximale Cachegröße die ich mit einer solchen Ausgabe überschreite?

Cachegröße kann ich mir nicht vorstellen. Du speichert die Daten doch nicht in dem Sinne ab. Serial.print → Daten raushauen.

Könntest du mal etwas mehr des Codes bereitstellen. Der Teil ist soweit korrekt.

Edit: Kommentier mal alle prints aus und schau ob das System dann noch abstürzt.

Zu seltsamen unerklärbaren Programmverhalten oder Abbrüchen kommt es weil:

  • RAM overflow ( mehr RAM gebraucht wird als physich vorhanden)
  • Über die Größe eines Arrays hinausgeschrieben wird.
  • Mit Pointern Fehler gemacht werden.

Ohne den gesamten Sketch kann ich nur Rätsaelraten.

Grüße Uwe

uthred:
Serial.println(" :met:;"); //funktioniert noch die darauf folgenden Zeilen werden ausgeführt

Hast Du eigentlich den RAM-Speicherverbrauch im Blick?
Wieviel RAM ist noch frei, wenn das Programm läuft?

So eine Zeile wie:
Serial.println(" :met:;");
Mit einer 7 Zeichen langen Textkonstante benötigt 8 Bytes RAM-Speicher, von nur 2 KB RAM in einem UNO.

8 Bytes mal hundert solche Ausgaben läppert sich am Ende auch.

Wenn Du Textkonstanten ausgibst und RAM-Speicher sparen mußt, dann verwende das F-Makro:
Serial.println(F(" :met:;"));
In dem Fall liegt die Konstante nur im Flash-Programmspeicher und wird direkt ausgegeben, ohne RAM zu verbrauchen.

Also Ich habe das Problem weiter eingeschränkt, an der Größe und der Menge von Ausgaben liegt es nicht aber anscheinend stören sich die Sensoren untereinander, Ich habe einen Luftfeuchtigkeitsmesser, dessen Werte geparst werden und in eine Struktur gebracht werden, wird dieser Sensor am Anfang aufgerufen bricht nichts ab am Ende und in der Mitte schon.

 float* temperaturAndHumidityValues=getTemperaturAndHumidityValues();
  Serial.print("Temperatur & Humidity Humidity: "); 
  Serial.print(temperaturAndHumidityValues[0]);
  Serial.println("; \t");
  Serial.print("Temperatur & Humidity Temperature: "); 
  Serial.print(temperaturAndHumidityValues[1],2);
  Serial.println(" :Celsius:;");
  Serial.print("Light: ");
  Serial.print(getLightValue()); 
 Serial.println(":Lumen:;");  
  Serial.print("Barometer Temperature: ");
  float* barometerValues=getBarometerValues();
  Serial.print(barometerValues[0], 2); //display 2 decimal places
  Serial.println(" :Celsius:;");
  Serial.print("Barometer Pressure: ");
  Serial.print(barometerValues[1], 0); //whole number only.
  Serial.println(" :Paskal:;");

  Serial.print("Barometer Ralated Atmosphere: ");
  Serial.print(barometerValues[2], 4); //display 4 decimal places
  Serial.println(" :Paskal:;");

  Serial.print("Barometer Altitude: ");
  Serial.print(barometerValues[3], 2); //display 2 decimal places
  Serial.println(" :Meter:;");

  float airquality=getAirQualityValue();
  Serial.print("Polution Rating: ");
  Serial.print(airquality);
  Serial.println(":µg/m³:; \t");

wird dieser Sensor am Anfang aufgerufen bricht nichts ab am Ende und in der Mitte schon.

Funktionen die Pointer zurückliefern, wie dein float* getTemperaturAndHumidityValues(); sind verdächtig:

  • wo ist denn der Speicher auf den der gelieferte Zeiger zeigt ?
  • ist er noch gültig nach Ende der Funktion ?

Ui - viele println’s …
Mach doch mal aus jedem erst mal ein

Serial.println(F(" … hier der jeweilige Text …"));

Dann hast du beim RAM erst mal ne Latte an Bytes mehr Luft, weil alle Texte im Flash gespeicher werden.

michael_x:
Funktionen die Pointer zurückliefern, wie dein float* getTemperaturAndHumidityValues(); sind verdächtig:

  • wo ist denn der Speicher auf den der gelieferte Zeiger zeigt ?
  • ist er noch gültig nach Ende der Funktion ?

Das habe ich mir auch gedacht.

"float* barometerValues" ist genau ein Pointer auf float. Wenn man dann barometerValues[1] macht ist man in ungültigem Speicher.

Generell können Funktionen in C/C++ keine Arrays zurückgegeben (es sei denn die Funktion legen diese mit "new" an was keine so gute Idee ist). Normalerweise erstellt man das Array vor dem Funktionsaufruf und übergibt den Pointer auf das Array (d.h. den Variablennamen) und eventuell die Größe des Arrays als Parameter.

Ok danke für die Antworten :wink:

"float* barometerValues" ist genau ein Pointer auf float. Wenn man dann barometerValues[1] macht ist man in ungültigem Speicher.

Ha, da kann ich mal wieder besserwissern :

float * barometerValues; ist ein Pointer auf float, soweit richtig.

Ob barometerValues[1], barometerValues[0] oder *barometerValues auf den erwarteten gültigen Speicher zeigt, ist alles offen.
Wennman es richtig macht, kann barometerValues[1] durchaus gültig sein.

Aber selbst

Serial.print( ( (float*)0 )[123] ); // sollte nur Unsinn mit 2 Nachkommastellen liefern

dürfte keinen Abbruch verursachen (aber wer weiss) ?