Forum: Projekte & Code Fertig: HSB->RGB Umrechnung rein in Assembler, auch für ATiny


von Jochen M. (taschenbuch)


Angehängte Dateien:

Lesenswert?

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

von Gast (Gast)


Lesenswert?

Hallo,

wozu braucht man diese Umrechnung?

von Micha (Gast)


Lesenswert?

Umrechung des HSV-Farbraums (+- malerisches Farbempfinden, ala Farbe 
heller/dunkler/satter) in den RGB-Farbraum (Farb-Led, rot-grün-blau)

von Jochen M. (taschenbuch)


Lesenswert?

>>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

von Telefonierer (Gast)


Lesenswert?

Lob für die Dokumentation! Leider die wenigsten geben konkret an, welche 
Ressourcen verwendet werden.

von Marius S. (lupin) Benutzerseite


Lesenswert?

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!

von Jochen M. (taschenbuch)


Lesenswert?

>>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

von Benedikt K. (benedikt)


Lesenswert?

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.

von Jochen M. (taschenbuch)


Lesenswert?

@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

von Benedikt K. (benedikt)


Lesenswert?

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.)

von Michael U. (amiga)


Lesenswert?

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

von Jochen M. (taschenbuch)


Lesenswert?

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
Noch kein Account? Hier anmelden.