Posts: 110
Threads: 10
Joined: Mar 2019
Reputation:
3
01.11.2020, 23:52
(This post was last modified: 03.11.2020, 20:10 by alexll.)
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!
Posts: 4654
Threads: 24
Joined: Aug 2017
Reputation:
208
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: 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
Posts: 110
Threads: 10
Joined: Mar 2019
Reputation:
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: 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 .
Posts: 110
Threads: 10
Joined: Mar 2019
Reputation:
3
No one? How is this supposed to be done? Perhaps I am not approaching the problem correctly...
Posts: 7770
Threads: 42
Joined: Jun 2015
Reputation:
447
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: 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: -- 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
Posts: 110
Threads: 10
Joined: Mar 2019
Reputation:
3
(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: 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: -- 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
Posts: 110
Threads: 10
Joined: Mar 2019
Reputation:
3
07.11.2020, 19:37
(This post was last modified: 07.11.2020, 19:37 by alexll.)
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!
Posts: 7770
Threads: 42
Joined: Jun 2015
Reputation:
447
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: 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
Posts: 110
Threads: 10
Joined: Mar 2019
Reputation:
3
(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: 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!!
|