iMX287A基於嵌入式Qt的新冠肺炎疫情監控平台

@

1.前言

之前我使用在桌面版本Qt實現了肺炎疫情監控平台:基於Qt的新冠肺炎疫情數據實時監控平台(開源小項目)。既然Qt是跨平台的,正好手裡有一塊iMX287A的開發套件,含一塊4.3寸的顯示器,那麼能不能在嵌入式平台實現一下呢?

最後實現的效果:

2.數據介面的獲取

疫情監控平台的實現,簡單的說,就是數據的展示,而數據從哪裡來呢?現在很多互聯網公司都做了自己的疫情監控平台,我這裡採用的是騰訊新聞的數據源,數據內容比較豐富,也比較穩定。

數據來源:實時更新:新冠肺炎疫情最新動態
介面地址的獲取方法可以參考:基於Qt的新冠肺炎疫情數據實時監控平台(開源小項目)

如果把所有的數據放在一個介面里,數據量會很大,騰訊把數據分成了幾個介面

#包含最新疫情數據、各省市最新數據、其他國家最新數據  https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5    #包含歷史數據d  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

由於液晶螢幕幕太小,只有4.3寸,解析度也比較低480 × 272,顯示不了太多的內容,所以我們只使用到了https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5這個介面中的chinaTotalchinaAdd這兩組數據。

這個介面包括很多數據,全國累計和新增的最新數據,各省市其他國家的最新數據等等。文件大小大概在160KB。

數據格式:

{      "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,所以只能使用第三方JSON解析庫,我這裡選擇的小巧的cJSON解析庫:cJSON download | SourceForge.net
只包含兩個文件: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));      else          lbe->setText(QString::number(num));  }  

3.2 根據編譯器的版本自動調整窗口大小

void Dialog::setLocation()  {        const QRect availableSize = QApplication::desktop()->availableGeometry(this);        qint32 DESKTOP_QT4 = 264199;      qint32 DESKTOP_QT5 = 329728;      qint32 ARM_IMX287  = 263939;      qint32 ARM_YA157C  = 264199;        //output current qt version id      qDebug() << QT_VERSION;        //output curretn screen resolution ratio      qint16 width  = availableSize.width();      qint16 height = availableSize.height();      qDebug() << "width: " << width << "height:" << height;        if(QT_VERSION == ARM_IMX287)          this->resize(width-5, height-15);      else          this->resize(width/3, height/3);        qint16 loc_width = this->width();      qint16 loc_height = this->height();      qint16 loc_x = (width - loc_width) / 2;      qint16 loc_y = (height - loc_height) / 2;      qDebug() << "locx:" << loc_x << "locy" << loc_y;        if(QT_VERSION == ARM_IMX287)          this->move(0, 0);      else          this->move(loc_x, loc_y);  }

3.3 獲取本地IP地址

//forexamle: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 localhost      if (ipAddress.isEmpty())          ipAddress = QHostAddress(QHostAddress::LocalHost).toString();      return ipAddress;  }  

桌面Linux版本的運行效果:
在這裡插入圖片描述

4.在開發板上運行Qt程式

如果在桌面運行正常,就可以使用iMX287A開發套件來構建工程,生成可以在iMX287A運行的程式,使用scp命令傳輸到開發板上還需要使用udhcpc命令來自動獲取路由器獲取的IP地址,並連接上互聯網。

#使用網線把開發板連接上路由器  #使用udhcpc自動獲取IP地址  udhcpc    #確認連接到互聯網  ping www.baidu.com  #如果有回複數據,說明已經成功連接上互聯網    #查看獲取到的ip地址  ifconfig    #使用scp命令或共享目錄的方式把可執行文件傳輸到開發板上  scp imx287a_qt_ncov [email protected]:/root    #執行程式  ./imx287a_qt_ncov

5.最終效果

開發板運行效果

這個版本是上一個版本的,右上角沒有顯示開發板的IP地址,和成功失敗次數統計,最新版本的程式中已經添加了這個功能。
桌面Linux版效果:
在這裡插入圖片描述

6.程式碼下載

程式碼已經開源在Github,如果下載速度很慢,可以選擇中國的Gitee速度會快很多。

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

我的公眾號:mcu149