0.前言 之前我使用桌面版本Qt实现了肺炎疫情监控平台(点击以下文章标题跳转到相关页面): [开源]我用Qt做了个疫情数据实时监控平台 既然Qt是跨平台的,那么能不能在嵌入式平台实现一下呢?最近刚好看到,ST官方在开展创客大赛活动,就买了米尔科技的YA157C开发板移植一下。 桌面Linux版本的运行效果: YA157C开发板实现效果: 1.准备工作 开发板简介 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# { 开发板如下: MYD-YA157C开发套件由核心板MYC-YA157C和底板MYB-YA157C组成,主控芯片是ST目前最高配置的MPU——STM32MP157AAC3,双核Corte-A7+Cortex-M4,主频最高可达650Mhz。 硬件准备 · 12v电源适配器 · USB-TTL模块:115200/8/1/无 · 网线 开发板和主机配置 · 开发板Linux版本:Linux4.19.9 · 开发板IP:192.168.1.136 · 主机配置:Ubuntu 16.04 · 主机IP:192.168.1.111 a+ r/ w9 l2 O( |, D/ t. a2.数据接口的获取 ! X+ u7 e' O# l* w8 C 疫情监控平台的实现,简单的说,就是数据的展示,而数据从哪里来呢? 现在很多互联网公司都做了自己的疫情监控平台,我这里采用的是腾讯新闻的数据源,数据内容很丰富,也比较稳定。 数据来源: 接口地址的获取方法可以参考(点击以下文章标题跳转到相关页面): [开源]我用Qt做了个疫情数据实时监控平台 如果把所有的数据放在一个接口里,数据量会很大,所以腾讯把数据分成了几个接口 " M5 n5 F" {; N% E% s目前只显示了一些基本的数据,所以我们只使用到了 * }' 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 Y3.Qt界面的实现 2 U8 u# P7 c5 j+ Q7 `( ] 之前的桌面应用程序中,是使用的是Qt5版本开发的,Qt5自带QJson解析类,而Qt 4没有带QJson。为了适配带有Qt 4库的板子,我使用了第三方JSON解析库。这里选择的是小巧的cJSON解析库: 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.在开发板上运行Qt程序 9 s1 x' M& P8 P9 O L: T 如果在桌面运行正常,就可以使用ya157c构建套件来编译工程,生成可以在开发板上运行的程序,然后使用scp命令传输到开发板上。 $ y9 Q$ w( I8 y; |$ a' |9 ~最终效果 这个界面是上一个版本的,右上角没有显示开发板的IP地址和成功失败次数统计,最新版本的程序中已经添加了这个功能。 桌面Linux版效果: 4 Q5 W/ u4 d- O7 m& V5.使用无线模块联网 YA157C开发板已经板载了一个WiFi& 蓝牙模组——AP6212,可以直接连接无线网,这样就不需要使用网线的方式联网了。 , I, X% p! ]: R% R) p/ }依次执行: # |, m3 M8 a# e实际运行: 为了方便快捷的连接WiFi,可以把以上命令写成一个shell脚本,需要连接WiFi时,直接执行这个脚本就可以了。先在本地生成WiFi配置信息: connect_wifi.sh脚本文件内容: WiFi账号和密码修改一下,就可以直接使用了。 2 B9 ?& z; \! L% J9 e: j0 J; `# N6 ~6.代码下载 9 W9 t X q& c. z1 \4 y2 H# P 整个Qt工程代码已经开源在Github,Qt4/Qt5兼容。如果下载速度很慢,可以选择国内的Gitee速度会快很多。 7 M' m) Z2 j! V# U目前界面还比较简单,7寸的显示屏可以显示很多内容,之后会尽量完善界面信息,欢迎大家关注! |
牛牛 |
linux系统移植吗?没有看懂怎么把系统放上去的 |
最新消息:意法半导体最具性价比、速度最快的单核MPU STM32MP13现已支持运行RTOS!意法半导体兑现了之前的承诺!
STM32MP135F-DK开发板评测-开箱亮屏
意法半导体扩展STM32Cube开发环境,简化单核STM32MP1裸机软件开发
1月18日有奖直播 | 如何在STM32MP13x上实现FOTA升级?
【STM32MP13x直播回顾】 直播答疑汇总
STM32MP135 开发平台介绍
使用STM32MP13: 如MCU般在Cortex-A核上裸 跑应用程序
米尔核心板加速基于STM32MP1的产品开发
STM32MP1充电桩全数字交互实现
STM32MP13 产品线 应用于工业和安全的高性价比MPU