基于QT的体温监测与报警项目

48 篇文章 5 订阅
29 篇文章 2 订阅

任务概述

在本次“新冠疫情”的冲击下,某智能物联网工程师所在的小区需要监控人员体温,现新进了一批可以采集人体体温的智能体温计,但是小区有三个门:正门,侧门,后门,每个门都会有人员流动,物业希望能够在监控室查看相关人员的体温,可以做匹配记录。刚好该智能物联网工程师拥有该能力,需要完成以下有关需求:
(1) 每个智能体温计都能采集体温数据并自动上传该数据到监控平台
(2) 监控平台可以实时查看各门,各人员的体温
(3) 对于出现异常体温(超过 37.3℃)监控平台会发出报警

涉及知识点

1、C 语言与C++基础,QT基础界面开发
2、TCP 协议的客户端与服务器连接
3、QCharts 框架使用
4、多媒体播放

具体实现过程

注意点:采用QT5.9,编译器选择MinGW

第一步:体温采集(模拟)与数据发送

在这里插入图片描述
在这里插入图片描述

细节步骤:

1、制作温度传感器,产生源数据
2、制作 TCP 客户端程序 (控制台应用)
3、开启服务器
4、链接服务器并传输数据
5、验证传输是否能完成,数据是否正确

以下为实现代码:

/*模拟温度发生器*/
/*通过随机数的方式产生温度*/
#include<time.h>
#include<unistd.h>
#include<stdlib.h>
#include<iostream>
#include<bitset>
#include<QTcpSocket>
#include<QHostAddress>
#include<QDebug>
#include<QThread>
using namespace std;
short gTemp;
//产生16位数据,占两个字节,而short也占两字节 ,高8位整数 低8位小数
void makeTemp()
{
    //配置随机种子,为了保证产生的数是相对随机的,避免随机数是固定的
    srand(clock());

    short temp = 0;
    char high = 0;
    char low = 0;
    //模拟人的体温34-43
    while(1)
    {
        usleep(100*1000); //100ms产生一个数据
        high = 34 + rand() % 9; //34加上一个0-9的随机数
        low = rand() % 100;

      //  cout << (int)high << endl;
      //  cout << (int)low << endl;

        //将产生的数送到temp中,做位运算处理
        temp = high;
        temp = temp << 8;

        //以16进制和二进制方式展示数据
       // cout << hex << temp << endl;
      //  cout << bitset<16>(temp) << endl;

        temp += low;
      //  cout << hex << temp << endl;
      //  cout << bitset<16>(temp) << endl;

        gTemp = temp; //对数据进行存储
    }
    //return temp;
}

/*TCP代表的是一个传输控制协议,本质是一个传输控制的模块,包括一个IP地址和端口*/
int main(int argc, char *argv[])
{
   //从哪里得到数据
   //开启多线程 ,避免卡住没办法产生数据
    QThread::create([](){
         makeTemp();
        })->start();

    /*TCP连接服务器*/
   QTcpSocket *client =new QTcpSocket; //建立一个socket对象
   QHostAddress address("127.0.0.1");  //IP
   client->connectToHost(address,8888); //端口

   if(client->waitForConnected())  //监控真正拿到对应的地址和端口,在进行数据传输
   {
        //连接的对方的端口和地址
       qDebug() << client->peerAddress();
       qDebug() << client->peerPort();
        //连接的自己的端口和地址
       qDebug() << client->localAddress();
       qDebug() << client->localPort();

       //数据循环发送
       while(1){
           //write的用法  两个参数:char *的地址 数据的长度
           //usleep(100*1000);

           sleep(rand()%10);//10s钟之内发送一个数据

         //cout << hex <<gTemp << endl;
          qDebug() << client->write((char *)&gTemp,2);
          client->flush();//缓冲区
       }
   }
    return 0;
}

这里需要用到一个网络调试助手工具:SSokit
在这里插入图片描述
当我们完成制作模拟温度传感器产生数据,并完成了 TCP 客户端建立,需要验证我们制作的功能是否完善,那么就需要使用网络调试来判断。
首先编译运行QT的客户端程序,然后开启网络调试助手的服务器功能,输入IP地址和端口号,点击连接
在这里插入图片描述
在这里插入图片描述
即实现了模拟温度的产生,TCP客户端的建立,客户端采集到温度数据,并向模拟服务器发送的功能

第二步:数据接收及图表显示

在这里插入图片描述

细节步骤:

1、制作 TCP 服务器 (创建Qwidgets应用)
2、制作图表显示
3、创建 LCDNumber 对象并配置添加到界面上
4、开启服务器
5、链接服务器并传输数据
6、将数据传递给 LCDNumber 对象进行显示
7、验证数据显示是否正确

以下为实现代码:

#include "mainwidget.h"
#include<QDebug>
#include<QtCharts/QValueAxis>
#include<QTime>

void MainWidget::createChart()
{
    //配置基础的图表数据
    mainChart = new QChart();
    dotSeries = new QScatterSeries;
    //X、Y坐标系
    QValueAxis *axisX = new QValueAxis;
    QValueAxis *axisY = new QValueAxis;

    //数值范围
    axisX->setRange(0,60);
    //数据形式
    axisX->setLabelFormat("%.2f");
    //是否显示表格分割虚线
    axisX->setGridLineVisible(true);
    //分割的格子数
    axisX->setTickCount(7);
    //最小分割
    axisX->setMinorTickCount(1);
    //坐标代表的含义标题
    axisX->setTitleText("时间");

    //数值范围
    axisY->setRange(34,43);
    //数据形式
    axisY->setLabelFormat("%.2f");
    //是否显示表格分割虚线
   // axisY->setGridLineVisible(true);
    //显示颜色
   //  axisY->setGridLineColor(Qt::red);
    //分割的格子数
    axisY->setTickCount(10);
    //坐标代表的含义标题
    axisY->setTitleText("体温");

    mainChart->addAxis(axisX,Qt::AlignBottom);
    mainChart->addAxis(axisY,Qt::AlignLeft);

    mainChart->addSeries(dotSeries);
    //隐藏图例
    mainChart->legend()->hide();

    //需要经坐标系和数值范围绑定在一起,否侧显示的数据不正确
    //必须是将图类型添加到图表上之后
    dotSeries->attachAxis(axisX);
    dotSeries->attachAxis(axisY);

}

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent),chartView(new QChartView(this)),currentTempLabel(new QLabel(this))
{
      //对于绝大部分的界面元素,创建对象时,可以添加父元素的指针,代表加到父界面
     // chartView = new QChartView(this);
     // this->setGeometry(500,500,800,600);
       this->setMinimumSize(800,600);
       createChart();

       chartView->setGeometry(200,0,600,400);
       chartView->setChart(mainChart);

       currentTempLabel->setGeometry(0,0,180,30);
       currentTempLabel->setText("");
       QFont f;
       f.setBold(true);
       f.setPointSize(10);
       currentTempLabel->setFont(f);
       currentTempLabel->setStyleSheet("color:red");

      if(startSever())
      {
          qDebug()<<"等待连接";
          connect(server,SIGNAL(newConnection()),this,SLOT(newConnectionAccept()));
      }
}

MainWidget::~MainWidget()
{
}
bool MainWidget::startSever()
{
    server = new QTcpServer();
    return server->listen(QHostAddress("127.0.0.1"),8888); //监听IP和端口
}

void MainWidget::newConnectionAccept()
{
    qDebug() <<"新连接已接入";

    //获取当前传输套接字 可以进行数据的发送和接收
    dataSocket = server->nextPendingConnection();
    dataSocket->write("hello");

    //客户端是否有新的数据发送
    //有->触发readyRead信号
    //可以对发送的数据进行处理

    qreal passMinute = QTime::currentTime().minute();

    connect(dataSocket,&QTcpSocket::readyRead,[=]()mutable{
       //按照高8位和低8位数据转换成真正的温度数据
       short temp = 0;
       dataSocket->read((char *)&temp,2);
       short t = temp >> 8;
       float realTemp = t +(temp & 0x00ff) / 100.00;
       qDebug() << realTemp;

       //如果显示的点太多会混乱,所以每隔一分钟清除之前的那个点
       if(passMinute != QTime::currentTime().minute())
       {
           dotSeries->clear();
           passMinute = QTime::currentTime().minute();
       }
       dotSeries->append(QTime::currentTime().second(),realTemp);
       QString tt("当前温度:");
       tt += QString("%1").arg(realTemp);//转换数值
       currentTempLabel->setText(tt);
    });
}

以上代码实现了服务器端的建立,从客户端接收温度数据并以图表方式显示出来
首先编译运行服务器端的代码,然后编译运行客户端的代码,最后客户端和服务器会自动连接并显示采集到的温度数值,如下:

在这里插入图片描述

第三步:可视化展示及体温报警机制

在这里插入图片描述

细节步骤:

1、 QCharts 图表细节处理
2、 多媒体框架及音乐播放

经过以上两个步骤我们实现了体温监测显示的基本功能,还差一个报警功能未实现,即当采集到的温度超过37.3℃,监测平台会发出报警,图表的显示也不是很直观,需要设立一个警戒线,把所有的温度点连接起来

以下为具体代码实现:

#include "mainwidget.h"
#include<QDebug>
#include<QtCharts/QValueAxis>
#include<QTime>
#include <QApplication>
#include <QtGlobal>

void MainWidget::createChart()
{
    //配置基础的图表数据
    mainChart = new QChart();
    dotSeries = new QScatterSeries;
    alertLineSeries = new QLineSeries;
    connectLineSeries = new QLineSeries;

    //X、Y坐标系
    QValueAxis *axisX = new QValueAxis;
    QValueAxis *axisY = new QValueAxis;

    //数值范围
    axisX->setRange(0,60);
    //数据形式
    axisX->setLabelFormat("%.2f");
    //是否显示表格分割虚线
    axisX->setGridLineVisible(true);
    //分割的格子数
    axisX->setTickCount(7);
    //最小分割
    axisX->setMinorTickCount(1);
    //坐标代表的含义标题
    axisX->setTitleText("时间");

    //数值范围
    axisY->setRange(34,43);
    //数据形式
    axisY->setLabelFormat("%.2f");
   
    axisY->setTickCount(10);
    //坐标代表的含义标题
    axisY->setTitleText("体温");

    mainChart->addAxis(axisX,Qt::AlignBottom);
    mainChart->addAxis(axisY,Qt::AlignLeft);

     mainChart->addSeries(connectLineSeries);
     mainChart->addSeries(alertLineSeries);
     mainChart->addSeries(dotSeries);   //注意这几条线的层次顺序,否则会覆盖住

    //隐藏图例
    mainChart->legend()->hide();

    //需要经坐标系和数值范围绑定在一起,否侧显示的数据不正确
    //必须是将图类型添加到图表上之后
    dotSeries->setMarkerSize(15);
    dotSeries->attachAxis(axisX);
    dotSeries->attachAxis(axisY);

    //警戒线
   // alertLineSeries->setColor(Qt::red); //红色警戒线
    alertLineSeries->setPen(QPen(Qt::red,5,Qt::DashDotLine));//设置红色同时设置线的粗细、样式
    alertLineSeries->attachAxis(axisX);
    alertLineSeries->attachAxis(axisY);

    //连接线
     connectLineSeries->setColor(Qt::blue);
     connectLineSeries->attachAxis(axisX);
     connectLineSeries->attachAxis(axisY);

     alertLineSeries->append(0,37.3);
     alertLineSeries->append(60,37.3);
}

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent),
      chartView(new QChartView(this)),
      currentTempLabel(new QLabel(this)),
      currentLcdnumber(new QLCDNumber(this))
{
      //对于绝大部分的界面元素,创建对象时,可以添加父元素的指针,代表加到父界面
     // chartView = new QChartView(this);
     // this->setGeometry(500,500,800,600);
       this->setMinimumSize(800,600);
       createChart();

       chartView->setGeometry(200,0,600,400);
       chartView->setChart(mainChart);
	   
       currentTempLabel->setGeometry(0,0,180,30);
       currentTempLabel->setText("");
       QFont f;
       f.setBold(true);
       f.setPointSize(10);
       currentTempLabel->setFont(f);
       currentTempLabel->setStyleSheet("color:red");

       //LCD显示数值
       currentLcdnumber->setGeometry(0,50,180,50);
     //  currentLcdnumber->display("2020");

       /*
          1、设置播放器
          2、配置多媒体资源
             (1)是否能做为一个内部资源,不要放太大的资源,否则会导致编译时间过长
             (2)是否能随着安装包发送
          3、播放处理
        */

       alertplayer = new QMediaPlayer;
      //   alertplayer -> setMedia(QUrl::fromLocalFile("/Users/KuGou/8069.mp3"));
       //1、作为一个内部资源去播放
      alertplayer->setMedia(QUrl("qrc:/8069.mp3"));
       alertplayer->setVolume(50);
      // alertplayer->play();

    //  qDebug() << qApp->applicationDirPath()<<endl;
       //2、本地路径找寻播放那个文件,与Debug文件同级
     //   alertplayer->setMedia(QUrl::fromLocalFile(qApp->applicationDirPath() + "/" +"8069.mp3"));

      if(startSever())
      {
          qDebug()<<"等待连接";
          connect(server,SIGNAL(newConnection()),this,SLOT(newConnectionAccept()));
      }
}
MainWidget::~MainWidget()
{
}
bool MainWidget::startSever()
{
    server = new QTcpServer();
    return server->listen(QHostAddress("127.0.0.1"),8888); //监听IP和端口
}

void MainWidget::newConnectionAccept()
{
    qDebug() <<"新连接已接入";
    //获取当前传输套接字 可以进行数据的发送和接收
    dataSocket = server->nextPendingConnection();
    dataSocket->write("hello");

    //客户端是否有新的数据发送
    //有->触发readyRead信号
    //可以对发送的数据进行处理
    qreal passMinute = QTime::currentTime().minute();
    connect(dataSocket,&QTcpSocket::readyRead,[=]()mutable{
       //按照高8位和低8位数据转换成真正的温度数据
       short temp = 0;
       dataSocket->read((char *)&temp,2);
       short t = temp >> 8;
       float realTemp = t +(temp & 0x00ff) / 100.00;
       qDebug() << realTemp;

       //如果显示的点太多会混乱,所以每隔一分钟清除之前的那个点
       if(passMinute != QTime::currentTime().minute())
       {
           dotSeries->clear();
           connectLineSeries->clear();
           passMinute = QTime::currentTime().minute();
       }

        connectLineSeries->append(QTime::currentTime().second(),realTemp);
        dotSeries->append(QTime::currentTime().second(),realTemp);

       QString tt("当前温度:");
       tt += QString("%1").arg(realTemp);//转换数值
       currentTempLabel->setText(tt);
       //LCD显示温度值
       currentLcdnumber->display(realTemp);

       if(realTemp >37.3)
       {
           if(alertplayer->state()==QMediaPlayer::PlayingState)
           {
               alertplayer->stop();
           }
           alertplayer->play();
       }
    });
}

经过以上步骤的细节处理,人体体温监测与报警项目就算是实现了,以下为现象:
在这里插入图片描述

备注:这是第二次做这个项目,之前可以完美运行,这次有点小问题,音乐暂时不能播放,最近也没时间弄了,以后有时间了在搞吧。。。

最后附上源码连接:

https://download.csdn.net/download/weixin_44618297/86415730
嵌入式基于Qt的温度计报警设计主要涉及硬件部分和软件部分。 硬件部分包括温度传感器、QT开发板、触摸屏及相关外设。温度传感器用于实时测量环境温度,QT开发板用于处理传感器数据,并控制报警器的工作。触摸屏则提供友好的人机交互界面,方便用户操作。 软件部分主要包括数据采集及温度判断算法、报警逻辑、用户界面设计等。数据采集部分负责读取温度传感器数据,并利用温度判断算法对数据进行分析和判断。当温度超过设定的报警阈值时,报警逻辑部分会触发相应的报警信号,同时在触摸屏上显示警示信息。用户界面设计部分则提供了温度设置、报警阈值调整等功能,使用户可以根据实际需要进行自定义设置。 整个系统的设计目的是在温度超过某个预设阈值时,及时发出报警,以便用户采取相应的措施。通过QT开发平台提供的丰富的图形库和强大的界面设计能力,可以方便地实现温度计报警功能,并通过触摸屏提供友好的操作界面。 这样的温度计报警设计在实际应用中具有很高的价值。例如,可以应用于工业生产线中,监测设备或环境的温度,及时预警并采取措施,以避免温度过高导致设备损坏或人员伤亡。此外,也可以应用于家庭环境中,监测室内温度,及时调整空调或其他设备,提高居住舒适度。 总之,嵌入式基于QT的温度计报警设计通过硬件和软件的配合,可以实现温度监测报警功能,并提供友好的操作界面,具备广泛的应用前景。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值