635 lines
27 KiB
C#
635 lines
27 KiB
C#
using MagFlux6200_metrology_reg_list;
|
|
using XYLEM.Device;
|
|
using XYLEM.Communication.ValueEncoders;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO.Ports;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Numerics;
|
|
using System.Xml.Linq;
|
|
using static System.Net.Mime.MediaTypeNames;
|
|
using XYLEM.Base;
|
|
using System.Text.RegularExpressions;
|
|
using System.Data;
|
|
using System.Security.Policy;
|
|
using System.Threading;
|
|
|
|
namespace XYLEM.Communication
|
|
{
|
|
/// <summary>
|
|
/// Modbus read and write return data type
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
public class ModbusDataResult<T> where T : IComparable, IFormattable, IComparable<T>, IEquatable<T>/*, IConvertible is not compatible with BigInteger*/
|
|
{
|
|
/// <summary>
|
|
/// Has the task succeded
|
|
/// </summary>
|
|
internal bool IsOkay;
|
|
|
|
/// <summary>
|
|
/// Data readed from or written to device
|
|
/// </summary>
|
|
internal T Data;
|
|
|
|
/// <summary>
|
|
/// What device value info for Data
|
|
/// </summary>
|
|
internal Device_value Info;
|
|
|
|
public ModbusDataResult(bool IsOkay, T DataRW, Device_value Info)
|
|
{
|
|
this.IsOkay = IsOkay;
|
|
this.Data = DataRW;
|
|
this.Info = Info;
|
|
}
|
|
}
|
|
|
|
public class ModbusDataRequest
|
|
{
|
|
/// <summary>
|
|
/// Has the task succeded
|
|
/// </summary>
|
|
internal bool IsOkay;
|
|
|
|
/// <summary>
|
|
/// Data for return read in from device
|
|
/// </summary>
|
|
internal object Data;
|
|
|
|
/// <summary>
|
|
/// What device value info for Data
|
|
/// </summary>
|
|
internal Device_value Info;
|
|
|
|
public ModbusDataRequest(bool IsOkay, object returnReadIn, Device_value Info)
|
|
{
|
|
this.IsOkay = IsOkay;
|
|
this.Data = returnReadIn;
|
|
this.Info = Info;
|
|
}
|
|
}
|
|
|
|
|
|
public class ModbusCom
|
|
{
|
|
const int ch_lng_dv = -15;
|
|
const int ch_lng_Version = -3;
|
|
const int ch_lng_MD_adr = -7;
|
|
const int dig_value = 10;
|
|
|
|
/// <summary>
|
|
/// Min delay before a DUT message is expected faild
|
|
// Is 1s for testing out that default modbus settings com don't fail
|
|
/// </summary>
|
|
private readonly int _MaxWaitForComRX_ms = 1000;
|
|
|
|
/// <summary>
|
|
/// Message ended detection delay
|
|
/// Min delay before bytes count received and haven't changed result in modbus message ended
|
|
/// The 50ms is found to be needed when using DUT RS485 and modbus messages is transparent to Metrology
|
|
/// </summary>
|
|
private readonly int _DelayBetweenRxByteCheck_ms = 50;
|
|
SerialPort _serial;
|
|
int _retry;
|
|
|
|
|
|
public int MsgErrorCount { get; private set; }
|
|
public int MsgCount { get; private set; }
|
|
|
|
public void ResetMsgCounters()
|
|
{
|
|
MsgCount = MsgErrorCount = 0;
|
|
}
|
|
|
|
public ModbusCom(string serial_port, int baudRate, Parity parity, int retry = 3)
|
|
{
|
|
ResetMsgCounters();
|
|
this._serial = new SerialPort();
|
|
_serial.PortName = serial_port;
|
|
_serial.BaudRate = baudRate;
|
|
_serial.Parity= parity;
|
|
_serial.DtrEnable = _serial.RtsEnable = true; // Need to be on for Application USB Serial com to detect a connection
|
|
//_serial.Handshake = Handshake.RequestToSendXOnXOff;
|
|
_serial.ReadTimeout = 100;
|
|
if (!_serial.IsOpen)
|
|
{
|
|
_serial.Open();
|
|
}
|
|
_retry=retry;
|
|
Console.WriteLine($"Serial connection {_serial.PortName}, {_serial.BaudRate}, {_serial.Parity}, retry = {_retry}");
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Is communication port connected
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool IsConnected()
|
|
{
|
|
return _serial.IsOpen;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generic value Read of a modbus value ex. "var ret = await Read(_serial, _device_id, req, new Single());"
|
|
/// </summary>
|
|
/// <typeparam name="T">UInt16, Single ...</typeparam>
|
|
/// <param name="device_id"> device ID to use for read</param>
|
|
/// <param name="dv"> device value to read</param>
|
|
/// <param name="retValue"> a new value of the type to read, to use for init and return</param>
|
|
/// <returns>as ModbusDataResult<T> where Item1 is true if okay and Item2 is the value read</returns>
|
|
public ModbusDataResult<T> Read<T>(int device_id, Device_value dv, T retValue) where T : IComparable, IFormattable, IComparable<T>, IEquatable<T>/*, IConvertible is not compatible with BigInteger*/
|
|
{
|
|
ModbusDataResult<T> ret = null;
|
|
try
|
|
{
|
|
byte[] answer = Read_bytes(device_id, dv.MD_adr, dv.Datatype.Length());
|
|
retValue = (T)DeviceValueEncoder.Decode(answer, dv.Datatype);
|
|
ret = new ModbusDataResult<T>(true, retValue, dv); // Okay
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var message = $"Read error! from ID={device_id} name={dv.Name} adr={dv.MD_adr} with {dv.Datatype.Length()}\n\r" + ex.Message + "\n\r";
|
|
Console.WriteLine(message);
|
|
AppConst.Logger.AddFuncLog(true, this.ToString(), "Read()", message);
|
|
ret = new ModbusDataResult<T>(false, retValue, dv); // Error
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Read multiple value optimized in one or more telegrams from device
|
|
/// </summary>
|
|
/// <param name="device_id"> Device ID to use for read</param>
|
|
/// <param name="dvList"> A list of values to read</param>
|
|
/// <returns>List with read okay or failed values</returns>
|
|
public List<ModbusDataRequest> Read(int device_id, List<Device_value> dvList)
|
|
{
|
|
List<ModbusDataRequest> ret = null;
|
|
try
|
|
{
|
|
// ----------- Generate blocks to read -----------
|
|
dvList.Sort((dvA, dvB) =>
|
|
{
|
|
return dvA.MD_adr.CompareTo(dvB.MD_adr);
|
|
});
|
|
List<List<ModbusDataRequest>> blocks = new List<List<ModbusDataRequest>>();
|
|
foreach (var dv in dvList)
|
|
{
|
|
// if first item, just add it
|
|
if ((blocks.Count == 0) || (blocks.Last().Count == 0))
|
|
{
|
|
if (blocks.Count == 0)
|
|
{
|
|
blocks.Add(new List<ModbusDataRequest>());
|
|
}
|
|
blocks.Last().Add(new ModbusDataRequest(false, null, dv));
|
|
}
|
|
else
|
|
{
|
|
var dvLast = blocks.Last().Last().Info;
|
|
// Only add it if a new value not already to be read
|
|
if (dvLast.Name != dv.Name)
|
|
{
|
|
var nextAdr = dvLast.MD_adr + (dvLast.Datatype.Length()/2);
|
|
// If not next to read in current block
|
|
if (dv.MD_adr != nextAdr)
|
|
{
|
|
// then add it to the next read block
|
|
blocks.Add(new List<ModbusDataRequest>());
|
|
}
|
|
blocks.Last().Add(new ModbusDataRequest(false, null, dv));
|
|
}
|
|
}
|
|
}
|
|
// ----------- Read blocks -----------
|
|
foreach (var dv_group in blocks)
|
|
{
|
|
try
|
|
{
|
|
var dvi_first = dv_group.First().Info;
|
|
var dvi_last = dv_group.Last().Info;
|
|
var startAdr = dvi_first.MD_adr;
|
|
var LenBytes = (dvi_last.MD_adr+(dvi_last.Datatype.Length()/2)-startAdr)*2;
|
|
if ((LenBytes < 0) || (LenBytes > 250))
|
|
{
|
|
throw new Exception($"Block length limit Error is {LenBytes}");
|
|
}
|
|
byte[] answer = Read_bytes(device_id, startAdr, LenBytes);
|
|
if (answer == null)
|
|
{
|
|
throw new Exception($"Read block error! from ID={device_id} from {dvi_first} to {dvi_last}");
|
|
}
|
|
foreach (var dv_data in dv_group)
|
|
{
|
|
var dv = dv_data.Info;
|
|
var start_idx = (dv.MD_adr-startAdr)*2;
|
|
var value_bytes = answer.Copy(start_idx, dv.Datatype.Length());
|
|
var value = DeviceValueEncoder.Decode(value_bytes, dv.Datatype);
|
|
if (ret == null)
|
|
{
|
|
ret = new List<ModbusDataRequest>();
|
|
}
|
|
ret.Add(new ModbusDataRequest(true, value, dv)); // Okay
|
|
}
|
|
}
|
|
//catch (Exception ex)
|
|
catch
|
|
{
|
|
// Retry read it as single values
|
|
foreach (var dv_data in dv_group)
|
|
{
|
|
var dv = dv_data.Info;
|
|
byte[] answer = Read_bytes(device_id, dv.MD_adr, dv.Datatype.Length());
|
|
var value = DeviceValueEncoder.Decode(answer, dv.Datatype);
|
|
if (ret == null)
|
|
{
|
|
ret = new List<ModbusDataRequest>();
|
|
}
|
|
ret.Add(new ModbusDataRequest(true, value, dv)); // Okay
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if ((dvList != null) && (dvList.Count() > 0))
|
|
{
|
|
foreach (var dv in dvList)
|
|
{
|
|
var message = $"Read error! from ID={device_id} name={dv.Name} adr={dv.MD_adr}\n\r" + ex.Message + "\n\r";
|
|
Console.WriteLine(message);
|
|
AppConst.Logger.AddFuncLog(true, this.ToString(), "Read()", message);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var message = $"Read error! from ID={device_id}\n\r" + ex.Message + "\n\r";
|
|
Console.WriteLine(message);
|
|
AppConst.Logger.AddFuncLog(true, this.ToString(), "Read()", message);
|
|
}
|
|
ret = null; // Error
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Generic value Write of a modbus value ex. "await Write(_serial, _device_id, req, value)"
|
|
/// </summary>
|
|
/// <typeparam name="T">UInt16, Single ..</typeparam>
|
|
/// <param name="device_id"> device ID to use for write</param>
|
|
/// <param name="dv"> device value to write</param>
|
|
/// <param name="value"> the value to write</param>
|
|
/// <returns></returns>
|
|
public bool Write<T>(int device_id, Device_value dv, T value) where T : IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T>
|
|
{
|
|
bool isOkay = true;
|
|
try
|
|
{
|
|
byte[] tx_data = DeviceValueEncoder.Encode(value, dv.Datatype);
|
|
if (!Write_bytes(device_id, dv.MD_adr, tx_data))
|
|
{
|
|
var message = $"Write failed={dv,ch_lng_dv}: Reg_Ver={dv.Version,ch_lng_Version} Adr={dv.MD_adr,-7} value={value,dig_value}";
|
|
Console.WriteLine(message);
|
|
AppConst.Logger.AddFuncLog(true, this.ToString(), "Write()", message);
|
|
isOkay = false;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var message = $"Write error! to ID={device_id} name={dv.Name} adr={dv.MD_adr} with {dv.Datatype.Length()}\n\r" + ex.Message + "\n\r";
|
|
Console.WriteLine(message);
|
|
AppConst.Logger.AddFuncLog(true, this.ToString(), "Write()", message);
|
|
isOkay = false;
|
|
}
|
|
return isOkay;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Write multiple value optimized in one or more telegrams to device
|
|
/// </summary>
|
|
/// <param name="device_id"> device ID to use for write </param>
|
|
/// <param name="reqList"> a list of values to write</param>
|
|
/// <returns>A list of values written okay or failed to device</returns>
|
|
public List<ModbusDataRequest> Write(int device_id, List<ModbusDataRequest> reqList)
|
|
{
|
|
List<ModbusDataRequest> ret = null;
|
|
try
|
|
{
|
|
// ----------- Generate blocks to write -----------
|
|
reqList.Sort((dvA, dvB) =>
|
|
{
|
|
return dvA.Info.MD_adr.CompareTo(dvB.Info.MD_adr);
|
|
});
|
|
List<List<ModbusDataRequest>> blocks = new List<List<ModbusDataRequest>>();
|
|
foreach (var req in reqList)
|
|
{
|
|
// if first item, just add it
|
|
if ((blocks.Count == 0) || (blocks.Last().Count == 0))
|
|
{
|
|
if (blocks.Count == 0)
|
|
{
|
|
blocks.Add(new List<ModbusDataRequest>());
|
|
}
|
|
blocks.Last().Add(req);
|
|
}
|
|
else
|
|
{
|
|
var req_Last = blocks.Last().Last();
|
|
// Only add it if a new value not already written
|
|
if (req_Last.Info.Name != req.Info.Name)
|
|
{
|
|
var nextAdr = req_Last.Info.MD_adr + (req_Last.Info.Datatype.Length()/2);
|
|
// If not next to read in current block
|
|
if (req.Info.MD_adr != nextAdr)
|
|
{
|
|
// then add it to the next read block
|
|
blocks.Add(new List<ModbusDataRequest>());
|
|
}
|
|
blocks.Last().Add(req);
|
|
}
|
|
else
|
|
{
|
|
throw new Exception($"Only a single Write object to {req_Last.Info.Name} is allowed!");
|
|
}
|
|
}
|
|
}
|
|
// ----------- Write blocks -----------
|
|
foreach (var req_group in blocks)
|
|
{
|
|
try
|
|
{
|
|
var dvi_first = req_group.First().Info;
|
|
var dvi_last = req_group.Last().Info;
|
|
var startAdr = dvi_first.MD_adr;
|
|
var LenBytes = (dvi_last.MD_adr+(dvi_last.Datatype.Length()/2)-startAdr)*2;
|
|
if ((LenBytes < 0) || (LenBytes > 250))
|
|
{
|
|
throw new Exception($"Block length limit Error is {LenBytes}");
|
|
}
|
|
var tx_group_data = new List<byte>();
|
|
foreach (var wr in req_group)
|
|
{
|
|
byte[] tx_data = DeviceValueEncoder.Encode(wr.Data, wr.Info.Datatype);
|
|
if (tx_data == null)
|
|
{
|
|
throw new Exception($"Fail getting write byte data for {wr.Info.Name}");
|
|
}
|
|
tx_group_data.AddRange(tx_data);
|
|
}
|
|
if (LenBytes != tx_group_data.Count)
|
|
{
|
|
throw new Exception($"Group write from {dvi_first.Name} to {dvi_last.Name} expected={LenBytes} bytes, encoded was={tx_group_data.Count} bytes");
|
|
}
|
|
var isOkay = Write_bytes(device_id, startAdr, tx_group_data.ToArray());
|
|
if (!isOkay)
|
|
{
|
|
throw new Exception($"Write block error! from ID={device_id} from {dvi_first} to {dvi_last}");
|
|
}
|
|
ret = new List<ModbusDataRequest>();
|
|
foreach (var req in req_group)
|
|
{
|
|
req.IsOkay = true;
|
|
ret.Add(req); // add request that succeed
|
|
}
|
|
}
|
|
//catch (Exception ex) //For debugging
|
|
catch
|
|
{
|
|
ret = new List<ModbusDataRequest>();
|
|
// Retry write as single values
|
|
foreach (var req in req_group)
|
|
{
|
|
var dv = req.Info;
|
|
byte[] tx_data = DeviceValueEncoder.Encode(req.Data, req.Info.Datatype);
|
|
req.IsOkay = Write_bytes(device_id, dv.MD_adr, tx_data);
|
|
ret.Add(req); //
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if ((reqList != null) && (reqList.Count() > 0))
|
|
{
|
|
foreach (var dv in reqList)
|
|
{
|
|
var message = $"Write error! from ID={device_id} name={dv.Info.Name} adr={dv.Info.MD_adr}\n\r" + ex.Message + "\n\r";
|
|
Console.WriteLine(message);
|
|
AppConst.Logger.AddFuncLog(true, this.ToString(), "Write()", message);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var message = $"Write error! from ID={device_id}\n\r" + ex.Message + "\n\r";
|
|
Console.WriteLine(message);
|
|
AppConst.Logger.AddFuncLog(true, this.ToString(), "Write()", message);
|
|
}
|
|
ret = null; // Error
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/// <summary>
|
|
/// A general modbus read function for just a bunch of bytes
|
|
/// </summary>
|
|
/// <param name="device_id"> device ID to use for modbus command </param>
|
|
/// <param name="md_adr">Start address to data accessed </param>
|
|
/// <param name="num_of_bytes">Number of bytes to request</param>
|
|
/// <returns>byte data read from device and is null if none / error </returns>
|
|
public byte[] Read_bytes(int device_id, int md_adr, int num_of_bytes)
|
|
{
|
|
var is_write = false;
|
|
try
|
|
{
|
|
// Read address 0 device
|
|
var p_transate = new ProtocolTranslateModbusRTUClass();
|
|
byte[] tx_data = p_transate.CreateTxData(device_id, (int)Func_RD.No3, md_adr, num_of_bytes, null, is_write);
|
|
return modbus_com(md_adr, tx_data, is_write, p_transate);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var message = $"!error No data received from ID={device_id} adr={md_adr} with {num_of_bytes} to {(is_write ? "Write" : "Read")}\n\r" + ex.Message + "\n\r";
|
|
Console.WriteLine(message);
|
|
AppConst.Logger.AddFuncLog(true, this.ToString(), "Read_bytes()", message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// A general modbus write function for just a bunch of bytes
|
|
/// </summary>
|
|
/// <param name="device_id"> device ID to use for modbus command </param>
|
|
/// <param name="md_adr">Start address to data accessed </param>
|
|
/// <param name="write_data">Byte data to Write</param>
|
|
/// <returns> Is true on write is okay </returns>
|
|
public bool Write_bytes(int device_id, int md_adr, byte[] write_data)
|
|
{
|
|
var is_write = true;
|
|
try
|
|
{
|
|
// Read address 0 device
|
|
var p_transate = new ProtocolTranslateModbusRTUClass();
|
|
byte[] tx_data = p_transate.CreateTxData(device_id, (int)Func_WR.No16, md_adr, write_data.Length, write_data, is_write);
|
|
var result = modbus_com(md_adr, tx_data, is_write, p_transate);
|
|
if (result != null)
|
|
{
|
|
return true; // Okay
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var message = $"!error writting data to ID={device_id} adr={md_adr} to {(is_write ? "Write" : "Read")}\n\r" + ex.Message + "\n\r";
|
|
Console.WriteLine(message);
|
|
AppConst.Logger.AddFuncLog(true, this.ToString(), "Write_bytes()", message);
|
|
}
|
|
return false; // Error
|
|
}
|
|
|
|
/// <summary>
|
|
/// A general modbus read / write function for just a bunch of bytes
|
|
/// </summary>
|
|
/// <param name="md_adr">Start address to data accessed </param>
|
|
/// <param name="tx_data"> a complet modbus telegram byte data to transmit</param>
|
|
/// <param name="is_write"> is the modbus telegram a write or read type to use for eval received result</param>
|
|
/// <param name="p_transate">Modbus protocol translater for eval received result</param>
|
|
/// <returns>will return null on error or received message on okay</returns>
|
|
public byte[] modbus_com(int md_adr, byte[] tx_data, bool is_write, ProtocolTranslateModbusRTUClass p_transate)
|
|
{
|
|
lock (_serial)
|
|
{
|
|
try
|
|
{
|
|
byte[] answer = null;
|
|
var retry = 0;
|
|
do
|
|
{
|
|
MsgCount++;
|
|
if (!_serial.IsOpen)
|
|
{
|
|
_serial.Open();
|
|
}
|
|
_serial.DiscardInBuffer();
|
|
_serial.Write(tx_data, 0, tx_data.Length);
|
|
|
|
int received = 0;
|
|
int max_count = _MaxWaitForComRX_ms/_DelayBetweenRxByteCheck_ms;
|
|
do
|
|
{
|
|
received = _serial.BytesToRead;
|
|
Thread.Sleep(_DelayBetweenRxByteCheck_ms);
|
|
} while (((received == 0) || (received != _serial.BytesToRead)) && (--max_count>0));
|
|
if (_serial.BytesToRead <= 0)
|
|
{
|
|
MsgErrorCount++;
|
|
}
|
|
} while ((_serial.BytesToRead <= 0) && (++retry < _retry));
|
|
if (_serial.BytesToRead <= 0)
|
|
{
|
|
throw new Exception("!error No data received from device");
|
|
}
|
|
#if (DEBUG)
|
|
// TODO just testing
|
|
if (retry > 1)
|
|
{
|
|
Console.WriteLine($"Warning modbus com {retry-1} retry needed for ID={md_adr} to {(is_write ? "Write" : "Read")}");
|
|
}
|
|
#endif //#if (DEBUG)
|
|
var bytesToRead = _serial.BytesToRead;
|
|
var rx_data = new byte[bytesToRead];
|
|
var rx_data_len = _serial.Read(rx_data, 0, bytesToRead);
|
|
bool isRxRW = p_transate.IsDataRW(rx_data, true);
|
|
// Check data func is Read or write
|
|
if (isRxRW)
|
|
{
|
|
// Read
|
|
if (!is_write)
|
|
{
|
|
if (p_transate.IsRead(rx_data, true))
|
|
{
|
|
answer = p_transate.GetReadData(rx_data, true);
|
|
//buf.CallBackOK(bDataTemp, txData, CallBackOK_Single);
|
|
}
|
|
else
|
|
{
|
|
throw new Exception("Data Rx Wrong");
|
|
}
|
|
}
|
|
else // Write
|
|
{
|
|
bool isWrite = p_transate.IsWrite(rx_data, true);
|
|
int adr = p_transate.GetRxAdr(rx_data, true);
|
|
if (isWrite && (!p_transate.IsAdrPossible(rx_data, true) ? true : (adr == md_adr)))
|
|
{
|
|
//buf.CallBackOK(null, txData, CallBackOK_Single);
|
|
return rx_data; // Is okay return received message
|
|
}
|
|
else
|
|
{
|
|
throw new Exception("Data Rx Wrong");
|
|
}
|
|
}
|
|
|
|
}
|
|
else // Exception received
|
|
{
|
|
// Normal
|
|
if (!p_transate.IsRxWaitForCommand(rx_data, true))
|
|
{
|
|
int exception = p_transate.GetRxAcknowledgeCode(rx_data, true);
|
|
//buf.CallBackError(exception, txData, "");
|
|
// If read .. try again after wait
|
|
}
|
|
else
|
|
{
|
|
if (!is_write)
|
|
{
|
|
//buf.Add(txData);
|
|
// if Write.. then all must be okay and put event on delay
|
|
}
|
|
else
|
|
{
|
|
//buf.CallBackOK(null, txData, CallBackOK_Single);
|
|
}
|
|
if (p_transate.IsRxWaitForFinishMax60S(rx_data, true))
|
|
{
|
|
Thread.Sleep((int)(60 * 1000));
|
|
}
|
|
else if (p_transate.IsRxWaitForFinishMax5Min(rx_data, true))
|
|
{
|
|
Thread.Sleep((int)(5 * 60 * 1000));
|
|
}
|
|
else if (p_transate.IsRxWaitForFinishMax5S(rx_data, true))
|
|
{
|
|
Thread.Sleep((int)(5 * 1000));
|
|
}
|
|
else
|
|
{
|
|
int waitTime = 5 * 1000; // default
|
|
Thread.Sleep(waitTime); // Wait for reset
|
|
}
|
|
}
|
|
}
|
|
return answer;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var message = "Error: \n\r" + ex.Message + "\n\r";
|
|
Console.WriteLine(message);
|
|
AppConst.Logger.AddFuncLog(true, this.ToString(), "modbus_com()", message);
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
_serial.Close();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|