C#编写Modbus协议加速度传感器上位机

  • 项目概述
  • 功能描述
  • 上位机原理
    • 初始化连接
    • 读取寄存器原始数据
    • 换算为实际物理量
    • 自动模式
    • 数据保存
  • 数据可视化分析
  • 尾言

项目概述

笔者利用下班时间,编写了初版上位机软件。通过USB转RS485线,走Modbus协议,成功读取了串口加速度传感器数据。笔者在万能的X宝自费不到200软妹币购置了此款传感器。系虎彩全厂首次尝试编写上位机软件。

功能描述

将此传感器固定于印刷机等中大型设备的电机等位置处,即可实现对机器振动情况(对应传感器加速度)的在线监测,对峰值与峰峰值的监控可以确保机器的振动幅度在安全范围。当传动系统有异物进入或紧固件掉落导致电机堵转、轴类零件窜动时及时报警,防止损失扩大。对采样的数据进行可视化数据分析即可获知设备的劣化情况。利用Fourier变换还可得知时域的曲线,从而得知振动频率是否提高(项目搁置,暂未完成)。

上位机原理

使用NModbus库,读取出传感器寄存器中的数值,将寄存器中的二进制数转化为16位整数,并利用公式计算出实际的物理量。读取出的数据格式化为txt。

初始化连接

//初始化private void Form1_Load(object sender, EventArgs e){button4.Text= "开始自动更新";comboBox2.SelectedIndex = 2;comboBox5.SelectedIndex = 0;comboBox3.SelectedIndex = 0;comboBox4.SelectedIndex = 0;functionCode = "03 Read Holding Registers";}private SerialPort InitSerialPortParameter(){portName = "COM3";baudRate = 9600;parity = Parity.None;dataBits = 8;stopBits = StopBits.One;port = new SerialPort(portName, baudRate, parity, dataBits, stopBits);return port;}private SerialPort InitSerialPortParameter(){portName = "COM3";baudRate = 9600;parity = Parity.None;dataBits = 8;stopBits = StopBits.One;port = new SerialPort(portName, baudRate, parity, dataBits, stopBits);return port;}
private void button1_Click(object sender, EventArgs e){richTextBox1.Clear();richTextBox2.Clear();}private void button2_Click(object sender, EventArgs e){try{//初始化串口参数InitSerialPortParameter();master = ModbusSerialMaster.CreateRtu(port);ExecuteFunction();}catch (Exception){MessageBox.Show("初始化异常");}}private void SetReadParameters(int dataaddress_read){slaveAddress = 80;startAddress = (ushort)dataaddress_read;numberOfPoints = 1;}

由于本款传感器默认按16进制计算,很多参数需自行转化为10进制。Modbus地址为0x50,换算后为80。我选用波特率9600的低速模式,占用的端口为COM3。

读取寄存器原始数据

        private async void ExecuteFunction(){try{//每次操作是要开启串口 操作完成后需要关闭串口//目的是为了slave更换连接是不报错if (port.IsOpen == false){port.Open();}//读取保持寄存器SetReadParameters(dataaddress_read);registerBuffer = master.ReadHoldingRegisters(slaveAddress, startAddress, numberOfPoints);str_register = registerBuffer[0].ToString();str_register_int = int.Parse(str_register);//求补码if (str_register_int <= 32767){//正数的原码=补码}else{str_register_int_short = (short)((~str_register_int - 0xFFFF0000) + 1);str_register_int = -str_register_int_short;}for (int i = 0; i < registerBuffer.Length; i++){SetMsg(registerBuffer[i] + "\t");}//     SetMsg("\t\n");port.Close();}catch (Exception ex){MessageBox.Show(ex.Message);}}public void SetMsg(string msg){richTextBox1.Invoke(new Action(() => { richTextBox1.AppendText(msg); }));}

由于C#中int为32位,传感器的寄存器是16位二进制补码且按大端存储,故按照字符串的方式读出后仍需要想办法计算出带±的原码,否则无法获取角度/加速度为-时的物理量。我采用了按位取反后减去高位并+1的方法获取到高位为0的int32数值,再强制转化为short(即int16)获取到正确的10进制原始数值。
为防止串口占用导致软件功能异常,每次读取后都要关闭串口。
SetMsg为委托更新数据,防止卡死。

换算为实际物理量

private void button3_Click(object sender, EventArgs e){try{//61,62,63为角度寄存器地址;52,53,54为加速度寄存器地址//显示时间richTextBox1.Text = richTextBox1.Text + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")+"\t";richTextBox2.Text = richTextBox2.Text + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") + "\t";for (dataaddress_read = 61; dataaddress_read < 64; dataaddress_read++){ExecuteFunction();if (dataaddress_read == 61){angel_x = (double)str_register_int / 32768 * 180;}else if (dataaddress_read == 62){angel_y = (double)str_register_int / 32768 * 180;}else{angel_z = (double)str_register_int / 32768 * 180;}label14.Text = angel_x.ToString();label15.Text = angel_y.ToString();label16.Text = angel_z.ToString();}//    richTextBox1.Text = richTextBox1.Text + "\n";for (dataaddress_read = 52; dataaddress_read < 55; dataaddress_read++){ExecuteFunction();if (dataaddress_read == 52){ax =- (double)str_register_int / 32768 * 16*9.8;}else if (dataaddress_read == 53){ay =- (double)str_register_int / 32768 * 16 * 9.8;}else{az =- (double)str_register_int / 32768 * 16 * 9.8;}label19.Text = ax.ToString();label18.Text = ay.ToString();label17.Text = az.ToString();                   }richTextBox2.Text = richTextBox2.Text + angel_x.ToString()+  "\t";richTextBox2.Text = richTextBox2.Text + angel_y.ToString() + "\t";richTextBox2.Text = richTextBox2.Text + angel_z.ToString() + "\t";richTextBox2.Text = richTextBox2.Text + ax.ToString() + "\t";richTextBox2.Text = richTextBox2.Text + ay.ToString() + "\t";richTextBox2.Text = richTextBox2.Text + az.ToString() + "\t";richTextBox1.Text = richTextBox1.Text + "\n";richTextBox2.Text = richTextBox2.Text + "\n";}catch (Exception){MessageBox.Show("初始化异常");}}

此为手动模式下的换算及格式化。

Modbus RS458转USB加速度传感器上位机

自动模式

private void button3_Click(object sender, EventArgs e){try{//61,62,63为角度寄存器地址;52,53,54为加速度寄存器地址//显示时间richTextBox1.Text = richTextBox1.Text + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")+"\t";richTextBox2.Text = richTextBox2.Text + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") + "\t";for (dataaddress_read = 61; dataaddress_read < 64; dataaddress_read++){ExecuteFunction();if (dataaddress_read == 61){angel_x = (double)str_register_int / 32768 * 180;}else if (dataaddress_read == 62){angel_y = (double)str_register_int / 32768 * 180;}else{angel_z = (double)str_register_int / 32768 * 180;}label14.Text = angel_x.ToString();label15.Text = angel_y.ToString();label16.Text = angel_z.ToString();}//    richTextBox1.Text = richTextBox1.Text + "\n";for (dataaddress_read = 52; dataaddress_read < 55; dataaddress_read++){ExecuteFunction();if (dataaddress_read == 52){ax =- (double)str_register_int / 32768 * 16*9.8;}else if (dataaddress_read == 53){ay =- (double)str_register_int / 32768 * 16 * 9.8;}else{az =- (double)str_register_int / 32768 * 16 * 9.8;}label19.Text = ax.ToString();label18.Text = ay.ToString();label17.Text = az.ToString();                   }richTextBox2.Text = richTextBox2.Text + angel_x.ToString()+  "\t";richTextBox2.Text = richTextBox2.Text + angel_y.ToString() + "\t";richTextBox2.Text = richTextBox2.Text + angel_z.ToString() + "\t";richTextBox2.Text = richTextBox2.Text + ax.ToString() + "\t";richTextBox2.Text = richTextBox2.Text + ay.ToString() + "\t";richTextBox2.Text = richTextBox2.Text + az.ToString() + "\t";richTextBox1.Text = richTextBox1.Text + "\n";richTextBox2.Text = richTextBox2.Text + "\n";}catch (Exception){MessageBox.Show("初始化异常");}}

由于采用的是只读模式,传感器在9600波特率可达到50Hz采样频率,115200波特率可达到100H在采样频率,考虑到使用txt保存数据的方式不足以解决数据量过大的问题,暂且使用计时器2Hz自动刷新。

C#编写的ModbusRTU加速度传感器上位机

数据保存

private void button6_Click(object sender, EventArgs e){//保存数据到txtif (richTextBox2.Text == string.Empty){MessageBox.Show("要写入的文件内容不能为空");}else{//设置保存文件的格式saveFileDialog1.Filter = "文本文件(*.txt)|*.txt";if (saveFileDialog1.ShowDialog() == DialogResult.OK){//使用“另存为”对话框中输入的文件名实例化StreamWriter对象StreamWriter sw = new StreamWriter(saveFileDialog1.FileName, true);//向创建的文件中写入内容sw.WriteLine(richTextBox2.Text);//关闭当前文件写入流sw.Close();richTextBox2.Text = string.Empty;}}}

数据可视化分析


将格式化后的txt手动粘贴到excel并链接到tableau。
利用获得的3轴角度及3轴加速度绘制曲线图。

容易看出笛卡尔坐标系下3个轴的振动情况。

尾言

使用costura可以将Nmodbus4.dll打包为一个exe,方便部署。

100Hz*86400s/d*365d=3153600000=31e条数据/年

可以看出,如果把数据全部保存,光是一个传感器的数据量就很庞大。如何保存如此庞大的数据量,并加以利用(如:拟合劣化曲线预测设备宕机的概率,实现预防性机修与保养)?这就需要大数据机器学习

C#编写Modbus协议加速度传感器上位机相关推荐

  1. modbus协议讲解,上位机与PLC交互

    开发过程中modbus-RTU需要电脑USB口对外交互,参考我的文章:C# 通过Com端口和单片机通讯(232/485/USB)_花开莫与流年错_的博客-CSDN博客_c#与单片机通信 上位机和PLC ...

  2. c语言编写modbus程序,C语言编写modbus协议

    <C语言编写modbus协议>由会员分享,可在线阅读,更多相关<C语言编写modbus协议(23页珍藏版)>请在人人文库网上搜索. 1.include / 字地址 0 - 25 ...

  3. 写字机上位机c语言,易懂 | 手把手教你编写你的第一个上位机

    一.前言 大家好,我是ZhengN,本次来教大家编写一个基于QT的简单的上位机. 学习一个新的东西我们都从最基础地实例开始,比如学习C语言我们会从编写一个hello程序开始.学习嵌入式我们从点灯开始. ...

  4. PROFINET转Modbus网关ET001助力上位机对接KUKA机械臂

    北京骥远自动化网关ET001助力上位机对接KUKA机械臂 项目背景 近年来,机械臂越来越高频的出现在社会生活和公众视线中.诸如工业装配车间,自动采集口鼻拭子做核酸检测-- 在某车间,中控室的上位机软件 ...

  5. modbus连续读取时数据不正确_使用MODBUS协议与传感器、工控屏对接时碰到的问题...

    当控制器作为可编程逻辑器件用于工控系统时,其需要与各种不同的传感器对接, 同时需要与工控屏对接,以提供人机界面与用户进行交互: 对接的传感器功能多种多样, 有检测环境的温.湿度.二氧化碳.光照等的传感 ...

  6. c语言写modbus协议,C语言编写modbus协议

    modbus.c #include "main.h" //字地址0 - 255 (只取低8位) //位地址0 - 255 (只取低8位) /* CRC 高位字节值表*/ const ...

  7. 物联网云平台DTU Modbus协议 上位机 下位机 源码 源代码 程序

    物联网云平台DTU Modbus协议 上位机 下位机 源码 源代码 程序 一.源码的使用基本说明: 1.1 编译语言: 下位机使用C语言:上位机使用C#语言 标准Modbus Slave通信下位机源码 ...

  8. 手把手教你编写一个上位机

    关注+星标公众号,不错过精彩内容 转自 | 嵌入式大杂烩 嵌入式开发,基本都会用到有一些上位机工具,比如串口助手就是最常用的工具之一. 那么,今天分享有一篇由ZhengN整理的用Qt写的简单上位机教程 ...

  9. 上位机与台达DVP-SS2 PLC串口通讯

    目标:上位机作为主站,PLC作为从站,采用标准的Modbus-rtu通讯协议,实现上位机对PLC的控制,例如读取X,Y状态,设置Y的状态,读取D的值等等. 配置:上位机,串口调试软件,RS232串口, ...

最新文章

  1. qtdesigner 组件全吗_百度营销工具有哪些?带你了解百度全链路营销
  2. 第44节:Java当中的JVM
  3. linux cp 命令使用一角
  4. leetcode 2. Add Two Numbers | 2. 两数相加(Java)
  5. 在JDK 8中可通过反射获得构造函数/方法参数元数据
  6. 堪称暴力美学的可视化大屏是怎么做的?附无代码硬核教程
  7. (转)淘淘商城系列——前台系统工程搭建
  8. mysql 8创建远程访问用户以及连接mysql速度慢的解决方法
  9. HDU1715 大菲波数【大数】
  10. Yate如何打开不同格式的音乐文件?
  11. matlab logistic拟合,用matlab拟合Logistic,4参数logistic
  12. redis 下载源地址
  13. fedora linux搜狗输入法,Linux_Fedora20 32位系统中安装搜狗拼音输入法图文教程,搜狗输入法在windows系统中是非 - phpStudy...
  14. JAVA事务@Transactional之propagation
  15. Debian10英语环境安装搜狗输入法
  16. 赛福天拟增资LG供应商,切入动力电池领域;清能股份氢燃料电池渣土车项目落地佛山 | 能动...
  17. 如何设计百万人抽奖系统
  18. 【测试用例练习】八、淘宝网站测试用例
  19. LIO-livox - 激光IMU初始化模块分析
  20. win10显示隐藏文件_如何在Mac上显示隐藏文件——macw

热门文章

  1. 英语自我介绍(简洁版)//2021-2-3
  2. Spark SQL之RDD, DataFrame, DataSet详细使用
  3. 知乎最高赞回答!零代码基础,把报表做出科技感是什么体验?
  4. sql注入php代码审计1
  5. 微信小程序跳转的几种方式
  6. 中国厨房机器人市场现状及未来发展趋势
  7. 微信小程序css篇----1.边框(Border)
  8. RK 3568 移植CH9344驱动流程记录
  9. 东营市鸿发广场6#楼消防应急照明和疏散指示系统的研究与应用-安科瑞耿敏花
  10. 突破windows 2g限制