《體溫監測與報警——基於C++ & QT》——開源

項目背景:

在本次“新冠疫情”的衝擊下,小區需要監控人員體溫,現新進了一批可以採集人體體溫的智能體溫計,但是小區有三個門:正門,側門,後門,每個門都會有人員流動,物業希望能夠在監控室查看相關人員的體溫,可以做匹配記錄。

項目需求:

(1)每個智能體溫計都能採集體溫數據並自動上傳該數據到監控平臺。
(2)監控平臺可以實時查看各門,各人員的體溫。
(3)對於出現異常體溫(超過37.3°C)監控平臺會發出報警。

項目開發環境:

(1)QT 5.14.2。
(2)SSokit網絡調試助手。

技術支持:

(1)C語言。
(2)C++。
(3)QT界面開發。
(4)TCP協議。

:具體的項目流程與實現,我用腦圖的方式展示給大家。

作者:Developer_XH

TCP客戶端核心代碼:
/*******************************************************
*
* Function name :makeTemp
* Description   :產生一個16位的數據:高8位整數+低8位小數
* Parameter     :NULL
* Return        :NULL
*
**********************************************************/
short makeTemp()
{
    // 配置隨機種子:根據系統的節拍取
    srand(clock());

    short temp = 0;
    char high = 0;
    char low = 0;

    while(1)
    {
        // 以100ms的時間間隔
        usleep(100 * 1000);

        // 正常體溫範圍:34-43
        // 體溫整數部分隨機數產生
        high = 34 + rand() % 9;
        // 體溫小數部分隨機數產生
        low = rand() % 100;

        // 將產生的數值傳遞給temp中:位運算處理
        temp = high;
        temp = temp << 8;

        // 最終產生的模擬體溫數值
        temp += low;
        gTemp = temp;
    }
}

// 全局變量:存儲產生的體溫數據
short gTemp;

int main(int argc, char *argv[])
{
    // 開啓多線程:將數據的產生,放在線程中
    QThread::create([](){
        makeTemp();
    })->start();

    // 連接到TCP服務器端
    QTcpSocket *client = new QTcpSocket;
    QHostAddress address("127.0.0.1");
    client->connectToHost(address,8888);

    if(client->waitForConnected())
    {
        // 打印對方地址和端口
        qDebug() << client->peerAddress();
        qDebug() << client->peerPort();
        // 打印自己的地址和端口
        qDebug() << client->localAddress();
        qDebug() << client->localPort();

        // 數據循環發送TCP服務器端
        while(1)
        {
            // 模擬人的流動 隨機延時
            sleep(1 + rand()% 9);
            // write的用法 char *的地址 數據長度(字節)
            client->write((char *)&gTemp,2);
            client->flush();
        }
    }
    return 0;
}
TCP客戶端數據發送驗證:

在這裏插入圖片描述

TCP服務器核心代碼:
/*******************************************************
*
* Function name :createChart
* Description   :配置主顯示界面
* Parameter     :NULL
* Return        :NULL
*
**********************************************************/
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->setGridLineVisible(true);
    axisY->setGridLineColor(Qt::gray);
    axisY->setTickCount(10);
    axisY->setTitleText("體溫");
    // 座標軸的位置
    mainChart->addAxis(axisX,Qt::AlignBottom);
    mainChart->addAxis(axisY,Qt::AlignLeft);
    // 數據點,警戒線,連接線的層級關係
    mainChart->addSeries(alertLineSeries);
    mainChart->addSeries(connectLineSeries);
    mainChart->addSeries(dotSeries);

    // 隱藏圖例
    mainChart->legend()->hide();

    // 需要將座標系和數值範圍綁定在一起,否則顯示的數據不正確
    // 必須是在將圖類型添加到圖表上之後
    dotSeries->attachAxis(axisX);
    dotSeries->attachAxis(axisY);

    alertLineSeries->attachAxis(axisX);
    alertLineSeries->attachAxis(axisY);

    connectLineSeries->attachAxis(axisX);
    connectLineSeries->attachAxis(axisY);

    // 設置警戒線:顏色,粗細,位置
    //alertLineSeries->setColor(QColor("red"));
    alertLineSeries->setPen(QPen(Qt::red,3,Qt::DashLine,Qt::RoundCap,Qt::RoundJoin));
    alertLineSeries->append(0,37.3);
    alertLineSeries->append(60,37.3);

    // 設置連接線:顏色,粗細,位置
    connectLineSeries->setPen(QPen(Qt::blue,1.5,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));

}

// 創建server,監聽端口和地址
bool MainWidget::startServer()
{
    server = new QTcpServer();
    return server->listen(QHostAddress("127.0.0.1"),8888);
}

void MainWidget::newConnectionAccept()
{
    // 定義一個刷新圖表的時間
    qreal passMinute = QTime::currentTime().minute();

    qDebug() << "新連接已接入";
    // 獲取當前的傳輸套接字 可以進行數據的發送和接收
    dataSocket = server->nextPendingConnection();
    dataSocket->write("HELLO");

    // 客服端是否有新的數據發送?
    // 有-> 觸發readyRead信號
    // 可以對發送的數據進行處理
    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();
        }

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

    QString tt("當前溫度爲:");
    tt += QString("%1").arg(realTemp);
    currentTempLabel->setText(tt);
    numberDisplay->display(realTemp);

    // 當體溫數值超過 37.3 就報警
    if(realTemp > 37.3)
       {
           alertPlayer->play();
       }

    });

}
打開客戶端和服務器端,進行最終的項目展示:

在這裏插入圖片描述

項目全部文件鏈接:
歡迎大家的留言和評論我會在看到的第一時間內答覆。
看完後感覺得到幫助的小夥伴,要點點贊哦!
給筆者一些動力嘛!謝謝啦~
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章