锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

STM32F103:三.(2)红外测温(MLX90614) (带上位机显示温度曲线)

时间:2022-12-09 07:00:00 con021传感器传感器pec09

上位机显示效果:

在这里插入图片描述

上位机代码:

(只有一个窗口)

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
     

相关文章