23.11.2020, 19:53
Hello.
In my home I have FN485 devices. They are controlled via dedicated RS485 bus. FN485 can to operate as stand alone device - it has input and output, when input is closed output relay is closed too. But I decided that I need additional control. To turn light from application, to know what inputs are closed, to turn light when switch that is controlled by other device is toggled. So I see at least three events that can to access to RS485 bus to operate with FN485. And I decided that I need to manage access to serial bus. The only way I know is to use semaphore. In scripting tab/user library I have created script you can to see below
From point of view code is correct.
For test purposes I have started to call read all input function from resident script with log output each time after read_all_inputs function is called. And I see that log is properly created only several times. Then I need to open resident script and save it to get again only several logs. But had expected continuous logs with timeout I had specified for resident script.
What I am doing wrong.
In my home I have FN485 devices. They are controlled via dedicated RS485 bus. FN485 can to operate as stand alone device - it has input and output, when input is closed output relay is closed too. But I decided that I need additional control. To turn light from application, to know what inputs are closed, to turn light when switch that is controlled by other device is toggled. So I see at least three events that can to access to RS485 bus to operate with FN485. And I decided that I need to manage access to serial bus. The only way I know is to use semaphore. In scripting tab/user library I have created script you can to see below
Code:
require('sem')
require('serial')
function readSerialFN485()
local buf = {}
while true do
local timeout = #buf > 0 and 0.5 or 15
local char = port:read(1, timeout)
if char then
buf[ #buf + 1 ] = char:byte()
else
return buf
end
end
end
function FN485_write(param1, relay, value)
local semaphore = sem.open("FN485_serial_access")
if semaphore:trywait() == false then
semaphore:wait()
end
if not port then
port = serial.open('/dev/RS485-1', { baudrate = 9600, duplex = 'half' })
port:flush()
end
data_addr = 100 + param1
data_relay = 100 + relay
data_value = 100
if value then
data_value = 100 + 1
end
qqq = string.format('%c%c%c%c%c%c%c%c%c%c', 99, data_addr, data_addr, 211, 211, data_relay, data_relay, data_value, data_value, 13)
if port then
port:write(qqq)
port:drain()
end
semaphore:post()
end
-- function reads all input states
-- returns bitwise UINT8 value; bit 0 = state of input 0
function FN485_read_all_inputs(param1)
local semaphore = sem.open("FN485_serial_access")
if semaphore:trywait() == false then
semaphore:wait()
end
if not port then
port = serial.open('/dev/RS485-1', { baudrate = 9600, duplex = 'half' })
port:flush()
end
data_addr = 100 + param1
qqq = string.format('%c%c%c%c%c%c%c%c%c%c', 99, data_addr, data_addr, 109, 109, 100, 100, 100, 100, 13)
if port then
port:write(qqq)
port:drain()
res = readSerialFN485()
end
-- parse read result
if res then
-- check read parameters and if parameters are OK return something
if (res[2] == data_addr and res[3] == data_addr and res[4] == 109 and res[5] == 109) then
local retValue = bit.lshift( res[7] - 100, 4) + res[9] - 100
return retValue
else
log(res)
end
end
end
From point of view code is correct.
For test purposes I have started to call read all input function from resident script with log output each time after read_all_inputs function is called. And I see that log is properly created only several times. Then I need to open resident script and save it to get again only several logs. But had expected continuous logs with timeout I had specified for resident script.
What I am doing wrong.