18.09.2016, 14:35 (This post was last modified: 18.09.2016, 14:36 by buuuudzik.)
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:
1234567891011
functionstring.fromhex(str)
return (str:gsub('..', function (cc)
returnstring.char(tonumber(cc, 16))
end))
endfunctionstring.tohex(str)
return (str:gsub('.', function (c)
returnstring.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����� �
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)
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.
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:
----------------------------------------------------------------------- *********************** START CONNECTION ********************** ------------------------------------------------------------------------- Load Modulesrequire('serial')
-- Open connectionport = 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 timeoutfunctionreadline(port, timeout)
localchar, bufbuf = {}
whiletruedochar = port:read(1, timeoutor0.2)
-- error (timeout) or newline, stop ifchar == nilorchar == '\n'thenbreak-- ignore cr char elseifchar ~= '\r'thentable.insert(buf, char)
endendreturntable.concat(buf)
end-- Function to write to port and return a replyfunctionwritetoport(port, timeout, command)
-- Write data to port as HEXport:write(command)
-- Call function to read dataline = readline(port, timeout)
if #line > 0thenreturnlineelsereturn"No reply received"endend-- Function to decode hex string value to readable string formatfunctionstr2hex(str)
raw_len = string.len(str)
i = 1whilei <= raw_lendocurrent_hexvalue = '0x' .. string.format("%02x", string.byte(str, i))
ifvaluethenvalue = value .. ', ' .. current_hexvalueelsevalue = current_hexvalueendi = i + 1endreturnvalueend----------------------------------------------------------------------- ************************ END FUNCTIONS ************************ ---------------------------------------------------------------------------------------------------------------------------------------------- *********************** START WRITE/READ ********************** ------------------------------------------------------------------------- Declare command to send to rotelcommand = string.char(0xfe, 0x03, 0xa5, 0x10, 0x0a, 0xc2) -- power toggle-- Send command to port and wait for reply or timeoutreply = writetoport(port, 1, command)-- Timeout is set to 1 second (default = 0.2)----------------------------------------------------------------------- ************************ END WRITE/READ *********************** ---------------------------------------------------------------------------------------------------------------------------------------------- ************************ START LOGGING ************************ ------------------------------------------------------------------------- Process the replyifreply == "No reply received"thenlog(reply)
else--Decode the reply if hexdecoded = str2hex(reply)
log(decoded)
end----------------------------------------------------------------------- ************************* END LOGGING ************************* ------------------------------------------------------------------------- Close portport:close()
----------------------------------------------------------------------- ************************ END CONNECTION *********************** -----------------------------------------------------------------------
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:
12345678910111213141516
functionconvert(str)
localres, byteres = ''-- discard last 2 bytesfori = 1, #str - 2do-- get single bytebyte = str:byte(i, i)
-- invertbyte = bit.bxor(byte, 0xFF)
-- add to resultres = res .. string.char(byte)
endreturnresend