Werbung
das erste in eine Funktion zu packen mit Rückgabewert, ist ja einfach -
kann man die Rückwärtstransformierung so programmieren (bin mir unsicher wegen pass per reference):Code://--------------------------------------------------------- // ColorRGB2color16bit //--------------------------------------------------------- int16_t ColorRGB2color16bit(uint16_t R, uint16_t G, uint16_t B) { return ((uint16_t)R << 11) | (((uint16_t)G << 5) & 0b0000011111100000) | ((uint16_t)B & 0b0000000000011111); ]
Code://--------------------------------------------------------- // Color16bit2RGB //--------------------------------------------------------- void Color16bit2RGB(uint16_t color16, uint16_t &R, uint16_t &G, uint16_t &B) { R = (0b1111100000000000 & color16) >> 11; G = (0b0000011111100000 & color16) >> 5; B = (0b0000000000011111 & color16); }
Geändert von HaWe (06.09.2018 um 23:12 Uhr)
im zweifelsfall mit pointer
muss gestehen dass ich solche reference calls meide, weils mir leicht spanisch istCode:void Color16bit2RGB(uint16_t color16, uint8_t* R, uint8_t* G, uint8_t* B) { *R = (uint8_t)((0b1111100000000000 & color16) >> 11); *G = (uint8_t)((0b0000011111100000 & color16) >> 5); *B = (uint8_t)((0b0000000000011111 & color16)); }![]()
pointer sind für mich persönlich einfacher zu handhaben
beim aufruf musst du dann natürlich dioe adressen auflösen
Code:uint8_t myR,myG,myB; Color16bit2RGB(some16bitColor, &myR, &myG, &myB); printf("<font color=\"#%00h%00h%00h\">",myR,myG,myB);
PS: ich habe die einzelnen farben mal auf 8 bit reduziert und einen expliziten cast mit eingebaut damit alles sauber aussieht![]()
Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
nicht.
danke für die Mühe!
Ich muss allerdings auch etwas gestehen...: dass mir das mit diese Pointern mit * und dann doch wieder & im Hauptprogramm noch viel unklarer ist, mit Pointer hin und vorher und hinterher referenzieren oder dereferenzieren oder wie auch immer das heißt - wenn möglich würde ich lieber eindeutige Variablennamen im Hauptprogramm verwenden, die dann per Referenz übergeben werden und auf die man dann nach Ende der Funktion wieder als aktuaisierte Werte per Variabennamen zugreifen kann.
Aber auch da komme ich immer ins Schleudern. Hatte gehofft, das könnte irgendwer aus dem Stegreif...![]()
so, nochmal getestet - das mit dem "&" klappt...
Rest nochmal in Arbeit...
funktioniert noch nicht ganz perfekt...
- - - Aktualisiert - - -
Ausgabe:Code:uint16_t ColorRGB216bit(uint16_t R, uint16_t G, uint16_t B) { return ((uint16_t)R << 11) | (((uint16_t)G << 5) & 0b0000011111100000) | ((uint16_t)B & 0b0000000000011111); } void Color16bit2colorRGB(uint16_t color16, uint16_t &R, uint16_t &G, uint16_t &B) { R = (uint8_t)((0b1111100000000000 & color16) >> 11); G = (uint8_t)((0b0000011111100000 & color16) >> 5); B = (uint8_t)((0b0000000000011111 & color16)); Serial.println(""); Serial.println("Unterprogramm color16 zu RGB:"); Serial.println( (String)"color16="+(String)color16); Serial.println( (String)"R="+(String)R); Serial.println( (String)"G="+(String)G); Serial.println( (String)"B="+(String)B); } void setup() { // put your setup code here, to run once: uint16_t r=255, g=102, b=78, col16=0; // Dark Pink (255,102,78) Serial.begin(115200); Serial.println("Hauptprogramm vor Aufruf:"); Serial.println( (String)"col16="+(String)col16); Serial.println( (String)"r="+(String)r); Serial.println( (String)"g="+(String)g); Serial.println( (String)"b="+(String)b); Serial.println(""); col16=ColorRGB216bit(r,g,b); r=g=b=0; // Rücksetzen! Serial.println("Hauptprogramm nach rgb zu col16-Berechnung (rgb Einzelwerte dann gelöscht):"); Serial.println( (String)"col16="+(String)col16); Serial.println( (String)"r="+(String)r); Serial.println( (String)"g="+(String)g); Serial.println( (String)"b="+(String)b); Color16bit2colorRGB(col16, r, g, b); Serial.println(""); Serial.println("Hauptprogramm nach col16 zu rgb:"); Serial.println( (String)"col16="+(String)col16); Serial.println( (String)"r="+(String)r); Serial.println( (String)"g="+(String)g); Serial.println( (String)"b="+(String)b); } void loop() { // put your main code here, to run repeatedly: }
Hauptprogramm vor Aufruf:
col16=0
r=255
g=102
b=78
Hauptprogramm nach rgb zu col16-Berechnung (rgb Einzelwerte dann gelöscht):
col16=64718
r=0
g=0
b=0
Unterprogramm color16 zu RGB:
color16=64718
R=31
G=38
B=14
Hauptprogramm nach col16 zu rgb:
col16=64718
r=31
g=38
b=14
Geändert von HaWe (10.09.2018 um 12:29 Uhr)
kann es sein, dass die zurück-Richtung clolor16 => r,g,b nicht richtig rechnet? Zumindest schein es so nach direkter Kontrolle der (lokalen) Rechenschritte
R = (uint8_t)((0b1111100000000000 & color16) >> 11);
G = (uint8_t)((0b0000011111100000 & color16) >> 5);
B = (uint8_t)((0b0000000000011111 & color16));
denn die geben ja andere Ergebnisse als die hinwärts-Richtung r,g,b => color16:
die hinwärts-Richtung ermittelt ja aus den 3 rgb-Werten
r=255
g=102
b=78
die color16-Zahl 64718
die Rückwärts-Funktion dann aber aus color16=64718
die (abweichenden) rgb-Werte
R=31
G=38
B=14
Hatte ich etwas falsch c+p'tet ?
Sorry dass ich nicht früher antworten konnte, hatte nicht viel gelegenheit überhaupt mal länger als 5 Minuten ins Forum zu schauen.
Mir ist da ein Denkfehler passiert, bei der Rückrechnung der einzelnen Komponenten stimmt zumindest schonmal deine Formel, bei der Umrechnung von Komponenten auf RGB16 allerdings ist rigendwas schief, da komme ich auf einen anderen Wert.
Der primäre Denkfehler liegt jedoch beim Rückrechnen von RGB16 auf R G B
G wird hier mit 6Bit aufgelöst, also müsste man streng genommen >> 6 statt >> 5 machen ... was allerdings der größte Denkfehler von mir war ... die Werte sind doch nur 5 bzw. 6Bit groß und müssten ja nochmal auf 8Bit aufgeblasen werden (inklusive eines Verlust der Auflösung selbsttverständlich)
Und ich glaube beim Maskieren und schieben ist auch noch ein dreher drinne ... ich habe immer die MSB ausmaskiert und da kann nur blödsinn bei rauskommen XD
Ich versuche heute Nachmittag mal eine Korrektur, da ich jetzt noch was wegschaffen muss bevor hier alles abbrennt![]()
Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
nicht.
besten Dank schon im vorraus - mach dir aber keinen Stress, es ist absolut nicht eilig, es hatte mich nur stutzig gemacht!
ja, ich habe ja schon mal einen Benchmarktest für verschiedene MCUs geschrieben, könnte ich mal machen
- - - Aktualisiert - - -
edit: Code aktualisiert nach Ceos' Einwand (s.u.!)
Ergebnis: doch identisch, anders als vermutet (Angaben in ms):Code:#define TimerMS() millis() //for cross plattform compatib uint32_t time0; long test_Int_multdiv2() { uint32_t x,y; volatile uint32_t s; for(y=0;y<10000;y++) { s=11; for(x=1;x<=16;x++) { s*=2;} for(x=16; x>0;x--) { s/=2;} s=7; for(x=1;x<=8;x++) { s*=8;} for(x=8; x>0;x--) { s/=8;} } return s; } long test_Int_shl_shr() { uint32_t x,y; volatile uint32_t s; for(y=0;y<10000;y++) { s=11; for(x=1;x<=16;x++) { s=(s<<1);} for(x=16; x>0;x--) { s=(s>>1);} s=7; for(x=1;x<=8;x++) { s=(s<<3);} for(x=8; x>0;x--) { s=(s>>3);} } return s; } // *SNIP* time0=TimerMS(); s=test_Int_multdiv2(); runtime[0]=TimerMS()-time0; sprintf (buf, "%3d %9ld Int_multdiv2", 0, runtime[0]); Serial.println( buf); time0=TimerMS(); s=test_Int_shl_shr(); runtime[1]=TimerMS()-time0; sprintf (buf, "%3d %9ld Int_shl_shr", 1, runtime[1]); Serial.println( buf);
Plattform: AVR (Arduino Mega2560, 16 MHz)
Code:start test 0 1220 Int_multdiv2 1 1220 Int_shl_shr
Plattform: ARM Cortex M0 (Adafruit Itsybitsy M0, 48 MHz)
Code:start test 0 93 Int_multdiv2 1 93 Int_shl_shr
Plattform: ARM Cortex M3 (Arduino Due, 84MHz)
Code:start test 0 49 Int_multdiv2 1 49 Int_shl_shr
Pattform: ESP8266 (nodeMCU, Xtensa LX106, 80 MHz)
edit:Code:start test start test 0 56 Int_multdiv2 1 55 Int_shl_shr
gleiches Ergebnis auch für Zuweisung an 2. Variable:
Code:long test_Int_multdiv2() { uint32_t x,y; volatile uint32_t s,t; for(y=0;y<10000;y++) { s=11; for(x=1;x<=16;x++) { t=s*2;} for(x=16; x>0;x--) { t=s/2;} s=7; for(x=1;x<=8;x++) { t=s*8;} for(x=8; x>0;x--) { t=s/8;} } return s; } long test_Int_shl_shr() { uint32_t x,y; volatile uint32_t s,t; for(y=0;y<10000;y++) { s=11; for(x=1;x<=16;x++) { t=(s<<1);} for(x=16; x>0;x--) { t=(s>>1);} s=7; for(x=1;x<=8;x++) { t=(s<<3);} for(x=8; x>0;x--) { t=(s>>3);} } return s; }
Geändert von HaWe (12.09.2018 um 18:29 Uhr)
Lesezeichen