Hi can anybody give me some tips for modbus writing with a bitmask?
The case is resetting an alarm on a cooling machine (Eliwell ST500 controller). Attached is the relevant part of the Modbus manual of the ST500 controller.
As I consulted the forum I tried this:
---
require('luamodbus')
mb = luamodbus.rtu()
mb:open('/dev/RS485', 9600, 'N', 8, 1, 'H')
mb:connect()
mbetslave(3) -- Enter the correct Modbus slave address of Airco
function setbit(value, nr)
return bit.bor(value, bit.lshift(1, nr))
end
value = 1
value = setbit(value, 2)
mb:writeregisters(33471, value)
----
But I doesn't seem to work. The error stays. Any other things like reading values or writing setpoints work like a charm.
The value that you are writing has both bits 0 and 2 set which the Modbus device might reject. Log the returned write result. It might have an error indication.
Code:
value = 4 -- bit 2 set to 1
res, err = mb:writeregisters(33471, value)
log(res, err)
Also keep in mind that using scripts can lead to random errors if two scripts try to access the same serial port in parallel. It is recommended to use profiles instead.
(09.02.2022, 07:52)admin Wrote: The value that you are writing has both bits 0 and 2 set which the Modbus device might reject. Log the returned write result. It might have an error indication.
Code:
value = 4 -- bit 2 set to 1
res, err = mb:writeregisters(33471, value)
log(res, err)
Also keep in mind that using scripts can lead to random errors if two scripts try to access the same serial port in parallel. It is recommended to use profiles instead.
Hi Admin,
I tried the above and this is the result in de errorlog:
"* arg: 1
* nil
* arg: 2
* string: Illegal function"
Do you have tips where to move ahead?
I also have a modbus profile in place (attached) and this works great for reading values, I didn't yet try to use this for writing values.
10.02.2022, 07:48 (This post was last modified: 10.02.2022, 07:49 by Erwin van der Zwart.)
Hi,
You can use your setbit script but instead of writing direct to modbus by script you should write the output value of your script to a virtual object and use the modbus template mapped to this virtual object.
10.02.2022, 17:09 (This post was last modified: 10.02.2022, 17:47 by jeroen@stevens.biz.)
(10.02.2022, 08:25)admin Wrote: Try using multiple register write instead:
Code:
value = 4 -- bit 2 set to 1
res, err = mb:writemultipleregisters(33471, value)
log(res, err)
I get this output now:
* arg: 1
* number: 1
* arg: 2
* nil
I see the alarms are reset this way. Thanks.
(10.02.2022, 07:48)Erwin van der Zwart Wrote: Hi,
You can use your setbit script but instead of writing direct to modbus by script you should write the output value of your script to a virtual object and use the modbus template mapped to this virtual object.
Hi Erwin,
The reset works with the writemultipleregisters in the script. Now I want to move on to the profile way as you suggested.
1/ Is it sufficient to add to the modbus profile something like this:
{
"name": "reset flow error (err 20)",
"bus_datatype": "int16",
"datatype": "int16",
"type": "register",
"address": 33471,
"writable": 1,
"value_bitmask": 0x4
}
and then link that to a virtual object?
2/ I've set the polling interval of that device to 55 seconds. Is then the value of the object written to the device every time? I'm asking because now I use a script to write values, but only when they change (like the setpoint for the cooling depending on the dewpoint).
Poll interval only affects reading. Writing is done as soon as possible.
As I've said before using scripts together with profile will lead to random errors. If you need scripts then you should use mbproxy instead of accessing the port directly. Examples: https://forum.logicmachine.net/showthrea...7#pid22637
(11.02.2022, 08:03)admin Wrote: You need to add write_only and write_multiple fields. Also you can simply map it a boolean object. Setting it to true will reset the error state.
Poll interval only affects reading. Writing is done as soon as possible.
As I've said before using scripts together with profile will lead to random errors. If you need scripts then you should use mbproxy instead of accessing the port directly. Examples: https://forum.logicmachine.net/showthrea...7#pid22637
I works with this in de modbus profile:
{
"name": "reset flow error (err 20)",
"bus_datatype": "int16",
"datatype": "int16",
"type": "register",
"address": 33471,
"writable": true,
"write_only": true,
"write_multiple": true,
"write_bitmask": true,
"value_bitmask": 0x4
}