基于STM32MP1和QT的疫情看板

2024-06-18 08:08
文章标签 qt 疫情 stm32mp1

本文主要是介绍基于STM32MP1和QT的疫情看板,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 1.前言
  • 2.数据接口的获取
  • 3.Qt界面的实现
  • 4.在开发板上运行Qt程序
  • 5.使用无线模块联网
  • 6.代码下载

1.前言

之前我使用桌面版本Qt实现了肺炎疫情监控平台:基于Qt的新冠肺炎疫情数据实时监控平台(开源小项目)。既然Qt是跨平台的,正好参加创客比赛,刚买了一块米尔科技的YA157C开发板,那么能不能在嵌入式平台实现一下呢?

桌面Linux版本的运行效果:
在这里插入图片描述
YA157C开发板实现效果:
在这里插入图片描述

2.数据接口的获取

疫情监控平台的实现,简单的说,就是数据的展示,而数据从哪里来呢?

现在很多互联网公司都做了自己的疫情监控平台,我这里采用的是腾讯新闻的数据源,数据内容很丰富,也比较稳定。

数据来源:实时更新:新冠肺炎疫情最新动态

接口地址的获取方法可以参考:基于Qt的新冠肺炎疫情数据实时监控平台(开源小项目)

如果把所有的数据放在一个接口里,数据量会很大,所以腾讯把数据分成了几个接口

#包含最新疫情数据、各省市最新数据、其他国家最新数据
https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5#包含历史数据
https://view.inews.qq.com/g2/getOnsInfo?name=disease_other#最新的辟谣信息
https://vp.fact.qq.com/loadmore?page=0#辟谣信息详情
https://vp.fact.qq.com/miniArtData?id=a2141851348ee5f3772c761e25bb57d7

目前只显示了一些基本的数据,所以我们只使用到了https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5这个接口中的chinaTotalchinaAdd这两组数据。

这个接口包括很多数据,全国累计和新增的最新数据,各省市其他国家的最新数据等等。文件大小大概在160KB,液晶屏是7寸IPS屏,1024x600分辨率的,还是比较大的,可以显示很多信息,后续版本会添加更多数据显示的。

数据格式:

{"ret": 0,"data": {"lastUpdateTime": "2020-03-04 11:12:04","chinaTotal": {"confirm": 80422,"heal": 49914,"dead": 2984,"nowConfirm": 27524,"suspect": 520,"nowSevere": 6416},"chinaAdd": {"confirm": 120,"heal": 2654,"dead": 38,"nowConfirm": -2572,"suspect": -67,"nowSevere": -390},...........其他数据............."isShowAdd": true}
}

3.Qt界面的实现

之前的桌面应用程序中,是使用的是Qt5版本开发的,Qt5自带QJson解析类,而Qt 4没有带QJson。为了适配带有Qt 4库的板子,我使用了第三方JSON解析库。这里选择的是小巧的cJSON解析库:cJSON download | SourceForge.net

如果你的板子是Qt 4的库,那么程序不用修改,直接交叉编译运行即可使用。

只包含两个文件:cJSON.c和cJSON.h,把这两个文件添加到工程里就行了。

整个工程代码也很简单:GET接口地址,把接收到的数据保存到本地,调用cJSON解析数据文件,把解析出的数据显示,数据文件删除。代码可以到文章末尾开源地址获取。下面介绍几个关键部分代码的实现:

3.1 JSON数据的解析

//打开保存的JSON数据文件,并调用解析函数
void Dialog::parseData(QString filename)
{QFile file(filename);if(!file.open(QIODevice::ReadOnly)){qDebug() << "file open failed";return;}QByteArray allData = file.readAll();file.close();
//    qDebug() << allData;getData(allData);file.remove();            //删除文件return;
}
//把数据解析出来并显示在标签上
void Dialog::getData(QByteArray str)
{cJSON *ret_obj;cJSON *root_obj;root_obj = cJSON_Parse(str);   //创建JSON解析对象,返回JSON格式是否正确if (!root_obj){disInfo("JSON format error");qDebug() << "json format error";}else{disInfo("json format ok");qDebug() << "json format ok";ret_obj = cJSON_GetObjectItem(root_obj, "ret");if(cJSON_IsNumber(ret_obj)){int ret = 1;ret = ret_obj->valueint;
//            qDebug() << ret_obj->valueint;}char *data_str = cJSON_GetObjectItem(root_obj, "data")->valuestring;cJSON *data_obj = cJSON_Parse(data_str);if(!data_obj){qDebug() << "data json err";cnt_error++;QString error = "err:" + QString::number(cnt_error);ui->lbe_error->setText(error);}else{qDebug() << "data json ok";char *lastUpdateTime = cJSON_GetObjectItem(data_obj, "lastUpdateTime")->valuestring;qDebug() << lastUpdateTime;ui->lbe_update_time->setText(lastUpdateTime);cJSON *chinaTotal_obj = cJSON_GetObjectItem(data_obj, "chinaTotal");int chinaTotal_confirm    = cJSON_GetObjectItem(chinaTotal_obj, "confirm")->valueint;int chinaTotal_heal       = cJSON_GetObjectItem(chinaTotal_obj, "heal")->valueint;int chinaTotal_dead       = cJSON_GetObjectItem(chinaTotal_obj, "dead")->valueint;int chinaTotal_nowConfirm = cJSON_GetObjectItem(chinaTotal_obj, "nowConfirm")->valueint;int chinaTotal_suspect    = cJSON_GetObjectItem(chinaTotal_obj, "suspect")->valueint;int chinaTotal_nowSevere  = cJSON_GetObjectItem(chinaTotal_obj, "nowSevere")->valueint;ui->lbe_total_confirm->setNum(chinaTotal_confirm);ui->lbe_total_heal->setNum(chinaTotal_heal);ui->lbe_total_dead->setNum(chinaTotal_dead);ui->lbe_total_nowConfirm->setNum(chinaTotal_nowConfirm);ui->lbe_total_suspect->setNum(chinaTotal_suspect);ui->lbe_total_nowSevere->setNum(chinaTotal_nowSevere);cJSON *chinaAdd_obj = cJSON_GetObjectItem(data_obj, "chinaAdd");int chinaAdd_confirm    = cJSON_GetObjectItem(chinaAdd_obj, "confirm")->valueint;int chinaAdd_heal       = cJSON_GetObjectItem(chinaAdd_obj, "heal")->valueint;int chinaAdd_dead       = cJSON_GetObjectItem(chinaAdd_obj, "dead")->valueint;int chinaAdd_nowConfirm = cJSON_GetObjectItem(chinaAdd_obj, "nowConfirm")->valueint;int chinaAdd_suspect    = cJSON_GetObjectItem(chinaAdd_obj, "suspect")->valueint;int chinaAdd_nowSevere  = cJSON_GetObjectItem(chinaAdd_obj, "nowSevere")->valueint;lbeDisplay(ui->lbe_add_confirm, chinaAdd_confirm);lbeDisplay(ui->lbe_add_heal, chinaAdd_heal);lbeDisplay(ui->lbe_add_dead, chinaAdd_dead);lbeDisplay(ui->lbe_add_nowConfirm, chinaAdd_nowConfirm);lbeDisplay(ui->lbe_add_suspect, chinaAdd_suspect);lbeDisplay(ui->lbe_add_nowSevere, chinaAdd_nowSevere);}
//        cJSON_Delete(ret_obj);
//        cJSON_Delete(data_obj);cJSON_Delete(root_obj);//释放内存disInfo("更新完成");cnt_success++;QString success = "ok:" + QString::number(cnt_success);ui->lbe_success->setText(success);}
}//数据的显示
void Dialog::lbeDisplay(QLabel *lbe, int num)
{if(num > 0)lbe->setText("+" + QString::number(num));elselbe->setText(QString::number(num));
}

3.2 获取本地IP地址

//forexample:192.168.1.111
QString Dialog::GetLocalmachineIP()
{QString ipAddress;QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();for(QHostAddress &addr : ipAddressesList){// 找到不是本地ip,并且是ipv4协议,并且不是169开头的第一个地址if(addr != QHostAddress::LocalHost && addr.protocol() == QAbstractSocket::IPv4Protocol && !addr.toString().startsWith("169")){ipAddress = addr.toString();break;}}// if we did not find one, use IPv4 localhostif (ipAddress.isEmpty())ipAddress = QHostAddress(QHostAddress::LocalHost).toString();return ipAddress;
}

桌面Linux版本的运行效果:
在这里插入图片描述

4.在开发板上运行Qt程序

如果在桌面运行正常,就可以使用ya157c构建套件来编译工程,生成可以在开发板上运行的程序,然后使用scp命令传输到开发板上。

#使用网线把开发板连接上路由器
#使用udhcpc自动获取IP地址
udhcpc #查看获取到的ip地址
ifconfig#确认连接到互联网
ping www.baidu.com
#如果有回复数据,说明已经成功连接上互联网#使用scp命令或共享目录的方式把可执行文件传输到开发板上
scp qte_2019_ncov root@192.168.1.109:/home/root#执行程序
./qte_2019_ncov

最终效果
在这里插入图片描述
这个版本是上一个版本的,右上角没有显示开发板的IP地址和成功失败次数统计,最新版本的程序中已经添加了这个功能。

桌面Linux版效果:
在这里插入图片描述

5.使用无线模块联网

YA157C开发板已经板载了一个WiFi & 蓝牙模组——AP6212,可以直接连接无线网,这样就不需要使用网线的方式联网了。
在这里插入图片描述

#关闭eth0
ifconfig eth0 down#启用wlan0
rfkill unblock wifi
ifconfig wlan0 up#在当前文件夹生成WiFi配置文件
wpa_passphrase "M6_Note" "qwert125" > wifi.conf#查看生成的WiFi配置信息
cat wifi.conf#加载WiFi配置文件
wpa_supplicant -B -c wifi.conf -i wlan0#扫描附近的WiFi信息
iw dev wlan0 scan | grep SSID#自动获取IP地址
udhcpc -i wlan0#设置DNS
echo "nameserver 114.114.114.114" > /etc/resolv.conf#连接互联网
iw wlan0 link#测试网络连接
ping www.wangchaochao.top

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

为了方便快捷的连接WiFi,可以把以上命令写成一个shell脚本,需要连接WiFi时,直接执行这个脚本就可以了。先在本地生成WiFi配置信息:

connect_wifi.sh脚本文件内容:

#!/bin/bashWF_SSID="M6_Note"
WF_PASSWORD="qwert125"#关闭eth0
ifconfig eth0 down#使能wlan0
rfkill unblock wifi
ifconfig wlan0 up#输出WiFi信息
echo "WiFi_SSID:$WF_SSID"
echo "WiFi_PASSWORD:$WF_PASSWORD"#在当前文件夹生成WiFi配置信息
wpa_passphrase $WF_SSID $WF_PASSWORD > $WF_SSID.conf#加载WiFi配置文件
wpa_supplicant -B -c /home/root/$WF_SSID.conf -i wlan0#扫描附近的WiFi
iw dev wlan0 scan | grep SSID#自动获取IP地址
udhcpc -i wlan0#配置DNS
echo "nameserver 114.114.114.114" > /etc/resolv.conf#连接网络
iw wlan0 linkecho "WiFi连接成功"

WiFi账号和密码修改一下,就可以直接使用了。
在这里插入图片描述

6.代码下载

整个Qt工程代码已经开源在Github,Qt4/Qt5兼容。如果下载速度很慢,可以选择国内的Gitee速度会快很多。

#Github
https://github.com/whik/qte_2019_ncov#Gitee
https://gitee.com/whik/qte_2019_ncov

目前界面还比较简单,7寸的显示屏可以显示很多内容,之后会尽量完善界面信息,欢迎大家关注!

本文转载来源:公众号:mcu149 作者 whik

这篇关于基于STM32MP1和QT的疫情看板的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1071735

相关文章

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

【QT】基础入门学习

文章目录 浅析Qt应用程序的主函数使用qDebug()函数常用快捷键Qt 编码风格信号槽连接模型实现方案 信号和槽的工作机制Qt对象树机制 浅析Qt应用程序的主函数 #include "mywindow.h"#include <QApplication>// 程序的入口int main(int argc, char *argv[]){// argc是命令行参数个数,argv是

Python QT实现A-star寻路算法

目录 1、界面使用方法 2、注意事项 3、补充说明 用Qt5搭建一个图形化测试寻路算法的测试环境。 1、界面使用方法 设定起点: 鼠标左键双击,设定红色的起点。左键双击设定起点,用红色标记。 设定终点: 鼠标右键双击,设定蓝色的终点。右键双击设定终点,用蓝色标记。 设置障碍点: 鼠标左键或者右键按着不放,拖动可以设置黑色的障碍点。按住左键或右键并拖动,设置一系列黑色障碍点

使用Qt编程QtNetwork无法使用

使用 VS 构建 Qt 项目时 QtNetwork 无法使用的问题 - 摘叶飞镖 - 博客园 (cnblogs.com) 另外,强烈建议在使用QNetworkAccessManager之前看看这篇文章: Qt 之 QNetworkAccessManager踏坑记录-CSDN博客 C++ Qt开发:QNetworkAccessManager网络接口组件 阅读目录 1.1 通用API函数

Qt多语种开发教程

Qt作为跨平台的开发工具,早已应用到各行各业的软件开发中。 今天讲讲,Qt开发的正序怎么做多语言开发。就是说,你设置中文,就中文显示;设置英语就英文显示,设置繁体就繁体显示,设置发育就显示法语等。 开发环境(其实多语种这块根环境没太大关系):win10,Qt.5.12.10 一.先用QtCreator创建一个简单的桌面程序 1.工程就随便命名“LanguageTest”,其他默认。 2.在设计师

Qt中window frame的影响

window frame 在创建图形化界面的时候,会创建窗口主体,上面会多出一条,周围多次一圈细边,这就叫window frame窗口框架,这是操作系统自带的。 这个对geometry的一些属性有一定影响,主要体现在Qt坐标系体系: 窗口当中包含一个按钮,这个按钮的坐标系是以父元素为参考,那么这个参考是widget本体作为参考,还是window frame作为参考,这两种参考体系都存在

【Qt】定时器事件

定时器事件 在之前学习QTimer中实现了定时器的功能,而在QTimer背后是QTimerEvent定时器事件进行支撑的。在QObject中提供了一个timeEvent这个函数。 startTimer启动定时器killTimer关闭定时器 Qt 中在进⾏窗⼝程序的处理过程中,经常要周期性的执⾏某些操作,或者制作⼀些动画效果,使⽤定 时器就可以实现。所谓定时器就是在间隔⼀定时间后,去执⾏某⼀

QT 编译报错:C3861: ‘tr‘ identifier not found

问题: QT 编译报错:C3861: ‘tr’ identifier not found 原因 使用tr的地方所在的类没有继承自 QObject 类 或者在不在某一类中, 解决方案 就直接用类名引用 :QObject::tr( )

在 Qt Creator 中,输入 /** 并按下Enter可以自动生成 Doxygen 风格的注释

在 Qt Creator 中,当你输入 /** 时,确实会自动补全标准的 Doxygen 风格注释。这是因为 Qt Creator 支持 Doxygen 以及类似的文档注释风格,并且提供了代码自动补全功能。 以下是如何在 Qt Creator 中使用和显示这些注释标记的步骤: 1. 自动补全 Doxygen 风格注释 在 Qt Creator 中,你可以这样操作: 在你的代码中,将光标放在

Qt: 详细理解delete与deleteLater (避免访问悬空指针导致程序异常终止)

前言 珍爱生命,远离悬空指针。 正文 delete 立即删除:调用 delete 后,对象会立即被销毁,其内存会立即被释放。调用顺序:对象的析构函数会被立即调用,销毁该对象及其子对象。无事件处理:如果在对象销毁过程中还涉及到信号和槽、事件处理等,直接 delete 可能会导致问题,尤其是在对象正在处理事件时。适用场景:适用于在确定对象已经不再被使用的情况下,并且不涉及异步处理或事件循环中的