private void ProcessRegisterGroup(IModbusClient client, Register register) { var dumpRepository = _unitOfWork.DumpsRepository; switch (register.Type) { case RegisterType.Coil: dumpRepository.AddRegisterResult(register, client.ReadCoils(register.Offset, register.Count)); break; case RegisterType.DiscreteInput: dumpRepository.AddRegisterResult(register, client.ReadInputRegisters(register.Offset, register.Count)); break; case RegisterType.HoldingRegister: dumpRepository.AddRegisterResult(register, client.ReadHoldingRegisters(register.Offset, register.Count)); break; case RegisterType.Input: dumpRepository.AddRegisterResult(register, client.ReadInputs(register.Offset, register.Count)); break; } //_logger.LogInformation("{date} - Register {num} processed", DateTimeOffset.Now, register.Id); }
/// <summary> /// Helper function reading discrete inputs. /// </summary> /// <param name="console"></param> /// <param name="client"></param> /// <param name="slave"></param> /// <param name="number"></param> /// <param name="offset"></param> /// <param name="header"></param> public static void ReadingDiscreteInputs(IConsole console, IModbusClient client, byte slave, ushort number, ushort offset, bool header = true) { if (number == 1) { if (header) { console.Out.WriteLine($"Reading a single discrete input[{offset}]"); } bool[] values = client.ReadCoils(slave, offset, number); console.Out.WriteLine($"Value of discrete input[{offset}] = {values[0]}"); } else { if (header) { console.Out.WriteLine($"Reading {number} discrete inputs starting at {offset}"); } bool[] values = client.ReadCoils(slave, offset, number); for (int index = 0; index < values.Length; ++index) { console.Out.WriteLine($"Value of discrete input[{offset + index}] = {values[index]}"); } } }
/// <summary> /// Helper function writing coils. /// </summary> /// <param name="console"></param> /// <param name="client"></param> /// <param name="slave"></param> /// <param name="offset"></param> /// <param name="data"></param> public static void WritingCoils(IConsole console, IModbusClient client, byte slave, ushort offset, string data) { // Writing datas. if (!string.IsNullOrEmpty(data)) { List <bool>?values = JsonSerializer.Deserialize <List <bool> >(data); if (!(values is null)) { if (values.Count == 1) { console.Out.WriteLine($"Write single coil[{offset}] = {values[0]}"); client.WriteSingleCoil(slave, offset, values[0]); } else { console.Out.WriteLine($"Writing {values.Count} coils starting at {offset}"); for (int index = 0; index < values.Count; ++index) { console.Out.WriteLine($"Value of coil[{offset + index}] = {values[index]}"); } client.WriteMultipleCoils(slave, offset, values.ToArray()); } } } }
private void but_open_Click(object sender, EventArgs e) { try { if (txt_content.Text.Contains("小技巧")) { txt_content.Text = string.Empty; } client?.Close(); EndianFormat format = EndianFormat.ABCD; switch (comboBox1.SelectedIndex) { case 0: format = EndianFormat.ABCD; break; case 1: format = EndianFormat.BADC; break; case 2: format = EndianFormat.CDAB; break; case 3: format = EndianFormat.DCBA; break; } if (chb_rtudata.Checked) { client = new ModbusTcpRtuClient(txt_ip.Text?.Trim(), int.Parse(txt_port.Text?.Trim()), format: format); } else { client = new ModbusTcpClient(txt_ip.Text?.Trim(), int.Parse(txt_port.Text?.Trim()), format: format); } var result = client.Open(); if (result.IsSucceed) { but_read.Enabled = true; but_write.Enabled = true; but_open.Enabled = false; but_close.Enabled = true; but_sendData.Enabled = true; AppendText($"连接成功"); ControlEnabledFalse(); } else { MessageBox.Show($"连接失败:{result.Err}"); } } catch (Exception ex) { MessageBox.Show(ex.Message); } }
/// <summary> /// 自动扫描可连接串口属性 /// </summary> /// <returns></returns> private void AutoOpenRead() { #region 当前选择的配置有效匹配 FirstItem(ref BaudRateList, int.Parse(cb_baudRate.Text.ToString())); FirstItem(ref DataBitList, int.Parse(txt_dataBit.Text.ToString())); FirstItem(ref StopBitsList, (StopBits)int.Parse(txt_stopBit.Text.ToString())); var firstParity = cb_parity.SelectedIndex == 0 ? Parity.None : (cb_parity.SelectedIndex == 1 ? Parity.Odd : Parity.Even); FirstItem(ref ParityList, firstParity); #endregion byte.TryParse(txt_stationNumber.Text?.Trim(), out byte stationNumber); if (!client.ReadInt16("0", stationNumber).IsSucceed) { foreach (var baudRate in BaudRateList) { foreach (var dataBit in DataBitList) { foreach (var stopBits in StopBitsList) { foreach (var parity in ParityList) { for (byte i = 0; i < 255; i++) { stationNumber = (byte)(i + 1); if (but_open.Enabled) { return; } client?.Close(); client = new ModbusRtuClient(cb_portNameSend.Text.ToString(), baudRate, dataBit, stopBits, parity); var result = client.Open(); if (result.IsSucceed) { if (client.ReadInt16("0", stationNumber).IsSucceed) { AppendText($@"连接【成功】 端口:{cb_portNameSend.Text.ToString()} 波特率:{baudRate} 数据位:{dataBit} 停止位:{stopBits} 奇偶:{parity} 站号:{stationNumber}"); return; } else { AppendText($@"连接失败 端口:{cb_portNameSend.Text.ToString()} 波特率:{baudRate} 数据位:{dataBit} 停止位:{stopBits} 奇偶:{parity} 站号:{stationNumber}"); } } else { AppendText($"连接异常 端口:{cb_portNameSend.Text.ToString()} 波特率:{baudRate} 数据位:{dataBit} 停止位:{stopBits} 奇偶:{parity} 站号:{stationNumber} Err:{result.Err}"); } } } } } } } else { AppendText($@"连接【成功】 端口:{cb_portNameSend.Text} 波特率:{cb_baudRate.Text} 数据位:{txt_dataBit.Text} 停止位:{txt_stopBit.Text} 奇偶:{cb_parity.Text} 站号:{stationNumber}"); } }
static void Main(string[] args) { IModbusClient modbusClient = null; ConsoleKeyInfo keyInfo = new ConsoleKeyInfo(); Console.WriteLine("Voulez vous utiliser une liaison série ou TCP ? s/t"); do { try { keyInfo = Console.ReadKey(); Console.WriteLine(); switch (keyInfo.KeyChar) { case 's': modbusClient = CreerMaitreModbusSerie(); break; case 't': modbusClient = CreerClientModbusOnTcp(); break; default: Console.WriteLine("Appuyez sur la touche s ou la touche t"); break; } } catch (Exception e) { Console.Write(e.Message); while ((e = e.InnerException) != null) { Console.Write(" / " + e.Message); } Console.WriteLine(); Console.WriteLine("Appuyez sur une touche pour terminer l'application."); Console.ReadKey(); return; } } while ((keyInfo.KeyChar != 's') && (keyInfo.KeyChar != 't')); // Boucle principale, s'arrête si une trame vide est entrée while (true) { // Saisie de la requète en hexadécimal (sans CRC ou MBAP) Console.Write("Entrez les valeurs hexa : "); string chaine = Console.ReadLine(); if (chaine == "") { break; } Communiquer(modbusClient, chaine); } }
/// <summary> /// 打开连接 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void but_open_Click(object sender, EventArgs e) { try { if (txt_content.Text.Contains("小技巧")) { txt_content.Text = string.Empty; } var PortName = cb_portNameSend.Text.ToString(); var BaudRate = int.Parse(cb_baudRate.Text.ToString()); var DataBits = int.Parse(txt_dataBit.Text.ToString()); var StopBits = (StopBits)int.Parse(txt_stopBit.Text.ToString()); var parity = cb_parity.SelectedIndex == 0 ? Parity.None : (cb_parity.SelectedIndex == 1 ? Parity.Odd : Parity.Even); client?.Close(); client = new ModbusRtuClient(PortName, BaudRate, DataBits, StopBits, parity); var result = client.Open(); if (result.IsSucceed) { but_open.Enabled = false; cb_portNameSend.Enabled = false; but_read.Enabled = true; but_write.Enabled = true; but_open.Enabled = false; but_close.Enabled = true; but_sendData.Enabled = true; //按了Ctrl后的鼠标点击 if ((ModifierKeys & Keys.Control) == Keys.Control) { Task.Run(() => { AutoOpenRead(); }); } else { AppendText("连接成功"); } } else { AppendText($"连接失败:{result.Err}"); } } catch (Exception ex) { MessageBox.Show(ex.Message); } }
private void ProcessChannel(Channel channel) { IModbusClient client = GetModbusClient(channel); // exception(?) channel.Devices.ToList().ForEach(device => { try { ProcessDevice(client, device); } catch (Exception e) { _unitOfWork.DumpsRepository.AddEmptyDeviceResult(device); _logger.LogError("{date} - Device {num} error: {exception}", DateTimeOffset.Now, device.Id, e.Message); } }); }
private void ProcessDevice(IModbusClient client, Device device) { client.SetSlave(device); client.Connect(); // exception: device connection device.Registers.ToList().ForEach(register => { try { ProcessRegisterGroup(client, register); // exception: connection gone away(?), exception: wrong registers data } catch (Exception e) { _unitOfWork.DumpsRepository.AddEmptyRegisterResult(register); _logger.LogError("{date} - Register group {num} error: {exception}", DateTimeOffset.Now, register.Id, e.Message); } //_logger.LogInformation("{date} - Device {num} processed", DateTimeOffset.Now, device.Id); }); client.Disconnect(); }
private void but_open_Click(object sender, EventArgs e) { try { if (txt_content.Text.Contains("小技巧")) { txt_content.Text = string.Empty; } client?.Close(); if (chb_rtudata.Checked) { client = new ModbusTcpRtuClient(txt_ip.Text?.Trim(), int.Parse(txt_port.Text?.Trim())); } else { client = new ModbusTcpClient(txt_ip.Text?.Trim(), int.Parse(txt_port.Text?.Trim())); } var result = client.Open(); if (result.IsSucceed) { but_read.Enabled = true; but_write.Enabled = true; but_open.Enabled = false; but_close.Enabled = true; but_sendData.Enabled = true; AppendText($"连接成功"); } else { MessageBox.Show($"连接失败:{result.Err}"); } } catch (Exception ex) { MessageBox.Show(ex.Message); } }
private static void Communiquer(IModbusClient modbusClient, string chaine) { try { modbusClient.EnvoyerRequete(chaine); while (!modbusClient.ReceptionFinie()) { } } catch (ModbusException e) { Console.WriteLine("Erreur Modbus : " + e.Message); if (e.InnerException != null) { Console.WriteLine("Cause : " + e.InnerException.Message); } } catch (FormatException e) { Console.WriteLine("Erreur de formatage d'une chaine de caractère : " + e.Message); } finally { // Affichage de la trame envoyée Console.WriteLine("Requête : " + modbusClient.LireRequete()); string reponse = null; if ((reponse = modbusClient.LireReponse()) != null) { // Affichage de la réponse reçue Console.WriteLine("Réponse : " + reponse); } else { Console.WriteLine("Pas de réponse."); } } }
/// <summary> /// Helper function reading input registers. /// </summary> /// <param name="console"></param> /// <param name="client"></param> /// <param name="slave"></param> /// <param name="number"></param> /// <param name="offset"></param> /// <param name="type"></param> /// <param name="hex"></param> /// <param name="header"></param> public static void ReadingInputRegisters(IConsole console, IModbusClient client, byte slave, ushort number, ushort offset, string type, bool hex, bool header = true) { if (!string.IsNullOrEmpty(type)) { switch (type.ToLowerInvariant()) { case "string": { if (hex) { if (header) { console.Out.WriteLine($"Reading a HEX string from offset = {offset}"); } string value = client.ReadOnlyHexString(slave, offset, number); console.Out.WriteLine($"Value of HEX string = {value}"); } else { if (header) { console.Out.WriteLine($"Reading an ASCII string from offset = {offset}"); } string value = client.ReadOnlyString(slave, offset, number); console.Out.WriteLine($"Value of ASCII string = {value}"); } break; } case "bits": { if (header) { console.Out.WriteLine($"Reading a 16 bit array from offset = {offset}"); } BitArray value = client.ReadOnlyBits(slave, offset); console.Out.WriteLine($"Value of 16 bit array = {value.ToDigitString()}"); break; } case "byte": { if (number == 1) { if (header) { console.Out.WriteLine($"Reading a single byte from offset = {offset}"); } byte[] values = client.ReadOnlyBytes(slave, offset, number); console.Out.WriteLine($"Value of single byte = {values[0]}"); } else { if (header) { console.Out.WriteLine($"Reading {number} bytes from offset = {offset}"); } byte[] values = client.ReadOnlyBytes(slave, offset, number); for (int index = 0; index < values.Length; ++index) { console.Out.WriteLine($"Value of byte array[{index}] = {values[index]}"); } } break; } case "short": { if (number == 1) { if (header) { console.Out.WriteLine($"Reading a single short from offset = {offset}"); } short value = client.ReadOnlyShort(slave, offset); console.Out.WriteLine($"Value of single short = {value}"); } else { if (header) { console.Out.WriteLine($"Reading {number} short values from offset = {offset}"); } short[] values = client.ReadOnlyShortArray(slave, offset, number); for (int index = 0; index < values.Length; ++index) { console.Out.WriteLine($"Value of short array[{index}] = {values[index]}"); } } break; } case "ushort": { if (number == 1) { if (header) { console.Out.WriteLine($"Reading a single ushort from offset = {offset}"); } ushort value = client.ReadOnlyUShort(slave, offset); console.Out.WriteLine($"Value of single ushort = {value}"); } else { if (header) { console.Out.WriteLine($"Reading {number} ushort values from offset = {offset}"); } ushort[] values = client.ReadOnlyUShortArray(slave, offset, number); for (int index = 0; index < values.Length; ++index) { console.Out.WriteLine($"Value of ushort array[{index}] = {values[index]}"); } } break; } case "int": { if (number == 1) { if (header) { console.Out.WriteLine($"Reading a single int from offset = {offset}"); } int value = client.ReadOnlyInt32(slave, offset); console.Out.WriteLine($"Value of single integer = {value}"); } else { if (header) { console.Out.WriteLine($"Reading {number} int values from offset = {offset}"); } int[] values = client.ReadOnlyInt32Array(slave, offset, number); for (int index = 0; index < values.Length; ++index) { console.Out.WriteLine($"Value of int array[{index}] = {values[index]}"); } } break; } case "uint": { if (number == 1) { if (header) { console.Out.WriteLine($"Reading a single unsigned int from offset = {offset}"); } uint value = client.ReadOnlyUInt32(slave, offset); console.Out.WriteLine($"Value of single unsigned int = {value}"); } else { if (header) { console.Out.WriteLine($"Reading {number} unsigned int values from offset = {offset}"); } uint[] values = client.ReadOnlyUInt32Array(slave, offset, number); for (int index = 0; index < values.Length; ++index) { console.Out.WriteLine($"Value of unsigned int array[{index}] = {values[index]}"); } } break; } case "float": { if (number == 1) { if (header) { console.Out.WriteLine($"Reading a single float from offset = {offset}"); } float value = client.ReadOnlyFloat(slave, offset); console.Out.WriteLine($"Value of single float = {value}"); } else { if (header) { console.Out.WriteLine($"Reading {number} float values from offset = {offset}"); } float[] values = client.ReadOnlyFloatArray(slave, offset, number); for (int index = 0; index < values.Length; ++index) { console.Out.WriteLine($"Value of float array[{index}] = {values[index]}"); } } break; } case "double": { if (number == 1) { if (header) { console.Out.WriteLine($"Reading a single double from offset = {offset}"); } double value = client.ReadOnlyDouble(slave, offset); console.Out.WriteLine($"Value of single double = {value}"); } else { if (header) { console.Out.WriteLine($"Reading {number} double values from offset = {offset}"); } double[] values = client.ReadOnlyDoubleArray(slave, offset, number); for (int index = 0; index < values.Length; ++index) { console.Out.WriteLine($"Value of double array[{index}] = {values[index]}"); } } break; } case "long": { if (number == 1) { if (header) { console.Out.WriteLine($"Reading a single long from offset = {offset}"); } long value = client.ReadOnlyLong(slave, offset); console.Out.WriteLine($"Value of single long = {value}"); } else { if (header) { console.Out.WriteLine($"Reading {number} long values from offset = {offset}"); } long[] values = client.ReadOnlyLongArray(slave, offset, number); for (int index = 0; index < values.Length; ++index) { console.Out.WriteLine($"Value of long array[{index}] = {values[index]}"); } } break; } case "ulong": { if (number == 1) { if (header) { console.Out.WriteLine($"Reading a single unsigned long from offset = {offset}"); } ulong value = client.ReadOnlyULong(slave, offset); console.Out.WriteLine($"Value of single ulong = {value}"); } else { if (header) { console.Out.WriteLine($"Reading {number} unsigned long values from offset = {offset}"); } ulong[] values = client.ReadOnlyULongArray(slave, offset, number); for (int index = 0; index < values.Length; ++index) { console.Out.WriteLine($"Value of ulong array[{index}] = {values[index]}"); } } break; } } } else { if (number == 1) { if (header) { console.Out.WriteLine($"Reading a input register[{offset}]"); } ushort[] values = client.ReadInputRegisters(slave, offset, number); if (hex) { console.Out.WriteLine($"Value of input register[{offset}] = {values[0]:X2}"); } else { console.Out.WriteLine($"Value of input register[{offset}] = {values[0]}"); } } else { if (header) { console.Out.WriteLine($"Reading {number} input registers starting at {offset}"); } ushort[] values = client.ReadInputRegisters(slave, offset, number); for (int index = 0; index < values.Length; ++index) { if (hex) { console.Out.WriteLine($"Value of input register[{offset + index}] = {values[index]:X2}"); } else { console.Out.WriteLine($"Value of input register[{offset + index}] = {values[index]}"); } } } } }
private static async Task <int> RunClientAsync(ILogger logger, CancellationToken cancellationToken) { Console.Write("Connection Type [1] TCP, [2] RS485: "); int cType = Convert.ToInt32(Console.ReadLine().Trim()); IModbusClient client = null; try { switch (cType) { case 1: { Console.Write("Hostname: "); string host = Console.ReadLine().Trim(); Console.Write("Port: "); int port = Convert.ToInt32(Console.ReadLine().Trim()); client = new TcpClient(host, port, logger); } break; case 2: { Console.Write("Interface: "); string port = Console.ReadLine().Trim(); Console.Write("Baud: "); int baud = Convert.ToInt32(Console.ReadLine().Trim()); Console.Write("Stop-Bits [0|1|2|3=1.5]: "); int stopBits = Convert.ToInt32(Console.ReadLine().Trim()); Console.Write("Parity [0] None [1] Odd [2] Even [3] Mark [4] Space: "); int parity = Convert.ToInt32(Console.ReadLine().Trim()); Console.Write("Handshake [0] None [1] X-On/Off [2] RTS [3] RTS+X-On/Off: "); int handshake = Convert.ToInt32(Console.ReadLine().Trim()); Console.Write("Timeout (ms): "); int timeout = Convert.ToInt32(Console.ReadLine().Trim()); Console.Write("Set Driver to RS485 [0] No [1] Yes: "); int setDriver = Convert.ToInt32(Console.ReadLine().Trim()); client = new SerialClient(port) { BaudRate = (BaudRate)baud, DataBits = 8, StopBits = (StopBits)stopBits, Parity = (Parity)parity, Handshake = (Handshake)handshake, SendTimeout = TimeSpan.FromMilliseconds(timeout), ReceiveTimeout = TimeSpan.FromMilliseconds(timeout) }; if (setDriver == 1) { ((SerialClient)client).DriverEnableRS485 = true; } } break; default: Console.Error.WriteLine($"Unknown type: {cType}"); return(1); } await Task.WhenAny(client.Connect(), Task.Delay(Timeout.Infinite, cancellationToken)); if (cancellationToken.IsCancellationRequested) { return(0); } while (!cancellationToken.IsCancellationRequested) { Console.Write("Device ID: "); byte id = Convert.ToByte(Console.ReadLine().Trim()); Console.Write("Function [1] Read Register, [2] Device Info, [9] Write Register : "); int fn = Convert.ToInt32(Console.ReadLine().Trim()); switch (fn) { case 1: { ushort address = 0; ushort count = 0; string type = ""; Console.WriteLine(); Console.Write("Address : "); address = Convert.ToUInt16(Console.ReadLine().Trim()); Console.Write("DataType: "); type = Console.ReadLine().Trim(); if (type == "string") { Console.Write("Register Count: "); count = Convert.ToUInt16(Console.ReadLine().Trim()); } Console.WriteLine(); Console.Write("Run as loop? [y/N]: "); string loop = Console.ReadLine().Trim().ToLower(); int interval = 0; if (yesList.Contains(loop)) { Console.Write("Loop interval (milliseconds): "); interval = Convert.ToInt32(Console.ReadLine().Trim()); } Console.WriteLine(); do { try { Console.Write("Result : "); List <Register> result = null; switch (type.Trim().ToLower()) { case "byte": result = await client.ReadHoldingRegisters(id, address, 1); Console.WriteLine(result?.First().GetByte()); break; case "ushort": result = await client.ReadHoldingRegisters(id, address, 1); Console.WriteLine(result?.First().GetUInt16()); break; case "uint": result = await client.ReadHoldingRegisters(id, address, 2); Console.WriteLine(result?.GetUInt32()); break; case "ulong": result = await client.ReadHoldingRegisters(id, address, 4); Console.WriteLine(result?.GetUInt64()); break; case "sbyte": result = await client.ReadHoldingRegisters(id, address, 1); Console.WriteLine(result?.First().GetSByte()); break; case "short": result = await client.ReadHoldingRegisters(id, address, 1); Console.WriteLine(result?.First().GetInt16()); break; case "int": result = await client.ReadHoldingRegisters(id, address, 2); Console.WriteLine(result?.GetInt32()); break; case "long": result = await client.ReadHoldingRegisters(id, address, 4); Console.WriteLine(result?.GetInt64()); break; case "float": result = await client.ReadHoldingRegisters(id, address, 2); Console.WriteLine(result?.GetSingle()); break; case "double": result = await client.ReadHoldingRegisters(id, address, 4); Console.WriteLine(result?.GetDouble()); break; case "string": result = await client.ReadHoldingRegisters(id, address, count); Console.WriteLine(); Console.WriteLine("UTF8: " + result?.GetString(count)); Console.WriteLine("Unicode: " + result?.GetString(count, 0, Encoding.Unicode)); Console.WriteLine("BigEndianUnicode: " + result?.GetString(count, 0, Encoding.BigEndianUnicode)); break; default: Console.Write("DataType unknown"); break; } } catch { } await Task.Delay(TimeSpan.FromMilliseconds(interval), cancellationToken); }while (interval > 0 && !cancellationToken.IsCancellationRequested); } break; case 2: { Console.Write("[1] Basic, [2] Regular, [3] Extended: "); int cat = Convert.ToInt32(Console.ReadLine().Trim()); Dictionary <DeviceIDObject, string> info = null; switch (cat) { case 1: info = await client.ReadDeviceInformation(id, DeviceIDCategory.Basic); break; case 2: info = await client.ReadDeviceInformation(id, DeviceIDCategory.Regular); break; case 3: info = await client.ReadDeviceInformation(id, DeviceIDCategory.Extended); break; } if (info != null) { foreach (var kvp in info) { Console.WriteLine($"{kvp.Key}: {kvp.Value}"); } } } break; case 9: { Console.Write("Address: "); ushort address = Convert.ToUInt16(Console.ReadLine().Trim()); Console.Write("Bytes (HEX): "); string byteStr = Console.ReadLine().Trim(); byteStr = byteStr.Replace(" ", "").ToLower(); byte[] bytes = Enumerable.Range(0, byteStr.Length) .Where(i => i % 2 == 0) .Select(i => Convert.ToByte(byteStr.Substring(i, 2), 16)) .ToArray(); var registers = Enumerable.Range(0, bytes.Length) .Where(i => i % 2 == 0) .Select(i => { return(new Register { Type = ModbusObjectType.HoldingRegister, Address = address++, HiByte = bytes[i], LoByte = bytes[i + 1] }); }) .ToList(); if (!await client.WriteRegisters(id, registers)) { throw new Exception($"Writing '{byteStr}' to address {address} failed"); } } break; } Console.Write("New Request? [y/N]: "); string again = Console.ReadLine().Trim().ToLower(); if (!yesList.Contains(again)) { return(0); } } return(0); } catch (OperationCanceledException) when(cancellationToken.IsCancellationRequested) { return(0); } finally { Console.WriteLine("Disposing"); client?.Dispose(); Console.WriteLine("Disposed"); } }
private static async Task MainAsync(string[] args) { Console.WriteLine("Console Demo Modbus Client"); Console.WriteLine(); Console.Write("Connection Type [1] TCP, [2] RS485: "); var cType = Convert.ToInt32(Console.ReadLine().Trim()); IModbusClient client = null; try { switch (cType) { case 1: { Console.Write("Hostname: "); var host = Console.ReadLine().Trim(); Console.Write("Port: "); var port = Convert.ToInt32(Console.ReadLine().Trim()); client = new TcpClient(host, port); } break; case 2: { Console.Write("Interface: "); var port = Console.ReadLine().Trim(); Console.Write("Baud: "); var baud = Convert.ToInt32(Console.ReadLine().Trim()); Console.Write("Stop-Bits [0|1|2|3=1.5]: "); var stopBits = Convert.ToInt32(Console.ReadLine().Trim()); Console.Write("Parity [0] None [1] Odd [2] Even [3] Mark [4] Space: "); var parity = Convert.ToInt32(Console.ReadLine().Trim()); Console.Write("Handshake [0] None [1] X-On/Off [2] RTS [3] RTS+X-On/Off: "); var handshake = Convert.ToInt32(Console.ReadLine().Trim()); Console.Write("Timeout: "); var timeout = Convert.ToInt32(Console.ReadLine().Trim()); Console.Write("Set Driver to RS485 [0] No [1] Yes: "); var setDriver = Convert.ToInt32(Console.ReadLine().Trim()); client = new SerialClient(port) { BaudRate = (BaudRate)baud, DataBits = 8, StopBits = (StopBits)stopBits, Parity = (Parity)parity, Handshake = (Handshake)handshake, SendTimeout = timeout, ReceiveTimeout = timeout }; if (setDriver == 1) { ((SerialClient)client).DriverEnableRS485 = true; } } break; default: throw new ArgumentException("Type unknown"); } await client.Connect(); while (run) { Console.Write("Device ID: "); var id = Convert.ToByte(Console.ReadLine().Trim()); Console.Write("Function [1] Read Register, [2] Device Info, [9] Write Register : "); var fn = Convert.ToInt32(Console.ReadLine().Trim()); try { switch (fn) { case 1: { ushort address = 0; ushort count = 0; string type = ""; Console.WriteLine(); Console.Write("Address : "); address = Convert.ToUInt16(Console.ReadLine().Trim()); Console.Write("DataType: "); type = Console.ReadLine().Trim(); if (type == "string") { Console.Write("Register Count: "); count = Convert.ToUInt16(Console.ReadLine().Trim()); } Console.WriteLine(); Console.Write("Result : "); List <Register> result = null; switch (type.Trim().ToLower()) { case "byte": result = await client.ReadHoldingRegisters(id, address, 1); Console.WriteLine(result?.First().GetByte()); break; case "ushort": result = await client.ReadHoldingRegisters(id, address, 1); Console.WriteLine(result?.First().GetUInt16()); break; case "uint": result = await client.ReadHoldingRegisters(id, address, 2); Console.WriteLine(result?.GetUInt32()); break; case "ulong": result = await client.ReadHoldingRegisters(id, address, 4); Console.WriteLine(result?.GetUInt64()); break; case "sbyte": result = await client.ReadHoldingRegisters(id, address, 1); Console.WriteLine(result?.First().GetSByte()); break; case "short": result = await client.ReadHoldingRegisters(id, address, 1); Console.WriteLine(result?.First().GetInt16()); break; case "int": result = await client.ReadHoldingRegisters(id, address, 2); Console.WriteLine(result?.GetInt32()); break; case "long": result = await client.ReadHoldingRegisters(id, address, 4); Console.WriteLine(result?.GetInt64()); break; case "float": result = await client.ReadHoldingRegisters(id, address, 2); Console.WriteLine(result?.GetSingle()); break; case "double": result = await client.ReadHoldingRegisters(id, address, 4); Console.WriteLine(result?.GetDouble()); break; case "string": result = await client.ReadHoldingRegisters(id, address, count); Console.WriteLine(); Console.WriteLine("UTF8: " + result?.GetString(count)); Console.WriteLine("Unicode: " + result?.GetString(count, 0, Encoding.Unicode)); Console.WriteLine("BigEndianUnicode: " + result?.GetString(count, 0, Encoding.BigEndianUnicode)); break; default: Console.Write("DataType unknown"); break; } } break; case 2: { var info = await client.ReadDeviceInformation(id, DeviceIDCategory.Regular); if (info != null) { foreach (var kvp in info) { Console.WriteLine($"{kvp.Key}: {kvp.Value}"); } } } break; case 9: { Console.Write("Address: "); var address = Convert.ToUInt16(Console.ReadLine().Trim()); Console.Write("Bytes (HEX): "); var byteStr = Console.ReadLine().Trim(); byteStr = byteStr.Replace(" ", "").ToLower(); var bytes = Enumerable.Range(0, byteStr.Length) .Where(i => i % 2 == 0) .Select(i => Convert.ToByte(byteStr.Substring(i, 2), 16)) .ToArray(); var registers = Enumerable.Range(0, bytes.Length) .Where(i => i % 2 == 0) .Select(i => { return(new Register { Address = address++, HiByte = bytes[i], LoByte = bytes[i + 1] }); }) .ToList(); if (!await client.WriteRegisters(id, registers)) { throw new Exception($"Writing '{byteStr}' to address {address} failed"); } } break; } } catch (Exception ex) { Console.WriteLine(); Console.WriteLine("ERROR: " + ex.Message); } Console.Write("New Request? [y/N]: "); var again = Console.ReadLine().Trim().ToLower(); if (again == "y" || again == "yes" || again == "j" || again == "ja") { run = true; } else { run = false; } } } finally { client?.Dispose(); } }
/// <summary> /// 打开连接 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void but_open_Click(object sender, EventArgs e) { try { if (txt_content.Text.Contains("小技巧")) { txt_content.Text = string.Empty; } var PortName = cb_portNameSend.Text.ToString(); var BaudRate = int.Parse(cb_baudRate.Text.ToString()); var DataBits = int.Parse(txt_dataBit.Text.ToString()); var StopBits = (StopBits)int.Parse(txt_stopBit.Text.ToString()); var parity = cb_parity.SelectedIndex == 0 ? Parity.None : (cb_parity.SelectedIndex == 1 ? Parity.Odd : Parity.Even); client?.Close(); EndianFormat format = EndianFormat.ABCD; switch (cmb_EndianFormat.SelectedIndex) { case 0: format = EndianFormat.ABCD; break; case 1: format = EndianFormat.BADC; break; case 2: format = EndianFormat.CDAB; break; case 3: format = EndianFormat.DCBA; break; } client = new ModbusRtuClient(PortName, BaudRate, DataBits, StopBits, parity, format: format); var result = client.Open(); if (result.IsSucceed) { but_open.Enabled = false; cb_portNameSend.Enabled = false; but_read.Enabled = true; but_write.Enabled = true; but_open.Enabled = false; but_close.Enabled = true; but_sendData.Enabled = true; //按了Ctrl后的鼠标点击 if ((ModifierKeys & Keys.Control) == Keys.Control) { Task.Run(() => { AutoOpenRead(); }); } else { AppendText($"连接成功\t\t\t\t耗时:{result.TimeConsuming}ms"); ControlEnabledFalse(); } } else { AppendText($"连接失败:{result.Err}"); } var config = ConnectionConfig.GetConfig(); config.ModBusRtu_PortName = PortName; config.ModBusRtu_BaudRate = BaudRate.ToString(); config.ModBusRtu_DataBits = DataBits.ToString(); config.ModBusRtu_StopBits = StopBits; config.ModBusRtu_Parity = parity; config.ModBusRtu_Value = txt_value.Text; config.ModBusRtu_Address = txt_address.Text; config.ModBusRtu_ShowPackage = chb_show_package.Checked; config.ModBusRtu_EndianFormat = format; config.SaveConfig(); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
/// <summary> /// Helper function writing holding registers. /// </summary> /// <param name="console"></param> /// <param name="client"></param> /// <param name="slave"></param> /// <param name="offset"></param> /// <param name="data"></param> /// <param name="type"></param> /// <param name="hex"></param> public static void WritingHoldingRegisters(IConsole console, IModbusClient client, byte slave, ushort offset, string data, string type, bool hex) { if (!string.IsNullOrEmpty(data)) { if (!string.IsNullOrEmpty(type)) { switch (type.ToLowerInvariant()) { case "string": { if (hex) { console.Out.WriteLine($"Writing a HEX string at offset = {offset}"); client.WriteHexString(slave, offset, data); } else { console.Out.WriteLine($"Writing an ASCII string at offset = {offset}"); client.WriteString(slave, offset, data); } break; } case "bits": { console.Out.WriteLine($"Writing a 16 bit array at offset = {offset}"); client.WriteBits(slave, offset, data.ToBitArray()); break; } case "byte": { List <byte>?bytes = JsonSerializer.Deserialize <List <byte> >(data); if (!(bytes is null)) { console.Out.WriteLine($"Writing {bytes.Count} bytes at offset = {offset}"); client.WriteBytes(slave, offset, bytes.ToArray()); } break; } case "short": { List <short>?values = JsonSerializer.Deserialize <List <short> >(data); if (!(values is null)) { if (values.Count == 1) { console.Out.WriteLine($"Writing a single short value at offset = {offset}"); client.WriteShort(slave, offset, values[0]); } else { console.Out.WriteLine($"Writing {values.Count} short values at offset = {offset}"); client.WriteShortArray(slave, offset, values.ToArray()); } } break; } case "ushort": { List <ushort>?values = JsonSerializer.Deserialize <List <ushort> >(data); if (!(values is null)) { if (values.Count == 1) { console.Out.WriteLine($"Writing a single unsigned short value at offset = {offset}"); client.WriteUShort(slave, offset, values[0]); } else { console.Out.WriteLine($"Writing {values.Count} unsigned short values at offset = {offset}"); client.WriteUShortArray(slave, offset, values.ToArray()); } } break; } case "int": { List <int>?values = JsonSerializer.Deserialize <List <int> >(data); if (!(values is null)) { if (values.Count == 1) { console.Out.WriteLine($"Writing a single int value at offset = {offset}"); client.WriteInt32(slave, offset, values[0]); } else { console.Out.WriteLine($"Writing {values.Count} int values at offset = {offset}"); client.WriteInt32Array(slave, offset, values.ToArray()); } } break; } case "uint": { List <uint>?values = JsonSerializer.Deserialize <List <uint> >(data); if (!(values is null)) { if (values.Count == 1) { console.Out.WriteLine($"Writing a single unsigned int value at offset = {offset}"); client.WriteUInt32(slave, offset, values[0]); } else { console.Out.WriteLine($"Writing {values.Count} unsigned int values at offset = {offset}"); client.WriteUInt32Array(slave, offset, values.ToArray()); } } break; } case "float": { List <float>?values = JsonSerializer.Deserialize <List <float> >(data); if (!(values is null)) { if (values.Count == 1) { console.Out.WriteLine($"Writing a single float value at offset = {offset}"); client.WriteFloat(slave, offset, values[0]); } else { console.Out.WriteLine($"Writing {values.Count} float values at offset = {offset}"); client.WriteFloatArray(slave, offset, values.ToArray()); } } break; } case "double": { List <double>?values = JsonSerializer.Deserialize <List <double> >(data); if (!(values is null)) { if (values.Count == 1) { console.Out.WriteLine($"Writing a single double value at offset = {offset}"); client.WriteDouble(slave, offset, values[0]); } else { console.Out.WriteLine($"Writing {values.Count} double values at offset = {offset}"); client.WriteDoubleArray(slave, offset, values.ToArray()); } } break; } case "long": { List <long>?values = JsonSerializer.Deserialize <List <long> >(data); if (!(values is null)) { if (values.Count == 1) { console.Out.WriteLine($"Writing a single long value at offset = {offset}"); client.WriteLong(slave, offset, values[0]); } else { console.Out.WriteLine($"Writing {values.Count} long values at offset = {offset}"); client.WriteLongArray(slave, offset, values.ToArray()); } } break; } case "ulong": { List <ulong>?values = JsonSerializer.Deserialize <List <ulong> >(data); if (!(values is null)) { if (values.Count == 1) { console.Out.WriteLine($"Writing a single unsigned long value at offset = {offset}"); client.WriteULong(slave, offset, values[0]); } else { console.Out.WriteLine($"Writing {values.Count} unsigned long values at offset = {offset}"); client.WriteULongArray(slave, offset, values.ToArray()); } } break; } } } else { List <ushort>?values = JsonSerializer.Deserialize <List <ushort> >(data); if (!(values is null)) { if (values.Count == 1) { console.Out.WriteLine($"Writing single holding register[{offset}] = {values[0]}"); client.WriteSingleRegister(slave, offset, values[0]); } else { console.Out.WriteLine($"Writing {values.Count} holding registers starting at {offset}"); for (int index = 0; index < values.Count; ++index) { console.Out.WriteLine($"Value of holding register[{offset + index}] = {values[index]}"); } client.WriteMultipleRegisters(slave, offset, values.ToArray()); } } } } }
private void but_open_Click(object sender, EventArgs e) { Task.Run(() => { try { but_open.Text = "连接中..."; if (txt_content.Text.Contains("小技巧")) { txt_content.Text = string.Empty; } client?.Close(); switch (cmb_EndianFormat.SelectedIndex) { case 0: format = EndianFormat.ABCD; break; case 1: format = EndianFormat.BADC; break; case 2: format = EndianFormat.CDAB; break; case 3: format = EndianFormat.DCBA; break; } if (chb_rtudata.Checked) { client = new ModbusRtuOverTcpClient(txt_ip.Text?.Trim(), int.Parse(txt_port.Text?.Trim()), format: format); } else { client = new ModbusTcpClient(txt_ip.Text?.Trim(), int.Parse(txt_port.Text?.Trim()), format: format); } var result = client.Open(); if (result.IsSucceed) { but_read.Enabled = true; but_brokenline.Enabled = true; but_write.Enabled = true; but_open.Enabled = false; but_close.Enabled = true; but_sendData.Enabled = true; AppendText($"连接成功\t\t\t\t耗时:{result.TimeConsuming}ms"); ControlEnabledFalse(); } else { MessageBox.Show($"连接失败:{result.Err}"); } } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { but_open.Text = "连接"; } }); }