Hallo,
ich schreibe grad an einer Steuerung für mein Zimmer mit Relaisschaltungen, Sensoren, usw. Das Problem ist, wie kann ich quasi gleichzeitig die Gui und den Rest ausführen? Erstmal gegooglet und auf diese Seite gestoßen(http://arduino.cc/en/Tutorial/MultipleBlinks). Soweit ich das verstanden habe, muss man delays einbauen, damit auch sichergestellt wird, dass alle Schleifen auch wirklich laufen.
Dann ein paar Stunden später beim Müsli machen komme ich auf die Idee stattdessen switch-Befehle zu verwenden, wie in dem Beispiel unten. Meine Frage nun, was haltet ihr davon? Gibt es irgendwelche No-Goes, die ich begangen habe? Ich bin leider nicht so der C-profi.
da wird dann gewartet bis der touchscreen berührt wir, das heißt es wird auch nicht im Hintergrund z.B. die Zeit synchronisiert oder Messdaten empfangen oder Steckdosen an und ausgeschaltet. Das will ich umgehen, indem immer anstatt gewartet wird, anderer Code ausgeführt wird. Und damit der Arduino weis wo er aufgehört hat, will ich einen switch dafür benutzen.
Wenn du diesen Scheduler verwenden willst, hast du das wichtigste vergessen:
Scheduler.startLoop(loop2);
Aber klassischerweise laufen alle Aktionen quasi parallel, wenn man kein delay() verwendet.
Hochtrabend "kooperatives multitasking" genannt:
Jede Funktion macht nur (max.) 1 Aktion, bzw. erkennt normalerweise, dass nichts zu tun ist, und beendet sich sofort wieder.
So wie du es wohl mit deiner switch Lösung vorhast, wobei da ein paar Ungereimtheiten drin sind:
ohne break; wird der folgende case mit ausgeführt
Serial.available() liefert die Anzahl Zeichen, nicht das Zeichen selbst.
Variablennamen und Funktionsnamen sollten unterschiedlich sein.
Diese Sequenz macht nichts, sieht aber gefährlich aus:
while(!touch.dataAvailable()){
break;
}
gefährlich, weil while meist so schlecht wie delay ist, da etwas längere Zeit hängen kann
hier Unsinn, weil entweder dataAvailable() == false ist und die while Schleife mit break verlassen wird, oder die while Schleife beendet wird.
Aber prinzipiell ist ein switch schon gut, um sich zu merken, wo in einer Steuerungssequenz man grade ist.
Das war durchaus so beabsichtigt. Wenn hier das touchscreen berührt wird soll sofort die position gespeichert werden
Serial.available() liefert die Anzahl Zeichen, nicht das Zeichen selbst.
Variablennamen und Funktionsnamen sollten unterschiedlich sein.
Das ist hier nur ein Beispiel zur Verdeutlichung meiner Idee. Ich hab die Methodennamen nicht alle im kopf, va. wenn ich damit sonst nichts zu tun habe.
hier Unsinn, weil entweder dataAvailable() == false ist und die while Schleife mit break verlassen wird, oder die while Schleife beendet wird.
Da habe ich nicht genau überlegt. Wie lautet denn der Syntax, wenn ich mit dem break den switch verlassen will?
Das war durchaus so beabsichtigt. Wenn hier das touchscreen berührt wird soll sofort die position gespeichert werden
OK, aber wofür dann der extra case ?
Die Variableint loop1brauchst du doch nur, um bei einem neuen loop-Aufruf in einem Zwischenzustand weiterzumachen, wo du vorher aufgehört hast. Und ohne break; hörst du immer mit loop1=0; auf.
Generell solltest du alle while durch ein if ersetzen. Es reicht, in einem Durchlauf nur 1 Zeichen einzulesen: wenn noch mehr erwartet wird, kommt das eben in einem der nächsten Durchläufe.
Hier (Umwandlung char* in char - #3 by Serenifly - Deutsch - Arduino Forum) hat Serenifly ein schönes Beispiel, ( denke dir Serial statt Wire). Am Ende von loop kannst du z.B. eine beliebige andere Funktion anfügen, die gleichzeitig mit der demo-Funktion "Text seriell einlesen" ausgeführt würde...
void loop()
{
char* SerialData = readString(); // reads max 1 char, returns NULL if input not complete
if ( SerialData ) Bearbeiten(SerialData);
TouchScreenInput();
SendData(); // falls was zu senden ist
}
void TouchScreenInput()
{
if (!touch.dataAvailable()) return; // keine Eingabe, sofort fertig
int x= UTouch.getX();
int y= UTouch.getY();
// hier könnte man evtl. eine switch Variable verwenden, um eine Menüführung zu realisieren
}
Jup. Ich sehe nicht wozu man da extra einen Scheduler braucht. Das läuft bei mir genauso mit Abfrage von Serial und Touchscreen hintereinander in loop(). Je nachdem in welchem Menü man ist, wird dann noch die Uhr oder Temperatur angezeigt.
MrSkuff:
Wenn hier das touchscreen berührt wird soll sofort die position gespeichert werden
definiere "sofort"!
Wenn du das in normalen seriellen bzw "kooperativem" Multitasking programmierst, dann liegen deine loop() durchläufe im Bereich weniger ms. Ich komme bei komplexen Programmen selten über 20ms. Selbst 100ms sind für einen Microkontroller eine Ewigkeit. Für den Menschen ist das aber noch "sofort".
Das kann z.B. so aussehen: (als Pseudocode)
void loop(){
Tastenlesen();
AnzeigeAkutaliesieren();
Relaisansteuern();
}
void Tastenlesen(){
if Tastegedrückt{
verarbeiten;
} else return;
}
void AnzeigeAkutaliesieren(){
if Wertegeändert{
neue Werte schreiben;
else return;
}
void Relaisansteuern(){
if neue Ausgangswerte;
else return;
}
Also, dann hau ich jetzt mal meine Kommentar raus.
OK, aber wofür dann der extra case ?
Ich hab das nur schnell hingetippt, damit man das Prinzip versteht, ich drücke mich nicht immer verständlich genug aus.
Generell solltest du alle while durch ein if ersetzen
Werde ich berücksichtigen beim coden.
Jup. Ich sehe nicht wozu man da extra einen Scheduler braucht. Das läuft bei mir genauso mit Abfrage von Serial und Touchscreen hintereinander in loop(). Je nachdem in welchem Menü man ist, wird dann noch die Uhr oder Temperatur angezeigt.
Das ist nur ein Beispiel zum verstehen vom Prinzip. Es geht bei mir darum:
Wenn sowas wie: if(touch.dataAvailable()){...} mitten im Code vorkommt und wenn dataAvailable==false ist, dann wird der Code vor if(touch.dataAvailable()){...} bei dem einfachen hintereinanderfügen in eine Loop nochmals ausgeführt. Das soll nicht passieren.
Wenn du das in normalen seriellen bzw "kooperativem" Multitasking programmierst, dann liegen deine loop() durchläufe im Bereich weniger ms. Ich komme bei komplexen Programmen selten über 20ms. Selbst 100ms sind für einen Microkontroller eine Ewigkeit. Für den Menschen ist das aber noch "sofort".
dann ist aber auch egal, ob zuerst dieser codeblock ausgeführt wird oder ein anderer
Danke für die Kommentare, Verbesserungen und Denkanstöße
MrSkuff:
Es geht bei mir darum:
Wenn sowas wie: if(touch.dataAvailable()){...} mitten im Code vorkommt und wenn dataAvailable==false ist, dann wird der Code vor if(touch.dataAvailable()){...} bei dem einfachen hintereinanderfügen in eine Loop nochmals ausgeführt. Das soll nicht passieren.
Man kann das um Statusvariablen und/oder Rückgabewerte erweitern, so dass Code-Teile nur ausgeführt werden wenn woanders was gemacht wurde.