一年多没有敲代码了,最近暑假在做一个项目,这里记录一下我遇到过的一些问题。
这是我使用的工具和开发环境:
- Modbus Poll
- Modbus Slave
- NModbus4
- VS2019开发环境
- C# WPF
NModbus4
引用NMdbus4,modbus RTU使用下面这个就OK
NMdbus4库传送门
using Modbus.Device;
开发流程
第一步,实现打开串口,modbus建立主站
//全局变量
ModbusSerialMaster master;//主站
byte slaveID = 1;//设备站号
ushort address = 0;//寄存器地址
ushort[] Registers = new ushort[30];//用来保存寄存器的数据
serialPort.PortName = COM_ComboBox.Text;//串口号
serialPort.BaudRate =Convert.ToInt32(BaudRate_ComboBox.Text);//波特率
serialPort.DataBits = Convert.ToInt16(DaTaBit_ComboBox.Text);//数据位
serialPort.Parity =(Parity)Convert.ToInt16(ParityBit_ComboBox.Text);//校验位
serialPort.StopBits = (StopBits)Convert.ToDouble(StopBit_Combobox.Text);//停止位
serialPort.Open(); //串口打开
master = ModbusSerialMaster.CreateRtu(serialPort); //建立连接
master.Transport.Retries = 3; //尝试三次
master.Transport.ReadTimeout = 1000; //milliseconds 响应时间
第二步,使用03功能码相对应的方法,03的功能是:读保持寄存器
Registers = master.ReadHoldingRegisters(slaveID, address, 30);//功能码03(从站地址,寄存器地址,读几个寄存器)
//Registers 收到数据,直接更新到界面就好了
//在这里朋友们注意一下,这个方法是一次性读完的。我之前就是不注意添加了for循环读取,结果总引发事件,提示bug
如果要实时读取,可以使用WPF界面专用的的定时器
using System.Windows.Threading;
public MainWindow()
{
InitializeComponent();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);//数据接收
}
DispatcherTimer dispatcherTimer = new DispatcherTimer();//计时器
//这里的代码放Button事件里,因为我是调试,所以我是跟串口打开,放一起的
dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 1);//定时
dispatcherTimer.Start();
private void dispatcherTimer_Tick(object sender, EventArgs e)//定时引发事件
{
Registers = master.ReadHoldingRegisters(slaveID, address, 30);//功能码03(从站地址,寄存器地址,读几个寄存器)
//Registers[这里我是直接对应寄存器地址了,这样方便]
CurrentSpeed.Content = "电机当前速度:" + Registers[0x10].ToString();
SystemVoltage.Content = "系统电压:" + Registers[0x11].ToString() + " V";
SystemTemp.Content = "系统温度:" + Registers[0x12].ToString() + " ℃";
SystemCurrent.Content = "系统电流:" + Registers[0x0f].ToString() + " mA";
}
如图,这就是我模拟调试的结果
本文暂时没有评论,来添加一个吧(●'◡'●)