ich bin seit kurzem dabei mit dem Arduino (MEGA) bestimmte Sensoren auszuwerten.
Nun bin ich dabei ein Interface für den Nutzer zu gestalten alles soweit gut, bis auf dass folgende Problem.
Es gibt ein Untermenü "XY" hier sollen von einem GYRO, Beschleunigungsmesser die Messwerte in Echtzeit angezeigt werden.
Wenn ich die folgenden Programmzeilen in den loop() {} packe funktioniert es einwandfrei, jedoch soll dies nun unter einem Menüpunkt gesetzt werden. So dass der Benutzer diesen auswählen kann und erst dann die Daten angezeigt werden.
Mein Problem:
Die Werte werden einmalig zu dem Zeitpunkt angezeigt in dem ich diesen Menüpunkt auswähle danach bleiben diese Daten. --> Also eine Schleife die solange durchlaufen soll bis ich die Taste "X" betätige, dies habe ich mit einer do …. while - Schleife versucht jedoch erfolglos, die Daten bleiben die selben.
Wenn ich dies mit einer for - Schleife schreibe funktioniert es aber auch nur solange bis der Zähler eben eine vorher bestimmten Wert einnimmt.
ghahn11:
Wenn ich fragen darf weshalb den gesamten Code ?
Meist zeigen Leute (also evtl. auch du) den Code, den sie schon 1000 mal geprüft haben.
Und der Code, wo sie noch nicht intensiv hingeschaut haben, wird vor uns geheim gehalten.
Aber genau da steckt der Fehler. Oft.
Der Fehler steckt dort, wo du ihn nicht vermutest.
Denn wenn er nicht dort wäre, dann hättest du ihn doch schon gefunden.
Oder?
Zeigst aber die Stelle, wo du ihn vermutest.
Merksatz:
Der Fehler ist IMMER dort, wo man ihn zuletzt sucht.
Hier:
Da while Schleifen perfekt funktionieren, immer, hast du ein Problem mit der Taste, oder ähnlich.
Aber die funktionierende For Schleife muss ja geheim bleiben, genauso wie die Tasteninitialisierung/Schaltplan.
Weil 20 Zeilen aus dem Kontext (Sketch) gerissen gleichgut völlig richtig wie grottenfalsch im Bezug zum restlichen Sketch sein können.
Bist Du 100% sicher daß die Schleife mehr als einmal durchlaufen wird?
Ah, einen Schaltplan bräuchten wir auch. Zum Schluß fehlt nur der Pullupwiderstand.
Grüße Uwe
Ich bevorzuge stattdessen "Kompletten Code, der das Problem zeigt, aber gern ohne alles Unnötige"
Das ist zwar für dich mehr Arbeit, hilft dir selbst aber enorm, wenn du beim Versuch, ein minimales Fehlerbeispiel zusammenzustellen, merkst, dass der Fehler gar nicht da ist, wo du ihn vermutest.
michael_x:
Ich bevorzuge stattdessen "Kompletten Code, der das Problem zeigt, aber gern ohne alles Unnötige"
Das ist zwar für dich mehr Arbeit, hilft dir selbst aber enorm, wenn du beim Versuch, ein minimales Fehlerbeispiel zusammenzustellen, merkst, dass der Fehler gar nicht da ist, wo du ihn vermutest.
Dem kann ich in allen Punkten, voll und ganz, zustimmen.
habs eingekürzt, jetzt schaust du erstmal zu wie das Programm auf deine Tastendrücke reagiert.
Was macht i ?
Globale zustand Variable für mehrere switch case ist gefährlich. Sollte hier auch unsigned sein, meistens reicht byte.
case default ist hier auch wichtig, weil dein zustandszähler wild geändert wird per Tastendruck.
Wenn der ins negative zählt bzw. außerhalb deiner case Nummern ist, kann dein Programm nichts machen bzw. wird nicht sauber ausgeführt. Könntest über eine Zählumfangsbegrenzung nachdenken.
const byte hoch = 4;
const byte runter = 5;
const byte ok = 6;
const byte zuruck = 7;
int i = 0;
int zustand = 1;
void setup()
{
Serial.begin(9600);
pinMode(hoch, INPUT_PULLUP);
pinMode(runter, INPUT_PULLUP);
pinMode(ok, INPUT_PULLUP);
pinMode(zuruck, INPUT_PULLUP);
updateMenu();
}
void loop()
{
if (!digitalRead(runter))
{
zustand++;
updateMenu();
delay(10);
while (!digitalRead(runter));
}
if (!digitalRead(hoch))
{
zustand--;
updateMenu();
delay(10);
while (!digitalRead(hoch));
}
if (!digitalRead(ok))
{
execute();
delay(10);
while (!digitalRead(ok));
}
if (!digitalRead(zuruck))
{
updateMenu();
delay(10);
while (!digitalRead(zuruck));
}
}
void updateMenu()
{
Serial.print("Menu zustand: ");
Serial.print(zustand);
switch (zustand)
{
case 0:
Serial.print(" im case: "); Serial.println(zustand);
zustand = 1;
break;
case 1:
Serial.print(" im case: "); Serial.println(zustand);
break;
case 2:
Serial.print(" im case: "); Serial.println(zustand);
break;
case 3:
Serial.print(" im case: "); Serial.println(zustand);
break;
case 4:
Serial.print(" im case: "); Serial.println(zustand);
break;
case 5:
Serial.print(" im case: "); Serial.println(zustand);
break;
case 6:
Serial.print(" im case: "); Serial.println(zustand);
zustand = 4;
break;
default: Serial.println(" Menu default");
break;
}
}
void gyro()
{
do {
Serial.println("bin in gyro() Funktion");
delay(200);
} while (!digitalRead(zuruck));
}
void action5() //GYRO-Set
{
gyro();
}
void execute()
{
Serial.print("execute zustand: ");
Serial.print(zustand);
switch (zustand)
{
case 1:
Serial.print(" im case: "); Serial.println(zustand);
// action1();
break;
case 2:
Serial.print(" im case: "); Serial.println(zustand);
//action2();
break;
case 3:
Serial.print(" im case: "); Serial.println(zustand);
//action3();
break;
case 4:
Serial.print(" im case: "); Serial.println(zustand);
//action4();
break;
case 5:
Serial.print(" im case: "); Serial.println(zustand);
action5();
break;
default: Serial.println(" execute default");
break;
}
}
ghahn11:
Also eine Schleife die solange durchlaufen soll bis ich die Taste "X" betätige, dies habe ich mit einer do …. while - Schleife versucht jedoch erfolglos, die Daten bleiben die selben.
Zum Einen: gewöhne dir bitte von Anfang an an, deine Programme vernünftig zu kommentieren. Ich finde es - gelinde gesagt - eine Zumutung, uns hier vollkommen unkommentierten Code vorzusetzen, durch den wir uns durchbeissen sollen. Insbesondere, da durch den fehlenden Kommentar nicht klar, ist was passieren SOLL. So kann man dann auch nicht feststellen, ob der Code das tut, was er tun soll.
Außerdem wirst Du dich selbst über jeden Kommentar freuen, wenn Du dir dein eigenes Programm nach längerer Zeit mal wieder vornimmst.
Zum Anderen: Da Du die Tasterinputs mit INPUT_PULLUP initiierst, gehe ich davon aus, dass deine Taster LOW-aktiv sind. D.h. im Ruhezustand ist der Input HIGH. Wenn Du dann in deiner while-Schleife auf LOW abfragst:
} while (!digitalRead(zuruck));
bedeutet dass, das die Schleife sofort beendet wird, denn bei nicht gedrücktem Taster ist dieser Ausdruck false. Wenn ich dich richtig verstehe, willst Du aber, dass die Schleife läuft bis der Taster gedrückt wird. Der Ausdruck muss als 'true' sein, wenn der Taster nicht gedrückt ist:
} while (digitalRead(zuruck));
P.S. ein gutes Programmkonzept ist das m.M. nach nicht. Während der Anzeige kann ringsrum die Welt zusammenbrechen - der Arduino merkt es nicht, denn er kann auf nichts anderes reagieren, als auf deinen 'zuruck' Taster.
ghahn11:
Aber leider funktioniert die do-while-Schleife immer noch nicht.
Hallo,
mein Ziel war es nicht deinen Sketch zu reparieren. Im dem Zustand ist das schlecht möglich. Mein Ziel war es dir Debugausgaben in die Hand zugeben damit DU siehst was dein Sketch macht und eben nicht macht. Die Schlussfolgerungen daraus solltest du dann ziehen.