added writing from single registers

This commit is contained in:
nikzori
2024-12-17 16:36:42 +03:00
parent eaeff51767
commit ab5c06df5e
2 changed files with 95 additions and 47 deletions

63
Main.cs
View File

@@ -182,7 +182,7 @@ namespace Gidrolock_Modbus_Scanner
{ {
try try
{ {
var send = await Modbus.ReadRegAsync(port, (byte)UpDown_ModbusID.Value, functionCode, address, length); await Modbus.ReadRegAsync(port, (byte)UpDown_ModbusID.Value, functionCode, address, length);
isAwaitingResponse = true; isAwaitingResponse = true;
await Task.Delay(port.ReadTimeout).ContinueWith(_ => await Task.Delay(port.ReadTimeout).ContinueWith(_ =>
{ {
@@ -431,7 +431,7 @@ namespace Gidrolock_Modbus_Scanner
int portParsed = Int32.Parse(portText); int portParsed = Int32.Parse(portText);
await socket.ConnectAsync(ipText, portParsed); await socket.ConnectAsync(ipText, portParsed);
byte[] data = new byte[8]; byte[] data = new byte[8];
Modbus.BuildMessage(0x1E, 0x03, 128, 1, ref data); Modbus.BuildReadMessage(0x1E, 0x03, 128, 1, ref data);
AddLog("Sending to " + ipText + ":" + portText + ":" + Modbus.ByteArrayToString(data)); AddLog("Sending to " + ipText + ":" + portText + ":" + Modbus.ByteArrayToString(data));
// set up an event listener to receive the response // set up an event listener to receive the response
@@ -475,55 +475,44 @@ namespace Gidrolock_Modbus_Scanner
{ {
case (FunctionCode.WriteCoil): case (FunctionCode.WriteCoil):
if (valueLower == "true" || valueLower == "1") if (valueLower == "true" || valueLower == "1")
await Modbus.WriteSingle(port, (FunctionCode)functionCode, (byte)UpDown_ModbusID.Value, (ushort)address, 0xFF_00); await Modbus.WriteSingleAsync(port, (FunctionCode)functionCode, (byte)UpDown_ModbusID.Value, (ushort)address, 0xFF_00);
else if (valueLower == "false" || valueLower == "0") else if (valueLower == "false" || valueLower == "0")
await Modbus.WriteSingle(port, (FunctionCode)functionCode, (byte)UpDown_ModbusID.Value, (ushort)address, 0x00_00); await Modbus.WriteSingleAsync(port, (FunctionCode)functionCode, (byte)UpDown_ModbusID.Value, (ushort)address, 0x00_00);
else MessageBox.Show("Неподходящие значения для регистра типа Coil"); else MessageBox.Show("Неподходящие значения для регистра типа Coil");
break; break;
case (FunctionCode.WriteRegister): case (FunctionCode.WriteRegister):
short value; short value = 0x00_00;
bool canWrite = false;
if (IsHex(valueLower)) //assume this is hex if (IsHex(valueLower)) //assume this is hex
{ {
try try { value = Convert.ToInt16(valueLower, 16); canWrite = true; }
{
value = Convert.ToInt16(valueLower, 16);
await Modbus.WriteSingle(port, (FunctionCode)functionCode, (byte)UpDown_ModbusID.Value, (ushort)address,
(ushort)value);
}
catch (Exception err) { MessageBox.Show(err.Message); } catch (Exception err) { MessageBox.Show(err.Message); }
break; break;
} }
else if (IsDec(valueLower)) else if (IsDec(valueLower))
{ {
try try { value = Convert.ToInt16(valueLower); canWrite = true; }
catch (Exception err) { MessageBox.Show(err.Message); }
break;
}
else if (valueLower == "true" || valueLower == "1")
{ {
value = Convert.ToInt16(valueLower); value = 0x00_01;
await Modbus.WriteSingle(port, (FunctionCode)functionCode, (byte)UpDown_ModbusID.Value, (ushort)address, canWrite = true;
}
else if (valueLower == "false" || valueLower == "0")
{
canWrite = true;
}
if (canWrite)
{
byte[] _value = BitConverter.GetBytes(value);
Array.Reverse( _value );
AddLog("Отправка сообщения: " + Modbus.ByteArrayToString(Modbus.BuildWriteSingleMessage((byte)UpDown_ModbusID.Value, (byte)functionCode, (ushort)address, _value)));
await Modbus.WriteSingleAsync(port, (FunctionCode)functionCode, (byte)UpDown_ModbusID.Value, (ushort)address,
(ushort)value); (ushort)value);
} }
catch (Exception err) { MessageBox.Show(err.Message); } else MessageBox.Show("Неподходящие значения для регистра типа Input Register");
break;
}
else if (valueLower == "true")
{
try
{
await Modbus.WriteSingle(port, (FunctionCode)functionCode, (byte)UpDown_ModbusID.Value, (ushort)address,
0x01);
}
catch (Exception err) { MessageBox.Show(err.Message); }
break;
}
else if (valueLower == "false")
{
try
{
await Modbus.WriteSingle(port, (FunctionCode)functionCode, (byte)UpDown_ModbusID.Value, (ushort)address,
0x00);
}
catch (Exception err) { MessageBox.Show(err.Message); }
break;
}
break; break;
default: default:
break; break;

View File

@@ -20,7 +20,7 @@ namespace Gidrolock_Modbus_Scanner
} }
#region Build Message #region Build Message
public static byte[] BuildMessage(byte modbusID, byte functionCode, ushort address, ushort length, ref byte[] message) public static byte[] BuildReadMessage(byte modbusID, byte functionCode, ushort address, ushort length, ref byte[] message)
{ {
//Array to receive CRC bytes: //Array to receive CRC bytes:
byte[] CRC = new byte[2]; byte[] CRC = new byte[2];
@@ -39,6 +39,26 @@ namespace Gidrolock_Modbus_Scanner
//Console.WriteLine("Message: " + msg); //Console.WriteLine("Message: " + msg);
return message; return message;
} }
public static byte[] BuildWriteSingleMessage(byte modbusID, byte functionCode, ushort address, byte[] data)
{
if (functionCode == 0x05 || functionCode == 0x06)
{
byte[] _message = new byte[8];
byte[] CRC = new byte[2];
_message[0] = modbusID;
_message[1] = functionCode;
_message[2] = (byte)(address >> 8);
_message[3] = (byte)address;
_message[4] = data[0];
_message[5] = data[1];
GetCRC(_message, ref CRC);
_message[6] = CRC[0];
_message[7] = CRC[1];
return _message;
}
else return new byte[1] { 0xFF };
}
#endregion #endregion
#region Read Functions #region Read Functions
@@ -55,7 +75,7 @@ namespace Gidrolock_Modbus_Scanner
byte[] message = new byte[8]; byte[] message = new byte[8];
//Build outgoing modbus message: //Build outgoing modbus message:
BuildMessage(slaveID, (byte)functionCode, address, length, ref message); BuildReadMessage(slaveID, (byte)functionCode, address, length, ref message);
//Send modbus message to Serial Port: //Send modbus message to Serial Port:
try try
@@ -65,7 +85,7 @@ namespace Gidrolock_Modbus_Scanner
} }
catch (Exception err) catch (Exception err)
{ {
MessageBox.Show(err.Message); MessageBox.Show(err.Message, "aeiou");
port.Close(); port.Close();
return false; return false;
} }
@@ -80,8 +100,43 @@ namespace Gidrolock_Modbus_Scanner
#endregion #endregion
#region Write Single Coil/Register #region Write Single Coil/Register
public static async Task<bool> WriteSingle(SerialPort port, FunctionCode functionCode, byte slaveID, ushort address, uint value) public static async Task<bool> WriteSingleAsync(SerialPort port, FunctionCode functionCode, byte slaveID, ushort address, ushort value)
{ {
//Ensure port is open:
if (!port.IsOpen)
{
try
{
port.Open();
}
catch (Exception err)
{
MessageBox.Show(err.Message);
return false;
}
}
//Clear in/out buffers:
port.DiscardOutBuffer();
port.DiscardInBuffer();
//Build outgoing modbus message:
byte[] _value = BitConverter.GetBytes(value);
Array.Reverse(_value);
byte[] message = BuildWriteSingleMessage(slaveID, (byte)functionCode, address, _value);
//Send modbus message to Serial Port:
try
{
port.Write(message, 0, message.Length);
return true;
}
catch (Exception err)
{
MessageBox.Show(err.Message);
port.Close();
return false;
}
} }
#endregion #endregion
@@ -107,9 +162,13 @@ namespace Gidrolock_Modbus_Scanner
} }
public static string ByteArrayToString(byte[] bytes) public static string ByteArrayToString(byte[] bytes, bool cleanEmpty = true)
{ {
byte[] res = CleanByteArray(bytes); byte[] res;
if (cleanEmpty)
res = CleanByteArray(bytes);
else res = bytes;
string dataString = BitConverter.ToString(res); string dataString = BitConverter.ToString(res);
string result = ""; string result = "";