Hallo, wie man am Betreff bereits erkennt, kennt es darum die serielle Daten vom Arduino auszulesen. In meinem Projekt sende ich zum Arduino über den seriellen Monitor immer ein char z.B. 'g'. Je nachdem was angekommen ist will ich eine RGB LED leuchten lassen. Dies gelingt mir auch in der loop(), jedoch möchte ich auch die Helligkeit variieren und lese die gesendeten Daten einfach in der jeweiligen Unterfunktion (green_led()) nochmal aus und hier liegt das PROBLEM. 2 bis 3 mal funktiniert meine Funktion, dann passiert murks. Ich kann dann nicht mehr zwischen den Funktionen in der loop() wechseln oder muss das char 2 mal senden, damit es registriert wird. Da ich noch ein Neuling in der Sache bin, hoffe ich ihr könnt mir helfen.. /////////////CODE//////////// int green = 12; int red = 11; int blue = 9; int color; int brightness; int bright = 0; void setup() { Serial.begin(9600); pinMode(green, OUTPUT); pinMode(red, OUTPUT); pinMode(blue, OUTPUT); bright = 205; } void loop() { if(Serial.available() > 0) { color = Serial.read(); char rec = color; Serial.println(color); Serial.println(rec); } if(color == 'a') { turn_off(); } else if(color == 'g') { green_led(); } } /////////////// Funktionen /////////////// int turn_off() { analogWrite(green, 0); analogWrite(red, 0); analogWrite(blue, 0); } int green_led() { analogWrite(green, bright); analogWrite(red, 0); analogWrite(blue, 0); if(Serial.available() > 0) { brightness = Serial.read(); char rec = brightness; Serial.println(brightness); Serial.println(rec); } if(brightness == 'u') { bright = bright + 50; if(bright >= 255) bright = 255; } else if(brightness == 'd') { bright = bright - 50; if(bright <= 5) bright = 5; } }
Hmm... So einen Parser habe ich noch nicht gesehen. Und wenn du das Problem hast, dass es nur manchmal funktioniert, dann solltest du ihn nochmal überarbeiten. In welchem Format sendest du die Daten? Leider kann ich das aus dem Code nicht erkennen. Darf ich dir den "Arduino CmdMessenger" ans Herz legen?
Also ich sende immer ein char, oder meinst das die Bitbreite? Ich glaube das wären bei dem Arduino 8Bit. Was ist denn der Arduino CmdMessenger ?
Jul H. schrieb: > 2 bis 3 mal funktiniert meine Funktion, dann passiert murks. Kannst du das mal naeher beschreiben? Was genau passiert? Und was genau erwartest du, was passieren sollte?
Jul H. schrieb: > Was ist denn der Arduino CmdMessenger ? Erster und zweiter Treffer bei Google, wenn du nach "Arduino CmdMessenger" suchst
Ich erwarte, wenn ich ein 'g' sende, dass analowWrite(green, bright) ausgeführt wird (also dass die grüne LED leuchtet) und wenn ich ein 'a' sende, soll die LED ausgehen. Das funktioniert auch alles mit dem Serial.read(), jedoch möchte ich die LED, wenn sie grün ist auch verschieden hell leuchten lassen -> mit 'd' weniger und mit 'u' mehr. Ich vermute das Problem liegt bei den beiden Serial.read() Funktionen, vielleicht wird eine Funktion schon ausgeführt, wenn die nachricht noch nicht komplett angekommen ist und dann kommt es zu diesen bugs -> man muss 2 mal 'g' senden damit es ausgeführt wird oder die funktion wird garnicht ausgeführt.
du hast zwei Serial.read in deinem Programmablauf. Angenommen du liest beim 2. read das ‘a‘ ein, dann ist das bei dir nicht vorgesehen. Abhilfe: •ein• read und schau dir state machines an
Hi, du löscht nach dem abarbeiten den Inhalt deiner Variablen die du für die if Abfragen nutzt nicht. Zudem ist es so das der neue Wert für "brightness" nur eingelesen wird wenn die Zeit zwischen dem "g" und dem neuen Buchstaben kürzer ist als die Zeit die das Programm braucht bis es
1 | if(Serial.available() > 0) { |
2 | brightness = Serial.read(); |
3 | char rec = brightness; |
4 | Serial.println(brightness); |
5 | Serial.println(rec); |
6 | }
|
erreicht. Wenn nicht dann wird das ausgeführt was noch in brightness drinnen steht. Das Programm wartet ja nicht bis was da ist , sondern nur wenn was gekommen ist wird der Wert eingelesen und verarbeitet. Du brauchst also eine state machine die nach dem "g" die nachfolgende Eingabe verarbeitet egal wann sie kommt. Gruß JackFrost
Vermutlich ist die Funktion green() schon durch bis das U oder das D ankommen. Außerdem solltest Du sicherstellen, dass ein Buchstabe nur genau einmal ausgewertet wird. Und überhaupt, wenn Du schon lauter verschiedene Buchstaben benutzt, werte an einer Stelle alle Möglichkeiten aus. Ansonsten läuft das irgendwann aus dem Ruder und Du empfängst eine Farbe, wenn Du bei der Helligkeit bist und umgekehrt.
am einfachsten ist doch ein vollständiges Komando senden green200<ENTER> (mit CR/LF) wenn der Ardu CR sieht Text übernehmen Text prüfen ob green drin ist und ob danach noch 1-3 Ziffern kommen, dann das Komando ausführen solange der Ardu CR nicht sieht Zeichen sammeln bis CR oder Buffer voll, dann Buffer leeren und verwerfen! Beitrag "Re: Hilfe bei Klingeltrafo & ESP32" so am Ardu und ESP
1 | void serialEvent(void) |
2 | { while (Serial.available()) |
3 | { char incomingByte = (char)Serial.read(); |
4 | if(incomingByte == 13) // Wenn das Enter ankommt |
5 | { serial_in_buff[chr_cnt] = '\0'; |
6 | strcpy(serial_in_command, serial_in_buff); |
7 | memset(&serial_in_buff[0], 0, sizeof(serial_in_buff)); // 30.554 Bytes |
8 | chr_cnt = 0; |
9 | stringComplete = true; |
10 | }
|
11 | else // Falls kein Enter kommt muss der Text gespeichert werden in dem inText Array |
12 | { if(isprint(incomingByte)) |
13 | { if(chr_cnt<(MAXBUFFER-2)) |
14 | serial_in_buff[chr_cnt++] = incomingByte; |
15 | else
|
16 | { Serial.println(F("serBUF ov-> DEL")); |
17 | memset(&serial_in_buff[0], 0, sizeof(serial_in_buff)); // 30.554 Bytes |
18 | memset(&serial_in_command[0], 0, sizeof(serial_in_command)); // 30.554 Bytes |
19 | // *serial_in_command=0;
|
20 | chr_cnt=0; |
21 | } // if(chr_cnt<(MAXBUFFER-2)) |
22 | } // if(isprint(incomingByte)) |
23 | } // if !(incomingByte == 13) |
24 | } // while (Serial.available()) |
25 | } // void serialEvent() |
:
Bearbeitet durch User
Joachim B. schrieb: > am einfachsten ist doch ein vollständiges Komando senden Für ihn evtl. nicht. Dann braucht er nämlich so was wie eine Statemachine zur Auswertung. Wenn ein R ein R ist, egal wann und nach was es kommt, vereinfacht dass die Auswertung. Und selbst damit tut er sich ja noch schwer.
fop schrieb: > Wenn ein R ein R ist, egal wann und nach was es kommt, vereinfacht dass > die Auswertung. Einen solchen primitiven Parser habe ich gerade vorgefunden. Den kann ich hier ja mal zeigen: (evtl. hilfts ja)
1 | enum Option |
2 | {
|
3 | WrOff = 12, |
4 | WrOn = 13, |
5 | ShuntOff = 14, |
6 | ShuntOn = 15 |
7 | };
|
8 | |
9 | void serialEvent() |
10 | {
|
11 | switch(Serial.read()) |
12 | {
|
13 | case ShuntOn : SHUNT_Set(true); |
14 | break; |
15 | |
16 | case ShuntOff: SHUNT_Set(false); |
17 | break; |
18 | |
19 | case WrOn : Wait(); |
20 | WR_Set(true); |
21 | break; |
22 | |
23 | case WrOff : Wait(); |
24 | WR_Set(false); |
25 | break; |
26 | }
|
27 | }
|
OK, der ist so primitiv, dass das Wort Parser schon fast eine Übertreibung ist. Aber bei dieser Anwendung könnte es reichen.
Danke für die vielen guten Antworten!!! Ich habe mich über FSM informiert und meinen Code überdacht :) Jetzt klappt alles nach Plan !!!
Jul H. schrieb: > Danke für die vielen guten Antworten!!! > > Ich habe mich über FSM informiert und meinen Code überdacht :) > Jetzt klappt alles nach Plan !!! Schön das du dein Problem gelöst hast. Leider hilft deine Schlußantwort niemandem weiter, der beim durchsuchen des Forums ein ähnliches Problem hat. Schön währe es, wenn du abschließend deine Problemlösung hier aufzeigen würdest, so könnte der Trööt auch anderen helfen. Gruss Volker
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.