Color wheel function

Maybe you have tested the Color wheel provided by the RGB Controller?
And now you want your LED Bulb to have a color from a Color wheel dependent on the out door temperature (or any other device)?

Here is sample LUA code that does just that.

Enjoy!

-- Convert value v to hex where 
-- v <= min returns '00'
-- v >= max returns 'FF'
-- min < v < max returns values in between
function hex(v, min, max)
  local k,out,x,d,i,f="0123456789ABCDEF","",0
  if v < min then
    v = min
  end
  if v > max then
    v = max
  end
  d = (v - min) * 255 / (max - min) / 16
  while x < 2 do
    i, f = math.modf(d)
    out = out..string.sub(k, i + 1, i +1)
    d = f * 16
    x = x + 1
  end
  return out
end

function int(v)
  local i, f = math.modf(v)
  return i
end

function frac(v)
  local i, f = math.modf(v)
  return f
end

-- v, dynamic value, e.g. temperature
-- s, start value, represented as Magenta
-- e, end value, also represented as Magenta
-- When v goes from s to e it make one turn in the Color wheel
-- 0 <= min <= 255, min value for R, G and B
-- 0 <= max <= 255, max value for R, G and B
-- return hex value for RGB
function colorWheel(v, s, e, min, max)
  local rv, phase, f, p2, f2, imin, imax, ivalue, value, color
  c = {}
  -- 0 <= rv < 1
  rv = frac((v - s)/ (e - s))
  -- phase = 0 .. 5
  -- 0 <= f < 1
  phase, f = math.modf(rv * 6)
  p2, f2 = math.modf(phase / 2)
  imin = 2 - int((phase + 1) / 2)
  if imin < 1 then
    imin = imin + 3
  end
  imax = 3 - p2
  ivalue = int(1.1 + frac(phase / 3) * 3)
  if f2 == 0 then
    -- max -> min
    value = max - (max - min) * f
  else
    -- min -> max
    value = min + (max - min) * f
  end
  c[imin] = min
  c[imax] = max
  c[ivalue] = value
  color = hex(c[1], 0, 255) .. hex(c[2], 0, 255) .. hex(c[3], 0, 255)
  return color
end

In this example the temperature is represented by the following colors:


6 Red
8 Magenta (s)
10 Blue
12 Cyan / Aqua
14 Green
16 Yellow
18 Red
20 Magenta (e)
22 Blue

local colorTargetValue = "#" ..  colorWheel(temperature, 8, 20, 16, 255) .. "0000"
luup.call_action("urn:upnp-org:serviceId:RGBController1", "SetColorTarget", {newColorTargetValue = colorTargetValue}, 29)

sorliden

Hi,

I have found a bug in the code. It fails if v < s for function colorWheel(v, s, e, min, max).
To fix this use the following frac function. E.g. frac(-1.7) = 0.3. So it’s not a real frac function for negative numbers but the color wheel works.

function frac(v) if (v < 0) then v = v + int(-v) + 1 end local i, f = math.modf(v) return f end

sorliden