Modbus : Multiple modules use common time scheduling (one Thread.Sleep in RunDeviceAfter), ver. 3.1.1605
This commit is contained in:
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
|
|||||||
// Build Number
|
// Build Number
|
||||||
// Revision
|
// Revision
|
||||||
//
|
//
|
||||||
[assembly: AssemblyVersion("3.1.1604.0")]
|
[assembly: AssemblyVersion("3.1.1605.0")]
|
||||||
[assembly: AssemblyFileVersion("3.1.1604.0")]
|
[assembly: AssemblyFileVersion("3.1.1605.0")]
|
||||||
|
|||||||
@@ -22,10 +22,20 @@ namespace TBF.Rig.Modbus.Common
|
|||||||
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
|
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
|
||||||
|
|
||||||
const int MaxTelegramsPerSecond = 5; /// Max. number of telegrams to be sent per second (100 ms for each telegram)
|
const int MaxTelegramsPerSecond = 5; /// Max. number of telegrams to be sent per second (100 ms for each telegram)
|
||||||
const int RegTelegramsPerSecond = 3; /// Number of registered polling telegrams per second
|
const int RegTelegramsPerSecond = 2; /// Number of registered polling telegrams per second
|
||||||
|
|
||||||
const int MinTelegramLen = 4;
|
const int MinTelegramLen = 4;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enumeration of modbus components via static fields and methods
|
||||||
|
/// </summary>
|
||||||
|
static int nextIdx = 0;
|
||||||
|
static int modbusComponentsCount { get { return nextIdx; } }
|
||||||
|
static Modbus[] modbusComponents;
|
||||||
|
///
|
||||||
|
int modbusComponentIx; /// 0-based diverter number assigned in Initialize()
|
||||||
|
|
||||||
|
|
||||||
private readonly ModbusCfg modbusCfg;
|
private readonly ModbusCfg modbusCfg;
|
||||||
|
|
||||||
/// Serial port and received data buffers
|
/// Serial port and received data buffers
|
||||||
@@ -56,23 +66,32 @@ namespace TBF.Rig.Modbus.Common
|
|||||||
: base(cfg)
|
: base(cfg)
|
||||||
{
|
{
|
||||||
modbusCfg = cfg as ModbusCfg;
|
modbusCfg = cfg as ModbusCfg;
|
||||||
log.Warn(this.ToString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
telegramsToSend = new Queue<byte[]>();
|
modbusComponentIx = nextIdx++;
|
||||||
|
///
|
||||||
|
if (modbusComponents == null || modbusComponents.Length < nextIdx)
|
||||||
|
{
|
||||||
|
Modbus[] componentsSoFar = modbusComponents;
|
||||||
|
modbusComponents = new Modbus[modbusComponentsCount];
|
||||||
|
if (componentsSoFar != null)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < componentsSoFar.Length; i++) modbusComponents[i] = componentsSoFar[i];
|
||||||
|
}
|
||||||
|
modbusComponents[modbusComponentsCount - 1] = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
telegramsToSend = new Queue<byte[]>();
|
||||||
receivedTelegrams = new Queue<byte[]>[256];
|
receivedTelegrams = new Queue<byte[]>[256];
|
||||||
for (int i = 0; i < receivedTelegrams.Length; i++)
|
for (int i = 0; i < receivedTelegrams.Length; i++)
|
||||||
{
|
{
|
||||||
receivedTelegrams[i] = new Queue<byte[]>();
|
receivedTelegrams[i] = new Queue<byte[]>();
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = new byte[BUFFER_SIZE];
|
buffer = new byte[BUFFER_SIZE];
|
||||||
rcvdData = new byte[BUFFER_SIZE];
|
rcvdData = new byte[BUFFER_SIZE];
|
||||||
rcvdBytesCount = 0;
|
rcvdBytesCount = 0;
|
||||||
|
|
||||||
registeredDevicesCount = 0;
|
registeredDevicesCount = 0;
|
||||||
firstScheduledTicketNo = 0;
|
firstScheduledTicketNo = 0;
|
||||||
|
|
||||||
@@ -86,12 +105,12 @@ namespace TBF.Rig.Modbus.Common
|
|||||||
serialPort = new SerialPort(comPortName, modbusCfg.BaudRate, modbusCfg.Parity, modbusCfg.DataBits, modbusCfg.StopBits);
|
serialPort = new SerialPort(comPortName, modbusCfg.BaudRate, modbusCfg.Parity, modbusCfg.DataBits, modbusCfg.StopBits);
|
||||||
serialPort.Handshake = modbusCfg.Handshake;
|
serialPort.Handshake = modbusCfg.Handshake;
|
||||||
serialPort.Open();
|
serialPort.Open();
|
||||||
log.FatalFormat("{0} - Device successfully initialized", Name);
|
log.FatalFormat("{0} initialized: {1}", Name, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
serialPort = null;
|
serialPort = null;
|
||||||
log.FatalFormat("{0} - Device simulated", Name);
|
log.FatalFormat("{0} simulated: {1}", Name, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,25 +275,72 @@ namespace TBF.Rig.Modbus.Common
|
|||||||
rcvdBytesCount -= lastValidOffset;
|
rcvdBytesCount -= lastValidOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Run this device</summary>
|
/// <summary>Run this device</summary>
|
||||||
public void RunDeviceAfter()
|
public void RunDeviceAfter()
|
||||||
{
|
{
|
||||||
int telegramsToSendNow = Math.Min(MaxTelegramsPerSecond, telegramsToSend.Count);
|
telegramsToSendInThisTick = Math.Min(MaxTelegramsPerSecond, telegramsToSend.Count);
|
||||||
|
|
||||||
for (int i = 0; i < telegramsToSendNow; i++, Thread.Sleep(100))
|
if (modbusComponentIx == 0)
|
||||||
{
|
{
|
||||||
WriteMessageToSerialPort(telegramsToSend.Dequeue());
|
int maxTelegramsToSendInThisTick = telegramsToSendInThisTick;
|
||||||
|
for (int i = 1; i < modbusComponentsCount; i++)
|
||||||
|
{
|
||||||
|
if (modbusComponents[i].telegramsToSendInThisTick > maxTelegramsToSendInThisTick)
|
||||||
|
{
|
||||||
|
maxTelegramsToSendInThisTick = modbusComponents[i].telegramsToSendInThisTick;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int t = 0; t < maxTelegramsToSendInThisTick; t++, Thread.Sleep(100))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < modbusComponentsCount; i++)
|
||||||
|
{
|
||||||
|
if (t < modbusComponents[i].telegramsToSendInThisTick)
|
||||||
|
{
|
||||||
|
modbusComponents[i].WriteOneMessageToSerialPort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
///
|
||||||
|
int telegramsToSendInThisTick;
|
||||||
|
///
|
||||||
|
void WriteOneMessageToSerialPort()
|
||||||
|
{
|
||||||
|
WriteMessageToSerialPort(telegramsToSend.Dequeue());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Stop this device</summary>
|
/// <summary>Stop this device</summary>
|
||||||
public void StopDevice()
|
public void StopDevice()
|
||||||
{
|
{
|
||||||
/// Send telegrams currently in the queue
|
telegramsToSendInThisTick = telegramsToSend.Count;
|
||||||
while (telegramsToSend.Count > 0)
|
|
||||||
|
/// Send all telegrams currently in all queues
|
||||||
|
if (modbusComponentIx == 0)
|
||||||
{
|
{
|
||||||
|
int maxTelegramsToSendInThisTick = telegramsToSendInThisTick;
|
||||||
|
for (int i = 1; i < modbusComponentsCount; i++)
|
||||||
|
{
|
||||||
|
if (modbusComponents[i].telegramsToSendInThisTick > maxTelegramsToSendInThisTick)
|
||||||
|
{
|
||||||
|
maxTelegramsToSendInThisTick = modbusComponents[i].telegramsToSendInThisTick;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
WriteMessageToSerialPort(telegramsToSend.Dequeue());
|
for (int t = 0; t < maxTelegramsToSendInThisTick; t++, Thread.Sleep(100))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < modbusComponentsCount; i++)
|
||||||
|
{
|
||||||
|
if (t < modbusComponents[i].telegramsToSendInThisTick)
|
||||||
|
{
|
||||||
|
modbusComponents[i].WriteOneMessageToSerialPort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serialPort != null && serialPort.IsOpen) serialPort.Close();
|
if (serialPort != null && serialPort.IsOpen) serialPort.Close();
|
||||||
|
|||||||
Reference in New Issue
Block a user