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

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

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

3 p, ]5 T  ^: f* e
桌面Linux版本的运行效果:

1 }- t, N: r4 ~& i
11.png
  C/ Y1 e! h0 A8 n0 g
YA157C开发板实现效果:

9 J1 E1 b1 }! X$ G% J6 ~) y7 L4 v
22.jpg
4 i+ z9 \2 \$ d6 v! g: K% n
1.准备工作

& E) z3 ?: ?3 p' k
开发板简介
8 I$ Q: u2 b" V9 N8 E# O2 F9 }
· 开发板型号:
MYD-YA157C,512MBDDR3,4GB eMMC
· 主控芯片:
STM32MP157AAC3
· 光盘资料版本:
MYD-YA157C-20191225.iso
/ M/ L* V; h  U4 \/ p; ^( _8 f# {
开发板如下:

" [, y7 M9 x; q: Z3 S- S
33.jpg
4 V8 z, i  o6 y
MYD-YA157C开发套件由核心板MYC-YA157C和底板MYB-YA157C组成,主控芯片是ST目前最高配置的MPU——STM32MP157AAC3,双核Corte-A7+Cortex-M4,主频最高可达650Mhz。

8 \: G& i) J. P1 V% X% j6 u
硬件准备

  Z. G; N0 @2 \9 |
· 12v电源适配器
· USB-TTL模块:115200/8/1/无
· 网线

- X+ K  g2 k; l0 k4 D
44.jpg

, }2 W/ S) D+ F! q+ ^/ H# k
开发板和主机配置
· 开发板Linux版本:Linux4.19.9
· 开发板IP:192.168.1.136
· 主机配置:Ubuntu 16.04
· 主机IP:192.168.1.111
  a+ r/ w9 l2 O( |, D/ t. a
55.png
+ M' l9 ^1 z( k7 v
2.数据接口的获取
! X+ u7 e' O# l* w8 C
疫情监控平台的实现,简单的说,就是数据的展示,而数据从哪里来呢?
现在很多互联网公司都做了自己的疫情监控平台,我这里采用的是腾讯新闻的数据源,数据内容很丰富,也比较稳定。

- A) h$ x% b! {* ]" Z" p' N
数据来源:
接口地址的获取方法可以参考(点击以下文章标题跳转到相关页面):
[开源]我用Qt做了个疫情数据实时监控平台
如果把所有的数据放在一个接口里,数据量会很大,所以腾讯把数据分成了几个接口
" M5 n5 F" {; N% E% s
66.png

- f& J3 p+ r+ ]/ f
目前只显示了一些基本的数据,所以我们只使用到了
* }' Z( }/ |; ]# T& u
这个接口中的chinaTotal和chinaAdd这两组数据。
5 N- s' `4 |9 @8 ?
这个接口包括很多数据,全国累计和新增的最新数据,各省市其他国家的最新数据等等。文件大小大概在160KB,液晶屏是7寸IPS屏,1024x600分辨率的,还是比较大的,可以显示很多信息,后续版本会添加更多数据显示的。
! S+ p3 d3 Q# w4 @3 w: L
数据格式:
+ m) ^: p, \* H! G& y- w9 Y
77.png
: q: {  a2 A8 ?4 F, B0 z2 t
3.Qt界面的实现
2 U8 u# P7 c5 j+ Q7 `( ]
之前的桌面应用程序中,是使用的是Qt5版本开发的,Qt5自带QJson解析类,而Qt 4没有带QJson。为了适配带有Qt 4库的板子,我使用了第三方JSON解析库。这里选择的是小巧的cJSON解析库:

; y( n7 _1 p4 y0 Q! ^  L; c1 I3 Q
http://sourceforge.net/projects/cjson/
( W, e1 l/ N* P0 Z9 M- d: h  y
如果你的板子是Qt 4的库,那么程序不用修改,直接交叉编译运行即可使用。
只包含两个文件:cJSON.c和cJSON.h,把这两个文件添加到工程里就行了。
整个工程代码也很简单:GET接口地址,把接收到的数据保存到本地,调用cJSON解析数据文件,把解析出的数据显示,数据文件删除。代码可以到文章末尾开源地址获取。下面介绍几个关键部分代码的实现:
: M: a  \$ _+ a* k6 n/ R
3.1 JSON数据的解析
# n4 p% O" m( N0 l2 ^
//打开保存的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版本的运行效果:

4 n9 G0 @0 C, i6 o; l+ Y* ^2 m& g
88.png

8 H; ^3 Z; z1 u8 E
4.在开发板上运行Qt程序
9 s1 x' M& P8 P9 O  L: T
如果在桌面运行正常,就可以使用ya157c构建套件来编译工程,生成可以在开发板上运行的程序,然后使用scp命令传输到开发板上。
$ y9 Q$ w( I8 y; |$ a' |9 ~
99.png
0 U. k3 }, L+ }( E' J# {
最终效果

0 ]6 e8 m. \% b+ j6 j
10.png

: L( t! o5 P$ K+ F- @# U( {+ ]
这个界面是上一个版本的,右上角没有显示开发板的IP地址和成功失败次数统计,最新版本的程序中已经添加了这个功能。
桌面Linux版效果:
4 Q5 W/ u4 d- O7 m& V
111.png
+ Y/ @3 R+ r2 P2 B( e+ l! ]% P
5.使用无线模块联网

. L6 M) x0 |# M3 A" f
YA157C开发板已经板载了一个WiFi& 蓝牙模组——AP6212,可以直接连接无线网,这样就不需要使用网线的方式联网了。
, I, X% p! ]: R% R) p/ }
222.jpg

& ^1 g( q* q! ]; C/ w7 G
依次执行:
# |, m3 M8 a# e
333.png
3 |4 W! o. z* u3 D$ I
实际运行:

1 Y5 z7 C" A7 l  F% e' ^8 C& I
444.png

4 m+ x7 F8 C4 ]4 Y4 i$ L3 m
为了方便快捷的连接WiFi,可以把以上命令写成一个shell脚本,需要连接WiFi时,直接执行这个脚本就可以了。先在本地生成WiFi配置信息:
connect_wifi.sh脚本文件内容:
555.png
2 i, v" }( U! m* t$ l3 k

0 c$ q1 x" d# d2 W! R9 K
WiFi账号和密码修改一下,就可以直接使用了。
2 B9 ?& z; \! L% J9 e: j0 J; `# N6 ~
666.png
2 C- n' I, d8 x8 p& D+ a
6.代码下载
9 W9 t  X  q& c. z1 \4 y2 H# P
整个Qt工程代码已经开源在Github,Qt4/Qt5兼容。如果下载速度很慢,可以选择国内的Gitee速度会快很多。
7 M' m) Z2 j! V# U
777.png

0 i) I) N: Q& Q8 s8 Z
目前界面还比较简单,7寸的显示屏可以显示很多内容,之后会尽量完善界面信息,欢迎大家关注!

4 l2 h/ r1 t$ n3 u: X
收藏 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 手机版