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

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

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

  {9 C) H1 S' G) }: P8 t; |
桌面Linux版本的运行效果:
8 K  ^/ u# b- Z' \7 V% E1 e
11.png
& f7 Y% a/ A% {7 B8 r0 X
YA157C开发板实现效果:
1 p/ a# r1 {7 C' _7 ^/ M' V( M
22.jpg

" O) ]# p. \, B7 G( o5 f2 n
1.准备工作
$ m* e4 t: `# w, N/ F( W! H: u
开发板简介

' }! C6 {1 J& G0 b* q) J' t$ c
· 开发板型号:
MYD-YA157C,512MBDDR3,4GB eMMC
· 主控芯片:
STM32MP157AAC3
· 光盘资料版本:
MYD-YA157C-20191225.iso
' G3 K' Y+ L- z$ k' B. Z+ [1 Z. N' Y
开发板如下:

+ \, A( ]1 w4 @
33.jpg
3 K& f( |1 Q3 C2 Q( R
MYD-YA157C开发套件由核心板MYC-YA157C和底板MYB-YA157C组成,主控芯片是ST目前最高配置的MPU——STM32MP157AAC3,双核Corte-A7+Cortex-M4,主频最高可达650Mhz。
3 H, k5 ?$ b: z9 @7 Q: C5 |3 ?
硬件准备

; ^2 H3 N/ g+ O, r
· 12v电源适配器
· USB-TTL模块:115200/8/1/无
· 网线

+ z, X; x( b! f6 \- J" \
44.jpg

9 N6 g% A0 K5 D4 H+ d
开发板和主机配置
· 开发板Linux版本:Linux4.19.9
· 开发板IP:192.168.1.136
· 主机配置:Ubuntu 16.04
· 主机IP:192.168.1.111

. A; {7 {$ e+ m" ~. C
55.png
0 L6 ]) B# I# |* l% p& {# t
2.数据接口的获取

5 f# y) {) |/ u4 W0 S0 Y
疫情监控平台的实现,简单的说,就是数据的展示,而数据从哪里来呢?
现在很多互联网公司都做了自己的疫情监控平台,我这里采用的是腾讯新闻的数据源,数据内容很丰富,也比较稳定。
% w0 h2 c: e3 J
数据来源:
接口地址的获取方法可以参考(点击以下文章标题跳转到相关页面):
[开源]我用Qt做了个疫情数据实时监控平台
如果把所有的数据放在一个接口里,数据量会很大,所以腾讯把数据分成了几个接口

# e% l, U+ P7 l0 M- `
66.png

8 t  i' {5 k& {* m* M& ^' f
目前只显示了一些基本的数据,所以我们只使用到了

  b0 g9 n% K2 u$ w8 _8 ^' L
这个接口中的chinaTotal和chinaAdd这两组数据。
" N0 B- i& i* `1 g
这个接口包括很多数据,全国累计和新增的最新数据,各省市其他国家的最新数据等等。文件大小大概在160KB,液晶屏是7寸IPS屏,1024x600分辨率的,还是比较大的,可以显示很多信息,后续版本会添加更多数据显示的。
  F; k6 \( u2 q1 |# z. p' k
数据格式:

4 H1 `' V: M: J; c
77.png

9 ~' u7 A" {( i7 X
3.Qt界面的实现

. M9 v; A  `' g; H& Z
之前的桌面应用程序中,是使用的是Qt5版本开发的,Qt5自带QJson解析类,而Qt 4没有带QJson。为了适配带有Qt 4库的板子,我使用了第三方JSON解析库。这里选择的是小巧的cJSON解析库:

" T* H) `& T  ?2 P& r# h4 ]; a
http://sourceforge.net/projects/cjson/
0 O( N' w" m8 F8 H2 H
如果你的板子是Qt 4的库,那么程序不用修改,直接交叉编译运行即可使用。
只包含两个文件:cJSON.c和cJSON.h,把这两个文件添加到工程里就行了。
整个工程代码也很简单:GET接口地址,把接收到的数据保存到本地,调用cJSON解析数据文件,把解析出的数据显示,数据文件删除。代码可以到文章末尾开源地址获取。下面介绍几个关键部分代码的实现:
4 I/ H$ C7 @5 i/ C+ t2 ?% i/ I
3.1 JSON数据的解析

4 `3 q+ P7 p8 R0 O* X
//打开保存的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版本的运行效果:

  J  _1 Y7 N! J1 V) b, I
88.png

) \- [6 d4 r/ w. \0 e
4.在开发板上运行Qt程序
0 [, f3 f: g2 P0 u
如果在桌面运行正常,就可以使用ya157c构建套件来编译工程,生成可以在开发板上运行的程序,然后使用scp命令传输到开发板上。

! M; \  ?$ K; t) R5 T, o  K1 z
99.png
7 R5 W: k/ \! h" ?4 E" B% \
最终效果
2 \  s! z: L9 B- r6 w9 |/ J
10.png
0 \6 @: ^& H" a" k
这个界面是上一个版本的,右上角没有显示开发板的IP地址和成功失败次数统计,最新版本的程序中已经添加了这个功能。
桌面Linux版效果:
+ C; `+ s, o8 m3 \: s; J
111.png
# _2 R1 C& }. f
5.使用无线模块联网
6 b- U3 A$ M1 ]5 q
YA157C开发板已经板载了一个WiFi& 蓝牙模组——AP6212,可以直接连接无线网,这样就不需要使用网线的方式联网了。
; M+ w) R% A0 j
222.jpg

" l, @9 c) ]) j6 W$ t2 a
依次执行:
* j+ c* H8 U4 I1 v/ q& S6 t
333.png

9 g7 C: ~, k" d7 O
实际运行:
0 U- }4 i) p9 U5 K1 g
444.png

3 B0 x* P( F0 w. |
为了方便快捷的连接WiFi,可以把以上命令写成一个shell脚本,需要连接WiFi时,直接执行这个脚本就可以了。先在本地生成WiFi配置信息:
connect_wifi.sh脚本文件内容:
555.png
3 h+ u& B- Q) D' m/ J( p/ b
; T. I3 m7 o% o. x: I& J
WiFi账号和密码修改一下,就可以直接使用了。
7 z: F( {' C0 E
666.png
% R( v/ M) N; w& q
6.代码下载
4 g. ?3 A% q% [' X) s
整个Qt工程代码已经开源在Github,Qt4/Qt5兼容。如果下载速度很慢,可以选择国内的Gitee速度会快很多。
9 V% \- m& F. C3 S+ G" A8 H
777.png
% b/ r/ h! P% b% M0 e. @
目前界面还比较简单,7寸的显示屏可以显示很多内容,之后会尽量完善界面信息,欢迎大家关注!

6 ~) l$ T& k) `. L, Z6 c& s6 C+ d
收藏 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管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版