Пример #1
0
        static int RunInteractive(InteractiveOptions opts)
        {
            using (var client = new ModbusRtuClient())
            {
                client.PortName = opts.PortName;
                client.BaudRate = opts.BaudRate;
                client.DataBits = opts.DataBits;
                client.Parity   = opts.Parity;

                if (!OpenPort(client))
                {
                    return(1);
                }

                var  parser = new InteractiveCommandParser(client);
                bool close  = false;
                do
                {
                    Console.Error.Write("] ");
                    var line = Console.In.ReadLine();
                    try
                    {
                        close = parser.ProcessCommand(line);
                    }
                    catch (Exception exp)
                    {
                        HandleException(exp);
                    }
                    Console.Out.WriteLine();
                }while (!close);
            }
            return(0);
        }
Пример #2
0
        static int RunRead3(Read3Options opts)
        {
            using (var client = new ModbusRtuClient())
            {
                client.PortName = opts.PortName;
                client.BaudRate = opts.BaudRate;
                client.DataBits = opts.DataBits;
                client.Parity   = opts.Parity;

                if (!OpenPort(client))
                {
                    return(1);
                }

                ushort[] values;
                try
                {
                    values = client.ReadHoldingRegisters(opts.UnitAddress, opts.RegisterAddress, opts.RegisterCount);
                }
                catch (Exception exp)
                {
                    return(HandleException(exp));
                }

                for (int i = 0; i < values.Length; i++)
                {
                    Console.Out.Write("0x");
                    Console.Out.Write(values[i].ToString("X4"));
                    Console.Out.Write("    ");
                    Console.Out.WriteLine(values[i].ToString("####0"));
                }

                return(0);
            }
        }
Пример #3
0
        static int RunWrite6(Write6Options opts)
        {
            using (var client = new ModbusRtuClient())
            {
                client.PortName = opts.PortName;
                client.BaudRate = opts.BaudRate;
                client.DataBits = opts.DataBits;
                client.Parity   = opts.Parity;

                if (!OpenPort(client))
                {
                    return(1);
                }

                try
                {
                    client.WriteHoldingRegister(opts.UnitAddress, opts.RegisterAddress, opts.Value);
                }
                catch (Exception exp)
                {
                    return(HandleException(exp));
                }

                return(0);
            }
        }
Пример #4
0
        public async void ServerHandlesRequestFire()
        {
            // Arrange
            var serialPort = new FakeSerialPort();

            var server = new ModbusRtuServer(unitIdentifier: 1);

            server.Start(serialPort);

            var client = new ModbusRtuClient();

            client.Connect(serialPort);

            await Task.Run(() =>
            {
                var data       = Enumerable.Range(0, 20).Select(i => (float)i).ToArray();
                var sw         = Stopwatch.StartNew();
                var iterations = 10000;

                for (int i = 0; i < iterations; i++)
                {
                    client.WriteMultipleRegisters(0, 0, data);
                }

                var timePerRequest = sw.Elapsed.TotalMilliseconds / iterations;
                _logger.WriteLine($"Time per request: {timePerRequest * 1000:F0} us. Frequency: {1 / timePerRequest * 1000:F0} requests per second.");

                client.Close();
            });

            server.Stop();

            // Assert
        }
Пример #5
0
        /// <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}");
            }
        }
Пример #6
0
        /// <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);
            }
        }
Пример #7
0
 static bool OpenPort(ModbusRtuClient client)
 {
     try
     {
         client.Open();
     }
     catch (Exception exp) when(
         exp is UnauthorizedAccessException ||
         exp is InvalidOperationException ||
         exp is IOException)
     {
         Console.Error.WriteLine("Unable to open port.");
         return(false);
     }
     return(true);
 }
Пример #8
0
        static int RunWrite16(Write16Options opts)
        {
            using (var client = new ModbusRtuClient())
            {
                client.PortName = opts.PortName;
                client.BaudRate = opts.BaudRate;
                client.DataBits = opts.DataBits;
                client.Parity   = opts.Parity;

                if (!OpenPort(client))
                {
                    return(1);
                }

                client.WriteMultipleHoldingRegisters(opts.UnitAddress, opts.RegisterAddress, opts.RegisterValues.ToArray());
                return(0);
            }
        }
Пример #9
0
        static void DoClientWork(ModbusRtuClient client, ILogger logger)
        {
            Span <byte> data;

            var sleepTime       = TimeSpan.FromMilliseconds(100);
            var unitIdentifier  = (byte)0x01;
            var startingAddress = (ushort)0;
            var registerAddress = (ushort)0;

            // ReadHoldingRegisters = 0x03,        // FC03
            data = client.ReadHoldingRegisters(unitIdentifier, startingAddress, 10);
            logger.LogInformation("FC03 - ReadHoldingRegisters: Done");
            Thread.Sleep(sleepTime);

            // WriteMultipleRegisters = 0x10,      // FC16
            client.WriteMultipleRegisters(unitIdentifier, startingAddress, new byte[] { 10, 00, 20, 00, 30, 00, 255, 00, 255, 01 });
            logger.LogInformation("FC16 - WriteMultipleRegisters: Done");
            Thread.Sleep(sleepTime);

            // ReadCoils = 0x01,                   // FC01
            data = client.ReadCoils(unitIdentifier, startingAddress, 10);
            logger.LogInformation("FC01 - ReadCoils: Done");
            Thread.Sleep(sleepTime);

            // ReadDiscreteInputs = 0x02,          // FC02
            data = client.ReadDiscreteInputs(unitIdentifier, startingAddress, 10);
            logger.LogInformation("FC02 - ReadDiscreteInputs: Done");
            Thread.Sleep(sleepTime);

            // ReadInputRegisters = 0x04,          // FC04
            data = client.ReadInputRegisters(unitIdentifier, startingAddress, 10);
            logger.LogInformation("FC04 - ReadInputRegisters: Done");
            Thread.Sleep(sleepTime);

            // WriteSingleCoil = 0x05,             // FC05
            client.WriteSingleCoil(unitIdentifier, registerAddress, true);
            logger.LogInformation("FC05 - WriteSingleCoil: Done");
            Thread.Sleep(sleepTime);

            // WriteSingleRegister = 0x06,         // FC06
            client.WriteSingleRegister(unitIdentifier, registerAddress, new byte[] { 65, 67 });
            logger.LogInformation("FC06 - WriteSingleRegister: Done");
        }
Пример #10
0
        static int RunDetectPorts(DetectPortsOptions opts)
        {
            var validPorts = new List <PortDescription>();

            using (var client = new ModbusRtuClient())
            {
                client.BaudRate = opts.BaudRate;
                client.DataBits = opts.DataBits;
                client.Parity   = opts.Parity;

                foreach (var portDesc in SerialPortStream.GetPortDescriptions())
                {
                    client.PortName = portDesc.Port;
                    if (opts.Verbose)
                    {
                        Console.Error.Write($"Trying {portDesc.Port}");
                        if (!string.IsNullOrEmpty(portDesc.Description))
                        {
                            Console.Out.Write($" ({portDesc.Description})");
                        }
                        Console.Out.Write("...");
                    }
                    try
                    {
                        client.Open();
                    }
                    catch (Exception exp) when(exp is UnauthorizedAccessException || exp is InvalidOperationException)
                    {
                        if (opts.Verbose)
                        {
                            Console.Error.WriteLine("already in use.");
                        }
                        continue;
                    }
                    catch (IOException)
                    {
                        if (opts.Verbose)
                        {
                            Console.Error.WriteLine("cannot open.");
                        }
                        continue;
                    }

                    try
                    {
                        client.ReadHoldingRegisters(opts.UnitAddress, 0, 1);
                    }
                    catch (TimeoutException)
                    {
                        if (opts.Verbose)
                        {
                            Console.Error.WriteLine("timeout.");
                        }
                        client.Close();
                        continue;
                    }
                    catch (FormatException)
                    {
                        if (opts.Verbose)
                        {
                            Console.Error.WriteLine("frame error.");
                        }
                        client.Close();
                        continue;
                    }
                    catch (ModbusException)
                    {
                    }
                    if (opts.Verbose)
                    {
                        Console.Error.WriteLine("valid.");
                    }
                    validPorts.Add(portDesc);
                    client.Close();
                }
            }
            if (opts.Verbose)
            {
                Console.Error.WriteLine();
            }
            foreach (var portDesc in validPorts)
            {
                Console.Out.Write($"{portDesc.Port}");
                if (!string.IsNullOrEmpty(portDesc.Description))
                {
                    Console.Out.Write($" ({portDesc.Description})");
                }
                Console.Out.WriteLine();
            }

            return(0);
        }
Пример #11
0
        static async Task Main(string[] args)
        {
            /* Modbus RTU uses a COM port for communication. Therefore, to run
             * this sample, you need to make sure that there are real or virtual
             * COM ports available. The easiest way is to install one of the free
             * COM port bridges available in the internet. That way, the Modbus
             * server can connect to e.g. COM1 which is virtually linked to COM2,
             * where the client is connected to.
             *
             * When you only want to use the client and communicate to an external
             * Modbus server, simply remove all server related code parts in this
             * sample and connect to real COM port using only the client.
             */

            /* define COM ports */
            var serverPort = "COM1";
            var clientPort = "COM2";

            /* prepare dependency injection */
            var services = new ServiceCollection();

            ConfigureServices(services);

            /* create types */
            var provider      = services.BuildServiceProvider();
            var loggerFactory = provider.GetRequiredService <ILoggerFactory>();
            var serverLogger  = loggerFactory.CreateLogger("Server");
            var clientLogger  = loggerFactory.CreateLogger("Client");

            /* create Modbus RTU server and client */
            var server = new ModbusRtuServer(unitIdentifier: 1);
            var client = new ModbusRtuClient();

            /* run Modbus RTU server */
            var cts = new CancellationTokenSource();

            var task_server = Task.Run(async() =>
            {
                server.Start(serverPort);
                serverLogger.LogInformation("Server started.");

                while (!cts.IsCancellationRequested)
                {
                    // lock is required to synchronize buffer access between this application and the Modbus client
                    lock (server.Lock)
                    {
                        DoServerWork(server);
                    }

                    // update server buffer content once per second
                    await Task.Delay(TimeSpan.FromSeconds(1));
                }

                server.Dispose();
            }, cts.Token);

            /* run Modbus RTU client */
            var task_client = Task.Run(() =>
            {
                client.Connect(clientPort);

                try
                {
                    DoClientWork(client, clientLogger);
                }
                catch (Exception ex)
                {
                    clientLogger.LogError(ex.Message);
                }

                client.Close();

                Console.WriteLine("Tests finished. Press any key to continue.");
                Console.ReadKey(true);
            });

            // wait for client task to finish
            await task_client;

            // stop server
            cts.Cancel();
            await task_server;

            server.Stop();
            serverLogger.LogInformation("Server stopped.");
        }
Пример #12
0
 /// <summary>
 /// 更新串口名
 /// </summary>
 public void UpdatePortNames()
 {
     cb_portNameSend.DataSource        = ModbusRtuClient.GetPortNames();
     cb_portNameSend_server.DataSource = ModbusRtuClient.GetPortNames();
 }
Пример #13
0
        static async Task Main(string[] args)
        {
            /* Modbus RTU uses a COM port for communication. Therefore, to run
             * this sample, you need to make sure that there are real or virtual
             * COM ports available. The easiest way is to install one of the free
             * COM port bridges available in the internet. That way, the Modbus
             * server can connect to e.g. COM1 which is virtually linked to COM2,
             * where the client is connected to.
             *
             * When you only want to use the client and communicate to an external
             * Modbus server, simply remove all server related code parts in this
             * sample and connect to real COM port using only the client.
             */

            /* define COM ports */
            var serverPort = "COM1";
            var clientPort = "COM2";

            /* create logger */
            var loggerFactory = LoggerFactory.Create(loggingBuilder =>
            {
                loggingBuilder.SetMinimumLevel(LogLevel.Debug);
                loggingBuilder.AddConsole();
            });

            var serverLogger = loggerFactory.CreateLogger("Server");
            var clientLogger = loggerFactory.CreateLogger("Client");

            /* create Modbus RTU server */
            using var server = new ModbusRtuServer(unitIdentifier: 1)
                  {
                      // see 'RegistersChanged' event below
                      EnableRaisingEvents = true
                  };

            /* subscribe to the 'RegistersChanged' event (in case you need it) */
            server.RegistersChanged += (sender, registerAddresses) =>
            {
                // the variable 'registerAddresses' contains a list of modified register addresses
            };

            /* create Modbus RTU client */
            var client = new ModbusRtuClient();

            /* run Modbus RTU server */
            var cts = new CancellationTokenSource();

            var task_server = Task.Run(async() =>
            {
                server.Start(serverPort);
                serverLogger.LogInformation("Server started.");

                while (!cts.IsCancellationRequested)
                {
                    // lock is required to synchronize buffer access between this application and the Modbus client
                    lock (server.Lock)
                    {
                        DoServerWork(server);
                    }

                    // update server register content once per second
                    await Task.Delay(TimeSpan.FromSeconds(1));
                }
            }, cts.Token);

            /* run Modbus RTU client */
            var task_client = Task.Run(() =>
            {
                client.Connect(clientPort);

                try
                {
                    DoClientWork(client, clientLogger);
                }
                catch (Exception ex)
                {
                    clientLogger.LogError(ex.Message);
                }

                client.Close();

                Console.WriteLine("Tests finished. Press any key to continue.");
                Console.ReadKey(true);
            });

            // wait for client task to finish
            await task_client;

            // stop server
            cts.Cancel();
            await task_server;

            server.Stop();
            serverLogger.LogInformation("Server stopped.");
        }
Пример #14
0
 public InteractiveCommandParser(ModbusRtuClient client)
 {
     _client = client;
 }
Пример #15
0
 byte stationNumber = 1;//站号
 public ModbusRtuClient_tests()
 {
     client = new ModbusRtuClient("COM3", 9600, 8, StopBits.One, Parity.None);
 }