HSB nach RGB Umrechnung (für LEDS) rein in AVR-Assembler. Der Code ist hier zwar für AVR geschrieben, ist aber derart simpel, dass er auf jeden Controller ohne grossen Aufwand portiert werden kann. Es bedarf keinerlei Spezialbefehle. ------------------------------------------------------------------- HSB -> RGB Wandler, in AVR-Assembler, für ATiny und ATmega Kurzfeatures: (Details und ausführliche Erläuterungen im Quelltext) ------------------------------------------------------------------- *Codegrösse nur ca.300 Words auf Atiny, ca.280 auf ATmega *Eingang: 3Byte im SRAM (H-S-B) *Ausgang: 3Byte im SRAM (R-G-B) *Belegt nur 6Byte SRAM und wenig Stack *Benötigt keine dauerhaften Register *komplett in AVR-Assembler, benötigt keine Zusatzmodule, o.Ä. *vollständig dokumentiert, praktisch zeilenweise ------------------- EIN-/AUSGANGSDATEN: ------------------- Die Routine erwartet 3 Bytes Eingangsdaten im SRAM: H byte[0..191°] Farbwinkel 0°=rot, 63°=grün, 127°=blau S byte[0..100%] Sättigung 0%=grau, 50%=wenig, 100%=reine Farbe B byte[0..100%] Helligkeit 0%=keine 100%=volle Helligkeit Es werden 3 Bytes zurückgegeben im SRAM: R byte[0..100] G byte[0..100] B byte[0..100] Details und Erläuterung des HSB-Systems im Quelltext. Gruss Jochen Müller
Hallo, wozu braucht man diese Umrechnung?
Umrechung des HSV-Farbraums (+- malerisches Farbempfinden, ala Farbe heller/dunkler/satter) in den RGB-Farbraum (Farb-Led, rot-grün-blau)
>>Umrechung des HSV-Farbraums (+- malerisches Farbempfinden, ala Farbe >>heller/dunkler/satter) in den RGB-Farbraum (Farb-Led, rot-grün-blau) Genau. Wenn mann sich algorithmisch mit Farben beschäftigt, Regenbogeneffekte, oder Helligkeiten bei konstanter Farbe ändern will, mit Grauwerten und Sättigungen spielen will, dann ist das RGB-Farbmodell völlig ungeeignet. Das geht mit HSB wunderbar einfach, nur zum Ansteuern der LEDS muss es halt in RGB umgerechnet werden, dazu dient die Routine. In C gibt es hier schon einiges dazu, in ASM nur sehr wenig oder nichts. Und da eben nicht jeder in C arbeitet fügte ich die ASM-Routine der Codesammlung hinzu. Gruss Jochen Müller
Lob für die Dokumentation! Leider die wenigsten geben konkret an, welche Ressourcen verwendet werden.
Ganz schön verkompliziert... Warum nimmst den Farbwinkel nicht von 0 bis 255? Und warum v1, v2 und v3 nicht von 0 bis 255 sondern von 0 bis 99? Ich hab hier mal meinen C Code hoch geladen: http://www.mikrocontroller.net/attachment/29450/main.c Ich denke wenn man die Funktion auf 8 Bit Genauigkeit beschränkt und in ASM schreibt sollte das um einiges kompakter werden. In Sachen Optimierung ist es halt wichtig alles zur Basis 2 zu haben um alles mit einfachen Shifts machen zu können. Die Doku und Erklärungen sind übrigens Top!
>>Warum nimmst den Farbwinkel nicht von 0 bis 255? Ist ausführlich im Quelltext erläutert. Ausführlich! >>Und warum v1, v2 und v3 nicht von 0 bis 255 sondern von 0 bis 99? Weil HSB eben so definiert ist, die S/B Angabe reicht von 0..100% und nicht von 0..255% !! Was macht es für einen Sinn, eine C-Umsetzung mit einer in ASM zu vergleichen? Gruss Jochen Müller
Jochen Müller wrote: >>>Und warum v1, v2 und v3 nicht von 0 bis 255 sondern von 0 bis 99? > Weil HSB eben so definiert ist, die S/B Angabe reicht von 0..100% und > nicht von 0..255% !! 100% sind aber 1 und nicht 100. Und eine 1 schreibt man als Festkommazahl als 256/256. Also wäre unter Verwendung von Festkommazahl der Wertebereich von 0-255 mindestens genauso richtig. Außerdem können dann die ganzen /100 Divisionen entfallen, denn eine Division durch 256 ist ledigleich ein Highbyte nach Lowbyte verschieben, und das macht die Software geschätzt um etwa 50% kleiner und um einiges schneller.
@benedikt >>100% sind aber 1 und nicht 100. Und eine 1 schreibt man als >>Festkommazahl als 256/256. Also wäre unter Verwendung von Festkommazahl >>der Wertebereich von 0-255 mindestens genauso richtig. Außerdem können Den Wertebereich von 0..1 kannst Du NATÜRLICH in jeder beliebigen Skalierung angeben, von mir aus auch in 723/723. Aber was soll das Gefeilsche eigentlich? In der Farbmetrik ist es nunmal so (ob das nun gefällt oder nicht), dass der Wertebereich von Sättigung und Helligkeit in einer dem normalen Leben angepassten Denkweise dargestellt wird. Und das ist eben 100% für "ganz", 50% für "halb", etc. Ob das nun als [0..1] oder [0..100] formuliert wird, spielt für die Betrachtung ja keine Rolle. Das aber auf einmal als 0..255 darzustellen ist ETWAS GANZ ANDERES für die Vorstellung! Und DARUM geht es, es geht NICHT um mathematische Erbsenzählerei! Farbtabellen, Farbprofile, Lichtwerte werden durchweg im S/B-Bereich 0..100% angegeben, was macht es da für einen Sinn in einem Anwendersystem auf einmal vom Benutzer zu verlangen, gefälligt nicht mehr von 0..100% zu denken, sondern in Zweierpotenzen? Von der Performance her könnte man sicher ein paar Takte sparen, da hast du recht. Die Routine ist aber für einen praktischen Zweck ausgelegt worden (warum sollte ich sie sonst schreiben...) und da würde ein Wertebereich von 0..255 beim "normalsterblichen" nichts als Verwirrung bringen. Für alle, die auf 0..255 bestehen, kann ich auch eine alternative Routine hochladen, die liegt hier für eine andere Anwendung irgendwo herum. Gruss Jochen Müller
Jochen Müller wrote: > Für alle, die auf 0..255 bestehen, kann ich auch eine alternative > Routine hochladen, die liegt hier für eine andere Anwendung irgendwo > herum. Es war ja nur als konstruktive Kritik gedacht. Ein µC rechnet nunmal lieber im Binärsystem, auch der ADC hat immer einen "krummen" Binärwert. Von daher ist es eigentlich im µC Bereich üblich 0-100% als 0-255 (oder 256) darzustellen, (außer die Werte werden vom Benutzer in dezimaler Form eingegeben.)
Hallo, wir können ja ASM-Frühsport machen für die Umrechnung 0...100 in 0...255 also * 2,55 Das hier passt halbwegs bis 99 -> 254 (254,6875) ldi r16, 99 mov r17, r16 lsl r17 ; *2 in r17, *1 in r16 inc r17 ; etwas nach oben runden push r16 ; r16 retten lsr r16 ; /2 = *0.5 in r16 add r17,r16 ; = *2,5 +1 in t17 pop r16 ; r16 zurück swap r16 andi r16, 0x0F ; /16 = *0,0625 add r17,r16 ; *2,5 + *0,0625 = *2,5625 +1 Dann könnte intern mit 0...255 gerechnet werden. Gruß aus Berlin Michael
Michael, Also wenn recht ist, werde ich mir Deine Routine mal in mmeine Sammlung nehmen, die ist echt nicht übel. Ich werde mal Benedikts Ansatz mit 255 als Wertebereich umsetzen, und dann über deine Variante zurückrechnen. Mal sehen was da abzüglich aller Rundungsfehler für eine Farbauflösung herauskommt. Mir persönlich scheint es sinnvoll, die Auflösung der Farbkreises zu erweitern, vielleicht auf "echte" 360Grad. Bei 192Grad passt das so schön mit der Teilung durch 6 Blocke / Restbildung ohne jeden Aufwand. Das wird bei 360Grad dann schon kribbeliger. Na, mal sehen... Jochen Müller @benedikt, Ich hatte das schon richtig als gutgemeinbte Kritik verstanden, alles easy. Ich wollte eben meine Gründe nur nochmal erläutern. :-)
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.