This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

RGB relative dimming from KNX
#1
Hi there. I'm trying to relative dimming, from a physical KNX button, a RGB LED strip connected to a DALI controller (https://www.dalcnet.com/en/DALI/15576-DLX1224-4CV-DALI). I'm using an ABB DALI-KNX gateway to control it (https://new.abb.com/products/2CDG110273R...-fold-mdrc).

Every colour is in 1 byte KNX object (R 1byte - G 1byte - B 1byte). As they are in separate channels, I don't know how to dimmer an specific colour (from LM visu is simple, but I can't find the way to do that from a KNX 4 bit object). 

I have started running this script https://forum.logicmachine.net/showthrea...27#pid8027 but I'm stuck in looking for the next step.

Can you help me, please? Thanks in advance!  Rolleyes
Reply
#2
Pure conversion of this script in to dimming of 3 objects is this but I'm not sure if this is what you need. Most likely you would have to calculate saturation.
Code:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
addressbyteoutput1 = '32/1/1' addressbyteoutput2 = '32/1/2' addressbyteoutput3 = '32/1/3' stepsize = 10 value = event.getvalue() current1 = grp.getvalue(addressbyteoutput1) current2 = grp.getvalue(addressbyteoutput2) current3 = grp.getvalue(addressbyteoutput3) if value < 8 and value ~= 0 then   log('down',value)   if current1 <= stepsize then     output = 0     if current1 ~= output then       grp.write(addressbyteoutput1, output)        end   else     output = current1 - stepsize     if current1 ~= output then       grp.write(addressbyteoutput1, output)     end   end if current2 <= stepsize then     output = 0     if current2 ~= output then       grp.write(addressbyteoutput2, output)        end   else     output = current2 - stepsize     if current2 ~= output then       grp.write(addressbyteoutput2, output)     end   end  if current3 <= stepsize then     output = 0     if current3 ~= output then       grp.write(addressbyteoutput3, output)        end   else     output = current3 - stepsize     if current3 ~= output then       grp.write(addressbyteoutput3, output)     end   end      elseif value > 8 then   log('up',value)   if current1 >= (100 - stepsize) then     output = 100     if current1 ~= output then       grp.write(addressbyteoutput1, output)     end   else     output = current1 + stepsize     if current1 ~= output then       grp.write(addressbyteoutput1, output)     end   end     if current2 >= (100 - stepsize) then     output = 100     if current2 ~= output then       grp.write(addressbyteoutput2, output)     end   else     output = current2 + stepsize     if current2 ~= output then       grp.write(addressbyteoutput2, output)     end   end     if current3 >= (100 - stepsize) then     output = 100     if current3 ~= output then       grp.write(addressbyteoutput3, output)     end   else     output = current3 + stepsize     if current3 ~= output then       grp.write(addressbyteoutput3, output)     end   end end
------------------------------
Ctrl+F5
Reply
#3
(02.11.2020, 14:57)Daniel. Wrote: Pure conversion of this script in to dimming of 3 objects is this but I'm not sure if this is what you need. Most likely you would have to calculate saturation.
Code:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
addressbyteoutput1 = '32/1/1' addressbyteoutput2 = '32/1/2' addressbyteoutput3 = '32/1/3' stepsize = 10 value = event.getvalue() current1 = grp.getvalue(addressbyteoutput1) current2 = grp.getvalue(addressbyteoutput2) current3 = grp.getvalue(addressbyteoutput3) if value < 8 and value ~= 0 then   log('down',value)   if current1 <= stepsize then     output = 0     if current1 ~= output then       grp.write(addressbyteoutput1, output)        end   else     output = current1 - stepsize     if current1 ~= output then       grp.write(addressbyteoutput1, output)     end   end if current2 <= stepsize then     output = 0     if current2 ~= output then       grp.write(addressbyteoutput2, output)        end   else     output = current2 - stepsize     if current2 ~= output then       grp.write(addressbyteoutput2, output)     end   end  if current3 <= stepsize then     output = 0     if current3 ~= output then       grp.write(addressbyteoutput3, output)        end   else     output = current3 - stepsize     if current3 ~= output then       grp.write(addressbyteoutput3, output)     end   end      elseif value > 8 then   log('up',value)   if current1 >= (100 - stepsize) then     output = 100     if current1 ~= output then       grp.write(addressbyteoutput1, output)     end   else     output = current1 + stepsize     if current1 ~= output then       grp.write(addressbyteoutput1, output)     end   end     if current2 >= (100 - stepsize) then     output = 100     if current2 ~= output then       grp.write(addressbyteoutput2, output)     end   else     output = current2 + stepsize     if current2 ~= output then       grp.write(addressbyteoutput2, output)     end   end     if current3 >= (100 - stepsize) then     output = 100     if current3 ~= output then       grp.write(addressbyteoutput3, output)     end   else     output = current3 + stepsize     if current3 ~= output then       grp.write(addressbyteoutput3, output)     end   end end
Thanks for the quick answer. That would work, but like dimming 3 independent lights.

I think the theorical way should be, first, to convert those 3 1byte objects in a 3byte RGB value (232.600). After that, to "dim" that value and, finally, go the other way round.
The problem is I can't achieve that  Undecided .
Reply
#4
No one? How is this supposed to be done? Perhaps I am not approaching the problem correctly...  Sad
Reply
#5
To dim a color your need to convert RGB to HSV, change V up/down and then convert back to RGB.
Here are the functions that you can use.
Code:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
function rgbtohsv(r, g, b)   local max, min, d, h, s, v   max = math.max(r, g, b)   min = math.min(r, g, b)   d = max - min   s = max == 0 and 0 or (d / max)   v = max / 255   if max == min then     h = 0   elseif max == r then     h = (g - b) + d * (g < b and 6 or 0)     h = h / (6 * d)   elseif max == g then     h = (b - r) + d * 2     h = h / (6 * d)   elseif max == b then     h = (r - g) + d * 4     h = h / (6 * d)   end   return h, s, v end function hsvtorgb(h, s, v)   local r, g, b, i, f, p, q, t, z   i = math.floor(h * 6)   f = h * 6 - i   p = v * (1 - s)   q = v * (1 - f * s)   t = v * (1 - (1 - f) * s)   z = i % 6   if z == 0 then     r = v     g = t     b = p   elseif z == 1 then     r = q     g = v     b = p   elseif z == 2 then     r = p     g = v     b = t   elseif z == 3 then     r = p     g = q     b = v   elseif z == 4 then     r = t     g = p     b = v   elseif z == 5 then     r = v     g = p     b = q   end   r = math.round(r * 255)   g = math.round(g * 255)   b = math.round(b * 255)   return r, g, b end function rgbstep(r, g, b, up, step)   local h, s, v = rgbtohsv(r, g, b)   local v2 = up and math.min(1, v + step) or math.max(0, v - step)     if v == v2 then     return   end   return hsvtorgb(h, s, v2) end

rgbstep(r, g, b, up, step) can perform up/down step of current RGB value.
arguments:
  • r, g, b - color components in 0..255 range
  • up - true = step up / false = step down
  • step - step size, V range is 0..1 so the step should be something like 0.1 or 0.05 depending on how many total steps you want
rgbstep will return new RGB values but it might also return nil when further step is not possible.
Code:
123456789101112131415
-- values from split RGB value r = 127 g = 255 b = 10 -- step down up = false -- maximum 20 steps between min and max step = 0.05 r, g, b = rgbstep(r, g, b, up, step) if r then   -- write new values else   -- stop dimming end
Reply
#6
(04.11.2020, 07:48)admin Wrote: To dim a color your need to convert RGB to HSV, change V up/down and then convert back to RGB.
Here are the functions that you can use.
Code:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
function rgbtohsv(r, g, b)   local max, min, d, h, s, v   max = math.max(r, g, b)   min = math.min(r, g, b)   d = max - min   s = max == 0 and 0 or (d / max)   v = max / 255   if max == min then     h = 0   elseif max == r then     h = (g - b) + d * (g < b and 6 or 0)     h = h / (6 * d)   elseif max == g then     h = (b - r) + d * 2     h = h / (6 * d)   elseif max == b then     h = (r - g) + d * 4     h = h / (6 * d)   end   return h, s, v end function hsvtorgb(h, s, v)   local r, g, b, i, f, p, q, t, z   i = math.floor(h * 6)   f = h * 6 - i   p = v * (1 - s)   q = v * (1 - f * s)   t = v * (1 - (1 - f) * s)   z = i % 6   if z == 0 then     r = v     g = t     b = p   elseif z == 1 then     r = q     g = v     b = p   elseif z == 2 then     r = p     g = v     b = t   elseif z == 3 then     r = p     g = q     b = v   elseif z == 4 then     r = t     g = p     b = v   elseif z == 5 then     r = v     g = p     b = q   end   r = math.round(r * 255)   g = math.round(g * 255)   b = math.round(b * 255)   return r, g, b end function rgbstep(r, g, b, up, step)   local h, s, v = rgbtohsv(r, g, b)   local v2 = up and math.min(1, v + step) or math.max(0, v - step)     if v == v2 then     return   end   return hsvtorgb(h, s, v2) end

rgbstep(r, g, b, up, step) can perform up/down step of current RGB value.
arguments:
  • r, g, b - color components in 0..255 range
  • up - true = step up / false = step down
  • step - step size, V range is 0..1 so the step should be something like 0.1 or 0.05 depending on how many total steps you want
rgbstep will return new RGB values but it might also return nil when further step is not possible.
Code:
123456789101112131415
-- values from split RGB value r = 127 g = 255 b = 10 -- step down up = false -- maximum 20 steps between min and max step = 0.05 r, g, b = rgbstep(r, g, b, up, step) if r then   -- write new values else   -- stop dimming end
Thank you very much! So my only doubt is which group addresses I need to define  Blush
Reply
#7
I'm so sorry, but I don't know how to combine that script with the objects I own. I have only three 1 byte KNX groups (R, G and B) in scale format (0-100%). Could someone help me in the next step? Thanks in advance!  Confused
Reply
#8
Use this event script for 4-bit object. Change R/G/B addresses as needed and modify step and delay to change the dimming speed and smoothness.

Code:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
raddr = '32/1/1' -- red value address gaddr = '32/1/2' -- green value address baddr = '32/1/3' -- blue value address step = 0.05 -- step side delay = 0.3 -- delay between steps value = event.getvalue() up = bit.band(value, 0x08) == 0x08 stop = bit.band(value, 0x07) == 0 if stop then   return   end -- get value and convert from 0..100 to 0..255 r = grp.getvalue(raddr) * 2.55 g = grp.getvalue(gaddr) * 2.55 b = grp.getvalue(baddr) * 2.55 function rgbtohsv(r, g, b)   local max, min, d, h, s, v   max = math.max(r, g, b)   min = math.min(r, g, b)   d = max - min   s = max == 0 and 0 or (d / max)   v = max / 255   if max == min then     h = 0   elseif max == r then     h = (g - b) + d * (g < b and 6 or 0)     h = h / (6 * d)   elseif max == g then     h = (b - r) + d * 2     h = h / (6 * d)   elseif max == b then     h = (r - g) + d * 4     h = h / (6 * d)   end   return h, s, v end function hsvtorgb(h, s, v)   local r, g, b, i, f, p, q, t, z   i = math.floor(h * 6)   f = h * 6 - i   p = v * (1 - s)   q = v * (1 - f * s)   t = v * (1 - (1 - f) * s)   z = i % 6   if z == 0 then     r = v     g = t     b = p   elseif z == 1 then     r = q     g = v     b = p   elseif z == 2 then     r = p     g = v     b = t   elseif z == 3 then     r = p     g = q     b = v   elseif z == 4 then     r = t     g = p     b = v   elseif z == 5 then     r = v     g = p     b = q   end   r = math.round(r * 255)   g = math.round(g * 255)   b = math.round(b * 255)   return r, g, b end function rgbstep(r, g, b, up, step)   local h, s, v = rgbtohsv(r, g, b)   local v2 = up and math.min(1, v + step) or math.max(0, v - step)      if v == v2 then     return   end   return hsvtorgb(h, s, v2) end while true do   r, g, b = rgbstep(r, g, b, up, step)   if r then     grp.write(raddr, r, dt.uint8)     grp.write(gaddr, g, dt.uint8)     grp.write(baddr, b, dt.uint8)   else     break   end   os.sleep(delay)   newvalue = grp.getvalue(event.dst)   if value ~= newvalue then     break   end end
Reply
#9
(09.11.2020, 08:56)admin Wrote: Use this event script for 4-bit object. Change R/G/B addresses as needed and modify step and delay to change the dimming speed and smoothness.

Code:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
raddr = '32/1/1' -- red value address gaddr = '32/1/2' -- green value address baddr = '32/1/3' -- blue value address step = 0.05 -- step side delay = 0.3 -- delay between steps value = event.getvalue() up = bit.band(value, 0x08) == 0x08 stop = bit.band(value, 0x07) == 0 if stop then   return  end -- get value and convert from 0..100 to 0..255 r = grp.getvalue(raddr) * 2.55 g = grp.getvalue(gaddr) * 2.55 b = grp.getvalue(baddr) * 2.55 function rgbtohsv(r, g, b)   local max, min, d, h, s, v   max = math.max(r, g, b)   min = math.min(r, g, b)   d = max - min   s = max == 0 and 0 or (d / max)   v = max / 255   if max == min then     h = 0   elseif max == r then     h = (g - b) + d * (g < b and 6 or 0)     h = h / (6 * d)   elseif max == g then     h = (b - r) + d * 2     h = h / (6 * d)   elseif max == b then     h = (r - g) + d * 4     h = h / (6 * d)   end   return h, s, v end function hsvtorgb(h, s, v)   local r, g, b, i, f, p, q, t, z   i = math.floor(h * 6)   f = h * 6 - i   p = v * (1 - s)   q = v * (1 - f * s)   t = v * (1 - (1 - f) * s)   z = i % 6   if z == 0 then     r = v     g = t     b = p   elseif z == 1 then     r = q     g = v     b = p   elseif z == 2 then     r = p     g = v     b = t   elseif z == 3 then     r = p     g = q     b = v   elseif z == 4 then     r = t     g = p     b = v   elseif z == 5 then     r = v     g = p     b = q   end   r = math.round(r * 255)   g = math.round(g * 255)   b = math.round(b * 255)   return r, g, b end function rgbstep(r, g, b, up, step)   local h, s, v = rgbtohsv(r, g, b)   local v2 = up and math.min(1, v + step) or math.max(0, v - step)     if v == v2 then     return   end   return hsvtorgb(h, s, v2) end while true do   r, g, b = rgbstep(r, g, b, up, step)   if r then     grp.write(raddr, r, dt.uint8)     grp.write(gaddr, g, dt.uint8)     grp.write(baddr, b, dt.uint8)   else     break   end   os.sleep(delay)   newvalue = grp.getvalue(event.dst)   if value ~= newvalue then     break   end end
Awesome! Thank you very much!!
Reply


Forum Jump: