UTFT: String als Farbe vorgeben

Hi,
ich bräuchte mal wieder die Hilfe von den C-Experten.

Ich verwende die UTFT-Bibliothek von Henning Karlsen.
Da gibt es den Befehl myGLCD.setColor(r,b,g)
Für r b g kann man entweder feste Werte, oder auch 3 Byte-Variablen vorgeben.
Das sagt der Compiler:

candidates are: void UTFT::setColor(byte, byte, byte)

Jetzt bekomme ich aus einer anderen Funktion die Farbe als String; z.B.: "128,0,128"
Habt ihr eine Idee, wie man den String als Vorgabe für die Farbdefinition verwenden kann?
Ich probier jetzt schon zwei Stunden rum, aber meine C-Kenntnisse sind dazu etwas zu mangelhaft.

Danke vorab/hk007

Wenn du mit "String" ein char Array meinst und kein Arduino String Objekt:

byte r = atoi(strtok(str, ","));
byte g = atoi(strtok(NULL, ","));
byte b = atoi(strtok(NULL, ","));

Eine Kombination aus strtok() um den String zu splitten und atoi() für die Wandlung nach int

Hi Serenifly,
leider großes "S".
Also ein String object.

Hintergrund: Ich habe eine Funktion, die mir für die grafische Ausgabe des Temperaturgefälles meines Warmwasserspeichers abhängig von der Temperatur bestimmte Farben ausgibt.
Die sende ich dann innerhalb einer HTML-Seite.

   void color (float tempin, String &stringout) {
      if  (tempin >= 90.0 && tempin < 100.0) { 
        stringout = "(175,0,0)";  
      }
      else if  ((tempin >= 75.0) && (tempin < 90.0)) { 
        stringout = "(255,0,0)"; 
...........

Jetzt bau ich noch ein Touchdisplay an den Arduino für die Vorort anzeige. Da will ich die Funktion gleich mitbenutzen, um auch hier die entsprechenden Farben anzuzeigen.

Am besten den Kram raus werfen. Taugt nicht viel und hat nur wenige Methoden. C Strings sind unendlich flexibler und werden von mehr Libs unterstützt.

Ansonsten kannst du vielleicht mit einer Kombination aus subString(), indexOf() und toInt() arbeiten. Das ist aber ein doofes Gefummel sich jedes mal den Index des Delimiters geben zu lassen, einen neuen String zu erzeugen und diesen zu konvertieren.

EDIT:
Du kannst genauso ein char Array mit strcpy(stringout, "(255,0,0)") füllen. Das musst du halt einmal anlegen. Üblicherweise macht man das in der aufrufenden Funktion. Deine Funktion sähe dann so aus:

void color (float tempin, char* stringout) 
{
}

Dabei nur beachten, dass du Platz für den Null-Terminator lässt. Also bei 3 * 3 Zeichen, 2 Klammern und 2 Kommas, sollte es die Größe 14 haben

Ok,
Ich hatte die Hoffnung, dass man es irgendwie so hinbekommt:

String temp1 = "128,0,128";
[color=red]myGLCD.setColor(temp1);[/color] // irgendwie geht die Farbfunktion nicht im code-tag :-(

aber auch mit nem C-String muss ich zerlegen und wandeln. Oder?

Dann schreib ich mir liebe ne neue Funktion, bei der ich gleich drei Byte mit den Farbwerten rausbekomme.

Ja, konvertieren muss man so oder so. string.h in der AVR libc ist nur viel mächtiger als die Arduino String Klasse.

Aber sich das direkt als Integer zurückgeben zu lassen ist wesentlich vernünftiger. Wenn du es doch als string für eine Ausgabe brauchst, dann kannst du die Zahlen immer noch mit sprintf() in einen string formatieren.

Ja mit den Strings steh ich voll auf Kriegsfuss. =(
Ich könnte die Funktion ja für beide Ausgabearten schreiben: Dann brauch ich nichts im HTML-Code ändern.

   void color (float tempin, String &stringout, byte red, byte green, byte blue) {
      if  (tempin >= 90.0 && tempin < 100.0) { 
//        stringout = "(175,0,0)";
        red = 175; green = 0; blue = 0; 
      }
      else if  ((tempin >= 75.0) && (tempin < 90.0)) { 
.....
 stringout = "(" + red + "," + green + "," + blue +")";  
  }

Allerdings ärgert mich da wieder die letzte Zeile. Anscheinend kann ich nur immer 2 Teilstrings zusammenführen.
Ich wollte mir halt sparen die Zuweisung für stringout in jeder if-Anweisung zu schreiben, sondern die nur einmal am Ende der Funtion "berechnen"
Der Befehl sprintf() ist ja nur für die Ausgabe gedacht. Oder kann ich den hier auch verwenden?

printf() ist für Ausgaben, wird aber auf dem Arduino nicht ohne weiteres unterstützt. sprintf() formatiert den string und schreibt ihn ein Array:

sprintf_P(stringout, PSTR("(%d,%d,%d)"), red, green, blue);

Hier mit der _P Version mit PSTR() Makro. Dadurch bleibt der Format String im Flash, was etwas RAM spart. :slight_smile:

Wie gesagt, du musst nur aufpassen, dass auch ein Array stringout der entsprechenden Größe existiert. Ich habe mir dafür ein Array stringBuffer mit 31 Bytes angelegt, dass ich für alle Arten von String-Manipulationen und Ausgaben verwende. Wobei 21 Byte auch reichen würden. Dann muss ich nicht immer neue Puffer auf dem Stack anlegen. Lediglich wenn ich die strings permanent brauche, brauche ich einen extra Puffer.

P.S. deine Funktion gibt den RGB Wert nicht zurück! Du musst die Parameter schon als Referenzen deklarieren. Sonst arbeitest du lediglich mit lokalen Kopien:

void color (float tempin, char* stringout, byte &red, byte &green, byte &blue)

Hier mit stringout als char*/C-String

Und printf() geht auf dem Arduino nicht mit float. Aber dafür gibt es dtostrf() als Zwischenschritt.

Serenifly:
P.S. deine Funktion gibt den RGB Wert nicht zurück! Du musst die Parameter schon als Referenzen deklarieren. Sonst arbeitest du lediglich mit lokalen Kopien:

Hehe, du bist echt gut. Und ich ne richtige C-Pfeife =(

Hab mir gerade den Arsch abgesucht, wieso ich immer "0" zurückbekomme.
Ich mach einfach zu wenig mit C. Und wenn ich wieder mal rumprogrammiere, dann fall ich über die einfachsten Sachen.

Danke dir für deine Hilfe!