作者:番茄炒鸡蛋
链接:https://www.zhihu.com/question/346164139/answer/2386256780
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
在原有上位机的基础上,简单做了一款显示转速波形和电压 电流的上位机。当然了其中还存在一些问题,不过用于显示和调试PID问题不大。 1.整体界面如下 分为串口选择和设置区,数据显示区,监控信息区,数据缓存以及曲线显示。
2.上位机在获取多个数据时候,串口如何识别哪个是电流电压和转速呢? 由于串口一次发送一个字节。对于超过255的数据 只能分开发。一次性发很多数据,上位机也不能把一组数据提取出来进行整合显示对应的物理量。基于以上问题,我就采用了以下的方法。单片机发送数据以一个包进行发送,包的开始以0xFF开始,结束以0x55结束(当然了也有局限性),程序如下: if(Transmit_Time>=800) //5ms { Transmit_Time=0; Main_Num++; if( Main_Num==1) { USART_SendData(USART1,0xFF); //字节0 } if( Main_Num==2) //实时性高的发送优先级高--转速 显示曲线 { USART_SendData(USART1,Motor.ActualSpeed/255); //字节1 USART_SendData(USART1,Motor.ActualSpeed%255); //字节2 } if( Main_Num==3) //优先级次之---电流 { USART_SendData(USART1,((uint16_t)(Motor.Current))/255);//字节3 USART_SendData(USART1,((uint16_t)(Motor.Current))%255);//字节4 } if(Main_Num==4) //电压 { USART_SendData(USART1,ADCSampPare.BUS_Voltage); //字节5 } if(Main_Num==5) //PCB温度 { USART_SendData(USART1,ADCSampPare.PCB_Temp);//字节 6 } if( Main_Num==3) { Main_Num=0; USART_SendData(USART1,0xFF); //字节7 } } 上位机接受数据程序: private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { try { int n = serialPort1.BytesToRead; byte[] Receive = new byte[n]; serialPort1.Read(Receive, 0, Receive.Length); bool DataCatched = false;//数据可以分析的标志 //缓存数据 ReceBuffer.AddRange(Receive); //完整性判断 while (ReceBuffer.Count >= 8) { //这里可以写成对数据的校验如CRC if (ReceBuffer[0] == 0xff && ReceBuffer[7] == 0xff) { ReceBuffer.CopyTo(0, DataTemp, 0, 8); DataBuf.AddRange(DataTemp); DataCatched = true;
ReceBuffer.RemoveRange(0, 8);//获得一条正确的数据,删除缓存 } else { ReceBuffer.RemoveAt(0);//不是数据头,删除数据 } } //分析数据 if (DataCatched == true) { while (DataBuf.Count > 0) { DataBuf.CopyTo(0, DataTemp2, 0, 8); //数据分析 Test.Speed_Buffer[0] = DataTemp2[1] * 255 + DataTemp2[2];//转速 Test.Speed_Buffer[2] = DataTemp2[3] * 255 + DataTemp2[4];//电流 if (Test.Speed_Buffer[0] > 0) { Flag_Data_Save = true; } string str = Convert.ToString((DataTemp2[1] * 255 + DataTemp2[2]), 10).ToUpper(); //转速 string str1 = Convert.ToString(DataTemp2[3] * 255 + DataTemp2[4], 10).ToUpper(); //电流 string str2 = Convert.ToString(DataTemp2[5], 10).ToUpper(); //电压 string str3 = Convert.ToString(DataTemp2[6], 10).ToUpper(); //温度
if ((Test.Speed_Buffer[0] - Test.Speed_Buffer[1]) > 50 || ((Test.Speed_Buffer[1] - Test.Speed_Buffer[0]) > 50)) { textBox3.Text = str + "r/min"; } if ((Test.Speed_Buffer[2] - Test.Speed_Buffer[3]) > 50 || ((Test.Speed_Buffer[3] - Test.Speed_Buffer[2]) > 50)) { textBox2.Text = str1 + "mA"; }
textBox1.Text = str2 + "V"; textBox4.Text = str3 + "℃"; Speed_Temp = str; if ((Test.Speed_Buffer[1] - Test.Speed_Buffer[0]>200)&&(Test.Speed_Buffer[0]>1000) ) //当前转速低于上一个太多 { textBox5.AppendText("转速异常\r\n");
} Test.Speed_Buffer[1] = Test.Speed_Buffer[0]; Test.Speed_Buffer[3] = Test.Speed_Buffer[2]; textBox1.AppendText((str.Length == 1 ? "0" + str : str) + " ");//速度 progressBar1.Value = DataTemp2[5]; //电压 progressBar2.Value = DataTemp2[3] * 255 + DataTemp2[4]; //电流 progressBar3.Value = DataTemp2[6]; //PCB温度 progressBar4.Value = DataTemp2[1] * 255 + DataTemp2[2];//转速
if(progressBar2.Value>=19000) { textBox5.AppendText("电流过大\r\n");
} Delay(1000);//不延时的话不显示 Thread.Sleep(10); DataBuf.RemoveRange(0, 4); } } } catch { } } 数据能够正常接收和显示,但这只是基础版本的,还有很多细节没有处理,后面会不管完善!以下是我电机转速调节转速曲线图:
|