Posts: 169
Threads: 58
Joined: Oct 2017
Reputation:
0
Hi all,
I'm scripting a process to simulate power meters with luamodbus functions, and it works wery well when I read all my registers with ModbusPoll scanner.
But using my script with a real Modbus master product, I have a lot of "connexion errors" (printed by the master).
@IP, port and slaveId are corrects...
Any idea about this ?
Thank's in advance.
All my best.
Dominique
Posts: 4638
Threads: 24
Joined: Aug 2017
Reputation:
207
Which script do you use?
------------------------------
Ctrl+F5
Posts: 169
Threads: 58
Joined: Oct 2017
Reputation:
0
(17.01.2023, 12:55)Daniel Wrote: Which script do you use?
Code: --------------------------------------------------------------------------------
-- Wiser For Knx : Modbus esclave TCP/IP
--------------------------------------------------------------------------------
-- Simulateur de centrale de mesure pour EcoStruxure EV Charging Expert
--------------------------------------------------------------------------------
--
-- Modèle : iEM3x5x pour Bornes de recharge PRO AC
--
--------------------------------------------------------------------------------
-- v1.2 du 17/01/2023 - D.Barboyon
--------------------------------------------------------------------------------
-- (c) Sigma Tec - 2023
--------------------------------------------------------------------------------
------------- Paramétrage ------------------------------------------------------
idPort = 503 -- No de port Modbus/TCP - toujours >= 502
idSlave = 3 -- No esclave Modbus/TCP - toujours >= 2
PMname = "iEM3155-B2" -- nom du compteur - long <= 14 car
--------------------------------------------------------------------------------
idGroup = idPort-500 -- idGroup/slaveNum/x
idSteMapping1 = 0
idSteMapping2 = 0
idSetMapping3 = 6502
idSteMapping4 = 6502
-- ---------------------------------------------------------------------
-- Table des objets Wiser For Knx et registres associés
-- ---------------------------------------------------------------------
groupList = {
{ addr = idGroup, datatype="string" , name=PMname ,reg=idPort , unit="" , tags="-"},
{ addr = idGroup, datatype="uint16" , name="I1" ,reg="3000" , unit="A" , tags="modbus"},
{ addr = idGroup, datatype="uint16" , name="I2" ,reg="3002" , unit="A" , tags="modbus"},
{ addr = idGroup, datatype="uint16" , name="I3" ,reg="3004" , unit="A" , tags="modbus"},
{ addr = idGroup, datatype="uint16" , name="P1" ,reg="3054" , unit="kW" , tags="modbus"},
{ addr = idGroup, datatype="uint16" , name="P2" ,reg="3056" , unit="kW" , tags="modbus"},
{ addr = idGroup, datatype="uint16" , name="P3" ,reg="3058" , unit="kW" , tags="modbus"},
{ addr = idGroup, datatype="uint16" , name="P" ,reg="3060" , unit="kW" , tags="modbus"},
{ addr = idGroup, datatype="uint32" , name="ET" ,reg="3204" , unit="kWh" , tags="modbus"},
{ addr = idGroup, datatype="bool" , name="PH1" ,reg="true" , unit="" , tags="-"},
{ addr = idGroup, datatype="bool" , name="PH2" ,reg="true" , unit="" , tags="-"},
{ addr = idGroup, datatype="bool" , name="PH3" ,reg="true" , unit="" , tags="-"},
{ addr = idGroup, datatype="bool" , name="BTN" ,reg="true" , unit="" , tags="-"},
{ addr = idGroup, datatype="unit16" , name="CURSEUR" ,reg="true" , unit="A" , tags="-"},
{ addr = idGroup, datatype="bool" , name="BTN MONO" ,reg="false" , unit="" , tags="-"},
{ addr = idGroup, datatype="bool" , name="BTN TRI" ,reg="true" , unit="" , tags="-"},
{ addr = idGroup, datatype="string" , name="TYPE MONO-TRI" ,reg="TRI" , unit="" , tags="-"},
{ addr = idGroup, datatype="bool" , name="PHASE MONO" ,reg="1" , unit="" , tags="-"},
{ addr = idGroup, datatype="uint16" , name="I Phase AVG" ,reg="3010" , unit="A" , tags="modbus"},
{ addr = idGroup, datatype="uint16" , name="U Phase1" ,reg="3028" , unit="V" , tags="modbus"},
{ addr = idGroup, datatype="uint16" , name="U Phase2" ,reg="3030" , unit="V" , tags="modbus"},
{ addr = idGroup, datatype="uint16" , name="U Phase3" ,reg="3032" , unit="V" , tags="modbus"},
{ addr = idGroup, datatype="uint16" , name="U AVG" ,reg="3036" , unit="V" , tags="modbus"},
{ addr = idGroup, datatype="uint16" , name="P apparente" ,reg="3076" , unit="kVA" , tags="modbus"},
{ addr = idGroup, datatype="uint16" , name="Fact Pu" ,reg="3084" , unit="" , tags="modbus"},
{ addr = idGroup, datatype="uint16" , name="Frequence" ,reg="3110" , unit="Hz" , tags="modbus"},
{ addr = idGroup, datatype="uint32" , name="QT E" ,reg="3220" , unit="kVAR", tags="modbus"},
{ addr = idGroup, datatype="uint16" , name="QT P total" ,reg="3068" , unit="kVAR", tags="modbus"}
}
-- Spécifique Pro AC : reg Modbus 6501 (uint16) = SlaveId obligatoire
------------------------------------------------------------------------
local proacSlaveReg = 6501
-- ---------------------------------------------------------------------
-- Gestion de la création des objets Wiser For Knx
-- ---------------------------------------------------------------------
function ST_grpCreate(STdatatype,STgroup,STname,STcomment,STunits,STtag)
------------------------------------------------------------------------
grp.create({
datatype = STdatatype,
address = STgroup,
name = STname,
comment = STcomment,
units = STunits,
tags = { "EVCE", STname },
})
end
-- Scan la table et crée les objets WFK si nécessaire
------------------------------------------------------------------------
for i, groupCurr in ipairs(groupList) do
STgroup = groupCurr.addr.."/"..idSlave.."/"..i
if i == 1 then -- spécifique objet "nom de la centrale de mesure"
nomGroupe = groupCurr.reg.."#"..idSlave
valGroupe = groupCurr.name
objGroupe = STgroup
-- Update objet "nom de la centrale de mesure"
grp.write(objGroupe, valGroupe)
end
if grp.find(STgroup) then
--existe deja
else
-- crée le groupe
STdatatype = groupCurr.datatype
STname = nomGroupe.."-"..groupCurr.name
STcomment = "-"
STunits = groupCurr.unit
STtag = groupCurr.tags
ST_grpCreate(STdatatype,STgroup,STname,STcomment,STunits,STtag)
end
end
-- -----------------------------------------------
-- Processus MaJ registres Modbus slave
-- -----------------------------------------------
if not mb then
log("EVCE cyclic - Modbus #2 : starting mb")
require('luamodbus')
-->>>>>>>>>Modbus slave setting<<<<<<<<<<<<<<<<<<<<<<<<
-- Modbus TCP
------------------------------------------------------
mb = luamodbus.tcp()
mb:open('0.0.0.0', idPort)
------------------------------------------------------
-->>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-- slave id
mb:setslave(idSlave)
-- init slave storage for coils, discrete inputs, holding registers and input registers
mb:setmapping(idSetMapping3, idSetMapping2, idSetMapping3, idSetMapping4)
--*****************************************************
-- >>>>>>>>>>>Coil write callback<<<<<<<<<<<<<<<<<<<<<<
mb:setwritecoilcb(function(coil, value)
if coil == 0 then
grp.write('0/0/12', value, dt.bool)
else
alert('coil: %d = %s', coil, tostring(value))
end
end)
--*****************************************************
-->>>>>>>>>>>Register write callback<<<<<<<<<<<<<<<<<<<
mb:setwriteregistercb(function(register, value)
if register == 0 then
-- send value limited to 0..100
grp.write('0/0/13', math.min(100, value), dt.scale)
else
alert('register: %d = %d', register, value)
end
end)
--*****************************************************
-- spécifique Pro Ac ----------------
addRegister = proacSlaveReg
addRegister = addRegister -1
mb:setregisters(addRegister, idSlave)
-------------------------------------
log("EVCE cyclic - Modbus #2 : END OF starting mb")
end
-- Scan la table et Maj des objets autres que Modbus slave
------------------------------------------------------------------------
for i, groupCurr in ipairs(groupList) do
dataType = groupCurr.datatype
if dataType == "bool" and groupCurr.tags == "-" then
nomGroupe = groupCurr.addr.."/"..idSlave.."/"..i
if grp.find(nomGroupe) then
-- groupe existe
else
grp.write(nomGroupe, groupCurr.reg)
end
end
if dataType == "string" and groupCurr.tags == "-" and i > 1 then
nomGroupe = groupCurr.addr.."/"..idSlave.."/"..i
if grp.find(nomGroupe) then
-- groupe existe
else
grp.write(nomGroupe, groupCurr.reg)
end
end
end
-- Scan la table et MaJ registres Modbus slave
------------------------------------------------------------------------
-- addr = idGroup, datatype="uint16" , name="I1" ,reg="3000" , unit="A" , tags=""
for i, groupCurr in ipairs(groupList) do
addRegister = groupCurr.reg
dataTags = groupCurr.tags
dataType = groupCurr.datatype
nomGroupe = groupCurr.addr.."/"..idSlave.."/"..i
-- valeur courante de l'objet WFK
value = grp.getvalue(nomGroupe)
if dataType == "uint16" and dataTags == "modbus" then
addRegister = addRegister -1
-- dt.float16, dt.float32, dt.int64, dt.int32
raw = knxdatatype.encode(value, dt.float32).dataraw
r1 = raw:byte(1) * 0x100 + raw:byte(2)
r2 = raw:byte(3) * 0x100 + raw:byte(4)
mb:setregisters(addRegister, r1, r2)
--mb:setregisters(addRegister, r1)
--mb:setregisters(addRegister+1, r2)
end
if dataType == "uint32" and dataTags == "modbus" then
addRegister = addRegister -1
-- dt.float16, dt.float32, dt.int64, dt.int32
raw = knxdatatype.encode(value, dt.int64).dataraw
r1 = raw:byte(1) * 0x100 + raw:byte(2)
r2 = raw:byte(3) * 0x100 + raw:byte(4)
r3 = raw:byte(5) * 0x100 + raw:byte(6)
r4 = raw:byte(7) * 0x100 + raw:byte(8)
mb:setregisters(addRegister, r1, r2, r3, r4)
--mb:setregisters(addRegister, r1)
--mb:setregisters(addRegister+1, r2)
--mb:setregisters(addRegister+2, r3)
--mb:setregisters(addRegister+3, r4)
end
end
mb:handleslave()
Posts: 7758
Threads: 42
Joined: Jun 2015
Reputation:
447
Consider using this script instead: https://forum.logicmachine.net/showthrea...6#pid27726
Your current script does a lot of busy polling via grp.getvalue after each slave step which can lead to timeouts.
Posts: 169
Threads: 58
Joined: Oct 2017
Reputation:
0
(17.01.2023, 13:35)admin Wrote: Consider using this script instead: https://forum.logicmachine.net/showthrea...6#pid27726
Your current script does a lot of busy polling via grp.getvalue after each slave step which can lead to timeouts.
It seemed to me that the problem was there. Thank you for this new version that I will try immediately.
Many thank's too for your help.
Dominique
|