我在循环中有问题,Lua中的表 这是带变量knx的表(现在它是静态的) regTable = { { RegEddr=3027, count=2, regType="float", knx="1/1/1"}, { RegEddr=3029, count=2, regType="float", knx="1/1/2"}, { RegEddr=3031, count=2, regT
这是带变量knx的表(现在它是静态的)
regTable = { { RegEddr=3027, count=2, regType="float", knx="1/1/1"}, { RegEddr=3029, count=2, regType="float", knx="1/1/2"}, { RegEddr=3031, count=2, regType="float", knx="1/1/3"}, { RegEddr=2999, count=2, regType="float", knx="1/1/4"}, { RegEddr=3001, count=2, regType="float", knx="1/1/5"}, { RegEddr=3003, count=2, regType="float", knx="1/1/6"}, { RegEddr=3109, count=2, regType="float", knx="1/1/7"}, { RegEddr=3083, count=2, regType="float", knx="1/1/8"}, { RegEddr=3059, count=2, regType="float", 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, count = 2, knx = "1/1/3", type = "int" } }
您也可以在循环中使用此函数.以下循环将创建一个非常类似于您的问题中的寄存器表.
for i=1, 9 do allocRegister'float' end allocRegister'int64'
编辑:以下代码应足以说明如何解决您的问题.
local sizes = {float = 2, int = 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, { addr = addr, 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' } }