200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > C#编写Modbus协议加速度传感器上位机

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

时间:2021-09-05 12:20:13

相关推荐

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

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条数据/年

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。