![]() |
|
Checksum XOR 4 bytes - Printable Version +- LogicMachine Forum (https://forum.logicmachine.net) +-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1) +--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8) +--- Thread: Checksum XOR 4 bytes (/showthread.php?tid=3764) |
Checksum XOR 4 bytes - sashhun - 21.12.2021 Hello. Please tell me how you can summarize 4 bytes with the XOR operation. I have 5 bytes should have this amount Code: addr = {'0x01','0x03','0x05','0x07','0x09','0x0b','0x0d','0x0f','0x11','0x13','0x15','0x17','0x19','0x1b','0x1d','0x1f','0x21'}
checksum = {'0xd3','0xd1','0xd7','0xd5','0xdb','0xd9','0xdf','0xdd','0xc3','0xc1','0xc7','0xc5','0xcb','0xc9','0xcf','0xcd','0xf3'}
for i=1,17,1 do
command = string.char(0x04,0x04,addr[i],0xd2,checksum[i])
reply = writetoport(port, 0.2, command)
decoded = str2hex(reply)
log('Device address: eA'.. i-1 .. ', Result: ' .. decoded)
endI have 17 devices, 3 bytes is the address of the device, which changes, respectively, and the XOR checksum will also change RE: Checksum XOR 4 bytes - admin - 21.12.2021 Use bit.bxor() and don't use quotes around numbers because not all functions will convert strings to numbers automatically. Code: function encode(...)
local checksum = bit.bxor(...)
return string.char(...) .. string.char(checksum)
end
addrs = {0x01,0x03,0x05,0x07,0x09,0x0b,0x0d,0x0f,0x11,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21}
for _, addr in ipairs(addrs) do
command = encode(0x04,0x04,addr,0xd2)
reply = writetoport(port, 0.2, command)
decoded = str2hex(reply)
log('Device address: eA'.. i-1 .. ', Result: ' .. decoded)
endRE: Checksum XOR 4 bytes - sashhun - 21.12.2021 (21.12.2021, 13:49)admin Wrote: Use bit.bxor() and don't use quotes around numbers because not all functions will convert strings to numbers automatically.Thanks for the help
RE: Checksum XOR 4 bytes - sashhun - 21.12.2021 Please tell me more, how can I make a script that sends a request to rs232, after execution it starts up again, I tried to make a resident script with an interval of 0 so it does not have time to read data from the port RE: Checksum XOR 4 bytes - admin - 22.12.2021 Can you describe your task in more detail? Protocol description would be helpful as well. The main rule with serial ports is that only a single script can access the port. For reading you can set read length to -1 to skip waiting and read only the data that is already buffered by the driver. RE: Checksum XOR 4 bytes - sashhun - 22.12.2021 (22.12.2021, 08:00)admin Wrote: Can you describe your task in more detail? Protocol description would be helpful as well. Good afternoon. I need to constantly poll the room presence sensors through the rs232 port, on average, all sensors are polled once every 2.5 seconds. I transfer the result of the survey to group addresses. My script is hovering at the bottom Code: if not port then
require('serial')
port, err = serial.open('/dev/RS232', {baudrate = 38400, databits = 8, stopbits = 1, parity = 'none', duplex = 'full'})
if port then
port:flush()
else
log('Error open port in: ' .. err)
end
end
function readline(port, timeout)
local char, buf
buf = {}
while true do
char = port:read(1, timeout or 0.2)
if char == nil or char == '\n' then
break
elseif char ~= '\r' then
table.insert(buf, char)
end
end
return table.concat(buf)
end
function writetoport(port, timeout, command)
port:write(command)
line = readline(port, timeout)
if #line > 0 then
return line
else
return "No reply received"
end
end
function str2hex(str)
raw_len = string.len(str)
i = 1
value = ''
while i <= raw_len do
if value then
if i == 4 then
value = string.byte(str, i)
end
else
value = string.byte(str, i)
end
i = i + 1
end
return value
end
function encode(...)
local checksum = bit.bxor(...)
return string.char(...) .. string.char(checksum)
end
addrs = {0x01,0x03,0x05,0x07,0x09,0x0b,0x0d,0x0f,0x11,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23}
local sum = 0
for _, addr in ipairs(addrs) do
command = encode(0x04,0x04,addr,0xc8)
reply = writetoport(port, 0.1, command)
decoded = str2hex(reply)
if grp.getvalue('37/3/'.. sum)~=decoded then
grp.update('37/3/'.. sum, decoded)
end
sum = sum + 1
end
value = event.getvalue()
if value == true then
grp.update(event.dst, false)
elseif value == false then
grp.update(event.dst, true)
endAt the end, I check the state of the address where the script is and run it anew when the request is received. RE: Checksum XOR 4 bytes - admin - 22.12.2021 This should be done via a resident script. Maybe add a small delay before each poll. You can also add port:flush() before writing and reading to clear the buffered data if there is anything left there. RE: Checksum XOR 4 bytes - sashhun - 22.12.2021 (22.12.2021, 08:45)admin Wrote: This should be done via a resident script. Maybe add a small delay before each poll. You can also add port:flush() before writing and reading to clear the buffered data if there is anything left there.I did thanks as advised, created a resident script with an interval of 3 seconds, and made the difference as a delay so that the script could finish the request, although I think I will remove the delay. The skrp is executed in an average of 2.5 seconds, and the difference in the interval of 3 seconds minus the query execution time will compensate for the pause after the execution of the script |