你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32MP1和Qt的新冠疫情监控平台

[复制链接]
ruigewei5 发布时间:2020-3-19 15:48
0.前言
之前我使用桌面版本Qt实现了肺炎疫情监控平台(点击以下文章标题跳转到相关页面):
[开源]我用Qt做了个疫情数据实时监控平台
既然Qt是跨平台的,那么能不能在嵌入式平台实现一下呢?最近刚好看到,ST官方在开展创客大赛活动,就买了米尔科技的YA157C开发板移植一下。

1 ?) Y8 s. n1 v5 m* \) t4 f
桌面Linux版本的运行效果:

" N. V, V7 j/ [$ Y7 z4 z) J
11.png
1 K/ \9 b6 s/ p5 A; v% O2 [$ N
YA157C开发板实现效果:

6 G, ?' }/ r* f5 v3 j
22.jpg

% u! K, E9 d+ N* A
1.准备工作

% Z, b; U& a  ]8 P& t! D" Q+ ?
开发板简介
+ _8 B2 n! |+ M6 H5 t8 E
· 开发板型号:
MYD-YA157C,512MBDDR3,4GB eMMC
· 主控芯片:
STM32MP157AAC3
· 光盘资料版本:
MYD-YA157C-20191225.iso

+ D! p, G% E$ B/ C. f) `
开发板如下:

( Z. H9 m0 f# F* T! ~
33.jpg

- w5 c) `' h/ A! |* p2 ]; G
MYD-YA157C开发套件由核心板MYC-YA157C和底板MYB-YA157C组成,主控芯片是ST目前最高配置的MPU——STM32MP157AAC3,双核Corte-A7+Cortex-M4,主频最高可达650Mhz。
6 t, Z9 S3 m5 M4 N
硬件准备
* r2 L/ A: B8 C  o  P
· 12v电源适配器
· USB-TTL模块:115200/8/1/无
· 网线
0 ^- [. C. E1 A. H
44.jpg
% X  h9 s$ B" P& g
开发板和主机配置
· 开发板Linux版本:Linux4.19.9
· 开发板IP:192.168.1.136
· 主机配置:Ubuntu 16.04
· 主机IP:192.168.1.111
7 e! L  x/ E/ r  X8 O
55.png
  m8 ]* p4 U# r, g+ e
2.数据接口的获取

4 @; e3 f4 o' e" {' N7 p5 T6 T! X) L
疫情监控平台的实现,简单的说,就是数据的展示,而数据从哪里来呢?
现在很多互联网公司都做了自己的疫情监控平台,我这里采用的是腾讯新闻的数据源,数据内容很丰富,也比较稳定。

9 z1 a6 g; j8 s& Y& e
数据来源:
接口地址的获取方法可以参考(点击以下文章标题跳转到相关页面):
[开源]我用Qt做了个疫情数据实时监控平台
如果把所有的数据放在一个接口里,数据量会很大,所以腾讯把数据分成了几个接口

* u. C& u4 U# }2 a# p# R/ V4 x
66.png
' M. a! n0 [0 }4 u8 a& P
目前只显示了一些基本的数据,所以我们只使用到了
, t* c5 q% Q; x* S0 _+ I3 N
这个接口中的chinaTotal和chinaAdd这两组数据。

* [: E% A4 M" w- l# j
这个接口包括很多数据,全国累计和新增的最新数据,各省市其他国家的最新数据等等。文件大小大概在160KB,液晶屏是7寸IPS屏,1024x600分辨率的,还是比较大的,可以显示很多信息,后续版本会添加更多数据显示的。
5 a( h. y, \4 l# b5 U: E
数据格式:
7 k/ w6 w8 E6 f$ m7 Q
77.png
6 ~0 n. b1 ?2 o; I
3.Qt界面的实现
8 d: L' G% k2 L. \( z6 D
之前的桌面应用程序中,是使用的是Qt5版本开发的,Qt5自带QJson解析类,而Qt 4没有带QJson。为了适配带有Qt 4库的板子,我使用了第三方JSON解析库。这里选择的是小巧的cJSON解析库:

& G% N3 x& ^4 D; O1 U
http://sourceforge.net/projects/cjson/
5 ]2 a: Y5 W$ A2 H/ M; u( z
如果你的板子是Qt 4的库,那么程序不用修改,直接交叉编译运行即可使用。
只包含两个文件:cJSON.c和cJSON.h,把这两个文件添加到工程里就行了。
整个工程代码也很简单:GET接口地址,把接收到的数据保存到本地,调用cJSON解析数据文件,把解析出的数据显示,数据文件删除。代码可以到文章末尾开源地址获取。下面介绍几个关键部分代码的实现:

7 k6 \! G' i6 R. a$ E% w4 L7 V) Z4 v
3.1 JSON数据的解析
8 Q, E; Z% I) |5 ?$ W
//打开保存的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, intnum)
{
   if(num > 0)
       lbe->setText("+" + QString::number(num));
   else
       lbe->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:ocalHost && addr.protocol() ==QAbstractSocket::IPv4Protocol && !addr.toString().startsWith("169"))
       {
           ipAddress = addr.toString();
           break;
       }
    }
   // if we did not find one, use IPv4 localhost
   if (ipAddress.isEmpty())
       ipAddress = QHostAddress(QHostAddress:ocalHost).toString();
   return ipAddress;
}
桌面Linux版本的运行效果:
' c, X2 M, [. \) f4 e- W
88.png
0 I8 x' ]4 p6 V* V5 _
4.在开发板上运行Qt程序
" g, h/ m. J' g2 @0 `
如果在桌面运行正常,就可以使用ya157c构建套件来编译工程,生成可以在开发板上运行的程序,然后使用scp命令传输到开发板上。
5 w+ `) e) u; u4 O0 ]
99.png
& D2 C/ b) x2 \+ d/ O/ _
最终效果
& V! e. T, m9 ~. O. r$ u- {
10.png

: Y8 S+ _  f% W3 ~/ y/ |% \4 E
这个界面是上一个版本的,右上角没有显示开发板的IP地址和成功失败次数统计,最新版本的程序中已经添加了这个功能。
桌面Linux版效果:

- k) U  P+ T8 z' G/ u. G2 H
111.png
6 r; [3 Q0 v" h
5.使用无线模块联网

4 C5 U# K: `: y& a' [
YA157C开发板已经板载了一个WiFi& 蓝牙模组——AP6212,可以直接连接无线网,这样就不需要使用网线的方式联网了。
4 j+ V6 p# V1 I* b7 W
222.jpg

4 _" f) ?2 O- _( P
依次执行:

: S; ]+ P  ]/ z
333.png

+ e7 f8 t. _5 Z6 N
实际运行:

  r: i/ Z5 `! P- s
444.png
& P; X3 {1 y& X! l: t4 F
为了方便快捷的连接WiFi,可以把以上命令写成一个shell脚本,需要连接WiFi时,直接执行这个脚本就可以了。先在本地生成WiFi配置信息:
connect_wifi.sh脚本文件内容:
555.png

2 v2 M, s6 W/ J9 a; z- r
& i8 v+ J& h" F& Z0 b
WiFi账号和密码修改一下,就可以直接使用了。

) D  l" A* v1 I+ P" e: ^
666.png
" Z$ f0 b* M( U$ ~$ ~8 u: i+ Y4 Q
6.代码下载

7 L, ^- n5 Q5 Z6 L0 z+ u9 U
整个Qt工程代码已经开源在Github,Qt4/Qt5兼容。如果下载速度很慢,可以选择国内的Gitee速度会快很多。

, e! |* c) e7 }8 H( a8 m* \5 F
777.png
7 p% h# V& D2 k" E, J
目前界面还比较简单,7寸的显示屏可以显示很多内容,之后会尽量完善界面信息,欢迎大家关注!
% _6 l7 P3 F2 _& g, ], F3 g$ |
收藏 2 评论2 发布时间:2020-3-19 15:48

举报

2个回答
Kevin_G 回答时间:2020-3-20 09:47:07
牛牛
goyhuan 回答时间:2020-3-21 09:07:56
linux系统移植吗?没有看懂怎么把系统放上去的
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版