ich bin dabei eine RGB Lampe mit Arduino zu bauen und habe dabei ein Problem. Ich kann in meinem Programm über ein Menü Unterprogramme auswählen um den LED's zu sagen was sie machen sollen. Mir geht es darum die PWM's mit Potis einzustellen was bereits funktioniert. Das Unterprogramm wird durch den IF Befehl andauernd wiederholt da die Bedingung esc_val=0 erfüllt ist wie bekomme ich es hin das ich in das Hauptprogramm zurück komme.
Eine Methode kannst du abbrechen in dem du "return" schreibst. Da der Rückgabe-Wert void (als nichts) ist, muss kein Wert zurückgegeben werden.
Also in Pseudocode:
if(Bedingung == true)
{
return;
}
Das Programm macht dann mit der nächsten Zeile nach dem ursprünglichen Methoden-Aufruf weiter.
else
{
loop();
}
Sowas darfst du nicht machen! Der Controller merkt sich schon die Rücksprung-Adresse wenn die Methode aufgerufen wurde. Wenn du dann so per Hand zurückspringst wird diese nicht vom Stack entfernt. Oder er kehrt nach Beenden der aufgerufenen Methode in die Unter-Methode zurück. Nach ein paar mal hin und her stimmt dann unter Umständen der Programmfluss wieder, aber es ist sehr unsicher.
Eine Methode sich selbst aufrufen zu lassen ist aus dem gleichen Grund keine gute Idee. Das nennt sich Rekursion und hat legitime Anwendungen, aber es ist durch das Speichern der Rücksprung-Adresse sehr Speicher-intensiv. Hier macht es einfach keinen Sinn.
Wenn du den Code in der Methode immer wieder aufrufen willst, dann mach eine while-Schleife herum:
while(Bedingung == false)
{
//Code hier
}
Dann führt er das solange aus bis die Bedingung eintritt (z.B. Knopf drücken).
Hier ist jetzt das komplette Programm wie komme ich jetzt zurück ich bekomme irgend wie esc_val im unterprogrmm analog_p (was ganz unten ist) nicht auf den wert 1 oder so das er zurück ins Hauptprogramm kommt.
Die Abfrage muss in die while-Schleife damit sie immer wieder abgerufen wird. Sonst ändert sich der Wert der Variablen nie und die steckst für immer in der Schleife.
int esc_val = 0;
while(true)
{
//Blah
if(digitalRead(esc))
{
esc_val++;
delay(100);
}
if(esc_val > 0)
return;
} //end while
Theoretisch könnte die Abfrage des Tasters auch direkt in die while-Schleife (wo die Bedingung abgefragt wird), aber durch das Entprellen ist das so besser
esc_val muss auch nicht global sein
Alternative:
int esc_val = 0;
while(esc_val == 0)
{
//Blah
if(digitalRead(esc))
{
esc_val++;
delay(100);
}
} //end while
Da kannst du dir das return ganz sparen. Die while-Schleife wird beendet und danach ist gleich die Methode zu Ende.
Habe nochmal ne kürzere Alternative oben hingeschrieben, mit der du dir die if-Abfrage auch sparen kannst. Schadet aber nichts wenn du dir über die Optionen im Klaren bist, da es für beide Fälle Anwendungen gibt. z.B. wenn die Bedingung mehrere Werte annehmen kann und man nur ein einem Fall zurückkehren will und sonst etwas anderes machen will.
While-Schleifen kann man auch mit "break" beenden. Daher würde das hier auch funktionieren und ist in diesem Fall wahrscheinlich das sauberste:
Du hast da zwei Versionen kombiniert. Da habe ich dich wahrscheinlich zu sehr verwirrt
Wenn du esc_val in der while-Schleife abfragst brauchst da das manuelle Return nicht. Die while-Schleife beendet sich automatisch wenn die Bedingung false ist. Und danach beendet sich gleich die Methode, da du am Ende bist.
Die Variable esc_val brauchst du auch überhaupt nicht. Ich bin da halt am Anfang erst bei deinem Code geblieben. Hätte ich vielleicht gleich verwerfen sollen. Schau dir mal mein vorheriges Post an. While(true){} und dann einfach "break" wenn die Bedingung zutrifft. Das ist in diesem Fall am kürzesten.
Kann es sein, dass du irgendwie noch in den inneren while-Schleifen drinnen hängst und daher der Taster nie abgefragt wird? Generell wird der Taster auch nur am Ende kurz abgefragt und dann macht er 3 while-Schleifen. Je nachdem wie lange die dauern bekommst du die Aktion gar nicht mit.
Dazu mußt Du die Funktion fade umschreiben.
So wie Du sie geschrieben hast mußt Du oft länger als 3 Sekunden warten bis der AUS-Taster gelesen wird. Machs mit millis und globalen Variablen welche Farbe gerade goch oder runtergezählt wird. Außerdem würde ich auch kontrollieren ob die min bzw maximalwerte des PWM erreicht sind damit kein Überlauf und damit die Farbe plötzlich hell ist.
Ich habe mir das gerade mal geschaut. Das Beenden der Funktion funktioniert nur beim wechsel in die nächste while Schleife. Die maximal und die minimal PWM Werte werden jeweils erreicht. Muss ich jetzt das rücksetzen in jede while schleife einzeln setzen?