STM32F103:三.(2)红外测温(MLX90614) (带上位机显示温度曲线)
时间:2022-12-09 07:00:00
上位机显示效果:
上位机代码:
(只有一个窗口)
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Threading; using System.Windows.Forms.DataVisualization.Charting; namespace WindowsFormsApplication1 { public partial class Form1 : Form { private Queue<double> dataQueue = new Queue<double>(50); private float Temp = 0; private int num = 5;///每次删除添加几个点 private delegate void SafeCallDelegate(string text); byte[] Arrive_time = new byte[3]; public Form1() { InitializeComponent(); InitChart(); serialPort1.Encoding = Encoding.GetEncoding("GB2312"); // 设置串口代码 Control.CheckForIllegalCrossThreadCalls = false; // 忽略多线程 x = this.Width; y = this
.Height ; setTag (this ) ; //全屏窗体时内容不受任务栏影响 this .MaximizedBounds = Screen .PrimaryScreen .WorkingArea ; } private void Form1_Load (object sender , EventArgs e ) { for ( int i = 0 ; i <= 10 ; i ++ ) { comboBox1 .Items . Add ( "COM" + i . ToString ( ) ) ; } // comboBox2.Items.Add("4800"); } private void button1_Click_1 (object sender , EventArgs e ) { //string str1; if (open_serial_button .Text == "打开串口" ) /* 先判断当前串口是打开状态还是关闭状态 */ { try { serialPort1 . Open ( ) ; // 打开串口 //serialPort1.StopBits = StopBits.One; //使用一个停止位 //serialPort1.Parity = Parity.None;//无奇偶校验 //串口号和波特率不能修改 comboBox1 .Enabled = false ; comboBox2 .Enabled = false ; serial .ForeColor = Color .Red ; label2 .ForeColor = Color .Red ; //更改字体颜色 // serialPort1.PortName = comboBox1.Text.ToString();//传递端口号 // str1 = comboBox2.Text.ToString(); // serialPort1.BaudRate = Convert.ToInt32(str1); open_serial_button .Text = "关闭串口" ; this .timer1 . Start ( ) ; } catch { MessageBox . Show ( "端口打开错误,请检查串口" , "错误" ) ; } } else // 串口已经打开 需要关闭 { try { serialPort1 . Close ( ) ; // 关闭串口 open_serial_button .Text = "打开串口" ; serial .ForeColor = Color .Black ; label2 .ForeColor = Color .Black ; //更改字体颜色 //串口号和波特 率能修改 comboBox1 .Enabled = true ; comboBox2 .Enabled = true ; this .timer1 . Stop ( ) ; } catch { MessageBox . Show ( "关闭串口错误" ) ; } } } private void serialPort1_DataReceived (object sender , System .IO .Ports .SerialDataReceivedEventArgs e ) { byte [ ] data = new byte [serialPort1 .ReadBufferSize ] ; //一次性读出缓冲区所有字节 serialPort1 . Read (data , 0 , serialPort1 .ReadBufferSize ) ; string str = Encoding .Default . GetString (data ) ; 显示到接收区 WriteTextSafe (str ) ; if (str . Contains ( "MLX90614" ) ) //判断是否含有相同字符串 { //Temperature:24 Humidity:41 例如 string result = System .Text .RegularExpressions .Regex . Replace (str , @ "[^0-9]+" , "" ) ; Temp = Convert . ToInt32 (result ) % 10000 ; Temp = Temp / 100 + ( float ) (Temp % 100 / 100 ) ; Arrive_time [ 2 ] = 1 ; //接收到数据标志位 } } private void WriteTextSafe (string text ) { string str = DateTime .Now . ToString ( "\r\nHH:mm:ss->" ) ; if (this .textBox_receive .InvokeRequired ) { var d = new SafeCallDelegate (WriteTextSafe ) ; if (Arrive_time [ 0 ] == 1 ) 如果点击显示时间 { this . Invoke (d , new object [ ] { str } ) ; } this . Invoke (d , new object [ ] { text } ) ; } else { textBox_receive . AppendText (text + " " ) ; } } private void OnResizeEnd (object sender , EventArgs e ) { 控件随窗体全屏显示 //float[] scale = (float[])Tag; //int i = 2; //foreach (Control ctrl in this.Controls) //{ // ctrl.Left = (int)(Size.Width * scale[i++]); // ctrl.Top = (int)(Size.Height * scale[i++]); // ctrl.Width = (int)(Size.Width / (float)scale[0] * ((Size)ctrl.Tag).Width);//!!! // ctrl.Height = (int)(Size.Height / (float)scale[1] * ((Size)ctrl.Tag).Height);//!!! // //每次使用的都是最初始的控件大小,保证准确无误。 //} } // #region 控件大小随窗体大小等比例缩放 private float x ; //定义当前窗体的宽度 private float y ; //定义当前窗体的高度 private void setTag (Control cons ) { foreach (Control con in cons .Controls ) { con .Tag = con .Width + ";" + con .Height + ";" + con .Left + ";" + con .Top + ";" + con .Font .Size ; if (con .Controls .Count > 0 ) { setTag (con ) ; } } } private void setControls ( float newx , float newy , Control cons ) { //遍历窗体中的控件,重新设置控件的值 foreach (Control con in cons .Controls ) { //获取控件的Tag属性值,并分割后存储字符串数组 if (con .Tag != null ) { string [ ] mytag = con .Tag . ToString ( ) . Split (new char [ ] { ';' } ) ; //根据窗体缩放的比例确定控件的值 con .Width = Convert . ToInt32 (System .Convert . ToSingle (mytag [ 0 ] ) * newx ) ; //宽度 con .Height = Convert . ToInt32 (System .Convert . ToSingle (mytag [ 1 ] ) * newy ) ; //高度 con .Left = Convert . ToInt32 (System .Convert . ToSingle (mytag [ 2 ] ) * newx ) ; //左边距 con .Top = Convert . ToInt32 (System .Convert . ToSingle (mytag [ 3 ] ) * newy ) ; //顶边距 Single currentSize = System .Convert . ToSingle (mytag [ 4 ] ) * newy ; //字体大小 con .Font = new Font (con .Font .Name , currentSize , con .Font .Style , con .Font .Unit ) ; if (con .Controls .Count > 0 ) { setControls (newx , newy , con ) ; } } } } private void Form1_Resize (object sender , EventArgs e ) { float newx = (this .Width ) / x ; float newy = (this .Height ) / y ; setControls (newx , newy , this ) ; } // #endregion //传递串口号的值 private void comboBox1_SelectedValueChanged (object sender , EventArgs e ) { serialPort1 .PortName = comboBox1 .Text . ToString ( ) ; } //传递串口波特率 private void comboBox2_SelectedValueChanged (object sender , EventArgs e ) { string str ; str = comboBox2 .Text . ToString ( ) ; serialPort1 .BaudRate = Convert . ToInt32 (str ) ; } private void checkBox2_CheckedChanged (object sender , EventArgs e ) { if (checkBox2 .Checked == true ) //发送时间 { Arrive_time [ 0 ] = 1 ; } else if (checkBox2 .Checked == false ) { Arrive_time [ 0 ] = 0 ; } } private void chart1_Click (object sender , EventArgs e ) { } private void textBox_receive_TextChanged (object sender , EventArgs e ) { } /********************************************************* ///
/// 初始化图表 /// private void InitChart ( ) { //定义图表区域 this .chart1 .ChartAreas . Clear ( ) ; ChartArea chartArea1 = new ChartArea ( "C1" ) ; this .chart1 .ChartAreas . Add (chartArea1 ) ; //定义存储和显示点的容器 this .chart1 .Series . Clear ( ) ; Series series1 = new Series ( "温度" ) ; series1 .ChartArea = "C1" ; this .chart1 .Series . Add (series1 ) ; //设置图表显示样式 this .chart1 .ChartAreas [ 0 ] .AxisY .Minimum = 0 ; this .chart1 .ChartAreas [ 0 ] .AxisY .Maximum = 50 ; this .chart1 .ChartAreas [ 0 ] .AxisX .Interval = num ; this .chart1 .ChartAreas [ 0 ] .AxisX .MajorGrid .LineColor = System .Drawing .Color .Silver ; //设置标题 this .chart1 .Titles . Clear ( ) ; this .chart1 .Titles . Add ( "S01" ) ; this .chart1 .Titles [ 0 ] .Text = "温度显示" ; this .chart1 .Titles [ 0 ] .ForeColor = Color .RoyalBlue ; this .chart1 .Titles [ 0 ] .Font = new System .Drawing . Font ( "Microsoft Sans Serif" , 12F ) ; //设置图表显示样式 this .chart1 .Series [ 0 ] .Color = Color .Red ; this .chart1 .Series [ 0 ] .ChartType = SeriesChartType .Line ; //线形状 this .chart1 .Series [ 0 ] .Points . Clear ( ) ; } //更新队列中的值 private void UpdateQueueValue ( ) { if (dataQueue .Count > 100 ) { //先出列 for ( int i = 0 ; i < num ; i ++ ) { dataQueue . Dequeue ( ) ; } } for ( int i = 0 ; i < num ; i ++ ) { dataQueue . Enqueue (Temp ) ; } } private void timer1_Tick_1 (object sender , EventArgs e ) { if (Arrive_time [ 2 ] == 1 ) { Arrive_time [ 2 ] = 0 ; UpdateQueueValue ( ) ; this .chart1 .Series [ 0 ] .Points . Clear ( ) ; for ( int i = 0 ; i < dataQueue .Count ; i ++ ) { this .chart1 .Series [ 0 ] .Points . AddXY ( (i + 1 ) , dataQueue . ElementAt (i ) ) ; //温度 } } } } }
下位机采集代码:
测试可用
MLX90614.c
/* Includes ------------------------------------------------------------------*/ #include "delay.h" #include "MLX90614.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define ACK 0 #define NACK 1 #define SA 0x00 //Slave address 单个MLX90614时地址为0x00,多个时地址默认为0x5a #define RAM_ACCESS 0x00 //RAM access command #define EEPROM_ACCESS 0x20 //EEPROM access command #define RAM_TOBJ1 0x07 //To1 address in the eeprom /* -------------------------------------------------------------------------------------*/ #define SMBUS_PORT GPIOB #define SMBUS_SCK GPIO_Pin_14 #define SMBUS_SDA GPIO_Pin_13 #define RCC_APB2Periph_SMBUS_PORT RCC_APB2Periph_GPIOB /* -------------------------------------------------------------------------------------*/ #define SMBUS_SCK_H() SMBUS_PORT->BSRR = SMBUS_SCK #define SMBUS_SCK_L() SMBUS_PORT->BRR = SMBUS_SCK #define SMBUS_SDA_H() SMBUS_PORT->BSRR = SMBUS_SDA #define SMBUS_SDA_L() SMBUS_PORT->BRR = SMBUS_SDA #define SMBUS_SDA_PIN() SMBUS_PORT->IDR & SMBUS_SDA //读取引脚电平 /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /******************************************************************************* * Function Name : SMBus_StartBit * Description : Generate START condition on SMBus * Input : None * Output : None * Return : None *******************************************************************************/ void SMBus_StartBit(void) { SMBUS_SDA_H(); // Set SDA line SMBus_Delay(5); // Wait a few microseconds SMBUS_SCK_H(); // Set SCL line