News:

Let's find out together what makes a PIC Tick!

Main Menu

HSV to RGB

Started by Trikkitt, Mar 14, 2022, 12:11 AM

Previous topic - Next topic

Trikkitt


Just thought I'd share a bit of code I pulled together to convert HSV in to RGB.  I needed a way to select a colour but then maintain that colour as I dimmed it up and down without lookup tables of values.  I did pinch the base of it from https://www.vagrearg.org/content/hsvrgb but that is written in C for an arduino.



To use the code the set the HSVs to the saturation you'd like (0-255), HSVv to how bright you want it (0-255), and HSVh upper byte selects the sextant of the 360 degree hue range (0-5) and then the lower byte to a value to select within that sextant (0-255).



So for example if I wanted a greeny cyan colour I'd pick the 120 to 180 degrees sextant, which is the third zero indexed so would be 2.  I'd then use a lower byte value towards the upper end of the 0-255 range the nearer to cyan the higher the number.

I welcome any thoughts on ways to optimise and improve this code.

HSV2RGB:
 
Dim HSVh As Word
Dim HSVs As Byte ' Only has bottom byte populated
Dim HSVv As Byte

Dim Cs As Byte ' Slope
Dim Cv As Byte ' top level
Dim Cc As Byte ' bottom level

Dim OutR As Byte
Dim OutG As Byte
Dim OutB As Byte

Dim bb As Byte
Dim ww As Word
Dim mm As Byte

If HSVs=0 Then  ' No saturation so monochrome
  OutR=HSVv
  OutG=HSVv
  OutB=HSVv
  Return
EndIf

If HSVh.HighByte >5 Then HSVh.HighByte=5 ' Ensure maximum sextant is limited
Cv=HSVv
bb=~HSVs
ww=HSVv * bb
Inc ww
ww=ww+ww.HighByte
Cc=ww.HighByte
If HSVh.8=0 Then ' sextant bit 1 (up or down slope)
  If HSVh.LowByte=0 Then
    ww.HighByte=HSVs
    Clear ww.LowByte
  Else
    mm=~HSVh.LowByte
    Inc mm
    ww=HSVs * mm
  EndIf
Else
  ww=HSVs * HSVh.LowByte
EndIf
ww=ww + ww.HighByte
bb=~ww.HighByte
ww=HSVv * bb
mm=HSVv>>1
ww=ww + mm
Cs=ww.HighByte

Select HSVh.HighByte
  Case 0
    OutR=Cv
    OutB=Cc
    OutG=Cs
  Case 1
    OutR=Cs
    OutB=Cc
    OutG=Cv
  Case 2
    OutR=Cc
    OutB=Cs
    OutG=Cv
  Case 3
    OutR=Cc
    OutB=Cv
    OutG=Cs
  Case 4
    OutR=Cs
    OutB=Cv
    OutG=Cc
  Case 5
    OutR=Cv
    OutB=Cs
    OutG=Cc
EndSelect

Return

top204

#1
That looks excellent!

I created a, similar, Hue procedure for the WS2812B RGB LEDs a few months ago, so the colours could be dimmed or brightened but still stay the same colour, or turned to greyscale but with the same brightness level, but I cannot find it on my drives, so I cannot share it. But I will look again later tonight. :-)

I'll try out your program and see what it does for the WS2812B chips as well.