C# Modbus RTU Master从站串口调试工具源码 - Visual Studio ...
C#实现ModbusRTU Master从站串口调试工具源码 功能如下 -Visual Studio 2019开发 -.NET Framwork4.8框架 -支持功能码030405061516 -支持读写数据类型ushort16short16int32uint32float32 -支持数据格式 Big-endian ABCD Little-endian DCBA Big-endian byte swap BADC Little-endian byte swap CDAB -使用datagridview表格实时更新接收数据一键回车修改数据数据展现更合理并且可以写注释 -源码已经写好注释接收数据和接收报文都是采用事件接收调用非常方便界面带有记忆功能实时显示收发报文这个Modbus调试工具折腾了我两周时间核心就解决一个问题——让串口通讯数据能像聊天记录一样直观展示。先说说数据解析这部分的门道Modbus那堆字节序转换能把人绕晕特别是处理32位浮点数的时候。看看这段字节序处理的核心代码switch (format) { case DataFormat.BigEndian: return new[] { bytes[0], bytes[1], bytes[2], bytes[3] }; case DataFormat.LittleEndian: return new[] { bytes[3], bytes[2], bytes[1], bytes[0] }; case DataFormat.BigEndianByteSwap: return new[] { bytes[1], bytes[0], bytes[3], bytes[2] }; case DataFormat.LittleEndianByteSwap: return new[] { bytes[2], bytes[3], bytes[0], bytes[1] }; }当时写这个switch的时候差点把咖啡当眼药水滴了。比如BADC格式其实是把两个寄存器的字节各自交换再拼起来。调试时发现个坑当读取浮点数时必须确保两个寄存器的读取顺序正确否则解析出来的数值能差出几个数量级。界面部分最满意的是这个DataGridView的数据绑定dataGridView.AutoGenerateColumns false; var addressCol new DataGridViewTextBoxColumn { DataPropertyName Address}; var valueCol new DataGridViewTextBoxColumn { DataPropertyName Value}; var commentCol new DataGridViewTextBoxColumn { DataPropertyName Comment}; dataGridView.Columns.AddRange(addressCol, valueCol, commentCol);特意关闭了自动生成列功能手动指定绑定关系。这样在用户敲回车修改数据时能直接触发数据源的更新事件不需要再手动同步数据。不过要吐槽DataGridView的验证机制最后不得不用CellEndEdit事件来处理即时提交。事件驱动的接收机制是项目的亮点看看报文接收的委托定义public delegate void MessageReceivedHandler(byte[] rawData); public event MessageReceivedHandler OnMessageReceived;在串口数据到达事件里直接触发这个自定义事件上层业务模块只需要注册监听完全不用操心数据拼接。测试时发现个有意思的现象——当连续快速发送报文时用事件队列的方式比直接处理更稳定不容易丢包。C#实现ModbusRTU Master从站串口调试工具源码 功能如下 -Visual Studio 2019开发 -.NET Framwork4.8框架 -支持功能码030405061516 -支持读写数据类型ushort16short16int32uint32float32 -支持数据格式 Big-endian ABCD Little-endian DCBA Big-endian byte swap BADC Little-endian byte swap CDAB -使用datagridview表格实时更新接收数据一键回车修改数据数据展现更合理并且可以写注释 -源码已经写好注释接收数据和接收报文都是采用事件接收调用非常方便界面带有记忆功能实时显示收发报文配置记忆功能用了最朴实的方案Properties.Settings.Default.WindowPosition this.Location; Properties.Settings.Default.ComPort cboPorts.Text; Properties.Settings.Default.Save();每次窗口移动或关闭时自动保存设置虽然简单但实用。有次用户反馈说重启软件后界面布局乱了最后发现是他用了多显示器办公把软件拖到副屏后关闭导致的坐标系问题。源码里特意加了这种注释// 注意西门子PLC的浮点数存储格式是CDAB // 遇到解析异常时先检查字节序设置 ParseFloat(rawData, DataFormat.LittleEndianByteSwap);毕竟Modbus设备厂家的实现五花八门这种实战踩坑经验比文档管用多了。后来收到用户反馈说注释救了他半天调试时间感觉这些备注加得值了。收发报文的显示处理有个细节——超过3秒未更新时自动清空显示区域。这个设计起初被吐槽太激进但实测发现长时间运行的报文堆积会严重影响性能。最后折中方案是保留200条最新报文既保证可追溯性又不吃内存。工具里藏了个彩蛋连续发送错误指令五次会弹出冷静下喝杯茶的提示框。有用户以为这是Modbus协议自带的特殊功能笑死。其实就是在错误计数器到达5时触发了个MessageBox.Show而已算是个开发过程中的小趣味吧。这个工具现在已经成为我们团队调试设备的标配后来还扩展了TCP支持。最大的收获是意识到好的工具不仅要功能齐全更要让数据流动变得肉眼可见。下次考虑加个数据波形图功能应该会更有意思。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2416139.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!