[Anfänger fragt] Werte eingeben und speichern.

Hallo zusammen,

zunächst erstmal sorry für's neue Thema. Ich habe echt viel gestöbert aber entweder nicht das passende gefunden, oder daraus einfach nicht schlau geworden. Meine Programmierkentnisse reichen leider nicht weit über den Grundkurs Informatik in der Schule hinaus.

Was ich möchte:
Ich möchte gerne ein Programm betreiben, welches kontinuierlich eine Temperatur überwacht und beim Überschreiten einer Grenztemperatur eine Aktion durchführt. Zusätzlich dazu sollen Werte wie die Grenztemperatur über Taster eingegeben werden können, die später im EEPROM gespeichert werden.

Ich habe bereits die LCDMenuLib gefunden, jedoch steht da, dass diese nicht mit einem Grafik-Display funktioniert. Ich verwende später allerdings das Nokia 5110 Display.

Wo ist mein Problem:
Zunächst einmal habe ich ein wenig meine Schwierigkeiten mit der Loop-Routine des Arduino. Um die Temperatur kontinuiertlich zu überwachen mag diese sehr nützlich sein. Um eine Grenztemperatur oder einen anderen Parameter einzugeben, scheint sie mir jedoch irgendwie hinterlich, sodass ich aus ihr ausbrechen möchte (z.B. mittels eines Schalters). Ich würde mir wünschen, von euch ein paar Tipps zu bekommen, was und vorallem wie ich es besser machen könnte. Ich habe einmal beigefügt, was ich mir bisher ausgedacht habe. Ich bin jedoch irgendwie mehr als unzufrieden. Das ganze rumgehüpfe mit den goto-Befehlen gefällt mir nicht, ebenso wie eigentlich der ganze Quellcode. :-[

Der Hardware-Aufbau:

Der Quellcode:

double TGrenz = 0;
double tPause = 0;

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


void loop() {
  if (digitalRead(1)==HIGH){ 	//Wippschalter umgelegt
  	Serial.println("Einstellungen:");
    delay (500);
    Grenztemperatur:
    Serial.println("Grenztemperatur");
    delay(500);
    abfrage:
    if (digitalRead(3)==HIGH){ 	//Rechter Taster gedrückt
      setTGrenz();}
    if (digitalRead(2)==HIGH){ 	//Linker Taster gedrückt
      Serial.println("Pausenzeit");
      delay(500);
      goto abfrage2;
    }
    if (digitalRead(3)==LOW && digitalRead(2)==LOW && digitalRead(1)==HIGH){
    goto abfrage;
    }
    abfrage2:
    if (digitalRead(3)==HIGH){
      settPause();}
    if (digitalRead(3)==LOW && digitalRead(2)==LOW && digitalRead(1)==HIGH){
      goto abfrage2;} else { if (digitalRead(1)==HIGH){goto Grenztemperatur;}}
  } else {
  Serial.println("Normaler Modus");
  delay(1000);
  }
}

void setTGrenz (){
Serial.println("Bitte Grenztemperatur eingeben: ");
    delay(1000);
    do
			{
      		if (digitalRead(3)==HIGH){
      			TGrenz = TGrenz + 0.5;
              	Serial.println(TGrenz);
              	delay(300);
            }
      		if (digitalRead(2)==HIGH){
      			TGrenz = TGrenz - 0.5;
              	Serial.println(TGrenz);
              	delay(300);
            }
			} while (digitalRead(1)==HIGH);
}

void settPause () {
Serial.println("Bitte Pausenzeit eingeben: ");
    delay(1000);
    do
			{
      		if (digitalRead(3)==HIGH){
      			tPause = tPause + 1;
              	Serial.println(tPause);
              	delay(300);
            }
      		if (digitalRead(2)==HIGH){
      			tPause = tPause - 1;
              	Serial.println(tPause);
              	delay(300);
            }
			} while (digitalRead(1)==HIGH);
}

"Normaler Modus" dient hier als Platzhalter für die spätere Temperaturüberwachung. Mittels des Schiebeschalters soll aus der Loopschleife ausgebrochen werden um Werte eingeben zu können. Es erscheint die Grenztemperatur. Durch Drücken des rechten Tasters kann diese verändert werden. Durch Drücken des linken Tasters kommt man zur nächsten Einstellung, der Pausenzeit. Durch Drücken des rechten Tasters kann diese verändert werden. Durch Drücken des linken Tasters gelangt man wieder zur Grenztemperatur. Wird der Schalter wieder umgelegt, kehrt man in den normalen Modus zurück.

Ich weiß, das ist alles sehr unelegant und unübersichtlich. Daher erhoffe ich mir hier ein paar Tipps und konkrete Verbesserungsvorschläge. :slight_smile:

Wo auch immer du das goto aufgeschnappt hast, dass gehört in fast allen zu der schlechtesten Programmiertechnik! Der Sketch ist jetzt schon dadurch relativ kompliziert zu lesen.

Schreibe das erst einmal um. Mit if und switch-Anweisungen.

Hier findest du die Informationen, wie Funktionen angelegt werden: http://www.arduino.cc/en/Reference/FunctionDeclaration. Damit werden deine Sprungmarken obsolet. Grob unterscheidet man die Funktionen in solche mit und solche ohne Rückgabewert (vorangestelltes void). Sollten Fragen auftreten, wir sind ja da. :wink:

sschultewolter:
Wo auch immer du das goto aufgeschnappt hast, dass gehört in fast allen zu der schlechtesten Programmiertechnik! [...] Schreibe das erst einmal um. Mit if und switch-Anweisungen.

Das war im Informatik-Unterricht.. :smiley: Da wurde auch switch-case behandelt, aber das hab ich wohl wieder verdrängt. Allerdings hilft mir das ja nicht viel, oder? Denn bei switch case kann man ja keine zwei Variablen übergeben?

sth77:
Damit werden deine Sprungmarken obsolet. Grob unterscheidet man die Funktionen in solche mit und solche ohne Rückgabewert

Methoden habe ich in meinem ersten Sketch ja auch schon benutzt (-> setTGrenz() und settPause() ). Dennoch habe ich jetzt versucht noch etwas aufzuräumen.

Hier mein neuer Sketch:

const int Schalter =1;
const int links = 2;
const int rechts = 3;
double TGrenz = 0;
double tPause = 0;

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


void loop() {
 if (digitalRead(Schalter)==HIGH){
 DataInput(); 
 }
Serial.println("Normaler Modus");
delay(1000);
}

void DataInput () {
  do{
    int inputlinks = digitalRead(links);
    int inputrechts = digitalRead(rechts);
    //switch case habe ich hier nur mal ausprobiert, klappt aber nicht
    /*switch (inputlinks, inputrechts){
    	case HIGH, LOW:
      	Serial.println("links");
      	case LOW, HIGH:
      	Serial.println("rechts");
    }*/
    if (inputrechts==HIGH){
    setTGrenz();
    }
    if (inputlinks==HIGH){
    settPause();
    }
    
    Serial.println("Unterscheidung zwischen");
    Serial.println("setTGrenz und settPause");
    delay(1000);
  } while (digitalRead(Schalter)==HIGH);
}

void setTGrenz (){
Serial.println("Bitte Grenztemperatur eingeben: ");
    delay(1000);
    do
			{
      		if (digitalRead(rechts)==HIGH){
      			TGrenz = TGrenz + 0.5;
              	Serial.println(TGrenz);
              	delay(500);
            }
      		if (digitalRead(links)==HIGH){
      			TGrenz = TGrenz - 0.5;
              	Serial.println(TGrenz);
              	delay(500);
            }
			} while (digitalRead(Schalter)==HIGH);
}

void settPause () {
Serial.println("Bitte Pausenzeit eingeben: ");
    delay(1000);
    do
			{
      		if (digitalRead(rechts)==HIGH){
      			tPause = tPause + 1;
              	Serial.println(tPause);
              	delay(500);
            }
      		if (digitalRead(links)==HIGH){
      			tPause = tPause - 1;
              	Serial.println(tPause);
              	delay(500);
            }
			} while (digitalRead(Schalter)==HIGH);
}

Problem:
Jetzt müsste auf dem Bildschirm quasi ausgegeben werden "Um TGrenz zu verändern, rechten Button drücken und um tPause zu verändern, linken Button drücken". Das funktioniert zwar soweit, aber dennoch hätte ich es gerne, dass man sich so durch klicken kann. Also z.B. mit dem rechten Button immer weiter 'durchscrollen' ("TGrenz verändern" -> "tPause verändern" -> "Platz für weiteres" -> "TGrenz verändern"...) und mit dem linken Button bestätigen, damit die jeweilige Methode aufgerufen wird.

Ich weiß nicht, wie ich das jetzt elegant umsetzen soll. Die Hardware ist gleich geblieben.

Ich bin leider immer noch nicht wirklich weiter gekommen.

Dafür habe ich mal dargestellt, wie's bisher bei mir aussieht:

Und nach Aufrufen der setTGrenz() Methode beispielsweise so:

Im Moment habe ich also für "Grenztemperatur" und "Intervallzeit" jeweils einen eigenen Taster, wie man auch im Quellcode im Post hierdrüber sehen kann. Ich würde das gerne so lösen, dass ein Taster den obersten Eintrag auswählt und die jeweilige Methode auswählt und der andere Taster sozusagen weiter durch die Einstellungen scrollt. Also dann steht "Intervallzeit" an oberster Stelle und würde mit dem anderen Taster ausgewählt werden können.

Kann mir da jemand nen Tipp oder einen groben Sketch geben, wie ich das ohne goto-Befehle anstelle?

Wo auch immer du das goto aufgeschnappt hast, dass gehört in fast allen zu der schlechtesten Programmiertechnik! [...] Schreibe das erst einmal um. Mit if und switch-Anweisungen.

Das war im Informatik-Unterricht.. :smiley: Da wurde auch switch-case behandelt, aber das hab ich wohl wieder verdrängt. Allerdings hilft mir das ja nicht viel, oder? Denn bei switch case kann man ja keine zwei Variablen übergeben?

Aber sicher nicht als Ihr C durchgemacht habt.

Lerne die basics von C ubd Arduino.

Grüße Uwe

Hi Uwe,

wann genau "goto" vorgestellt wurde weiß ich nicht mehr, könnte aber noch zu Zeiten von Basic gewesen sein. Wie auch immer.. :smiley:

Zunächst muss ich noch sagen: Ich möchte natürlich nicht, dass mir andere die Arbeit abnehmen, aber so richtig hilft mir eine Antwort wie "lerne die Basics" auch nicht weiter. Natürlich versuche ich mir im Moment die Basics selbst beizubringen, aber ich bin eben auch erst seit 2 Wochen mit Arduino zu gange und wäre da für einen konkreteren Tipp auch dankbar gewesen.

Ich habe jetzt grundsätzlich geschafft, was ich wollte. Das ganze muss ich dann später noch konkretisieren und ausbauen, aber ich kann immerhin schon durch verschiedene Seiten navigieren. Hier ein Ausschnitt:

int Seite = 1;

void loop() {
 if (digitalRead(Schalter)==HIGH){
 DataInput(); 
 }
Serial.println("Normaler Modus");
delay(1000);
}

void DataInput () {
  Serial.print(Seite);
  do{
    int inputlinks = digitalRead(links);
    int inputrechts = digitalRead(rechts);
    if (inputrechts==HIGH){
    Seite++;
      if (Seite==4){Seite=1;}
    Serial.print(Seite);
    }
    
    if (inputlinks==HIGH){
    	aktion();
    }
    
    delay(200);
  } while (digitalRead(Schalter)==HIGH);
}

void aktion(){
  Serial.println("aktion()");
  switch (Seite){   //Hier wird jetzt unterschieden, welches Element auf der Seite jeweils oben steht
  case 1:
    Serial.println("Einstellungen auf Seite 1");
    setTGrenz();
    break;
  case 2:
    Serial.println("Einstellungen auf Seite 2");
    settPause();
    break;
  case 3:
    Serial.println("Platz für weitere Funktionen");
    break;
  }
}

Na, sehr gut, das wird doch! Der Code schaut doch schon ganz brauchbar aus.

Noch ein Tip:
Die eigentliche Arbeit liegt meist vor dem Programmieren.
Mach dir erstmal eine skizze die der Programmablauf sein soll. Was in welchem Menuepunkt passieren soll, wann welche Aktion ausgeführt werden soll.

Erst wenn du weißt, wass dein Arduino eigentlich genau tun soll, dann versuche das in Code zu übersetzen.

Schrauber47:
wann genau "goto" vorgestellt wurde weiß ich nicht mehr, könnte aber noch zu Zeiten von Basic gewesen sein. Wie auch immer.. :smiley:

Mit goto kann man Spagetticode erzeugen oder strukturiert programmieren. Das liegt nur am Programmierer und was er gelernt hat. Das geht sogar in Assembler ... ;D

Anbei Dein von mir leicht veränderte Sketch.
Anm.: Ich verwende die internen Pullups. Pin 1 wird von TXD verwendet, da würde ich lieber einen anderen Pin nutzen.

Bei Fragen bitte fragen. :slight_smile:

Test_Forum.ino (1.16 KB)