diff --git a/IOB-UT-NEXT/Enums.cs b/IOB-UT-NEXT/Enums.cs
index 60cefa8f..8b141de7 100644
--- a/IOB-UT-NEXT/Enums.cs
+++ b/IOB-UT-NEXT/Enums.cs
@@ -174,12 +174,25 @@ namespace IOB_UT_NEXT
public enum MachineSetupMode
{
ND = 0,
+
///
- /// Modalità Mecolpress (3 parametri IN, se variati --> porto a 1 la variabile di controllo)
+ /// Modalità Mecolpress (3 parametri IN, se variati --> porto a 1 la variabile di controllo)
///
MECOLPRESS = 1
}
+ ///
+ /// Tipo di memoria Modbus
+ ///
+ public enum modbusMemType
+ {
+ Coil = 0,
+ DiscreteInput = 1,
+ NotDefined = 2,
+ InputRegister = 3,
+ HoldingRegister = 4
+ }
+
///
/// StFlag32: set di 32 bit (4 word) contente semaforo di variabili
///
@@ -544,5 +557,4 @@ namespace IOB_UT_NEXT
///
ULog
}
-
}
\ No newline at end of file
diff --git a/IOB-UT-NEXT/baseUtils.cs b/IOB-UT-NEXT/baseUtils.cs
index 9e5d63f6..cf312fdd 100644
--- a/IOB-UT-NEXT/baseUtils.cs
+++ b/IOB-UT-NEXT/baseUtils.cs
@@ -66,6 +66,27 @@ namespace IOB_UT_NEXT
#region Public Methods
+ ///
+ /// Restituisce la prima cifra (a sx) da un numero (es x decodere quale memoria modbus sia)
+ ///
+ /// Numero di cui trovare la priam cifra
+ ///
+ public static int getFirstInt(int num)
+ {
+ if (num >= 100000000) num /= 100000000;
+ if (num >= 10000) num /= 10000;
+ if (num >= 100) num /= 100;
+ if (num >= 10) num /= 10;
+
+#if false
+ // formulazione alternativa con ciclo...
+ while (num >= 10)
+ num /= 10;
+#endif
+
+ return num;
+ }
+
///
/// formatta un numero in forma binaria 0/1
///
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_SAIM_003.ini b/IOB-WIN-NEXT/DATA/CONF/GIACO_SAIM_003.ini
index b2923fa2..69721ced 100644
--- a/IOB-WIN-NEXT/DATA/CONF/GIACO_SAIM_003.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_SAIM_003.ini
@@ -24,11 +24,15 @@ CMDADV1=?valore=
CMDREBO=/sendReboot.aspx?idxMacchina=
[MEMORY]
-ADDR_READ=40001
-ADDR_WRITE=40001
+ADDR_READ=40000
+ADDR_WRITE=40000
SIZE_READ=200
SIZE_WRITE=0
HR_BASE_ADDR=40000
+;DELTA_BASE=0
+DELTA_BASE=1
+;0=false,1=true
+MODBUS_EXT_REG=1
[BLINK]
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_SAIM_003_MBlock.json b/IOB-WIN-NEXT/DATA/CONF/GIACO_SAIM_003_MBlock.json
index f20d1551..431c7d15 100644
--- a/IOB-WIN-NEXT/DATA/CONF/GIACO_SAIM_003_MBlock.json
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_SAIM_003_MBlock.json
@@ -1,5 +1,7 @@
{
"ReadBlocks": {
+ "10000": 10,
+ "10100": 10,
"40010": 10,
"40100": 40,
"40140": 30
diff --git a/IOB-WIN-NEXT/IobGeneric.cs b/IOB-WIN-NEXT/IobGeneric.cs
index a637919c..72c9713f 100644
--- a/IOB-WIN-NEXT/IobGeneric.cs
+++ b/IOB-WIN-NEXT/IobGeneric.cs
@@ -340,6 +340,16 @@ namespace IOB_WIN_NEXT
return baseUtils.CRB("DemoInSample");
}
}
+ ///
+ /// Verifica se sia abilitato test lettura blocchi memoria all'avvio
+ ///
+ public static bool EnableTest
+ {
+ get
+ {
+ return baseUtils.CRB("enableTest");
+ }
+ }
///
/// Verifica se sia in modalità DEMO x dati OUTPUT
diff --git a/IOB-WIN-NEXT/IobModbusTCP.cs b/IOB-WIN-NEXT/IobModbusTCP.cs
index 3c124a4a..84a92234 100644
--- a/IOB-WIN-NEXT/IobModbusTCP.cs
+++ b/IOB-WIN-NEXT/IobModbusTCP.cs
@@ -194,6 +194,7 @@ namespace IOB_WIN_NEXT
{
foreach (var item in memSetR)
{
+ // verifico il tipo di dati da leggere e salvare... FIXME TODO FARE !!!
readBlockHoldingReg(item.Key, item.Value, parametri.holdRegBaseAddr);
int waitTime = rnd.Next(minWait, maxWait);
Thread.Sleep(waitTime);
@@ -575,14 +576,33 @@ namespace IOB_WIN_NEXT
#region Protected Fields
+ ///
+ /// Copia locale dei valori in COIL (OUT) | 0.000/09.999, oppure 0.000/65.536 = 0xFFFF, come
+ /// array chiave (int) valori int[] letti tramite ModBus, da convertire secondo tipo
+ ///
+ protected Dictionary CoilsLUT = new Dictionary();
+
protected ModbusClient currPLC;
///
- /// Copia locale dei valori in Holding Registry, come array chiave (int) valori int[] letti
- /// tramite ModBus, da convertire secondo tipo
+ /// Copia locale dei valori in Discrete Inputs (IN) | 10.000/19.999, oppure 100.000/165.536
+ /// = 1xFFFF, come array chiave (int) valori int[] letti tramite ModBus, da convertire
+ /// secondo tipo
+ ///
+ protected Dictionary DiscreteInputLUT = new Dictionary();
+
+ ///
+ /// Copia locale dei valori in Holding Registers | 40.000/49.999, oppure 400.000/465.536 =
+ /// 4xFFFF, come array chiave (int) valori int[] letti tramite ModBus, da convertire secondo tipo
///
protected Dictionary HoldingRegisterLUT = new Dictionary();
+ ///
+ /// Copia locale dei valori in Input Registers | 30.000/39.999, oppure 300.000/365.536 =
+ /// 3xFFFF, come array chiave (int) valori int[] letti tramite ModBus, da convertire secondo tipo
+ ///
+ protected Dictionary InputRegisterLUT = new Dictionary();
+
///
/// Ultimo controllo ping x evitare ping flood...
///
@@ -853,6 +873,8 @@ namespace IOB_WIN_NEXT
parametri.holdRegBaseAddr = fIni.ReadInteger("MEMORY", "HR_BASE_ADDR", 40001);
// valore delta base e shift
deltaBase = fIni.ReadInteger("MEMORY", "DELTA_BASE", 0);
+ // verifico eventuale parametro memoria estesa (non 0...10'000 ma 0...xFFFF=65536)
+ modbusExtReg = fIni.ReadBoolean("MEMORY", "MODBUS_EXT_REG");
// salvo vettori memoria...
lgInfoStartup("Set RawInput dimensions...");
RawInput = new byte[parametri.memSizeRead];
@@ -1022,6 +1044,104 @@ namespace IOB_WIN_NEXT
return answ;
}
+ ///
+ /// Effettua ciclo letture di ogni area configurata
+ ///
+ /// indirizzo di partenza
+ /// num valori da leggere
+ protected void testBlockReadExt(int baseAddr, int numVals)
+ {
+ int baseHold = deltaBase;
+ modbusMemType currMemType = modbusMemType.NotDefined;
+ int maxVal = 10000;
+ int baseMult = 10000;
+ int[] readTestInt = new int[2];
+ bool[] readTestBool = new bool[2];
+ lgTrace($"-------------------- Inizio test lettura EXT {baseAddr} --------------------");
+ try
+ {
+ stopwatch.Restart();
+
+ // memoria estesa... 0 ... xFFFF per ogni set da 100'000...
+ if (modbusExtReg)
+ {
+ maxVal = 65536;
+ baseMult = 100000;
+ }
+
+ // determino tipo di memoria
+ if (baseAddr <= maxVal)
+ {
+ currMemType = modbusMemType.Coil;
+ }
+ else if (baseAddr <= baseMult + maxVal)
+ {
+ currMemType = modbusMemType.DiscreteInput;
+ }
+ else if (baseAddr <= 3 * baseMult + maxVal)
+ {
+ currMemType = modbusMemType.InputRegister;
+ }
+ else
+ {
+ currMemType = modbusMemType.HoldingRegister;
+ }
+ switch (currMemType)
+ {
+ case modbusMemType.Coil:
+ readTestBool = currPLC.ReadCoils(baseAddr - baseHold, numVals);
+ break;
+
+ case modbusMemType.DiscreteInput:
+ readTestBool = currPLC.ReadDiscreteInputs(baseAddr - (1 * baseMult + baseHold), numVals);
+ break;
+
+ case modbusMemType.InputRegister:
+ readTestInt = currPLC.ReadInputRegisters(baseAddr - (3 * baseMult + baseHold), numVals);
+ break;
+
+ case modbusMemType.HoldingRegister:
+ readTestInt = currPLC.ReadHoldingRegisters(baseAddr - (4 * baseMult + baseHold), numVals);
+ break;
+
+ case modbusMemType.NotDefined:
+ default:
+ break;
+ }
+ stopwatch.Stop();
+ lgTrace($"Stats lettura | {readTestInt.Length} val | {stopwatch.ElapsedMilliseconds}ms");
+ }
+ catch
+ { }
+
+ switch (currMemType)
+ {
+ case modbusMemType.Coil:
+ case modbusMemType.DiscreteInput:
+ for (int i = 0; i < readTestBool.Length; i++)
+ {
+ lgTrace($"{currMemType} | {baseAddr + i:000} | Val: {readTestBool[i]}");
+ }
+ break;
+
+ case modbusMemType.InputRegister:
+ case modbusMemType.HoldingRegister:
+ for (int i = 0; i < readTestInt.Length / 2; i++)
+ {
+ int[] thisSet = new int[2];
+ Array.Copy(readTestInt, i * 2, thisSet, 0, 2);
+ lgTrace($"{currMemType} | {baseAddr + i * 2:000} | Valori: {thisSet[0]} / {thisSet[1]} | Val Int: {ModbusClient.ConvertRegistersToInt(thisSet)} | Val Real: {ModbusClient.ConvertRegistersToFloat(thisSet):N6}");
+ }
+ break;
+
+ case modbusMemType.NotDefined:
+ default:
+ lgTrace($"Errore: tipo memoria non definitito per {baseAddr} / {numVals}");
+ break;
+ }
+ lgTrace($"-------------------- Completato test lettura {baseAddr} --------------------");
+ }
+
///
/// Test connessione CNC
///
@@ -1112,7 +1232,7 @@ namespace IOB_WIN_NEXT
//answ = (currStatus == OptCheckCondInt[cKey].ValOk);
// controllo se il valore sia in elenco di quelli validi...
answ = OptCheckCondInt[cKey].ValOk.Contains(currStatus);
- lgTrace($"testIntCondition for {cKey} | BaseAddr: {OptCheckCondInt[cKey].BaseAddr} | currStatus: {currStatus} | ValOk: {string.Join(",",OptCheckCondInt[cKey].ValOk)}");
+ lgTrace($"testIntCondition for {cKey} | BaseAddr: {OptCheckCondInt[cKey].BaseAddr} | currStatus: {currStatus} | ValOk: {string.Join(",", OptCheckCondInt[cKey].ValOk)}");
}
else
{
@@ -1121,6 +1241,18 @@ namespace IOB_WIN_NEXT
return answ;
}
+ ///
+ /// Test di lettura dei blocchi di memoria ESTESO (considerato memorie xFFFF e tutti e 4 i
+ /// tipi di dati modbus)
+ ///
+ protected void testReadExt()
+ {
+ foreach (var item in memSetR)
+ {
+ testBlockReadExt(item.Key, item.Value);
+ }
+ }
+
#endregion Protected Methods
#region Private Fields
@@ -1139,6 +1271,12 @@ namespace IOB_WIN_NEXT
///
private int deltaBase { get; set; } = 0;
+ ///
+ /// Indica se usare gli indirizzi estesi per ogni blocco: false = 0...10'000 true =
+ /// 0...65'536 (= xFFFF)
+ ///
+ private bool modbusExtReg { get; set; } = false;
+
#endregion Private Properties
#region Private Methods
diff --git a/IOB-WIN-NEXT/IobModbusTCPSaim.cs b/IOB-WIN-NEXT/IobModbusTCPSaim.cs
index 973749aa..b98cfdea 100644
--- a/IOB-WIN-NEXT/IobModbusTCPSaim.cs
+++ b/IOB-WIN-NEXT/IobModbusTCPSaim.cs
@@ -33,12 +33,17 @@ namespace IOB_WIN_NEXT
try
{
processDynData();
+ if (EnableTest)
+ {
+ testReadExt();
+ }
}
catch (Exception exc)
{
lgError($"Eccezione in processDynData iniziale x ModBus TCP SAIM:{Environment.NewLine}{exc}");
}
}
+
}
#endregion Public Constructors
@@ -168,40 +173,6 @@ namespace IOB_WIN_NEXT
#region Private Methods
- private void testBlockRead(int baseAddr, int numByte)
- {
- int baseHold = 40001;
- int[] readTestFull = new int[2];
- lgTrace($"-------------------- Inizio test lettura {baseAddr} --------------------");
- try
- {
- stopwatch.Restart();
- readTestFull = currPLC.ReadHoldingRegisters(baseAddr - baseHold, numByte);
- stopwatch.Stop();
- lgTrace($"Stats lettura | {readTestFull.Length} val | {stopwatch.ElapsedMilliseconds}ms");
- }
- catch
- { }
-
- for (int i = 0; i < readTestFull.Length / 2; i++)
- {
- int[] thisSet = new int[2];
- Array.Copy(readTestFull, i * 2, thisSet, 0, 2);
- lgTrace($"{baseAddr + i * 2:000} | HoldingRegisters: {thisSet[0]} / {thisSet[1]} | Val Real: {ModbusClient.ConvertRegistersToFloat(thisSet):N6}");
- }
- lgTrace("-------------------- Completato test lettura {baseAddr} --------------------");
- }
-
-
-
- private void testRead()
- {
- foreach (var item in memSetR)
- {
- testBlockRead(item.Key, item.Value);
- }
- }
-
#endregion Private Methods
}
}
\ No newline at end of file