Files
gidrolock-configurator/Datasheet.cs

161 lines
6.1 KiB
C#
Raw Normal View History

2024-12-05 15:57:07 +03:00
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
2024-12-05 15:57:07 +03:00
using System.Linq;
2024-12-09 16:24:02 +03:00
using System.Net;
using System.Runtime.Remoting.Messaging;
2024-12-05 15:57:07 +03:00
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Gidrolock_Modbus_Scanner
{
public partial class Datasheet : Form
{
2024-12-09 16:24:02 +03:00
bool isAwaitingResponse = false;
bool isProcessingResponse = false;
byte[] message = new byte[255];
int timeout = 3000;
2024-12-05 15:57:07 +03:00
int pollDelay = 250; // delay between each entry poll, ms
byte slaveID;
2024-12-05 17:52:25 +03:00
Device device = App.device;
List<Entry> entries;
2024-12-09 16:24:02 +03:00
int activeEntryIndex; // entry index for modbus responses
SerialPort port = Modbus.port;
2024-12-09 16:24:02 +03:00
bool closed = false;
public Datasheet(byte slaveID)
2024-12-05 15:57:07 +03:00
{
Modbus.ResponseReceived += PublishResponse;
this.slaveID = slaveID;
entries = device.entries;
2024-12-05 17:52:25 +03:00
InitializeComponent();
2024-12-05 15:57:07 +03:00
DGV_Device.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
DGV_Device.MultiSelect = false;
DGV_Device.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders;
DGV_Device.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
2024-12-05 17:52:25 +03:00
DGV_Device.Columns.Add("#", "#");
DGV_Device.Columns[0].FillWeight = 20;
DGV_Device.Columns.Add("Name", "Имя");
DGV_Device.Columns[1].FillWeight = 40;
DGV_Device.Columns.Add("Value", "Значение");
DGV_Device.Columns[2].FillWeight = 60;
DGV_Device.Columns.Add("Address", "Адрес");
DGV_Device.Columns[3].FillWeight = 30;
DGV_Device.Columns.Add(new DataGridViewCheckBoxColumn());
DGV_Device.Columns[4].Name = "Опрос";
DGV_Device.Columns[4].FillWeight = 20;
2024-12-05 17:52:25 +03:00
2024-12-09 16:24:02 +03:00
for (int i = 0; i < entries.Count; i++)
2024-12-05 17:52:25 +03:00
{
DGV_Device.Rows.Add(i.ToString(), entries[i].name, "", entries[i].address);
2024-12-09 16:24:02 +03:00
DGV_Device.Rows[i].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
}
2024-12-09 16:24:02 +03:00
FormClosing += (s, e) => { closed = true; };
Task.Run(() => AutoPollAsync());
}
2024-12-05 17:52:25 +03:00
2024-12-09 16:24:02 +03:00
public async void AutoPollAsync()
{
2024-12-09 16:24:02 +03:00
if (!port.IsOpen)
port.Open();
port.ReadTimeout = timeout;
try
{
2024-12-09 16:24:02 +03:00
while (!closed)
{
2024-12-09 16:24:02 +03:00
for (int i = 0; i < entries.Count; i++)
{
2024-12-09 16:24:02 +03:00
activeEntryIndex = i;
await PollForEntry(entries[i]);
}
}
}
2024-12-09 16:24:02 +03:00
catch (Exception err)
{
MessageBox.Show(err.Message);
}
}
2024-12-09 16:24:02 +03:00
public async Task PollForEntry(Entry entry)
{
2024-12-09 17:58:37 +03:00
byte[] message = new byte[9];
2024-12-09 16:24:02 +03:00
Console.WriteLine("Sending message: " + Modbus.ByteArrayToString(Modbus.BuildMessage(slaveID, (byte)entry.registerType, entry.address, entry.length, ref message)));
var send = await Modbus.ReadRegAsync(port, slaveID, (FunctionCode)entry.registerType, entry.address, entry.length);
isAwaitingResponse = true;
2024-12-09 16:24:02 +03:00
Task delay = Task.Delay(timeout).ContinueWith((t) =>
{
2024-12-09 16:24:02 +03:00
if (isAwaitingResponse)
{
2024-12-09 16:24:02 +03:00
Console.WriteLine("Response timed out.");
isAwaitingResponse = false;
}
});
await delay;
}
void PublishResponse(object sender, ModbusResponseEventArgs e)
2024-12-09 16:24:02 +03:00
{
if (isAwaitingResponse)
{
isAwaitingResponse = false;
try
{
byte length = e.message[2];
Console.WriteLine("Data length is:" + length);
byte[] data = new byte[length];
for (int i = 0; i < length; i++)
data[i] = e.message[i + 3];
Console.WriteLine("Data after processing in Datasheet.cs: " + Modbus.ByteArrayToString(data));
switch (entries[activeEntryIndex].dataType)
2024-12-09 16:24:02 +03:00
{
case ("bool"):
DGV_Device.Rows[activeEntryIndex].Cells[2].Value = data[0] > 0x00 ? "true" : "false";
break;
case ("uint16"):
Array.Reverse(data); // BitConverter.ToUInt is is little endian, I guess, so we need to flip the array
ushort test = BitConverter.ToUInt16(data, 0);
Console.WriteLine("ushort parsed value: " + test);
DGV_Device.Rows[activeEntryIndex].Cells[2].Value = test;
break;
case ("uint32"):
Array.Reverse(data);
DGV_Device.Rows[activeEntryIndex].Cells[2].Value = BitConverter.ToUInt32(data, 0);
break;
case ("utf8"):
DGV_Device.Rows[activeEntryIndex].Cells[2].Value = System.Text.Encoding.UTF8.GetString(data);
break;
default:
MessageBox.Show("Wrong data type set for entry " + entries[activeEntryIndex].name);
break;
}
//MessageBox.Show("Получен ответ от устройства: " + dataCleaned, "Успех", MessageBoxButtons.OK);
port.DiscardInBuffer();
}
catch (Exception err)
{
//MessageBox.Show(err.Message, "Event Error");
}
2024-12-05 17:52:25 +03:00
}
2024-12-05 15:57:07 +03:00
}
}
2024-12-09 16:24:02 +03:00
}