From 96b77d418148e0ff6f4aa15872176026fe6244e1 Mon Sep 17 00:00:00 2001 From: nikzori Date: Tue, 8 Apr 2025 17:11:57 +0300 Subject: [PATCH] added data byte counter for incoming port data --- Datasheet.cs | 27 ++++++++++++++-------- Main.cs | 3 ++- Modbus.cs | 64 ++++++++++++++++++++++++++++------------------------ 3 files changed, 54 insertions(+), 40 deletions(-) diff --git a/Datasheet.cs b/Datasheet.cs index 81ef2c6..7b73f5a 100644 --- a/Datasheet.cs +++ b/Datasheet.cs @@ -26,7 +26,7 @@ namespace Gidrolock_Modbus_Scanner static bool responseReceived = false; - bool isValveClosed = false; + bool isValveClosed = false; bool alarmStatus = false; bool cleaningStatus = false; @@ -257,18 +257,18 @@ namespace Gidrolock_Modbus_Scanner catch (Exception err) { MessageBox.Show(err.Message); } } - //Опрос всех записей async Task PollEntry(Entry entry) { + latestMessage = null; bool res = false; isAwaitingResponse = true; - Modbus.ReadRegAsync(modbusID, (FunctionCode)entry.registerType, entry.address, entry.length); + Modbus.ReadRegAsync(modbusID, (FunctionCode)entry.registerType, entry.address, entry.length); stopwatch.Restart(); - while (isAwaitingResponse) + while (isAwaitingResponse && latestMessage == null) { - if (stopwatch.ElapsedMilliseconds > 1000) + if (stopwatch.ElapsedMilliseconds > 5000) { Console.WriteLine("Response timed out."); break; @@ -287,12 +287,13 @@ namespace Gidrolock_Modbus_Scanner { byte newID = (byte)nudModbusID.Value; // should prevent assigning wrong ID if UpDown is fiddled with in the middle of request isAwaitingResponse = true; + latestMessage = null; Modbus.WriteSingleAsync(FunctionCode.WriteRegister, modbusID, 128, newID); stopwatch.Restart(); while (isAwaitingResponse) { - if (stopwatch.ElapsedMilliseconds > 1000) + if (stopwatch.ElapsedMilliseconds > port.ReadTimeout) { Console.WriteLine("Response timed out."); break; @@ -308,12 +309,13 @@ namespace Gidrolock_Modbus_Scanner { ushort value = isValveClosed ? (ushort)0 : (ushort)0xFF00; isAwaitingResponse = true; + latestMessage = null; Modbus.WriteSingleAsync(FunctionCode.WriteCoil, modbusID, device.valveStatus.address, value); stopwatch.Restart(); while (isAwaitingResponse) { - if (stopwatch.ElapsedMilliseconds > 1000) + if (stopwatch.ElapsedMilliseconds > port.ReadTimeout) { Console.WriteLine("Response timed out."); break; @@ -333,12 +335,13 @@ namespace Gidrolock_Modbus_Scanner { ushort value = alarmStatus ? (ushort)0 : (ushort)0xFF00; isAwaitingResponse = true; + latestMessage = null; Modbus.WriteSingleAsync(FunctionCode.WriteCoil, modbusID, device.alarmStatus.address, value); stopwatch.Restart(); while (isAwaitingResponse) { - if (stopwatch.ElapsedMilliseconds > 1000) + if (stopwatch.ElapsedMilliseconds > port.ReadTimeout) { Console.WriteLine("Response timed out."); break; @@ -358,6 +361,7 @@ namespace Gidrolock_Modbus_Scanner { ushort value = cleaningStatus ? (ushort)0 : (ushort)0xFF00; isAwaitingResponse = true; + latestMessage = null; Modbus.WriteSingleAsync(FunctionCode.WriteCoil, modbusID, device.cleaningMode.address, value); stopwatch.Restart(); @@ -391,12 +395,14 @@ namespace Gidrolock_Modbus_Scanner // send speed value to device // await for response isAwaitingResponse = true; + latestMessage = null; Modbus.WriteSingleAsync(FunctionCode.WriteRegister, modbusID, device.baudRate.address, newSpeed); stopwatch.Restart(); + while (isAwaitingResponse) { - if (stopwatch.ElapsedMilliseconds > 1000) + if (stopwatch.ElapsedMilliseconds > port.ReadTimeout) { Console.WriteLine("Response timed out."); break; @@ -510,13 +516,14 @@ namespace Gidrolock_Modbus_Scanner return; } isAwaitingResponse = true; + latestMessage = null; Console.WriteLine("Outgoing firmware message: " + Modbus.ByteArrayToString(message.ToArray())); port.Write(message.ToArray(), 0, message.Count); stopwatch.Restart(); while (isAwaitingResponse) { - if (stopwatch.ElapsedMilliseconds > 1000) + if (stopwatch.ElapsedMilliseconds > port.ReadTimeout) { Console.WriteLine("Response timed out."); cntr++; diff --git a/Main.cs b/Main.cs index f268924..b76e4d4 100644 --- a/Main.cs +++ b/Main.cs @@ -129,11 +129,12 @@ namespace Gidrolock_Modbus_Scanner if (stopwatch.ElapsedMilliseconds > 1000) { AddLog("Истекло время ожидания ответа от устройства. Повторный запрос..."); - isAwaitingResponse = false; + stopwatch.Restart(); counter++; if (counter > 3) { AddLog("Устройство не отвечает. Проверьте соединение с устройством."); + isAwaitingResponse = false; return; } } diff --git a/Modbus.cs b/Modbus.cs index b83763c..91e85cc 100644 --- a/Modbus.cs +++ b/Modbus.cs @@ -274,59 +274,65 @@ namespace Gidrolock_Modbus_Scanner static byte[] buffer = new byte[255]; static int offset = 0; static int count = 0; + static bool bytecountFound = false; + static int expectedBytes = 0; static void PortDataReceived(object sender, EventArgs e) { - //reset values on every event call; buffer = new byte[255]; offset = 0; + bytecountFound = false; + expectedBytes = 0; + + Console.WriteLine("Port data received"); try { stopwatch.Restart(); - while (stopwatch.ElapsedMilliseconds < 50) + while (stopwatch.ElapsedMilliseconds < port.ReadTimeout) { + if (bytecountFound && offset >= expectedBytes + 5) + break; if (port.BytesToRead > 0) { stopwatch.Restart(); count = port.BytesToRead; - port.Read(buffer, offset, port.BytesToRead); + port.Read(buffer, offset, count); offset += count; + if (!bytecountFound && offset >= 2) + { + expectedBytes = buffer[2]; + Console.WriteLine("Found data byte count: " + expectedBytes); + bytecountFound = true; + } + if (bytecountFound && offset >= expectedBytes + 5) // reached end of message + { + Console.WriteLine("Reached end of message"); + break; + } + stopwatch.Restart(); } } + // Console.WriteLine("Buffer: " + ByteArrayToString(buffer, false)); // assume that the message ended + Console.WriteLine("Message reception ended"); + byte[] message = new byte[expectedBytes + 5]; + for (int i = 0; i < expectedBytes + 5; i++) + message[i] = buffer[i]; - List message = new List(); - for (int i = 0; i < offset; i++) - { - message.Add(buffer[i]); - } - if (message.Count == 0) - return; - - Console.WriteLine("Incoming message: " + ByteArrayToString(message.ToArray(), false)); - /* - if (!CheckResponse(message.ToArray())) - { + Console.WriteLine("Incoming message: " + ByteArrayToString(message, false)); + + if (!CheckResponse(message)) Console.WriteLine("Bad CRC or not a modbus message!"); - } - */ + if (message[1] <= 0x04) // read functions - { - //Console.WriteLine("It's a read message"); - ResponseReceived.Invoke(null, new ModbusResponseEventArgs(message.ToArray(), ModbusStatus.ReadSuccess)); - } + ResponseReceived.Invoke(null, new ModbusResponseEventArgs(message, ModbusStatus.ReadSuccess)); + else { if (message[1] <= 0x10) // write functions - { - //Console.WriteLine("It's a write message"); - ResponseReceived.Invoke(null, new ModbusResponseEventArgs(message.ToArray(), ModbusStatus.WriteSuccess)); - } + ResponseReceived.Invoke(null, new ModbusResponseEventArgs(message, ModbusStatus.WriteSuccess)); else // error codes - { - //Console.WriteLine("It's an error"); - ResponseReceived.Invoke(null, new ModbusResponseEventArgs(message.ToArray(), ModbusStatus.Error)); - } + ResponseReceived.Invoke(null, new ModbusResponseEventArgs(message, ModbusStatus.Error)); } } catch (Exception err)