Hex manipulation - buuuudzik - 18.09.2016
Hello,
maybe do you know functions for hex<->string conversion? I am preparing a full integration with Somfy blinds via RS485 and I want receive some data. After this I must delete last 2 bytes(checksum) and inverse all other bytes.
I've tried used this function which I've found in some forum:
Code: function string.fromhex(str)
return (str:gsub('..', function (cc)
return string.char(tonumber(cc, 16))
end))
end
function string.tohex(str)
return (str:gsub('.', function (c)
return string.format('%02X', string.byte(c))
end))
end
but unfortunately after using string.fromhex(str) for data from the serial port I have such error:
bad argument #1 to '?' (number expected, got nil)
and this is raw data from the serial port when I've log it via log(data)
string: O�C��C����� �
RE: Hex manipulation - Erwin van der Zwart - 18.09.2016
Hi Buuuuudzik,
Try this:
Code: -- String to HEX
strvalue = 'this is my string'
result = lmcore.strtohex(strvalue)
log(result)
-- HEX to String
hexvalue = '74686973206973206D7920737472696E67'
result = lmcore.hextostr(hexvalue)
log(result)
-- Remove last 2 chars (or checksum)
strvalue = 'this is my string'
result = string.sub(strvalue, 0, (string.len(strvalue) -2))
log(result)
BR,
Erwin
RE: Hex manipulation - buuuudzik - 19.09.2016
(18.09.2016, 21:31)Erwin van der Zwart Wrote: Hi Buuuuudzik,
Try this:
Code: -- String to HEX
strvalue = 'this is my string'
result = lmcore.strtohex(strvalue)
log(result)
-- HEX to String
hexvalue = '74686973206973206D7920737472696E67'
result = lmcore.hextostr(hexvalue)
log(result)
-- Remove last 2 chars (or checksum)
strvalue = 'this is my string'
result = string.sub(strvalue, 0, (string.len(strvalue) -2))
log(result)
BR,
Erwin
Hey Erwin,
thanks for your help but unfortunately it not works probably because I can't use hex in this way:
Code: hexvalue = '74686973206973206D7920737472696E67'
but only in this way:
Code: command = string.char(0xBF,0xF4,0xFA,0xB8,0x43,0xFA,0x00,0x00,0x00,0x04,0xA2)
Is there any way to convert such data to string?
RE: Hex manipulation - Erwin van der Zwart - 19.09.2016
Hi Buuuudzik,
command = string.char(0xBF,0xF4,0xFA,0xB8,0x43,0xFA,0x00,0x00,0x00,0x04,0xA2) is the same as command = 'BFF4FAB843FA00000004A2'
Can you show some more you are trying to achieve as this should work ..
BR,
Erwin
RE: Hex manipulation - admin - 19.09.2016
By default hextostr discards zero bytes, you have to pass a second argument for it to keep zeros. Next two lines result in the same binary string:
Code: c1 = string.char(0xBF,0xF4,0xFA,0xB8,0x43,0xFA,0x00,0x00,0x00,0x04,0xA2)
c2 = lmcore.hextostr('BFF4FAB843FA00000004A2', true)
Your script should probably read:
Code: result = lmcore.strtohex(data)
log(result)
RE: Hex manipulation - buuuudzik - 19.09.2016
I've tried and this is not the same when I will send to RS485:
Code: string.char(0x7F,0xF2,0xFA,0xB8,0x43,0xFA,0x00,0x00,0x00,0xFE,0xFD,0x06,0x5B)
and
Code: '7FF2FAB843FA000000FEFD065B'
Only first way works good second not.
This is my task:
I am preparing:
1) sending commands to somfy rts transmitter without feedback(and it works nice),
2) sending commands to somfy with a feedback message. (to do)
This is a function prepared on this forum:
Code: function sendSOMFY(command)
require('serial')
port = serial.open('/dev/RS485', { baudrate = 4800, parity = 'odd', duplex = 'half', databits = 8, stopbits = 1 })
port:flush()
port:write(command)
port:close()
sleep(0.1)
end
I must prepare also reading data after sending command GET. But I don't know how many chars will be sended. I've tried this:
Code: function send_receiveSOMFY(command)
require('serial')
port = serial.open('/dev/RS485', { baudrate = 4800, parity = 'odd', duplex = 'half', databits = 8, stopbits = 1 })
port:flush()
port:write(command)
data = port:read(20, 1)
port:close()
sleep(0.1)
end
And also in this function is some problem. But this is second thing. When I receive a data from device I must:
1. Delete last 2 bytes which are the checksum.
2. Inverse all bytes.
RE: Hex manipulation - Erwin van der Zwart - 19.09.2016
Hi Buuuudzik,
Here is a script i use for other devices, here is a function to read a line without knowing the lenght, also another HEX function you might want to use:
Code: ---------------------------------------------------------------------
-- *********************** START CONNECTION ********************** --
---------------------------------------------------------------------
-- Load Modules
require('serial')
-- Open connection
port = serial.open('/dev/RS485', { baudrate = 4800, parity = 'odd', duplex = 'half', databits = 8, stopbits = 1 })
---------------------------------------------------------------------
-- *********************** START FUNCTIONS *********************** --
---------------------------------------------------------------------
-- Function to read until carier return is received or timeout
function readline(port, timeout)
local char, buf
buf = {}
while true do
char = port:read(1, timeout or 0.2)
-- error (timeout) or newline, stop
if char == nil or char == '\n' then
break
-- ignore cr char
elseif char ~= '\r' then
table.insert(buf, char)
end
end
return table.concat(buf)
end
-- Function to write to port and return a reply
function writetoport(port, timeout, command)
-- Write data to port as HEX
port:write(command)
-- Call function to read data
line = readline(port, timeout)
if #line > 0 then
return line
else
return "No reply received"
end
end
-- Function to decode hex string value to readable string format
function str2hex(str)
raw_len = string.len(str)
i = 1
while i <= raw_len do
current_hexvalue = '0x' .. string.format("%02x", string.byte(str, i))
if value then
value = value .. ', ' .. current_hexvalue
else
value = current_hexvalue
end
i = i + 1
end
return value
end
---------------------------------------------------------------------
-- ************************ END FUNCTIONS ************************ --
---------------------------------------------------------------------
---------------------------------------------------------------------
-- *********************** START WRITE/READ ********************** --
---------------------------------------------------------------------
-- Declare command to send to rotel
command = string.char(0xfe, 0x03, 0xa5, 0x10, 0x0a, 0xc2) -- power toggle
-- Send command to port and wait for reply or timeout
reply = writetoport(port, 1, command)-- Timeout is set to 1 second (default = 0.2)
---------------------------------------------------------------------
-- ************************ END WRITE/READ *********************** --
---------------------------------------------------------------------
---------------------------------------------------------------------
-- ************************ START LOGGING ************************ --
---------------------------------------------------------------------
-- Process the reply
if reply == "No reply received" then
log(reply)
else
--Decode the reply if hex
decoded = str2hex(reply)
log(decoded)
end
---------------------------------------------------------------------
-- ************************* END LOGGING ************************* --
---------------------------------------------------------------------
-- Close port
port:close()
---------------------------------------------------------------------
-- ************************ END CONNECTION *********************** --
---------------------------------------------------------------------
Hope this helps you..
BR,
Erwin
RE: Hex manipulation - admin - 19.09.2016
Of course second one does not work because '7F' == string.char(0x37, 0x46). If you want to send hex string as binary you have to convert it using lmcore.hextostr(str, true) or use string.char.
If by inversion you mean binary XOR, then your function should look like this:
Code: function convert(str)
local res, byte
res = ''
-- discard last 2 bytes
for i = 1, #str - 2 do
-- get single byte
byte = str:byte(i, i)
-- invert
byte = bit.bxor(byte, 0xFF)
-- add to result
res = res .. string.char(byte)
end
return res
end
RE: Hex manipulation - buuuudzik - 19.09.2016
Thanks a lot for Edwin and Admin.
I have a lot of material I've checked if the result from hex calculator is the same as from LM and it's perfect
|