reworked serial port data processing, added firmware writing
This commit is contained in:
115
Datasheet.cs
115
Datasheet.cs
@@ -23,9 +23,10 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
SerialPort port = Modbus.port;
|
SerialPort port = Modbus.port;
|
||||||
bool isPolling = false;
|
bool isPolling = false;
|
||||||
static bool isAwaitingResponse = false;
|
static bool isAwaitingResponse = false;
|
||||||
|
static bool responseReceived = false;
|
||||||
|
|
||||||
|
|
||||||
bool isValveClosed = false;
|
bool isValveClosed = false;
|
||||||
bool alarmStatus = false;
|
bool alarmStatus = false;
|
||||||
bool cleaningStatus = false;
|
bool cleaningStatus = false;
|
||||||
|
|
||||||
@@ -80,7 +81,7 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
labelBattery.Text = "Нет";
|
labelBattery.Text = "Нет";
|
||||||
else labelBattery.Text = "???%";
|
else labelBattery.Text = "???%";
|
||||||
|
|
||||||
Modbus.ResponseReceived += (sndr, msg) => { isAwaitingResponse = false; latestMessage = msg; };
|
Modbus.ResponseReceived += (sndr, msg) => { responseReceived = true; latestMessage = msg; isAwaitingResponse = false; };
|
||||||
|
|
||||||
for (int i = 0; i < device.wiredSensors; i++)
|
for (int i = 0; i < device.wiredSensors; i++)
|
||||||
{
|
{
|
||||||
@@ -246,7 +247,6 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
bool res = false;
|
bool res = false;
|
||||||
isAwaitingResponse = true;
|
isAwaitingResponse = true;
|
||||||
Modbus.ReadRegAsync(modbusID, (FunctionCode)entry.registerType, entry.address, entry.length);
|
Modbus.ReadRegAsync(modbusID, (FunctionCode)entry.registerType, entry.address, entry.length);
|
||||||
|
|
||||||
|
|
||||||
stopwatch.Restart();
|
stopwatch.Restart();
|
||||||
|
|
||||||
@@ -396,7 +396,7 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
fileThread.TrySetApartmentState(ApartmentState.STA);
|
fileThread.SetApartmentState(ApartmentState.STA);
|
||||||
fileThread.Start();
|
fileThread.Start();
|
||||||
while (!fileThread.IsAlive) { Thread.Sleep(1); }
|
while (!fileThread.IsAlive) { Thread.Sleep(1); }
|
||||||
Thread.Sleep(1);
|
Thread.Sleep(1);
|
||||||
@@ -414,7 +414,8 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
MessageBox.Show("Выберите файл прошивки.");
|
MessageBox.Show("Выберите файл прошивки.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
int cntr = 0;
|
||||||
|
|
||||||
FileStream fileStream = File.OpenRead(firmwarePath);
|
FileStream fileStream = File.OpenRead(firmwarePath);
|
||||||
long bytesLeft = fileStream.Length;
|
long bytesLeft = fileStream.Length;
|
||||||
long bytesTotal = fileStream.Length;
|
long bytesTotal = fileStream.Length;
|
||||||
@@ -425,15 +426,13 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
byte[] flashAddr = new byte[2];
|
byte[] flashAddr = new byte[2];
|
||||||
byte[] CRC;
|
byte[] CRC;
|
||||||
List<byte> message;
|
List<byte> message;
|
||||||
bool responseReceived = false;
|
|
||||||
Modbus.ResponseReceived += (sndr, msg) => { responseReceived = true; };
|
|
||||||
bool firstMessageSent = false;
|
bool firstMessageSent = false;
|
||||||
long bytesWritten = 0;
|
long bytesWritten = 0;
|
||||||
await Task.Run(() =>
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
while (bytesLeft > 0)
|
while (bytesLeft > 0)
|
||||||
{
|
{
|
||||||
if (firstMessageSent) // after first message the device is sent into recovery mode which only supports 9600 bps
|
if (firstMessageSent && port.BaudRate != 9600) // after first message the device is sent into recovery mode which only supports 9600 bps
|
||||||
{
|
{
|
||||||
port.Close();
|
port.Close();
|
||||||
port.BaudRate = 9600;
|
port.BaudRate = 9600;
|
||||||
@@ -477,50 +476,64 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
message[message.Count - 2] = CRC[0];
|
message[message.Count - 2] = CRC[0];
|
||||||
message[message.Count - 1] = CRC[1];
|
message[message.Count - 1] = CRC[1];
|
||||||
|
|
||||||
Console.WriteLine("Outgoing firmware message: " + Modbus.ByteArrayToString(message.ToArray()));
|
responseReceived = false;
|
||||||
|
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (cntr > 3)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Response timed out 4 times in a row, aborting. Check connection.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isAwaitingResponse = true;
|
||||||
|
Console.WriteLine("Outgoing firmware message: " + Modbus.ByteArrayToString(message.ToArray()));
|
||||||
|
port.Write(message.ToArray(), 0, message.Count);
|
||||||
|
stopwatch.Restart();
|
||||||
|
|
||||||
|
while (isAwaitingResponse)
|
||||||
|
{
|
||||||
|
if (stopwatch.ElapsedMilliseconds > 1000)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Response timed out.");
|
||||||
|
cntr++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (responseReceived)
|
||||||
|
{
|
||||||
|
if (latestMessage.Status == ModbusStatus.Error)
|
||||||
|
Console.WriteLine("Response received: Error!");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("Response received: all good;");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cntr = 0;
|
||||||
|
bytesLeft -= count;
|
||||||
|
bytesWritten += count;
|
||||||
|
firmwareProgressBar.Invoke((MethodInvoker)delegate { firmwareProgressBar.Increment((int)(bytesWritten / bytesTotal) * 100); });
|
||||||
|
|
||||||
|
_flashAddr += (short)count;
|
||||||
|
if (port.BaudRate != 9600)
|
||||||
|
firstMessageSent = true;
|
||||||
|
|
||||||
|
if (bytesLeft <= 0)
|
||||||
|
Console.WriteLine("Reached the end of firmware file.");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
MessageBox.Show(ex.Message);
|
MessageBox.Show(ex.Message, "Firmware writing error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
responseReceived = false;
|
|
||||||
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
|
|
||||||
isAwaitingResponse = true;
|
|
||||||
port.Write(message.ToArray(), 0, message.Count);
|
|
||||||
stopwatch.Restart();
|
|
||||||
|
|
||||||
while (isAwaitingResponse)
|
|
||||||
{
|
|
||||||
if (stopwatch.ElapsedMilliseconds > 1000)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Response timed out.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (responseReceived)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
bytesLeft -= count;
|
|
||||||
bytesWritten += count;
|
|
||||||
firmwareProgressBar.Increment( (int)(bytesWritten / bytesTotal) * 100 );
|
|
||||||
|
|
||||||
_flashAddr += (short)count;
|
|
||||||
if (port.BaudRate != 9600)
|
|
||||||
firstMessageSent = true;
|
|
||||||
|
|
||||||
if (bytesLeft <= 0)
|
|
||||||
Console.WriteLine("Reached the end of firmware file.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Final Message */
|
/* Final Message */
|
||||||
message = new List<byte>();
|
message = new List<byte>();
|
||||||
message.Add(modbusID); // device ID
|
message.Add(modbusID); // device ID
|
||||||
message.Add(0x10); // function code
|
message.Add(0x10); // function code
|
||||||
message.Add(0xFF); // register address
|
message.Add(0xFF); // register address
|
||||||
@@ -534,24 +547,32 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
Modbus.GetCRC(message.ToArray(), ref CRC);
|
Modbus.GetCRC(message.ToArray(), ref CRC);
|
||||||
message[message.Count - 2] = CRC[0];
|
message[message.Count - 2] = CRC[0];
|
||||||
message[message.Count - 1] = CRC[1];
|
message[message.Count - 1] = CRC[1];
|
||||||
Console.WriteLine("Outgoing firmware message: " + Modbus.ByteArrayToString(message.ToArray()));
|
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
isAwaitingResponse = true;
|
isAwaitingResponse = true;
|
||||||
|
Console.WriteLine("Outgoing firmware message: " + Modbus.ByteArrayToString(message.ToArray()));
|
||||||
port.Write(message.ToArray(), 0, message.Count);
|
port.Write(message.ToArray(), 0, message.Count);
|
||||||
stopwatch.Restart();
|
stopwatch.Restart();
|
||||||
|
|
||||||
while (isAwaitingResponse)
|
while (isAwaitingResponse)
|
||||||
{
|
{
|
||||||
if (stopwatch.ElapsedMilliseconds > 250)
|
if (stopwatch.ElapsedMilliseconds > 1000)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Response timed out.");
|
Console.WriteLine("Response timed out.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (responseReceived)
|
if (responseReceived)
|
||||||
break;
|
{
|
||||||
|
if (latestMessage.Status == ModbusStatus.Error)
|
||||||
|
Console.WriteLine("Response received: Error!");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("Response received: all good;");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
21
Main.cs
21
Main.cs
@@ -59,12 +59,6 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
System.Diagnostics.FileVersionInfo fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location);
|
System.Diagnostics.FileVersionInfo fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location);
|
||||||
string version = fvi.FileVersion;
|
string version = fvi.FileVersion;
|
||||||
Console.WriteLine("Version: " + version);
|
Console.WriteLine("Version: " + version);
|
||||||
|
|
||||||
Modbus.ResponseReceived += (sndr, msg) =>
|
|
||||||
{
|
|
||||||
latestMessage = msg;
|
|
||||||
isAwaitingResponse = false;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void App_FormClosed(object sender, FormClosedEventArgs e)
|
void App_FormClosed(object sender, FormClosedEventArgs e)
|
||||||
@@ -129,17 +123,27 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
isAwaitingResponse = true;
|
isAwaitingResponse = true;
|
||||||
var send = Modbus.ReadRegAsync((byte)upDownModbusID.Value, FunctionCode.ReadInput, 200, 6);
|
var send = Modbus.ReadRegAsync((byte)upDownModbusID.Value, FunctionCode.ReadInput, 200, 6);
|
||||||
stopwatch.Restart();
|
stopwatch.Restart();
|
||||||
|
int counter = 0;
|
||||||
while (isAwaitingResponse)
|
while (isAwaitingResponse)
|
||||||
{
|
{
|
||||||
if (stopwatch.ElapsedMilliseconds > 1000)
|
if (stopwatch.ElapsedMilliseconds > 1000)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Response timed out.");
|
AddLog("Истекло время ожидания ответа от устройства. Повторный запрос...");
|
||||||
break;
|
isAwaitingResponse = false;
|
||||||
|
counter++;
|
||||||
|
if (counter > 3)
|
||||||
|
{
|
||||||
|
AddLog("Устройство не отвечает. Проверьте соединение с устройством.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (latestMessage is null)
|
if (latestMessage is null)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Latest message is null;");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if (latestMessage.Status == ModbusStatus.Error)
|
if (latestMessage.Status == ModbusStatus.Error)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -194,6 +198,7 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
|
|
||||||
void OnResponseReceived(object sender, ModbusResponseEventArgs e)
|
void OnResponseReceived(object sender, ModbusResponseEventArgs e)
|
||||||
{
|
{
|
||||||
|
latestMessage = e;
|
||||||
isAwaitingResponse = false;
|
isAwaitingResponse = false;
|
||||||
AddLog("Получен ответ: " + Modbus.ByteArrayToString(e.Message));
|
AddLog("Получен ответ: " + Modbus.ByteArrayToString(e.Message));
|
||||||
switch (e.Status)
|
switch (e.Status)
|
||||||
|
|||||||
56
Modbus.cs
56
Modbus.cs
@@ -7,6 +7,7 @@ using System.Threading.Tasks;
|
|||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using static System.Net.Mime.MediaTypeNames;
|
using static System.Net.Mime.MediaTypeNames;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace Gidrolock_Modbus_Scanner
|
namespace Gidrolock_Modbus_Scanner
|
||||||
{
|
{
|
||||||
@@ -267,39 +268,68 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
port.DiscardInBuffer();
|
port.DiscardInBuffer();
|
||||||
}));
|
}));
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static Stopwatch stopwatch = new Stopwatch();
|
||||||
|
static byte[] buffer = new byte[255];
|
||||||
|
static int offset = 0;
|
||||||
|
static int count = 0;
|
||||||
static void PortDataReceived(object sender, EventArgs e)
|
static void PortDataReceived(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Thread.Sleep(50);
|
stopwatch.Restart();
|
||||||
byte[] message = new byte[port.BytesToRead];
|
while (stopwatch.ElapsedMilliseconds < 10)
|
||||||
//Console.WriteLine("Bytes to read:" + port.BytesToRead);
|
|
||||||
port.Read(message, 0, port.BytesToRead);
|
|
||||||
if (message.Length == 0)
|
|
||||||
return;
|
|
||||||
Console.WriteLine("Incoming message: " + ByteArrayToString(message, false));
|
|
||||||
if (!CheckResponse(message))
|
|
||||||
{
|
{
|
||||||
Console.WriteLine("Bad CRC or not a modbus message!");
|
if (port.BytesToRead > 0)
|
||||||
return;
|
{
|
||||||
|
stopwatch.Restart();
|
||||||
|
count = offset;
|
||||||
|
port.Read(buffer, offset, port.BytesToRead);
|
||||||
|
offset += count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// assume that the message ended
|
||||||
|
List <byte> message = new List <byte>();
|
||||||
|
int endOfMessage = buffer.Length - 1;
|
||||||
|
for (int i = buffer.Length-1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (buffer[i] != 0x00)
|
||||||
|
{
|
||||||
|
endOfMessage = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < endOfMessage + 1; i++)
|
||||||
|
{
|
||||||
|
message.Add(buffer[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (message.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Console.WriteLine("Incoming message: " + ByteArrayToString(message.ToArray(), false));
|
||||||
|
/*
|
||||||
|
if (!CheckResponse(message.ToArray()))
|
||||||
|
{
|
||||||
|
Console.WriteLine("Bad CRC or not a modbus message!");
|
||||||
|
}
|
||||||
|
*/
|
||||||
if (message[1] <= 0x04) // read functions
|
if (message[1] <= 0x04) // read functions
|
||||||
{
|
{
|
||||||
//Console.WriteLine("It's a read message");
|
//Console.WriteLine("It's a read message");
|
||||||
ResponseReceived.Invoke(null, new ModbusResponseEventArgs(message, ModbusStatus.ReadSuccess));
|
ResponseReceived.Invoke(null, new ModbusResponseEventArgs(message.ToArray(), ModbusStatus.ReadSuccess));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (message[1] <= 0x10) // write functions
|
if (message[1] <= 0x10) // write functions
|
||||||
{
|
{
|
||||||
//Console.WriteLine("It's a write message");
|
//Console.WriteLine("It's a write message");
|
||||||
ResponseReceived.Invoke(null, new ModbusResponseEventArgs(message, ModbusStatus.WriteSuccess));
|
ResponseReceived.Invoke(null, new ModbusResponseEventArgs(message.ToArray(), ModbusStatus.WriteSuccess));
|
||||||
}
|
}
|
||||||
else // error codes
|
else // error codes
|
||||||
{
|
{
|
||||||
//Console.WriteLine("It's an error");
|
//Console.WriteLine("It's an error");
|
||||||
ResponseReceived.Invoke(null, new ModbusResponseEventArgs(message, ModbusStatus.Error));
|
ResponseReceived.Invoke(null, new ModbusResponseEventArgs(message.ToArray(), ModbusStatus.Error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user