From f33bc4f167e23941265242be76d4196dc0fb1dcf Mon Sep 17 00:00:00 2001 From: Milan Hanajik Date: Fri, 9 Apr 2021 13:05:06 +0200 Subject: [PATCH] Modbus : Multiple modules use common time scheduling (one Thread.Sleep in RunDeviceAfter), ver. 3.1.1605 --- TBF/Properties/AssemblyInfo.cs | 4 +- TBF/Rig/Modbus/Common/Modbus.cs | 96 +++++++++++++++++++++++++++------ 2 files changed, 83 insertions(+), 17 deletions(-) diff --git a/TBF/Properties/AssemblyInfo.cs b/TBF/Properties/AssemblyInfo.cs index 37a3cfaae..cea1127a3 100644 --- a/TBF/Properties/AssemblyInfo.cs +++ b/TBF/Properties/AssemblyInfo.cs @@ -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")] diff --git a/TBF/Rig/Modbus/Common/Modbus.cs b/TBF/Rig/Modbus/Common/Modbus.cs index bede01597..bc8b69e51 100644 --- a/TBF/Rig/Modbus/Common/Modbus.cs +++ b/TBF/Rig/Modbus/Common/Modbus.cs @@ -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; + + /// + /// Enumeration of modbus components via static fields and methods + /// + 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(); + 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(); receivedTelegrams = new Queue[256]; for (int i = 0; i < receivedTelegrams.Length; i++) { receivedTelegrams[i] = new Queue(); } - 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; } + /// Run this device 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()); + } + /// Stop this device 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();