Do-while Problem

Hallo, bin noch nicht lange am Arduino programmieren und habe in Problem mit einer Schleife, mit der ich das OLED Display beschreibe.
Das funktioniert alles bestens, aber nach ca 5 Minuten bleibt das Programm regungslos
Habe schon den verbleibenden Speicher geloggt, alles gut bei 5888.
Nach Neustart läuft alles eine Weile, dann Ende.
Dann dachte ich, es liegt am Oled, habe dann aber Oled-clear getestet, geht, aber bleibt doch stehen.
Kann mir da jemand helfen?
Das Programm bleibt in Zeile 58 stehen Ich rufe das OLED "Unterprogramm" mehrmals bei der Messung auf.
Soll übrigends eine automatische Bewässerung für meinen Balkon werden, da ich das oft vergesse und ich immer irgend etwas tun muss!

Letzte Meldung von seriell:

Freier Speicher (RAM): 5888

Zeile 071
Sensor 01 Wert
Zeile 084
Zeile 044 OLED
Zeile 053 OLED
Zeile 057 OLED
Zeile 058 OLED
Zeile 085
4% Wert: 771 Zeile 044 OLED
Zeile 053 OLED
Zeile 057 OLED
Zeile 058 OLED
Zeile 121
Zeile 044 OLED
Zeile 053 OLED
Zeile 057 OLED

Codeausschnitt: falls mehr von Nöten bitte fragen

int OLED (){ // Infobildschirm schreiben
Serial.println("Zeile 044 OLED");
u8g2.firstPage();
do {
// u8g2.clear();
// u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(0,10,Name);
u8g2.drawStr(0,23,Sensor);
u8g2.drawStr(0,36,Prozent);
Serial.println("Zeile 053 OLED");
u8g2.drawStr(95,36," %");
u8g2.drawStr(0,49,Giessen);
u8g2.drawStr(0,61,"-----------------------------");
Serial.println("Zeile 057 OLED");
} while ( u8g2.nextPage() ); // hier bleibt es stehen nach ca 5 Minuten, ist Zeile 58
Serial.println("Zeile 058 OLED");
}

void setup() {
u8g2.begin();
Serial.begin(9600);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
Speicher = (freeRam());

Gruß Thommy

Sie sollten im Forum auf Deutsch schreiben, und ich bin sicher, dass die Teilnehmer auch die Code-Tags dort mögen ... ...

Welche Hardware hast Du?
Kann mit dem Ausschnitt der Fehler reproduziert werden?
Nein? dann reicht der Ausschnitt nicht.
Grüße Uwe

Hallo,

mir ist nicht klar warum du eine do , oder while schleife verwenden willst. ich sehe auch nicht wie Du da jemals wieder rauskommen willlst. Benutze if Verzweigungen mum den Inhalt für die unterschiedlichen Seiten anzuzeigen.

Heinz

Danke für die Antworten, und ich gehe ins Forumauf deutsch, wie jemand vorgeschlagen hat! Gerne dort weiter diskutieren!
Bis gleich im Forum auf deutsch
Thommy

sunthommy:
Danke für die Antworten, und ich gehe ins Forumauf deutsch, wie jemand vorgeschlagen hat! Gerne dort weiter diskutieren!
Bis gleich im Forum auf deutsch
Thommy

Du bist im deutschen Forum

Heinz

OK, habe nicht gemerkt, dass ich schon im deutschen Forum angekommen bin.

Also nochmal: Es funktioniert alles, aber bleibt nach ein paar Minuten stehen.
Das soll später für 5 Sensoren gehen, deshalb sind 2 weitere auskommentiert , damit ich den Fehler schneller orten kann!

Hier der volle code
Kann man den als Datei hier anhängen, damit die Zeilennummern auch dabei sind?

#include <U8g2lib.h>
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ 
U8X8_PIN_NONE); 
const int Trocken = 790;
const int Nass = 370;
const int PumpeAn = 4000;  // Laufzeit Pumpe
const int Warten = 500;   // Zeit bis zum nächsten Sensor
const int Proz = " %";
int prozentfeuchte = 0;
int Feuchtigkeit;
int Name = "Thomas Meister";
int Sensor = "Strasse";
int Prozent = " Berlin";
int Giessen = "Tel: 0555 5555";
char buf[100];
int sprintf(int , char);
void U8G2::clear(void);
void U8G2::clearBuffer(void);
int Speicher;
int freeRam ()
{
extern int __heap_start, *__brkval; 
int v; 
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}


int OLEDA (){     // Startbildschirm schreiben

         u8g2.firstPage();
        do {
//          u8g2.clear();
//          u8g2.clearBuffer();
         u8g2.setFont(u8g2_font_ncenB08_tr);
         u8g2.drawStr(0,10,Name);
         u8g2.drawStr(0,23,Sensor);
         u8g2.drawStr(0,36,Prozent);
         u8g2.drawStr(0,49,Giessen);
         u8g2.drawStr(0,61,"------------Start------------");
       } while ( u8g2.nextPage() );
       }

int OLED (){     // Infobildschirm schreiben
Serial.println("Zeile 044  OLED");
         u8g2.firstPage();
        do {
//          u8g2.clear();
//          u8g2.clearBuffer();
         u8g2.setFont(u8g2_font_ncenB08_tr);
         u8g2.drawStr(0,10,Name);
         u8g2.drawStr(0,23,Sensor);
         u8g2.drawStr(0,36,Prozent);
         Serial.println("Zeile 053  OLED");
         u8g2.drawStr(95,36,"  %");
         u8g2.drawStr(0,49,Giessen);
         u8g2.drawStr(0,61,"-----------------------------");
         Serial.println("Zeile 057  OLED");
       } while ( u8g2.nextPage() );  // hier bleibt es stehen nach ca 5 Minuten
       Serial.println("Zeile 058  OLED");
       }

void setup() {
u8g2.begin();
Serial.begin(9600);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
Speicher = (freeRam());

OLEDA ();
}

void loop(void) {
Serial.println("Zeile 071");
delay(PumpeAn);
Name = "Thommys Giesskanne";
 

//Sensor 1

 Feuchtigkeit = analogRead(A0);
 prozentfeuchte = map(Feuchtigkeit, Trocken, Nass, 0, 100);
   Serial.println("Sensor 01 Wert ");
   
   Sensor = " --------Sensor 01-------";
  Serial.println("Zeile 084");
   OLED ();
   Serial.println("Zeile 085");
//    
 if(prozentfeuchte > 100)
 {
   Serial.print("100 ");
   Serial.print("%  Wert:  ");
   Serial.print(Feuchtigkeit);
   Serial.print("  ");
   
   Prozent = "  Feuchtigkeit 100%";
   Giessen = "    Pumpe 1 ist aus ";
   OLED ();
  
 }
 else if(prozentfeuchte >0)
 {
   Serial.print(prozentfeuchte);
   Serial.print("%  Wert:  ");
   Serial.print(Feuchtigkeit);
   Serial.print("  ");
   
   sprintf(buf, "Feuchtigkeit:   %d", prozentfeuchte);
   Prozent =(buf);
   OLED ();
   
 }
 else //if(prozentfeuchte <0 ;
  {
   Serial.print(prozentfeuchte);
   Serial.print("%  Wert:  ");
   Serial.print(Feuchtigkeit);
   Serial.print("  ");
   Prozent = " Feuchtigkeit 1:   0%";
   OLED ();
 }
// Pumpe 1 schalten
         Serial.println("Zeile 121");
     if (prozentfeuchte < 75) {
     digitalWrite(3, HIGH);
     Giessen = "    Pumpe 1 ist AN   ";  
     OLED ();  
     delay(PumpeAn);
     digitalWrite(3, LOW);
     Giessen = "    Pumpe 1 ist AUS ";
     OLED ();
     delay(PumpeAn);
     u8g2.clearBuffer(); //hiermit dachte ich einen eventuellOLED Buffer overflow zu eleminieren. Fehler bleibt aber
     Serial.println();
     Serial.print("Freier Speicher (RAM):  ");
     Serial.println(Speicher);
     Serial.println();
}
else {
 digitalWrite(3, LOW);
 u8g2.clearBuffer();
 Serial.println("Zeile 140");
}
}

Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Dann ist er auch auf mobilen Geräten besser lesbar.
Das kannst Du auch noch nachträglich ändern.

Gruß Tommy

Setze deine Code bitte in Code-Tags. Das geht auch nachträglich: Code markieren und den Button </> oben links im Editor drücken. Er ist auch nicht vollständig - zumindest fehlt eine ‘}’ am Ende.
Edit - Ok, Tommy war schneller :wink:

Was für einen Arduino hast Du? Dein Umgang mit Zeichenketten ist sehr ‘kreativ’, um es mal vorsichtig auszudrücken. Du solltest dich dringend mit char-Arrays und c-strings (Zeichenketten) befassen. Der AVR-Compiler schmeisst da haufenweise ‘warnings’ - was der dann wirklich daraus macht …

Andere Compiler ( z.B. ESP8266 oder Arm/Due ) sind da wesentlich restriktiver, die nehmen so einen Unsinn gar nicht an.

Hier ist ein kostenloses Paar Codetags :grin:

[code]`` ``[/code].

Hallo,

du kannst Ihn in Code tags einschliessen dann können Ihn alle lesen. Wenn Du Preview unten recht benutzt bekommst Du den vollen Editor mit Symbolleiste da gibts oben links </> Du kannst auch in der IDE “für Forum kopieren” und dann hier einfügen Maus rechts click nutzen.

Stelle auch den gesamten Sketch mit hier rein , damit wir das komplett in Ihre IDE laden können.

Aber zu Deinem Problem . Was meinst Du mit “er bleibt stehen” er wird in der while Schleife hängen und nicht mehr raus kommen weil die Bedingung zum beenden fehlt.

Es geht um eine Seitenumschaltung richtig ? Benutze nicht die Schleifen verwende eine Variable für die Seitennummer 1…n. dann kannst Du mit if else oder select case in den passenden Programmteil verzweigen. Wie machst Du denn jetzt die Seitenumschaltung ich kann das nicht erkennen. Dann hast Du da noch einige delay () drin. Delay macht eine Pause da passiert nix mehr.

Heinz

Nachtrag : hat sich überschnitten , hast Du ja inzwischen gemacht

Rentner:
Aber zu Deinem Problem . Was meinst Du mit "er bleibt stehen" er wird in der while Schleife hängen und nicht mehr raus kommen weil die Bedingung zum beenden fehlt.

Dann müsste aber ständig auf dem ser. Monitor was ausgegeben werden, denn das

    Serial.println("Zeile 057  OLED");

steht in der Schleife.

MicroBahner:
Setze deine Code bitte in Code-Tags. Das geht auch nachträglich: Code markieren und den Button </> oben links im Editor drücken. Er ist auch nicht vollständig - zumindest fehlt eine ‘}’ am Ende.
Edit - Ok, Tommy war schneller :wink:

Was für einen Arduino hast Du? Dein Umgang mit Zeichenketten ist sehr ‘kreativ’, um es mal vorsichtig auszudrücken. Du solltest dich dringend mit char-Arrays und c-strings (Zeichenketten) befassen. Der AVR-Compiler schmeisst da haufenweise ‘warnings’ - was der dann wirklich daraus macht …

Andere Compiler ( z.B. ESP8266 oder Arm/Due ) sind da wesentlich restriktiver, die nehmen so einen Unsinn gar nicht an.

Danke für den Hinweis, bin neu hier und man möge mir verzeihen!
Daher auch die unkonventionelle Programmierung. Bin ja am Lernen!
Ich habe Mega2560 von Elegoo. und 1,3 " Oled über I2c

MicroBahner:
Dann müsste aber ständig auf dem ser. Monitor was ausgegeben werden, denn das

    Serial.println("Zeile 057  OLED");

steht in der Schleife.

sunthommy:
Daher auch die unkonventionelle Programmierung. Bin ja am Lernen!

Dann lerne den Umgang mit Zeichenketten erstmal an einfachen Sketchen mit der seriellen Schnittstelle. Wenn Du Dir gleich so was komplexes vornimmst, weist Du letztendlich nie, wo das Problem liegt. Wenn Du dann weist, wie man mit Zeichenketten umgeht, kannst Du das auch im Zusammenhang mit deinem Oled angehen. Da hast Du dann schon eine Fehlerquelle weniger.

MicroBahner:
Dann müsste aber ständig auf dem ser. Monitor was ausgegeben werden, denn das

    Serial.println("Zeile 057  OLED");

steht in der Schleife.

das stimmt natürlich , dennoch ist das while die Abbruch Bedingung für die do . while schleife.

Bekommst Du denn die Seriellen ausgaben mit Zeile 53 und 57 ständig ? und die 58 kommt nicht ?

do {
    //          u8g2.clear();
    //          u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_ncenB08_tr);
    u8g2.drawStr(0, 10, Name);
    u8g2.drawStr(0, 23, Sensor);
    u8g2.drawStr(0, 36, Prozent);
    Serial.println("Zeile 053  OLED");
    u8g2.drawStr(95, 36, "  %");
    u8g2.drawStr(0, 49, Giessen);
    u8g2.drawStr(0, 61, "-----------------------------");
    Serial.println("Zeile 057  OLED");
  } while ( u8g2.nextPage() );  // hier bleibt es stehen nach ca 5 Minuten
  Serial.println("Zeile 058  OLED");

sunthommy:
Daher auch die unkonventionelle Programmierung.

int Name = "Thomas Meister";
int Sensor = "Strasse";
int Prozent = " Berlin";
int Giessen = "Tel: 0555 5555";

Das ist extrem unkonventionelle Programmierung!

Gruß Fips

Derfips:

int Name = "Thomas Meister";

int Sensor = "Strasse";
int Prozent = " Berlin";
int Giessen = "Tel: 0555 5555";




Das ist extrem unkonventionelle Programmierung!


Gruß Fips

Oh je den Blödsinn hab ich gar nicht erst gesehen , wie kommt man denn auf sowas ?? hatte mich zu lange mit dem Listing ohne code tags beschäftigt

Heinz

Ich weiß, aber ich habe erst den Startbildschirm OLEDA und danach die Bildschirme der einzelnen Sensoren, deren Inhalt ich aber immer in den Bildschirm schreibe OLED.
Wie gesagt, funktioniert gut , aber nicht lange.
Und wie schon geschrieben: Die Seriellen sind Ausgaben zur Kontrolle und die mit Zeilennummer um zu sehen, wo er hängen bleibt! Das muss dann nach der letzten seriellen Ausgabe der Zeilennummer sein
Den Arbeitsspeicher kontrolliere ich auch mit seriel.print (Speicher). Liegt immer bei 5998

Wie gesagt, funktioniert gut , aber nicht lange.

sunthommy:
Den Arbeitsspeicher kontrolliere ich auch mit seriel.print (Speicher). Liegt immer bei 5998

sorry, das ist witzlos.
Du ermittelst sowas wie “Speicher” im Setup und gibst dann immer wieder das gleiche aus:

Serial.print("Freier Speicher (RAM): ");
Serial.println(Speicher);

ob deine Funktion im Setup macht, was du glaubst, müssen andere checken. Aber dass du davon später zur Laufzeit nichts ableiten kannst, das traue ich mir sagen.