Hi,
hoffe Ihr habt alle frohe Festtage !
Ich versuche gerade über den Seriellen Monitor in eine Switch-CASE zu
springen.
jedoch funktioniert das nicht ganz. Der Compiler meldet folgendes:
if (Serial.available() > 0) {
const char a = Serial.read();
}
if (millis() - Millis >= 10000) {
switch (a) {
case 1:
Serial.println("Case 1");
a = 2;
Millis = millis();
break;
}
So wird da eher ein Schuh draus. Keine goto's nötig da switch case über
den Inhalt des Identifier a gesteuert wird.
Man ist gut beraten goto's nicht zu nutzen.
kenny schrieb:> Man ist gut beraten goto's nicht zu nutzen.
Zumindest sollte man etwas Disziplin dabei wahren.
Was hier nicht geht, ist das Springen mitten in eine Funktion hinein.
@ Franco O.
Leider kann ich nicht erkennen, WAS gebaut werden soll, nur, dass du
einen falschen Weg gewählt hast.
Arduino Fanboy D. schrieb:> kenny schrieb:>> Man ist gut beraten goto's nicht zu nutzen.>> Zumindest sollte man etwas Disziplin dabei wahren.
Das habe ich aber auch oft gelesen dass man davon die finger lassen
sollte.
> Was hier nicht geht, ist das Springen mitten in eine Funktion hinein.>> @ Franco O.> Leider kann ich nicht erkennen, WAS gebaut werden soll, nur, dass du> einen falschen Weg gewählt hast.
Was genau ist der falsche weg?
also Der plan ist dass der die das Switch-Case normal laufen soll mit
dem Zusatz dass ich einen Bestimmten Case aufrufen kann er dann diesen
case ausführt und normal über die Millis weiter läuft
Du möchtest eine Ablaufsteuerung bauen?
Einen auf switch/case basierenden endlichen Automaten?
Dann musst du nicht springen!
Es reicht einfach:
STK500-Besitzer schrieb:> mach daraus: goto case 1;> Case = 1;
Wenn der Automat das nächste mal dran kommt, macht er mit 1 weiter.
Arduino Fanboy D. schrieb:> Wenn der Automat das nächste mal dran kommt, macht er mit 1 weiter.
Da da sowieso eine "}"-Klammer zu viel ist, macht er gar nichts weiter
(der Compiler wird weter rummeckern).
Ich habe die if-Else-If-Orgie so verstanden, dass bei Eingabe einer
Ziffer über die serielle Schnittstelle ein neuer Automatenzustand
gewählt werden soll.
Die Stelle wird ja auch nur angesprungen, wenn '1' auf der Schnittstelle
empfangen wurde.
Ich kann natrlich auch mal wieder komplett daneben liegen...
STK500-Besitzer schrieb:> Ich habe die if-Else-If-Orgie so verstanden, dass bei Eingabe einer> Ziffer über die serielle Schnittstelle ein neuer Automatenzustand> gewählt werden soll.
Kann ja sein!
Case = geleseneZahl - '0';
Arduino Fanboy D. schrieb:> Du möchtest eine Ablaufsteuerung bauen?> Einen auf switch/case basierenden endlichen Automaten?> Wenn der Automat das nächste mal dran kommt, macht er mit 1 weiter.
nene Das habe ich ja schon. Er starte bei 1 nach jedem ablauf
Franco O. schrieb:> case 1:> Serial.println("Case 1");>> Case = 2; <-- Nach jedem Case setzt er ihn auf den nächsten> Millis = millis();
so wird alle 10 Sekunden der nächste Case ausgeführt was auch so sein
soll
Jetzt möchte ich aber Case 2 aufrufen. So sind wir bei dem Geschreibsel
gelandet. Meine Idee war per Seriellen Monitor den Case einzugeben und
dann direkt dort hinzuspringen.
Arduino Fanboy D. schrieb:> Kann ja sein!>> Case = geleseneZahl - '0';
Vielleicht möchte er aber auch "Something completely different" in den
anderen Abfragen machen.
Die Abfragen kann man natürlich auch in einer Switch-Case-Abfrage
verarbeiten.
Man kann auch die Millis-Neuberechnungsgeschichten zusammenfassen und
vor der zweiten Switch-Case einfügen, sofern nicht vielleicht doch ein
Fall dabei ist, bei dem die Rechnung nicht durchgeführt werden soll.
Oliver S. schrieb:> So ginge es:> //...>> goto label1;> //....>> switch (Case) {>> case 1:> label1:> Serial.println("Case 1");>> break;> }
Würde er diesen Case dann Trotzdem selber ausführen wie bei mir oder nur
wenn ich label1 aufrufe ?
Einfach die Bedingung schaffen, dass er direkt nach Empfang eines
Characters das "switch" Statement ausführt, also:
if (Serial.available() > 0) {
const char a = Serial.read();
if (a == '1') {
Millis = millis() - 10000;
Case = 1;
}
...
if (millis() - Millis >= 10000) {
switch (Case) {
...
Das ist aber fast schon genauso fehlerhaft wie das von TO
Oliver S. schrieb:> So ginge es:
1
>//...
2
>
3
>gotolabel1;
4
>//....
5
>
6
>switch(Case){
7
>
8
>case1:
9
>label1:
10
>Serial.println("Case 1");
11
>
12
>break;
13
>}
Nö, das ist in den meisten Fällen eher wie mit dem Großkalibergewehr ins
Knie geschossen.
Kleiner Tipp, mal über den Gültigkeitsbereich von Variablen und über
wild im Quellcode verstreute "break" nachdenken.
Danke für die vielen Vorschläge!
Irgend W. schrieb:> Nö, das ist in den meisten Fällen eher wie mit dem Großkalibergewehr ins> Knie geschossen.
So hats bei mir geklappt. Sollte ich das denn lieber nicht so machen?
Franco O. schrieb:> So hats bei mir geklappt. Sollte ich das denn lieber nicht so machen?
Nimm lieber die Variante mit der Hilfsvariable so in der Art wie von
Dirk.B vorgeschlagen. Sowas ist allemal sauberer als mit goto mitten in
irgendwelche Konstrukte reinzuspringen und dann zu hoffen das sie
dennoch sauber verlassen werden.
---
Das mit dem goto|switch|case|label|break habe ich gerade mal mit clang
rumexperimentiert.
Interessanter weise tut der break genauso als wäre switch|case
ausgeführt worden und springt an die gleiche Stelle.
Erweckt bei mir jetzt eher den Eindruck dass das c-goto 1:1 in einen
ASM-Jump umgesetzt wird ohne darauf zu achten das dadurch das
eigentliche C-Konstrukt etwas ausgehebelt wird.
goto|irgendwas|label|break oder goto|for|switch|case|label|break frist
der Compiler dagegen nicht ohne heftig zu meckern.
Mich würde jetzt mal interessieren ob diese "als ob" verhalten bei einem
goto mitten in eine switch irgendwo im Standard definiertes Verhalten
ist auf das man sich theoretisch verlassen könnte oder eher "Zufall"
ist. So auf die schnell konnte ich diesbezüglich nichts finden.
PS: ich habe garantiert nicht vor sowas ernsthaft zu verwenden, es
interessiert mich nur gerade mal wieder was C/C++ so alles an
"fragwürdigen" Konstrukten zulässt.
Irgend W. schrieb:> Mich würde jetzt mal interessieren ob diese "als ob" verhalten bei einem> goto mitten in eine switch irgendwo im Standard definiertes Verhalten> ist auf das man sich theoretisch verlassen könnte oder eher "Zufall"> ist.
Ist kein Zufall.
Schaue dir dazu mal dem Adam Dunkel seine ProtoThreads an.
Eine Variante arbeitet mit Switch/case, welches auch Case in
untergerodneten Blöcken "anspringen" kann. Auch mitten in for Schleifen
rein usw.
Die andere Variante nutzt computed goto für den selben Zweck.
Es gibt viele weitere Implementierungen dieses Prinzips.
z.B.
https://forum.arduino.cc/index.php?action=dlattach;topic=415229.0;attach=176389https://forum.arduino.cc/index.php?action=dlattach;topic=596279.0;attach=293747
Irgend W. schrieb:> Nimm lieber die Variante mit der Hilfsvariable so in der Art wie von> Dirk.B vorgeschlagen. Sowas ist allemal sauberer als mit goto mitten in> irgendwelche Konstrukte reinzuspringen und dann zu hoffen das sie> dennoch sauber verlassen werden.
Gut dann nehme ich das Lieber :)
Herzlichen Glückwunsch Dirk du wirst für immer und ewig in meinem Code
verewigt.
Dankeschön!