我在循环中有问题,Lua中的表
这是带变量knx的表(现在它是静态的)
这是带变量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
解决方法
您需要一个寄存器分配器功能,它考虑了最后一个寄存器的地址和大小.此分配器将在您请求时动态创建新寄存器.
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' } }