String Variable für FastLED umwandeln

Hallo,

habe folgendes Problem:

Sende mir über Bluetooth von einer App einen String z.b. FF6347. Dieser soll als Farbcode für einen RGB-Streifen dienen. Diesen habe ich nun zerlegt für Rot,Grün und Blau (Also Rot = FF, Grün = 63, Blau = 47). Da es sich immer noch um einen String handelt kann ich diese Werte nicht weiter verarbeiten. Der String muss denke ich mal in char, int oder dec gewandelt werden aber wie funktioniert das?

#include <FastLED.h>


#define DATA_PIN  6
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
#define NUM_LEDS 37
int BRIGHTNESS  = 120;
CRGB leds [NUM_LEDS];

//String data;
//String rot;
//String gruen;
//String blau;



void setup() 
{
 Serial.begin(9600);
 FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);   // passt die Farben je nach Chip etwas an
 FastLED.setBrightness(BRIGHTNESS);
}

void loop()
{
  if (Serial.available())
  {
  String data = Serial.readString();      //lese Empfangene Daten
  Serial.print("Empfangen: ");
  Serial.println(data);
  String rot = data.substring(0,2);       //zerlegen Empfangene Daten von Stelle 0-2
  Serial.print("Rot: ");
  Serial.println(rot);
  String gruen = data.substring(2,4);     //zerlege Empfangene Daten von Stelle 2-4
  Serial.print ("Grün: ");
  Serial.println(gruen);
  String blau = data.substring(4,6);
  Serial.print("Blau: ");
  Serial.println(blau);                   // String muss in char umgewandelt werden für FastLED
  char x = rot.toInt();                   // erkennt Buchstaben nicht
  Serial.println(x); 

  
  }

 /* if (Serial.available())               // als char auslesen, liest jedes Zeichen einzeln
  {
  char data = Serial.read();
  Serial.println("Empfangen: ");
  Serial.print(data);
  }
  
  
  FastLED.showColor (CRGB (rot, gruen, blau));
  */
}
unsigned red,green,blue;
sscanf("FF6347","%2X%2X%2X",&red,&green,&blue);

Hallo,
muss es RGB sein schau Dir mal das HSV Farbschema der Lib an

HSV

eventuell ist das einfacher
Heinz

Nachtrag
@combie super Lösung ich war schon wieder dabei den String zu zerlegen in je zwei zeichen :wink:

#include <FastLED.h>


#define DATA_PIN  6
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
#define NUM_LEDS 37
int BRIGHTNESS  = 120;
CRGB leds [NUM_LEDS];

//String data;
//String rot;
//String gruen;
//String blau;



void setup()
{
  Serial.begin(9600);
  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); // passt die Farben je nach Chip etwas an
  FastLED.setBrightness(BRIGHTNESS);
}

void loop()
{
  if (Serial.available())
  {
    String data = Serial.readString();      //lese Empfangene Daten
    Serial.print("Empfangen: ");
    Serial.println(data);
    String rot = data.substring(0, 2);      //zerlegen Empfangene Daten von Stelle 0-2
    Serial.print("Rot: ");
    Serial.println(rot);
    // Weiter rechnen
    Serial.println(strtol(rot.c_str(), 0, 16));
    // Ende Weiter gerechnet
    String gruen = data.substring(2, 4);    //zerlege Empfangene Daten von Stelle 2-4
    Serial.print ("Grün: ");
    Serial.println(gruen);
    // Weiter rechnen
    Serial.println(strtol(gruen.c_str(), 0, 16));
    // Ende Weiter gerechnet
    String blau = data.substring(4, 6);
    Serial.print("Blau: ");
    Serial.println(blau);                   // String muss in char umgewandelt werden für FastLED
    // Weiter rechnen
    Serial.println(strtol(blau.c_str(), 0, 16));
    // Ende Weiter gerechnet
    byte x = strtol(blau.c_str(), 0, 16);                   // erkennt Buchstaben nicht
    Serial.print(x);
    Serial.print('\t');
    Serial.print(x+1);
  }
}

Ich bin kein Freund von String, wenn es auch anders geht, aber was solls....

Danke für die Blumen.....
Irgendwann "durfte" ich mal die Doku zu den Werkzeugen lesen, welche ich nutze.
Ist also nicht meine Erfindung.

Mantra:
Alles wurde schon mal gedacht!
Unwahrscheinlich, dass ich der erste mit dem Problem bin.

Die waren doch schon zerlegt :wink:
Und da nicht klar ist, ob die (Sub-)Strings noch weiter verwendet werden sollen, kann man das auch nutzen...

Auf HSV soll es am schluss hinauslaufen, da ich einen WS2812B Led-Streifen verwende. Muss die Farben aber mit ihrem Zahlencode verwenden

Hallo,
das schon , aber halt nur mit einem und nicht mit 3 :wink:

Ich auch nicht, und es geht auch anders

char code[7] ;
Serial.readBytes(code,6); 
code[6]=0; // Endekennung anhängen
Serial.print("Empfangen: ");          // Deine Testausgabe
Serial.println(data);  // "FF6347"
unsigned red,green,blue;
sscanf(code,"%2X%2X%2X",&red,&green,&blue);  // combies Lösung

Wie du eventuellen zusätzlichen Müll (NewLine etc.) aus dem Eingabepuffer kriegst, ist das eigentliche Problem. Lies die Doku zu readBytes

1 Like

Danke schonmal, bekomme dabei aber eine Fehlermeldung, das man den String nicht in einen char wandeln kann.

cannot convert 'String' to 'const char*' for argument '1' to 'int sscanf(const char*, const char*, ...)'

'String' kann nicht in 'const char*' für Argument '1' in 'int sscanf(const char*, const char*, ...)' konvertiert werden.

Hatte ich schon mal und das wieder verworfen, weil ich immer auf das Steuerzeichen ohne feste Länge prüfe.
In dem Fall aber eine Alternative, wenn sichergestellt ist, das das immer als 3x2Byte Hexcode kommt und nichts anderes dazwischen funkt.

Auch dir danke, ist ähnlich zu dem von @combie, das mit der String länge ist immer fest, kann nur verschieden sein je nachdem welche Farbe man ausgewählt hat. Bekomme auch nur eine String wenn ich diesen an der App auslöse.

Nein. Du bekommst eine Zeichenfolge.
Du hast #4 verschmäht. Da wird weiter mit Deinen Substrings gearbeitet.

Denn haben ich gerade getestet, funktioniert soweit aber nur einmal. Sobald ich einen zweite Zeichenkette schicke werden die Werte nicht aktuallisiert.

void loop()
{
  if (Serial.available())
  {
  String data = Serial.readString();      //lese Empfangene Daten
  Serial.print("Empfangen: ");
  Serial.println(data);
  String rot = data.substring(0,2);       //zerlegen Empfangene Daten von Stelle 0-2
  Serial.print("Rot: ");
  Serial.println(rot);
  Serial.print("Rot_DEC: ");
  Serial.println(strtol(rot.c_str(),0,16));
  String gruen = data.substring(2,4);     //zerlege Empfangene Daten von Stelle 2-4
  Serial.print ("Grün: ");
  Serial.println(gruen);
  Serial.print("Grün_DEC: ");
  Serial.println(strtol(gruen.c_str(),0,16));
  String blau = data.substring(4,6);
  Serial.print("Blau: ");
  Serial.println(blau);                   // String muss in char umgewandelt werden für FastLED
  Serial.print("Blau_DEC: ");
  Serial.println(strtol(blau.c_str(),0,16));
  
  FastLED.showColor (CRGB (rot.c_str(), gruen.c_str(), blau.c_str()));
}
Ausgabe sieht so aus:

Empfangen: FFFF00
Rot: FF
Rot_DEC: 255
Grün: FF
Grün_DEC: 255
Blau: 00
Blau_DEC: 0
Empfangen: A20283
Rot: A2
Rot_DEC: 162
Grün: 02
Grün_DEC: 2
Blau: 83
Blau_DEC: 131

String hat die Methode c_str.

String ist kompliziert und sollte nur verwendet werden, wenn es funktioniert.
Wenn nicht, einfach String nicht verwenden.

Ja!
Aber das bekommst du schon in den Griff!
Die String Doku ist schließlich nicht geheim.

Könnte man die Zeichenkette nicht auch als Byte auslesen? Ist das dann besser wie String

Denke / Hoffe ich auch mal, habe die Funktionen jetzt nur mal schnell abgetippt ohne sie wirklich zu verstehen.
Werde sie morgen früh mal genauer anschauen.

Siehe #9
Da sparst du dir, c_str() aufzurufen. Und brauchst nicht über die Warnungen in der Doku zu rätseln.

Hast gewonnen @michael_x , diese Version funktioniert jetzt.

void loop() 
{
  if (Serial.available())
  {
    char code[7];
    Serial.readBytes(code,6);
    code[6] = 0;
    Serial.println(code);
    unsigned red, green, blue;
    sscanf (code,"%2X%2X%2X",&red,&green,&blue);
    
    FastLED.showColor (CRGB (red, green, blue));
  }

}

Ob ich das mit der Enderkennung wirklich brauche muss ich noch testen.

Die anderen Funktionen schaue ich mir morgen mal genauer an, müssten schließlich auch funktioniern.