Jetzt würde ich es aber gerne so ändern, das ich auch nur einzelne Werte ändern kann, ich schicke also z.B. ein r=100, und es ändert sich nur der wert für Rot.
Mir fehlt aber irgendwie der richtige Ansatz dazu.
Ein erster Versuch:
byte val_green;
byte val_red;
byte val_blue;
byte led_num;
int string;
void setup() {
Serial.begin(9600);
}
void loop() {
string=Serial.read();
if (string=='g=') {
val_green=Serial.parseInt();
}
if (string=='r=') {
val_redn=Serial.parseInt();
}
if (string=='b=') {
val_blue=Serial.parseInt();
}
if (string == '\n') {
Serial.print("R=");
Serial.println(val_red);
Serial.print("G=");
Serial.println(val_green);
Serial.print("B=");
Serial.println(val_blue);
}
}
'x' ist ein Zeichen. Kein String. Aktivtiere die Warnungen dann siehst du dass das der Compiler auch merkt
Sende dabei ein Linefeed am Ende (sonst geht es nicht!):
const int SERIAL_BUFFER_SIZE = 6;
char serialBuffer[SERIAL_BUFFER_SIZE];
byte r, g, b;
void setup()
{
Serial.begin(9600);
}
void loop()
{
if (readSerial(Serial)) //liefert true wenn das LF eingelesen wurde
parseSerial();
}
void parseSerial()
{
switch (serialBuffer[0])
{
case 'r':
case 'R':
r = atoi(serialBuffer + 2);
break;
case 'g':
case 'G':
g = atoi(serialBuffer + 2);
break;
case 'b':
case 'B':
b = atoi(serialBuffer + 2);
break;
}
Serial.print("R: "); Serial.println(r);
Serial.print("G: "); Serial.println(g);
Serial.print("B: "); Serial.println(b);
Serial.println();
}
bool readSerial(Stream& stream)
{
static byte index;
while (stream.available())
{
char c = stream.read();
if (c == '\n' && index > 0) //wenn LF eingelesen und String länger als 0 ist
{
serialBuffer[index] = '\0'; //String terminieren
index = 0;
return true; //melden dass String fertig eingelesen wurde
}
else if (c >= 32 && index < SERIAL_BUFFER_SIZE - 1) //solange noch Platz im Puffer ist
{
serialBuffer[index++] = c; //Zeichen abspeichern und Index inkrementieren
}
}
return false; //noch nicht fertig
}
Mehr Code aber du hast so unendlich mehr Flexibilität als mit parseInt(). So kann man beliebige Strings einlesen und auswerten.
Außerdem ist es nicht-blockierend und du kannst "gleichzeitig" noch andere Dinge tun. Das ist gerade bei LED Sachen wichtig. parseInt() braucht normal eine ganze Sekunde und auch wenn man die Timeout Zeit nach unten setzt (siehe setTimeout()) ist es nicht schön
Du kannst auch das = weglassen. Ist eigentlich überflüssig. Aber dann muss das +2 bei der atoi() Konvertierung durch +1 ausgetauscht werden!
Und für RGB Werte hat FastLED übrigens ein Color struct
parseInt() kann gehen. Gut ist es aber nicht. Und in jedem Fall sollte man unbedingt die Timeout Zeit nach unten setzten:
z.B. auf 10ms
Sonst blockiert jeder Aufruf für 1 Sekunde! Das ist typisch für viele Standard Arduino Funktionen die zwar machen was sie sagen, aber alles andere als schnell sind
Wenn man was fertiges verwendet, dann besser readStringUntil() oder readBytesUntil()
Das Beispiel "ConsoleShell.ino", deckt schon fast das hier gewünschte ab.
Die nötigen Anpassungen sind trivial.
(wenn ich die Frage richtig verstanden habe)
Ok, das muss ich jetzt erstmal durcharbeiten. Sind eine Menge Infos fürs erste.
Werde mich erstmal mit dem ersten Code,von Serenifly, auseinandersetzen.
Glaube das kommt meinem Ziel schon recht nahe. Möchte es aber auch selber schreiben können, deshalb erstmal verstehen.
Danach werde ich mir mal den CmdMessenger zu gemüte führen.
Rentner:
dann trennst Du das erste Zeichen ab und bringst den Rest in einen Integer Wert
Abtrennen muss man da gar nichts. Man fragt mit switch/case auf das erste Zeichen ab.
Und macht dann atoi(... + 1). Letzteres ist auch ein großer Vorteil von char Arrays. Man kann Zeigerarithmetik verwenden.
In meinem Beispiel ist es +2 weil da noch das = danach kommt. Dass man das nicht braucht habe ich schon erwähnt