Bozza metodo scrittura modbus (da testare da ufficio)

This commit is contained in:
Samuele Locatelli
2021-10-28 19:23:03 +02:00
parent 503531d1f6
commit cfb6a0c291
+129 -238
View File
@@ -133,7 +133,7 @@ namespace IOB_WIN_NEXT
/// <param name="size"></param>
/// <param name="tipoMem"></param>
/// <returns></returns>
private static double convertVal(int[] listInt, int size, plcDataType tipoMem)
private static double convertFromReg(int[] listInt, int size, plcDataType tipoMem)
{
double valore = 0;
//verifico se sia INT o real x convertire...
@@ -165,6 +165,58 @@ namespace IOB_WIN_NEXT
return valore;
}
/// <summary>
/// Converte valore reale nel tipo desiderato in forma di int[] adatti a scrivere nei registri
/// </summary>
/// <param name="listInt"></param>
/// <param name="size"></param>
/// <param name="tipoMem"></param>
/// <returns></returns>
private static int[] convertToReg(object origVal, int size, plcDataType tipoMem)
{
int[] answ = new int[2];
//verifico se sia INT o real x convertire...
switch (tipoMem)
{
case plcDataType.Real:
if (size == 4)
{
answ = ModbusClient.ConvertDoubleToRegisters((double)origVal);
}
else if (size == 2)
{
answ = ModbusClient.ConvertFloatToRegisters((float)origVal);
}
break;
case plcDataType.Int:
default:
if (size == 4)
{
answ = ModbusClient.ConvertLongToRegisters((long)origVal);
}
else if (size == 2)
{
answ = ModbusClient.ConvertIntToRegisters((int)origVal);
}
break;
}
return answ;
}
private static double getScaledDouble(dataConf currMem)
{
double valDouble;
// prima faccio eventuale fattore di scala...
double.TryParse(currMem.value, out valDouble);
if (currMem.factor > 1)
{
valDouble = valDouble * (double)currMem.factor;
}
return valDouble;
}
private static int getScaledInt(dataConf currMem)
{
int valInt;
@@ -219,13 +271,13 @@ namespace IOB_WIN_NEXT
case modBusAddrType.InputRegister:
listInt = readInputReg(item.Value.index, item.Value.size);
valore = convertVal(listInt, item.Value.size, item.Value.tipoMem);
valore = convertFromReg(listInt, item.Value.size, item.Value.tipoMem);
break;
case modBusAddrType.HoldingRegister:
listInt = readHoldReg(item.Value.index - 1, item.Value.size);
valore = convertVal(listInt, item.Value.size, item.Value.tipoMem);
valore = convertFromReg(listInt, item.Value.size, item.Value.tipoMem);
break;
default:
@@ -307,10 +359,9 @@ namespace IOB_WIN_NEXT
/// <param name="updatedPar"></param>
protected override void plcWriteParams(ref List<objItem> updatedPar)
{
#if false
dataConf currMem = null;
int byteSize = 0;
byte[] MemBlock = new byte[1];
int[] CurrVal = new int[1];
string memAddrWrite = "";
bool fatto = false;
string serObj = "";
@@ -324,6 +375,7 @@ namespace IOB_WIN_NEXT
memAddrWrite = "";
int valInt = 0;
uint valUInt = 0;
double valDouble = 0;
// cerco in area memMapWrite...
if (memMap.mMapWrite.ContainsKey(item.uid))
{
@@ -331,7 +383,7 @@ namespace IOB_WIN_NEXT
currMem = memMap.mMapWrite[item.uid];
byteSize = currMem.size;
memAddrWrite = currMem.memAddr;
MemBlock = new byte[byteSize];
CurrVal = new int[byteSize];
// faccio preliminarmente upsertKey...
upsertKey(currMem.name, currMem.value);
serObj = JsonConvert.SerializeObject(item, Formatting.Indented);
@@ -345,45 +397,47 @@ namespace IOB_WIN_NEXT
case plcDataType.Int:
valInt = getScaledInt(currMem);
saveIntOnMemBlock(ref MemBlock, 0, valInt.ToString());
CurrVal = convertToReg(valInt, 2, plcDataType.Int);
fatto = writeInputReg(currMem.index, CurrVal);
break;
case plcDataType.DInt:
valInt = getScaledInt(currMem);
saveDIntOnMemBlock(ref MemBlock, 0, valInt.ToString());
valUInt = getScaledUInt(currMem);
CurrVal = convertToReg(valInt, 4, plcDataType.Int);
fatto = writeInputReg(currMem.index, CurrVal);
break;
case plcDataType.Word:
valUInt = getScaledUInt(currMem);
saveWordOnMemBlock(ref MemBlock, 0, valInt.ToString());
break;
//case plcDataType.Word:
// valUInt = getScaledUInt(currMem);
// saveWordOnMemBlock(ref MemBlock, 0, valInt.ToString());
// break;
case plcDataType.DWord:
valUInt = getScaledUInt(currMem);
saveDWordOnMemBlock(ref MemBlock, 0, valInt.ToString());
break;
//case plcDataType.DWord:
// valUInt = getScaledUInt(currMem);
// saveDWordOnMemBlock(ref MemBlock, 0, valInt.ToString());
// break;
case plcDataType.Real:
saveRealOnMemBlock(ref MemBlock, 0, currMem.value);
valDouble = getScaledDouble(currMem);
CurrVal = convertToReg(valInt, 2, plcDataType.Real);
fatto = writeInputReg(currMem.index, CurrVal);
break;
case plcDataType.String:
// se ho writePre --> "allungo" di 2 la dimensione della stringa x MemBlock...
if (writePre)
{
MemBlock = new byte[byteSize + 2];
}
saveStringOnMemBlock(ref MemBlock, 0, currMem.size, currMem.value);
break;
//case plcDataType.String:
// // se ho writePre --> "allungo" di 2 la dimensione della stringa x MemBlock...
// if (writePre)
// {
// MemBlock = new byte[byteSize + 2];
// }
// saveStringOnMemBlock(ref MemBlock, 0, currMem.size, currMem.value);
// break;
default:
break;
}
lgInfo($"---------------MemBlock data---------------{Environment.NewLine}{BitConverter.ToString(MemBlock)}{Environment.NewLine}--------------- END data ---------------");
lgInfo($"---------------MemBlock data---------------{Environment.NewLine}CurrVal: {CurrVal}{Environment.NewLine}--------------- END data ---------------");
if (!string.IsNullOrEmpty(memAddrWrite))
{
// scrivo su ModBusTCP
fatto = S7WriteBB(ref MemBlock, memAddrWrite);
// se fatto --> aggiorno!
if (fatto)
{
@@ -391,6 +445,7 @@ namespace IOB_WIN_NEXT
item.reqValue = "";
item.lastRead = DateTime.Now;
}
#if false
// se configurato faccio verifica write...
if (getOptPar("WRITE_CHECK") == "TRUE")
{
@@ -406,6 +461,7 @@ namespace IOB_WIN_NEXT
lgInfo($"Scrittura corretta: {BitConverter.ToString(MemBlockRead)}");
}
}
#endif
}
else
{
@@ -423,7 +479,6 @@ namespace IOB_WIN_NEXT
}
}
}
#endif
}
/// <summary>
@@ -849,214 +904,6 @@ namespace IOB_WIN_NEXT
}
}
#if false
/// <summary>
/// wrapper chiamata LETTURA in blocco MULTI BYTE dell'area read DI DEFAULT...
/// </summary>
/// <param name="MATRICE valori letti"></param>
/// <returns></returns>
public bool S7ReadBB(ref byte[] Value)
{
return S7ReadBB(ref Value, parametri.memAddrRead, parametri.memSizeRead);
}
/// <summary>
/// wrapper chiamata LETTURA in blocco MULTI BYTE...
/// </summary>
/// <param name="Value">MATRICE valori letti</param>
/// <param name="memAddrRead">Area memoria da leggere...</param>
/// <param name="numByte">Numero byte da leggere</param>
/// <returns></returns>
public bool S7ReadBB(ref byte[] Value, string memAddrRead, int numByte)
{
bool answ = false;
if (Value != null)
{
sw.Restart();
parentForm.commPlcActive = true;
parentForm.commPlcActive = false;
sw.Stop();
if (utils.CRB("recTime"))
{
TimingData.addResult(cIobConf.codIOB, string.Format("{0}|{1}", parametri.memAddrRead, numByte), sw.ElapsedTicks);
}
}
return answ;
}
/// <summary>
/// wrapper chiamata LETTURA in blocco MULTI BYTE... default size a parametri.memSizeRead
/// </summary>
/// <param name="MATRICE valori letti"></param>
/// <param name="memAddrRead">Area memoria da leggere...</param>
/// <returns></returns>
public bool S7ReadBB(ref byte[] Value, string memAddrRead)
{
bool answ = false;
answ = S7ReadBB(ref Value, memAddrRead, parametri.memSizeRead);
return answ;
}
/// <summary>
/// wrapper chiamata SCRITTURA in blocco MULTI BYTE, DI DEFAULT su area configurata x scrittura CONTINUA...
/// </summary>
/// <param name="MATRICE valori scritti"></param>
/// <returns></returns>
public bool S7WriteBB(ref byte[] Value)
{
return S7WriteBB(ref Value, parametri.memAddrWrite);
}
/// <summary>
/// Override scrittura in area DBB
/// </summary>
/// <param name="Value"></param>
/// <param name="memAddrWrite"></param>
/// <returns></returns>
public bool S7WriteBB(ref byte[] Value, string memAddrWrite)
{
bool answ = false;
if (Value == null)
{
lgError($"Errore in S7WriteBB: Value è null");
}
else
{
if (string.IsNullOrEmpty(memAddrWrite))
{
lgError($"Errore in S7WriteBB: memAddrWrite è vuoto");
}
else
{
sw.Restart();
sw.Stop();
}
}
return answ;
}
/// <summary>
/// Override scrittura in area DBB
/// </summary>
/// <param name="Value">Valore byte[] da scrivere</param>
/// <param name="DbNum">Numero del DB (es 700 per DB700)</param>
/// <param name="IndiceMem">Indice interno al datablock del byte da cui partire</param>
/// <returns></returns>
public bool S7WriteBB(ref byte[] Value, int DbNum, int IndiceMem)
{
bool answ = false;
if (Value == null)
{
lgError($"Errore in S7WriteBB: Value è null");
}
else
{
if (DbNum < 0 || IndiceMem < 0)
{
lgError($"Errore in S7WriteBB | DbNum: {DbNum} | IndiceMem: {IndiceMem}");
}
else
{
sw.Restart();
sw.Stop();
}
}
return answ;
}
#endif
/// <summary>
/// Salvo in memblock il valore Int indicato con formattazione ModBus TCP
/// </summary>
/// <param name="MemBlock">Blocco memoria come byte[] dove scrivere</param>
/// <param name="startPos">Posizione inizio scrittura</param>
/// <param name="valore">valore da scrivere</param>
public void saveIntOnMemBlock(ref byte[] MemBlock, int startPos, string valore)
{
try
{
short valInt = 0;
short.TryParse(valore, out valInt);
byte[] strByte = S7.Net.Types.Int.ToByteArray(valInt);
int byteLen = 2;
Buffer.BlockCopy(strByte, 0, MemBlock, startPos, byteLen);
//var verifica = S7.Net.Types.String.FromByteArray(MemBlock);
}
catch (Exception exc)
{
lgError($"Errore in gestione scrittura INT {valore} alla posizione {startPos} byte{Environment.NewLine}{exc}");
}
}
/// <summary>
/// Salvo in memblock il valore Int indicato con formattazione ModBus TCP
/// </summary>
/// <param name="MemBlock">Blocco memoria come byte[] dove scrivere</param>
/// <param name="stringKey">Nome del parametro da recuperare da prodData x scrivere</param>
/// <param name="startPos">Posizione inizio scrittura</param>
public void saveIntOnMemBlock(ref byte[] MemBlock, string stringKey, int startPos)
{
if (currProdData.ContainsKey(stringKey))
{
try
{
string valore = currProdData[stringKey];
saveIntOnMemBlock(ref MemBlock, startPos, valore);
}
catch (Exception exc)
{
lgError($"Errore in gestione scrittura INT {stringKey}{Environment.NewLine}{exc}");
}
}
}
/// <summary>
/// Salvo in memblock il valore stringa indicato con formattazione ModBus TCP
/// </summary>
/// <param name="MemBlock">Blocco memoria come byte[] dove scrivere</param>
/// <param name="startPos">Posizione inizio scrittura</param>
/// <param name="valore">Valore scrivere</param>
public void saveRealOnMemBlock(ref byte[] MemBlock, int startPos, string valore)
{
try
{
byte[] stringPar = new byte[2];
double valReal = 0;
double.TryParse(valore, out valReal);
byte[] strByte = S7.Net.Types.Double.ToByteArray(valReal);
int byteLen = 4;
Buffer.BlockCopy(strByte, 0, MemBlock, startPos, byteLen);
//var verifica = S7.Net.Types.String.FromByteArray(MemBlock);
}
catch (Exception exc)
{
lgError($"Errore in gestione scrittura REAL {valore} alla posizione {startPos} byte{Environment.NewLine}{exc}");
}
}
/// <summary>
/// Salvo in memblock il valore stringa indicato con formattazione ModBus TCP
/// </summary>
/// <param name="MemBlock">Blocco memoria come byte[] dove scrivere</param>
/// <param name="stringKey">Valore scrivere</param>
/// <param name="startPos">Posizione inizio scrittura</param>
public void saveRealOnMemBlock(ref byte[] MemBlock, string stringKey, int startPos)
{
if (currProdData.ContainsKey(stringKey))
{
try
{
string valore = currProdData[stringKey];
saveRealOnMemBlock(ref MemBlock, startPos, valore);
}
catch (Exception exc)
{
lgError($"Errore in gestione scrittura REAL {stringKey}{Environment.NewLine}{exc}");
}
}
}
/// <summary>
/// Effettua salvataggio in LUT del valore ricevuto (double)
/// </summary>
@@ -1181,6 +1028,50 @@ namespace IOB_WIN_NEXT
}
}
/// <summary>
/// Scrittura di un singolo valore COIL (1...)
/// </summary>
/// <param name="startAddr"></param>
/// <param name="currValue"></param>
/// <returns></returns>
public bool writeCoil(int startAddr, bool currValue)
{
bool answ = false;
if (currPLC.Connected)
{
try
{
currPLC.WriteSingleCoil(startAddr, currValue);
answ = true;
}
catch
{ }
}
return answ;
}
/// <summary>
/// Scrittura di un valore Input Register (4...)
/// </summary>
/// <param name="startAddr"></param>
/// <param name="currRegVal">Valore in formato INT da registri</param>
/// <returns></returns>
public bool writeInputReg(int startAddr, int[] currRegVal)
{
bool answ = false;
if (currPLC.Connected)
{
try
{
currPLC.WriteMultipleRegisters(startAddr, currRegVal);
answ = true;
}
catch
{ }
}
return answ;
}
#endregion Public Methods
}
}