Modbus : Multiple modules use common time scheduling (one Thread.Sleep in RunDeviceAfter), ver. 3.1.1605
This commit is contained in:
parent
d84588650f
commit
f33bc4f167
@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("3.1.1604.0")]
|
||||
[assembly: AssemblyFileVersion("3.1.1604.0")]
|
||||
[assembly: AssemblyVersion("3.1.1605.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)); }
|
||||
|
||||
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;
|
||||
|
||||
|
||||
/// <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;
|
||||
|
||||
/// Serial port and received data buffers
|
||||
@ -56,23 +66,32 @@ namespace TBF.Rig.Modbus.Common
|
||||
: base(cfg)
|
||||
{
|
||||
modbusCfg = cfg as ModbusCfg;
|
||||
log.Warn(this.ToString());
|
||||
}
|
||||
|
||||
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];
|
||||
for (int i = 0; i < receivedTelegrams.Length; i++)
|
||||
{
|
||||
receivedTelegrams[i] = new Queue<byte[]>();
|
||||
}
|
||||
|
||||
buffer = new byte[BUFFER_SIZE];
|
||||
rcvdData = new byte[BUFFER_SIZE];
|
||||
rcvdBytesCount = 0;
|
||||
|
||||
registeredDevicesCount = 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.Handshake = modbusCfg.Handshake;
|
||||
serialPort.Open();
|
||||
log.FatalFormat("{0} - Device successfully initialized", Name);
|
||||
log.FatalFormat("{0} initialized: {1}", Name, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Run this device</summary>
|
||||
public void RunDeviceAfter()
|
||||
{
|
||||
int telegramsToSendNow = Math.Min(MaxTelegramsPerSecond, telegramsToSend.Count);
|
||||
|
||||
for (int i = 0; i < telegramsToSendNow; i++, Thread.Sleep(100))
|
||||
telegramsToSendInThisTick = Math.Min(MaxTelegramsPerSecond, telegramsToSend.Count);
|
||||
|
||||
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>
|
||||
public void StopDevice()
|
||||
{
|
||||
/// Send telegrams currently in the queue
|
||||
while (telegramsToSend.Count > 0)
|
||||
telegramsToSendInThisTick = telegramsToSend.Count;
|
||||
|
||||
/// 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);
|
||||
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();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user