User Tools

Site Tools


modbus_rtu_custom

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
modbus_rtu_custom [2019/01/09 12:18] – created emozolyakmodbus_rtu_custom [2023/11/30 10:01] (current) emozolyak
Line 9: Line 9:
   *Validation error message: Invalid register address. Valid ModBus addresses are Cxxx, DIxxx, IRxxx, HRxxx.   *Validation error message: Invalid register address. Valid ModBus addresses are Cxxx, DIxxx, IRxxx, HRxxx.
 Code: Code:
-<code lua>+<code lua ModBus RTU custom protocol.lua>
 -- MODBUS RTU Demo Driver -- MODBUS RTU Demo Driver
 +
 +function createDevices ()
 +                                                     -- read FC write FC
 +    addDevice({name = "C",      shift = 0, base = 10, xtraFields = {1, 5}})
 +    addDevice({name = "DI",     shift = 0, base = 10, xtraFields = {2, 0}})
 +    addDevice({name = "HR",     shift = 0, base = 10, xtraFields = {3, 6}})
 +    addDevice({name = "HRI",    shift = 0, base = 10, xtraFields = {3, 6, 1, 0}})   -- uint 0 inverse 
 +    addDevice({name = "HRIF",   shift = 0, base = 10, xtraFields = {3, 6, 1, 5}})   -- float inverse (maybe 7 ? https://docs.webhmi.com.ua/access_via_api?s[]=float)
 +    addDevice({name = "HRF",    shift = 0, base = 10, xtraFields = {3, 6, 0, 5}})   -- float 5
 +    addDevice({name = "IR",     shift = 0, base = 10, xtraFields = {4, 0}})
 + 
 +end
 + 
 +local errorCount = 0
 + 
 +SLAVE_ADDR    = 1
 +FUNC_CODE     = 2
 +REG_ADDR_HI   = 3
 +REG_ADDR_LO   = 4
 +DATA_LEN_HI   = 5;
 +DATA_LEN_LO   = 6
 +CRC_POS_LO    = 7 -- CRC LITTLE-ENDIAN (lowest comes first!)
 +CRC_POS_HI    = 8
 +
 +CRC_BIG_ENDIAN      = false
 +if CRC_BIG_ENDIAN then
 +    CRC_POS_HI      = 7
 +    CRC_POS_LO      = 8 -- CRC BIG-ENDIAN (biggest comes first)
 +end
 +-- template 
 +local request = {SLAVE_ADDR, FUNC_CODE,     
 +                 REG_ADDR_HI,  REG_ADDR_LO,   
 +                 DATA_LEN_HI,  DATA_LEN_LO,   
 +                 CRC_POS_LO,  CRC_POS_HI
 +                }     
 + 
 +EXCEPTIONS = {  "Illegal Function",         "Illegal Data Address",
 +                "Illegal Data Value",       "Slave Device Failure",
 +                "Acknowledge",              "Slave Device Busy",
 +                "Negative Acknowledge",     "Memory Parity Error",
 +                "Gateway Path Unavailable", "Gateway Target Device Failed to Respond"
 +              }
 +
 +-- dataType – The type of data that the user specified for the register. 0 = Bit, 1 = Byte, 2 = Word, 3 = Double Word, 4 = UnixTime
 +DATATYPE    = {DW = 3}
 +DATALEN     = {DW = 4, WORD=2, BYTE=1,BIT=1}
 +FORMAT      = {UINT = 0, FLOAT_32=5}
 +
 +table.unpack = unpack
 +function readRegister (reg, device, unitId)
 +--------------------------------------------- FORMING REQUEST ----------------------------------------------
 +  request[SLAVE_ADDR] = unitId
 +
 +  request[FUNC_CODE] = device.xtraFields[1]
 +
 +
 +  request[REG_ADDR_HI] = GetHiByte(reg.internalAddr)
 +  request[REG_ADDR_LO] = GetLoByte(reg.internalAddr)
 +
 +  count = reg.dataType == DATATYPE.DW and 2 or 1
 +  
 +  request[DATA_LEN_HI] = GetHiByte(count)
 +  request[DATA_LEN_LO] = GetLoByte(count)
 +
 +
 +  local crc = GetCRC(request, 2)
 +  local crcLo, crcHi -- will be used below too
 +  crcLo = GetLoByte(crc) ; request[CRC_POS_LO] = crcLo
 +  crcHi = GetHiByte(crc) ; request[CRC_POS_HI] = crcHi
 +
 +---------------------------------------------- SENDING REQUEST ----------------------------------------------
 +  if not (sendBytes(request)) then
 +      DEBUG("Can't send bytes")
 +      return false
 +  end
 +
 +---------------------------------------------- RECEIVING REPLY ----------------------------------------------
 +  local respHead, respData, respCRC = {}, {}, {}
 +
 +    -- read Header with length
 +  respHead = readBytes(3)
 +  if (respHead == false) then
 +      DEBUG("Can't read response")
 +      return false
 +  end
 +
 +  if (respHead[SLAVE_ADDR] ~= request[SLAVE_ADDR]) then
 +      ERROR("Wrong slaveID in response!")
 +      return false
 +  end
 +
 +    if (respHead[FUNC_CODE] ~= request[FUNC_CODE]) then
 +        if (respHead[FUNC_CODE] >= 0x81) then
 +          ERROR("EXCEPTION: "..EXCEPTIONS[bit.band(respHead[FUNC_CODE], 0x0F)])
 +          readBytes(2) -- read till the end
 +        else
 +          ERROR("Wrong Func Code in response. In response = 0d" .. tostring( respHead[FUNC_CODE]) .. ', but expected = 0d' .. tostring(request[FUNC_CODE]))
 +        end
 +        return false;
 +    end
 +
 +    local resp_Lentgh = respHead[3];
 +        respData = readBytes(resp_Lentgh)
 +    if (respData == false) then
 +      DEBUG("Can't read response");
 +      return false;
 +    end
 +    local tmpResponseTab = {}
 +    for i,v in ipairs(respHead) do
 +        table.insert(tmpResponseTab, v)
 +    end
 +    for i,v in ipairs(respData) do
 +        table.insert(tmpResponseTab, v)
 +    end
 +
 +    -- check CRC in reply
 +    crc = GetCRC(tmpResponseTab, 0)
 +    crcLo = GetLoByte(crc)
 +    crcHi = GetHiByte(crc)
 +
 +    respCRC = readBytes(2)
 +    if (respCRC == false) then
 +        DEBUG("Can't read response");
 +        return false;
 +    end
 +    if (respCRC[1] ~= crcLo) or (respCRC[2] ~= crcHi) then
 +        DEBUG("Wrong CRC in reply! "..string.format("%X", crcLo).." "..string.format("%X", crcHi));
 +        return false;
 +    end
 +
 +    if (device.name == "DI") or (device.name == "C" then
 +      if (resp_Lentgh ~= count) then
 +          ERROR("Wrong length in response");
 +          return false;
 +      end
 +    else
 +        if (resp_Lentgh ~= count*2) then
 +          ERROR("Wrong length in response");
 +          return false;
 +        end
 +    end
 +---------------------------------------------- RETURN DATA ----------------------------------------------
 +
 +    local inversion = device.xtraFields[3]
 +    return GetHexFromTable(respData, not((inversion or 0) == 1))
 +
 +end -- readRegister
 +
 +function GetHexFromTable(inputTab, _invert)
 +    if #inputTab > 2 then
 +    local invert = _invert or false
 +        if invert then
 +            invertedInputTab = {}
 +            half1, half2 = SplitInHalf(inputTab)
 +
 +            for i, v in pairs(half2) do table.insert(invertedInputTab, v) end
 +            for i, v in pairs(half1) do table.insert(invertedInputTab, v) end
 +            inputTab = invertedInputTab;
 +        end
 +
 +        local toReturn = {}
 +        for i,v in pairs(inputTab) do toReturn[i]=tonumber(string.format("%X",v),16) end
 +
 +        return toReturn
 +    else
 +        -- get hex and concat it to number via string operatoin
 +                                        -- TRACE("entered GetHexFromTable with table - "..table.concat(inputTab))
 +        local numberAs_String = ""
 +        local tmpStr = ""
 +
 +            for i,v in pairs(inputTab) do
 +                tmpStr = string.format("%X",v)
 +                if (#tmpStr == 1) then
 +                    tmpStr = "0"..tmpStr
 +                end
 +                numberAs_String = numberAs_String..tmpStr
 +            end
 +                                        -- TRACE("GetHexFromTable: decimal number is "..table.concat(inputTab).." hexadecimal = ".. numberAs_String)
 +        return tonumber(numberAs_String, 16)
 +    end
 +end
 +     
 +function writeRegister (reg, device, unitId, newValue)
 +    local inversion = not(device.xtraFields[3] == 1 or false)
 +
 +    reg.value_format = device.xtraFields[4]
 +    if reg.dataType == DATATYPE.DW and reg.value_format == FORMAT.FLOAT_32 then
 +        DEBUG("Going to write this value ".. (decodeIEEE754FloatToLua(newValue) or 'nil') .. ', \nuint(dec): ' .. '0d'..newValue .. ', binary: '  .. '0b'..table.concat(toBits(newValue,32)) .. ', uint(hex): ' .. string.format("0x%x", newValue)) -- TRACE("newValue = 0d" .. newValue .. ' hex = 0x' .. string.format("%X", newValue))
 +    else
 +        DEBUG("Going to write this value "..newValue)
 +    end
 +
 +    if device.name == "IR" or device.name == "DI" then
 +         ERROR("Can't write these type of registers (" .. device.name .. ")")
 +        return true
 +    end
 +    
 +    local wrRequest = {};
 +    wrRequest[SLAVE_ADDR] = unitId;
 +
 +    wrRequest[FUNC_CODE] = device.xtraFields[2]
 +
 +    wrRequest[REG_ADDR_HI] = GetHiByte(reg.internalAddr)
 +    wrRequest[REG_ADDR_LO] = GetLoByte(reg.internalAddr)
 +
 +    local dataTable = GetDataAsTable(newValue, reg.dataType)
 +    if reg.dataType == DATATYPE.DW and inversion then
 +        dataTableTmp = {}
 +        dataTableTmp[1]=dataTable[3]; dataTableTmp[2]=dataTable[4]
 +        dataTableTmp[3]=dataTable[1]; dataTableTmp[4]=dataTable[2]
 +        dataTable=dataTableTmp
 +    end
 +
 +    -- local coilsTmp = 0
 +    if (device.name == "C") then
 +        local coilsTmp = dataTable[2] * 0xFF
 +        dataTable[2] = dataTable[1]
 +        dataTable[1] = coilsTmp
 +    end
 +    wrRequest[DATA_LEN_HI] = dataTable[1]
 +    wrRequest[DATA_LEN_LO] = dataTable[2]
 +
 +    local crc, crcLo, crcHi = 0,0,0
 +    crc = GetCRC(wrRequest, 0)
 +    crcLo = GetLoByte(crc)
 +    crcHi = GetHiByte(crc)
 +    wrRequest[CRC_POS_LO] = crcLo
 +    wrRequest[CRC_POS_HI] = crcHi
 +
 +    local res = sendBytes(wrRequest);
 +    if (res == false) then
 +        DEBUG("Can't send request");
 +        return false;
 +    end
 + 
 +    -- read response
 +    res = readBytes(8) 
 + 
 +    if (res == false) then
 +        DEBUG("Can't receive reply")
 +        return false
 +    end 
 +
 +    if (table.concat(res) ~= table.concat(wrRequest)) then 
 +        DEBUG("Response does not match!")
 +        return false
 +    end 
 + 
 +    if (#dataTable == DATALEN.DW) then 
 +        -- TRACE("DWORD CASE!!!")
 +        -- repeat steps for 2nd Word 
 +        wrRequest[REG_ADDR_HI] = GetHiByte(reg.internalAddr + 1)
 +        wrRequest[REG_ADDR_LO] = GetLoByte(reg.internalAddr + 1)
 +        wrRequest[DATA_LEN_HI] = dataTable[3]
 +        wrRequest[DATA_LEN_LO] = dataTable[4]
 +        
 +            crc = GetCRC(wrRequest, 2); crcLo = GetLoByte(crc); crcHi = GetHiByte(crc)  -- offset = 2 for omit crc from previous word 
 +            
 +            wrRequest[CRC_POS_LO] = crcLo
 +            wrRequest[CRC_POS_HI] = crcHi 
 +        
 +        res = sendBytes(wrRequest);
 +        if (res == false) then
 +            DEBUG("Can't send request");
 +            return false;
 +        end
 +    end 
 +    return true
 +end
 + 
 + 
 +-- Calculating CRC16 for MODBUS RTU 
 +function GetCRC(req, offset) 
 + 
 +  local crc = 0xffff
 +  local mask = 0
 + 
 +  -- iterate bytes
 +for i=1,#req-offset do
 +      crc = bit.bxor(crc,req[i])
 +      -- iterate bits in byte 
 +      for j=1,8 do
 +          mask = bit.band(crc,0x0001)
 +          if mask == 0x0001 then
 +              crc = bit.rshift(crc,1)
 +              crc = bit.bxor(crc,0xA001)
 +          else
 +              crc = bit.rshift(crc,1)
 +          end
 + 
 +      end 
 +end 
 +     return crc
 +end
 + 
 +function GetHiByte(c)
 +        assert(c < 65536, "This is not a two bytes!")
 +                                    -- DEBUG("Going to get high byte from "..c .. '      0x'.. string.format("%04X", c))
 +   return bit.rshift(c,8)
 +end
 + 
 +function GetLoByte(c)
 +        assert(c < 65536, "This is not a two bytes!")
 +                                    -- DEBUG("Going to get  low byte from "..c .. '      0x'.. string.format("%04X", c))
 +    return bit.band(c,0xFF)
 +end
 + 
 +function SplitInHalf(full)
 +    local h1, h2 = {}, {}
 +    local half = math.ceil(#full/2)
 +    for i = 1, half do
 +        table.insert(h1, full[i])
 +    end
 +    for i = half+1, #full do
 +        table.insert(h2, full[i])
 +    end
 +    return h1,h2
 +end
 +
 +function GetDataAsTable(value, datatype)
 + 
 +    local highWord, lowWord, tmpTable = 0, 0, {}
 + 
 +    if (datatype ~= DATATYPE.DW) then 
 +        DEBUG("GetDataAsTable - going to process value  "..value)
 +        tmpTable[1] = GetHiByte(value) ; DEBUG('tmpTable[1] = ' .. tmpTable[1])
 +        tmpTable[2] = GetLoByte(value) ; DEBUG('tmpTable[2] = ' .. tmpTable[2])
 +    else 
 +        highWord    = bit.rshift(value,     16)
 +        lowWord     = bit.band  (value,     0xFFFF)
 + 
 +        tmpTable[1] = GetHiByte(highWord)
 +        tmpTable[2] = GetLoByte(highWord)
 +        tmpTable[3] = GetHiByte(lowWord)
 +        tmpTable[4] = GetLoByte(lowWord)
 +        
 +        DEBUG("GetDataAsTable DW = - " .. table.concat(tmpTable))
 +    end 
 +    return tmpTable
 +end
 +
 +function toBits(num,bits)
 + -- returns a table of bits, most significant first.
 + bits = bits or math.max(1, select(2, math.frexp(num)))
 + local t = {} -- will contain the bits
 + for b = bits, 1, -1 do
 + t[b] = math.fmod(num, 2)
 + num = math.floor((num - t[b]) / 2)
 + end
 + return t
 +end
 +
 +
 +function Bin2Hex(s)
 +    assert (type(s) == "string", "binary as string expected")
 +    -- s -> binary string
 +    local bin2hex = {
 +    ["0000"] = "0", ["0001"] = "1", ["0010"] = "2", ["0011"] = "3",
 +    ["0100"] = "4", ["0101"] = "5", ["0110"] = "6", ["0111"] = "7",
 +    ["1000"] = "8", ["1001"] = "9", ["1010"] = "A", ["1011"] = "B",
 +    ["1100"] = "C", ["1101"] = "D", ["1110"] = "E", ["1111"] = "F"
 + }
 +
 +    tabBytes={}
 +    
 +    local l = 0
 +    local h, b = "", ""
 +    local rem
 +    
 +    l = string.len(s)
 +    rem = l % 4
 +    l = l-1
 +
 + -- need to prepend zeros to eliminate mod 4
 + if (rem > 0) then
 + s = string.rep("0", 4 - rem)..s
 + end
 +
 + for i = 1, l, 4 do
 + b = string.sub(s, i, i+3)
 + table.insert(tabBytes,bin2hex[b])
 + if not b then ERROR("bin2hex b is nil") end
 + TRACE("bin2hex b = " .. tostring(b))
 + h = h..bin2hex[b]
 + end
 +
 + return h, tabBytes
 +end
 +
 +
 +function hex2dec(hexstr)
 + return tonumber(hexstr,16)
 +end
 +
 +function decodeIEEE754FloatToLua(input)
 +    sign = input < 0 and -1 or 1 
 +    input = math.abs(input)
 +    
 + bitsTable = toBits(input,32)
 +    
 + exponentTable={table.unpack(bitsTable, 2,9)} 
 + mantissaTable={table.unpack(bitsTable,10)}
 +
 + mantissaStr, manstissaTabBytes = Bin2Hex(table.concat(mantissaTable))
 + mantissaNum = hex2dec(table.concat(manstissaTabBytes))  
 +
 +
 + exponentStr, exponentBytesTable = Bin2Hex(table.concat(exponentTable)) 
 + exponentNum =  hex2dec(table.concat(exponentBytesTable)) 
 +
 + exponent = exponentNum - 127 -- 0 - 127 = -127 --> denormalized mode
 + mantissa=mantissaNum/8388608
 +
 + if exponent == -127 then -- denormalized mode
 + exponent = -126
 + mantissa = mantissa
 + else
 + mantissa = mantissa + 1
 + end
 +
 + float_number=math.ldexp(mantissa,exponent) * sign
 + return float_number
 +end
 +
 +</code>
 +
 +==== Version 2 ====
 +<code lua>
 +-- MODBUS RTU Driver
  
 function createDevices () function createDevices ()
Line 18: Line 447:
   addDevice({name = "HR", shift = 0, base = 10, xtraFields = {3, 6}})   addDevice({name = "HR", shift = 0, base = 10, xtraFields = {3, 6}})
   addDevice({name = "IR", shift = 0, base = 10, xtraFields = {4, 0}})   addDevice({name = "IR", shift = 0, base = 10, xtraFields = {4, 0}})
 +  addDevice({name = "MHR",shift = 0, base = 10, xtraFields = {3, 16}})
      
 end end
Line 25: Line 455:
 -- template  -- template 
 local request = {1, 2,      -- slaveId FC local request = {1, 2,      -- slaveId FC
-                 3,  4,  -- addr high lo  +                 3,  4,     -- addr high lo  
-                 5,  6, -- count hi lo +                 5,  6,     -- count hi lo 
                  0,  0      -- crc high lo                   0,  0      -- crc high lo 
-                }     +                } 
 +                 
 +local requestM = {1, 2,     -- Адрес устройства, Функциональный код 
 +                 3,  4,     -- Адрес первого регистра Hi, Lo 
 +                 5,  6,     -- Количество регистров Hi, Lo 
 +                 7,         -- Количество байт далее 
 +                 8,  9,     -- Значение1 Hi, Lo 
 +                 10, 11,    -- Значение2 Hi, Lo 
 +                 ------------------------------- 
 +                 0,  0      -- Контрольная сумма CRC Hi, Lo 
 +                }  
  
 EXCEPTIONS = {"Illegal Function",     "Illegal Data Address", EXCEPTIONS = {"Illegal Function",     "Illegal Data Address",
Line 134: Line 574:
   end    end 
                                   -- RETURN DATA --                                     -- RETURN DATA --  
-    return GetHexFromTable(respData)+    --return GetHexFromTable(respData) 
 +    return respData
  
 end -- readRegister end -- readRegister
Line 147: Line 588:
         return true          return true 
     end      end 
-    local wrRequest {}; +    if device.name == "MHR" then  
-     +         ERROR("Can't write these type of registers (" .. device.name .. ")") 
-    -- slave address +          
-    wrRequest[1] unitId;    +        -------------------------------------- My Write MHR -------------------------------------- 
-     +        local wrRequest = {}; 
-    -- function code +        local n_byte =1;
-    wrRequest[2] = device.xtraFields[2] +
-     +
-    -- address of register +
-    wrRequest[3] GetHiByte(reg.internalAddr) +
-    wrRequest[4] = GetLoByte(reg.internalAddr) +
-     +
-    local dataTable GetDataAsTable(newValue, device.dataType)+
                  
-        local coilsTmp  +        -- Адрес устройства 
-        if (device.name == "C"then  +        wrRequest[n_byte] unitId;    
-            coilsTmp dataTable[2* 0xFF  +         
-            dataTable[2] = dataTable[1] +        -- Функциональный код 
-            dataTable[1] = coilsTmp+        n_byte = n_byte +1; 
 +        wrRequest[n_byte] = device.xtraFields[2] 
 +         
 +        -- Адрес первого регистра Hi, Lo 
 +        n_byte n_byte +1; 
 +        wrRequest[n_byte] GetHiByte(reg.internalAddr
 +        n_byte n_byte +1; 
 +        wrRequest[n_byte= GetLoByte(reg.internalAddr) 
 +         
 +        -- копируем в dataTable байты которые нужно записать 
 +        local dataTable = GetDataAsTable(newValue, reg.dataType) 
 +         
 +        local kol = #dataTable; -- количество байт которые нужно записать 
 +        -- Количество регистров Hi, Lo 
 +        n_byte = n_byte +1; 
 +        wrRequest[n_byte] = 0; 
 +        n_byte = n_byte +1; 
 +        wrRequest[n_byte] = kol/2; 
 +         
 +        -- Количество байт далее 
 +        n_byte = n_byte +1
 +        wrRequest[n_byte= kol; 
 +         
 +        -- Значение 1,2,3... Hi, Lo 
 +        for i = 1, kol do  
 +            n_byte = n_byte +1; 
 +            wrRequest[n_byte] = dataTable[i] 
 +        end 
 +         
 +        -- CRC 
 +        local crc, crcLo, crcHi = 0,0,0 
 +        crc = GetCRC(wrRequest, 0) 
 +        crcLo = GetLoByte(crc) 
 +        crcHi = GetHiByte(crc)  
 +        n_byte = n_byte +1
 +        wrRequest[n_byte] = crcLo 
 +        n_byte = n_byte +1; 
 +        wrRequest[n_byte] = crcHi  
 +         
 + 
 +        DEBUG("Going to send this packet "..table.concat(wrRequest))     
 +        local res = sendBytes(wrRequest); 
 +        if (res == false) then 
 +            DEBUG("Can't send request"); 
 +            return false; 
 +        end 
 +         
 +        -- читаем ответ  
 +        res = readBytes(8)  
 +         
 +        if (res == false) then 
 +            DEBUG("Can't receive reply"
 +            return false
         end          end 
-    DEBUG("#dataTable now "..#dataTable)+         
 +        -- проверяем записалось или нет по количеству записанных регистров 
 +        if ( res[6] ~= (kol/2)) then  
 +            DEBUG("Response does not match!") 
 +            return false 
 +        end 
 +        -------------------------------------- My Write MHR -------------------------------------- 
 +          
 +        return true  
 +    else 
          
-    wrRequest[5] dataTable[1] +        local wrRequest = {}; 
-    wrRequest[6] = dataTable[2] +         
-     +        -- slave address 
-    -- CRC +        wrRequest[1] = unitId;    
-    local crc, crcLo, crcHi = 0,0,0 +         
-    crc = GetCRC(wrRequest, 0) +        -- function code 
-    crcLo = GetLoByte(crc) +        wrRequest[2] = device.xtraFields[2] 
-    crcHi = GetHiByte(crc)  +         
-    wrRequest[7] = crcLo +        -- address of register 
-    wrRequest[8] = crcHi  +        wrRequest[3] = GetHiByte(reg.internalAddr
-     +        wrRequest[4] = GetLoByte(reg.internalAddr
-    DEBUG("Going to send this packet "..table.concat(wrRequest)    +         
-    local res = sendBytes(wrRequest); +        local dataTable GetDataAsTable(newValue, reg.dataType
-    if (res == false) then +             
-        DEBUG("Can't send request"); +            local coilsTmp  
-        return false; +            if (device.name == "C"then  
-    end +                coilsTmp = dataTable[2] * 0xFF  
-     +                dataTable[2] = dataTable[1] 
-    -- читаем ответ  +                dataTable[1] = coilsTmp 
-    res readBytes(8)  +            end  
-     +        DEBUG("#dataTable now "..#dataTable) 
-    if (res == false) then +         
-        DEBUG("Can't receive reply"+        wrRequest[5] = dataTable[1
-        return false +        wrRequest[6] = dataTable[2
-    end  +         
-     +        -- CRC 
-    if (table.concat(res) ~table.concat(wrRequest)) then  +        local crc, crcLo, crcHi = 0,0,0 
-        DEBUG("Response does not match!") +        crc = GetCRC(wrRequest, 0) 
-        return false +        crcLo = GetLoByte(crc) 
-    end  +        crcHi = GetHiByte(crc) 
-     +
-    if (#dataTable == 4) then  +
-        -- DWORD +
-        -- repeat steps for 2nd Word  +
-        wrRequest[3] = GetHiByte(reg.internalAddr + 1) +
-        wrRequest[4] = GetLoByte(reg.internalAddr + 1+
-        wrRequest[5] = dataTable[3+
-        wrRequest[6] = dataTable[4+
-        crc, crcLo, crcHi = GetCRC(wrRequest, 0)GetLoByte(crc) GetHiByte(crc) +
         wrRequest[7] = crcLo         wrRequest[7] = crcLo
         wrRequest[8] = crcHi          wrRequest[8] = crcHi 
-        res = sendBytes(wrRequest);+         
 +        DEBUG("Going to send this packet "..table.concat(wrRequest))     
 +        local res = sendBytes(wrRequest);
         if (res == false) then         if (res == false) then
             DEBUG("Can't send request");             DEBUG("Can't send request");
             return false;             return false;
         end         end
-    end  +         
-    return true+        -- читаем ответ  
 +        res = readBytes(8)  
 +         
 +        if (res == false) then 
 +            DEBUG("Can't receive reply"
 +            return false 
 +        end  
 +         
 +        if (table.concat(res) ~= table.concat(wrRequest)) then  
 +            DEBUG("Response does not match!"
 +            return false 
 +        end  
 +         
 +        if (#dataTable == 4) then  
 +            -- если пишем DWORD 
 +            -- repeat steps for 2nd Word  
 +            wrRequest[3] = GetHiByte(reg.internalAddr + 1) 
 +            wrRequest[4] = GetLoByte(reg.internalAddr + 1) 
 +            wrRequest[5] = dataTable[3] 
 +            wrRequest[6] = dataTable[4] 
 +             
 +            wrRequest[7] = nil -- удаляем ячейку со старым CRC 
 +            wrRequest[8] = nil -- удаляем ячейку со старым CRC 
 +             
 +            -- CRC 
 +            crc = GetCRC(wrRequest, 0) 
 +            crcLo = GetLoByte(crc) 
 +            crcHi = GetHiByte(crc)  
 +            wrRequest[7] = crcLo 
 +            wrRequest[8] = crcHi  
 +             
 +            DEBUG("Going to send this packet "..table.concat(wrRequest))  
 +            res = sendBytes(wrRequest); 
 +            if (res == false) then 
 +                DEBUG("Can't send request"); 
 +                return false; 
 +            end 
 +             
 +            -- читаем ответ  
 +            res = readBytes(8)  
 +             
 +            if (res == false) then 
 +                DEBUG("Can't receive reply"
 +                return false 
 +            end  
 +        end  
 +        return true 
 +    end
 end end
  
Line 281: Line 816:
     else      else 
         highWord = bit.rshift(value,16)         highWord = bit.rshift(value,16)
-        lowWord = bit.band(c,0xFFFF)+        lowWord = bit.band(value,0xFFFF)
                  
         tmpTable[1] = GetHiByte(highWord)         tmpTable[1] = GetHiByte(highWord)
Line 290: Line 825:
     return tmpTable     return tmpTable
 end end
 +
 +
 </code> </code>
  
  
modbus_rtu_custom.1547036328.txt.gz · Last modified: 2019/01/09 12:18 by emozolyak

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki