微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

循环 – 用于在表中创建变量的Lua循环

我在循环中有问题,Lua中的表
这是带变量knx的表(现在它是静态的)

regTable = {
      { RegEddr=3027,count=2,regType="float",knx="1/1/1"},{ RegEddr=3029,knx="1/1/2"},{ RegEddr=3031,knx="1/1/3"},{ RegEddr=2999,knx="1/1/4"},{ RegEddr=3001,knx="1/1/5"},{ RegEddr=3003,knx="1/1/6"},{ RegEddr=3109,knx="1/1/7"},{ RegEddr=3083,knx="1/1/8"},{ RegEddr=3059,knx="1/1/9"},{ RegEddr=3203,count=4,regType="int64",knx="1/1/10"},}

    function readRegisters()

    for idx,register in pairs(regTable) do
      if register.regType=="int" then
        valueInt = mb:readregisters(register.RegEddr)
        grp.write(register.knx,valueInt)




            elseif register.regType=="float" then
                     value1,value2 = mb:readregisters(register.RegEddr,register.count)

            if value1 then
                     valueFloat = bit.lshift(value1,16) + value2
                     valueFloat = lmcore.inttohex(valueFloat,4)
                     valueFloat = knxdatatype.decode(valueFloat,dt.float32)
            grp.write(register.knx,valueFloat)
               end

           elseif register.regType=="int64" then
          valueInt1,valueInt2,valueInt3,valueInt4 = mb:readregisters(register.RegEddr,register.count)
          if valueInt4 then
            valueInt64 = valueInt4
                log(valueInt64)
                grp.write(register.knx,valueInt64)
            end




       end

      end     --end for

    end --end function

从另一个脚本我调用函数readRegisters()
所以我有地址列表,但我不知道用户需要多少个地址.如果是10或100.这就是为什么拥有地址列表而不是最佳状态的原因,只有1步的动态列表

1/1/1
1/1/2
...
1/1/255

有可能帮助我如何动态地将地址变量knx添加到此表中?

解决方法

您需要一个寄存器分配器功​​能,它考虑了最后一个寄存器的地址和大小.此分配器将在您请求时动态创建新寄存器.

local startAddr = 3000
local sizes = {float = 2,int = 2,int64 = 4}
local registers = {}

local function allocRegister(type)
  if sizes[type] == nil then
    error'invalid register type'
  end

  local n = #registers
  local addr

  if n == 0 then -- If this is the first register,use the starting address.
    addr = startAddr
  else -- Determine the next starting address based on the last register's address & size.
    addr = registers[n].addr + registers[n].count
  end

  table.insert(registers,{ addr = addr,count = sizes[type],type = type,knx = '1/1/' .. n + 1 })
end

-- Example usage:
allocRegister'float'
allocRegister'int64'
allocRegister'int'
-- Resulting table:
{
  { addr = 3000,count = 2,knx = "1/1/1",type = "float" },{ addr = 3002,count = 4,knx = "1/1/2",type = "int64" },{ addr = 3006,knx = "1/1/3",type = "int" }
}

您也可以在循环中使用此函数.以下循环将创建一个非常类似于您的问题中的寄存器表.

for i=1,9 do allocRegister'float' end
allocRegister'int64'

编辑:以下代码应足以说明如何解决您的问题.

local sizes = {float = 2,int64 = 4}
local registers = {}
local usedspace = {}

local function allocRegisters(t)
  for i=1,#t do
    local addr,size = t[i].addr,sizes[t[i].type]

    if size == nil then
      error('invalid register type: ' .. t[i].type)
    end

    -- Check if there's free space for this register.
    for j=addr,addr+size-1 do
      if usedspace[j] then
        error('address already in use: ' .. addr)
      end
    end

    -- Mark the space for this register as used.
    for j=addr,addr+size-1 do
      usedspace[j] = true
    end

    -- copy the register into the registers table,setting knx by using the length of the table.
    table.insert(registers,count = size,type = t[i].type,knx = '1/1/' .. #registers + 1})
  end
end

-- Example usage:
allocRegisters {
  { addr = 3000,type = 'float' },{ addr = 3003,type = 'int' },{ addr = 3009,type = 'int64' }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐