微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 之基于Qt的环境信息采集系统设计(结项篇)

之基于Qt的环境信息采集系统设计(结项篇)

时间:10-02 整理:3721RD 点击:

基于Qt的环境信息采集系统

项目概述:

   随着科学技术的发展,大数据、机器学习、人工智能、物联网不断涌入人们的生活,因此人们生活质量的相比之前也得到很大的改善。本项目即结合Rico Board设计的一套基于Qt的环境采集系统,旨在用于智能家居领域为我们的生活提供便利。系统主要实现利用Rico Board结合相应传感器,来采集当前环境下的温湿度等信息,另外可以实现对家居电器的智能控制,同时具有对环境信息超过阈值自动报警等功能。

系统硬件设计:

   由于需要采集各种环境信息,同时要能对危险情况下产生报警动作,所以之类需要采用传感器和继电器来实现,另外根据Rico Board自身的一些接口和外置音频接口,可以实现简单的多媒体等功能,因此综上系统设计硬件框图如下:



图一 硬件设计框图


实验准备:

  • Rico Board板卡
  • HDMI转接线
  • HDMI显示器
  • 5V/2A电源
  • ESP8266模块
  • 继电器模块
  • AM2302传感器


系统软件部分:

   系统上位机使用Qt4.8.5编写程序,Qt就是一个C++的类库,实际上就是编写C++程序。所以说只要学过C++的去编写Qt程序很容易上手。C++是在C语言上进行开发的语言,很多语法跟C语言很像。不过C++在C语言上扩展了很多语法。C语言是面向过程的语言,而C++是面向对象的一种语言。同时调用了Linux驱动程序。在上位机设计时,自己创建了许多类,下面就以表格的方式来介绍这些类。类的部分成员如表下表所示。


类的成员表1



类的成员表2



   上面是上位机设计用到的一些类图,由于有些类成员很多,所以只是把其中重要的写了出来。下面我用一张图来表示这些类之间的关系,如下图所示。注:箭头这个类包含指向的那个类的指针变量


图二 类间关系

程序流程图:

1.加载驱动:
   系统会自动加载串口驱动和HDMI接口驱动。

2.创建mainface对象:
   
首先定义mainface的一个对象。这是整个显示界面的类,里面包含整个程序运行的所有资源,在创建这个类时会先创建一个Wifi类。这个Wifi对象就是和ESP8266通信的接口。创建完对象以后函数打开ESP8266服务器,打开这个服务器是为了跟下位机的ESP8266进行TCP连接,然后进行上位机和下位机的通信(这部分还些问题)。然后再初始化Qt界面,初始化键盘类,初始化时间而且实时显示在界面上,初始化几个furniture对象,每个furniture对象代表一个电器,还要初始化一个Alarm类,这个类用来表示现在是否处于报警状态。还初始化几个Dial来显示温湿度,这个类实际上是画了一个仪表盘样子的表,然后还有一个指针指向当前的数据。

3.创建Login对象:
   
这部分是在创建一个Login对象,在创建这个对象时还会,添加两个lineEdit对象用来输入用户名和密码,然后添加两个pushButton对象,这是两个按键一个用来当登陆按钮,一个用来清除输入的账号密码。创建完成后显示这个登陆界面。

4.进入Qt循环事件:
   执行完以上步骤以后程序就进入Qt循环事件,同时还有两个进程再运行,用来采集信息和图形界面进行实时显示。

5.进行事件处理:
   接受到数据,然后执行他们各自的数据处理,并发出事件,该事件与mainface对象的一个槽函数相连接,所以会转到该事件进行执行。同时也有可能是点击按键事件,每个按键都对应一个槽函数,当点击该案件时就会转到该按键对应的槽函数去执行相应的处理。


项目工程代码:

  1. #include "dialog.h"
  2. #include "ui_dialog.h"
  3. #include "./keyboard/keyboard.h"

  4. Dialog::Dialog(QWidget *parent) :
  5.     QDialog(parent),
  6.     ui(new Ui::Dialog)
  7. {
  8.     setWindowFlags(Qt::FramelessWindowHint);
  9.     setAttribute(Qt::WA_TranslucentBackground);
  10.     ui->setupUi(this);
  11.     lineEditkeyboard = new Keyboard();
  12.     connect(ui->lineEdit ,SIGNAL(selectionChanged()),this ,SLOT(open_keyboard_lineEdit()));
  13.     connect(ui->lineEdit_2,SIGNAL(selectionChanged()),this ,SLOT(open_keyboard_lineEdit()));
  14. }

  15. Dialog::~Dialog()
  16. {
  17.     delete ui;
  18. }

  19. void Dialog::open_keyboard_lineEdit()
  20. {
  21.     QLineEdit *line = (QLineEdit *)sender();
  22.     lineEditkeyboard->setLineEdit(line);
  23.     lineEditkeyboard->show();
  24. }

  25. void Dialog::on_pushButton_clicked()
  26. {
  27.     if(this->ui->lineEdit->text().trimmed()== tr("zdl") &&
  28.          this->ui->lineEdit_2->text().trimmed()==tr("935520"))
  29.       {
  30.           accept();
  31.       }
  32.     else
  33.     {
  34.           QTextCodec::setCodecForTr( QTextCodec::codecForName("GBK") );
  35.           QMessageBox::warning(this,tr("Warning"),tr("username and password are wrong!"),QMessageBox::Yes);
  36.           this->ui->lineEdit->clear();
  37.           this->ui->lineEdit_2->clear();
  38.           this->ui->lineEdit->setFocus();
  39.       }
  40. }

  41. void Dialog::on_pushButton_2_clicked()
  42. {
  43.     this->ui->lineEdit->clear();
  44.     this->ui->lineEdit_2->clear();
  45.     this->ui->lineEdit->setFocus();
  46. }

复制代码

  1. #include "mainface.h"
  2. #include "ui_mainface.h"
  3. #include "wendu/qcw_meter.h"
  4. #include"./wifi/Wifi.h"
  5. #include "./keyboard/keyboard.h"

  6. mainface::mainface(QWidget *parent) :
  7.     QMainWindow(parent),
  8.     ui(new Ui::mainface)
  9. {
  10.     ui->setupUi(this);
  11.     wifi_init();
  12.     initData();
  13.     enviroment_init();
  14.     keyboard_init();
  15.     time_init();
  16.     alarm_init();
  17.     led_init();
  18. }

  19. mainface::~mainface()
  20. {
  21.     delete ui;
  22. }

  23. void mainface::open_keyboard_lineEdit()
  24. {
  25.     QLineEdit *line = (QLineEdit *)sender();
  26.     lineEditkeyboard->setLineEdit(line);
  27.     lineEditkeyboard->show();
  28. }



  29. void mainface::initData()
  30. {
  31.     setWindowFlags(Qt::FramelessWindowHint);
  32.     setAttribute(Qt::WA_TranslucentBackground);
  33.     m_vecBtn.push_back(ui->environment);
  34.     m_vecBtn.push_back(ui->control);
  35.     m_vecBtn.push_back(ui->music);
  36.     m_vecBtn.push_back(ui->option);
  37.     m_vecBtn.push_back(ui->set);

  38.     for (int i = 0; i != m_vecBtn.size(); ++i)
  39.     {
  40.         ///功能选择键只有一个被选中;
  41.         m_vecBtn[i]->setCheckable(true);
  42.         m_vecBtn[i]->setAutoExclusive(true);
  43.     }
  44. }

  45. void mainface::setCurrentWidget()
  46. {
  47.     for (int i = 0; i != m_vecBtn.size(); ++i)
  48.     {
  49.         if ( m_vecBtn[i]->isChecked() )
  50.         {
  51.             ui->stackedWidget->setCurrentIndex(i);
  52.         }
  53.     }
  54. }

  55. void mainface::on_environment_clicked()
  56. {
  57.     setCurrentWidget();
  58. }

  59. void mainface::on_control_clicked()
  60. {
  61.     setCurrentWidget();
  62. }

  63. void mainface::on_music_clicked()
  64. {
  65.     setCurrentWidget();
  66. }

  67. void mainface::on_option_clicked()
  68. {
  69.     setCurrentWidget();
  70. }

  71. void mainface::on_set_clicked()
  72. {
  73.     setCurrentWidget();
  74. }

  75. void mainface::enviroment_init()
  76. {
  77.     wendu1=new QcwMeter(ui->temp);
  78.     shidu1=new QcwMeter(ui->shidu);
  79.     shidu1->setUnits("%");
  80.     wendu1->setMinValue(0);
  81.     wendu1->setMaxValue(40);
  82.     shidu1->setMinValue(0);
  83.     shidu1->setMaxValue(80);

  84.     wendu2=new QcwMeter(ui->temp_2);
  85.     shidu2=new QcwMeter(ui->shidu_2);
  86.     shidu2->setUnits("%");
  87.     wendu2->setMinValue(0);
  88.     wendu2->setMaxValue(40);
  89.     shidu2->setMinValue(0);
  90.     shidu2->setMaxValue(80);
  91. }

  92. void mainface::wifi_init()
  93. {
  94.    wifi2=new Wifi();
  95.    wifi2->openserver();
  96.    QObject::connect(wifi2,SIGNAL(readyRead(QString)),this,SLOT(DataComing(QString)),Qt::QueuedConnection);
  97. }
  98. void mainface::keyboard_init()
  99. {
  100.     lineEditkeyboard = new Keyboard();
  101.     connect(ui->lineEdit ,SIGNAL(selectionChanged()),this ,SLOT(open_keyboard_lineEdit()));
  102.     connect(ui->lineEdit_2 ,SIGNAL(selectionChanged()),this ,SLOT(open_keyboard_lineEdit()));
  103.     connect(ui->lineEdit_3 ,SIGNAL(selectionChanged()),this ,SLOT(open_keyboard_lineEdit()));
  104.     connect(ui->lineEdit_4,SIGNAL(selectionChanged()),this ,SLOT(open_keyboard_lineEdit()));
  105. }

  106. void mainface::time_init()
  107. {
  108.     ui->lcdNumber->setNumDigits(8); //显示格式 hh:mm:ss

  109.     ui->lcdNumber->setSegmentStyle(QLCDNumber::Flat); //设置时间显示字体

  110.     ui->lcdNumber->display(QTime::currentTime().toString("hh:mm:ss"));


  111.     timer = new QTimer();

  112.     QObject::connect(timer,SIGNAL(timeout()),this,SLOT(chTime()));

  113.     timer->start(1000);
  114. }
  115. void mainface::alarm_init()
  116. {
  117.     alarm1=new QcwIndicatorLamp(ui->alarm);
  118.     alarm2=new QcwIndicatorLamp(ui->alarm_2);
  119.     wen1_alarm="100";
  120.     shi1_alarm="100";
  121.     wen2_alarm="100";
  122.     shi2_alarm="100";
  123. }


  124. void mainface::led_init()
  125. {
  126.     led11=new Led(ui->widget);
  127.     led12=new Led(ui->widget_3);
  128.     led21=new Led(ui->widget_2);
  129.     led22=new Led(ui->widget_4);
  130. }



  131. void mainface::chTime()
  132. {
  133.     QTime time = QTime::currentTime();

  134.     QString text = time.toString("hh:mm:ss");

  135.     ui->lcdNumber->display(text);
  136. }



  137. void mainface::DataComing(QString buf)
  138. {
  139.     int id=buf.mid(0,1).toInt();
  140.     QString wen,shi,yanwu,led1,led2;
  141.     wen=buf.mid(1,3);
  142.     shi=buf.mid(4,3);
  143.     yanwu=buf.mid(7,1);
  144.     if(id==1)
  145.     {
  146.        wendu1->setValue(wen.toDouble()/10);
  147.        shidu1->setValue(shi.toDouble()/10);
  148.     }
  149.     if(id==2)
  150.     {
  151.         wendu2->setValue(wen.toDouble()/10);
  152.         shidu2->setValue(shi.toDouble()/10);
  153.     }
  154.     is_alarm(id,yanwu.toInt());

  155.     if(wifi2->idflag==1)
  156.     {
  157.             wifi2->idflag=0;
  158.             wifi2->SendData("AT+RST\r");
  159.             wifi2->id1="";
  160.             wifi2->id2="";
  161.             //sleep(5);
  162.             wifi2->openserver();
  163.     }
  164. }
  165. void mainface::is_alarm(int id,int yanwu)
  166. {
  167.     if(id==1)
  168.     {
  169.         if(yanwu==1||wendu1->value()>wen1_alarm.toDouble()||shidu1->value()>shi1_alarm.toDouble())
  170.         {
  171.             if(alarm1->isAlarm()==false)
  172.             {
  173.                  alarm1->setAlarm(true);
  174.             }
  175.         }
  176.         else
  177.         {
  178.             if(alarm1->isAlarm()==true)
  179.             {
  180.                  alarm1->setAlarm(false);
  181.             }
  182.         }
  183.     }
  184.     if(id==2)
  185.     {
  186.         if(yanwu==1||wendu2->value()>wen2_alarm.toDouble()||shidu2->value()>shi2_alarm.toDouble())
  187.         {
  188.             if(alarm2->isAlarm()==false)
  189.             {
  190.                  alarm2->setAlarm(true);
  191.             }
  192.         }
  193.         else
  194.         {
  195.             if(alarm2->isAlarm()==true)
  196.             {
  197.                  alarm2->setAlarm(false);
  198.             }
  199.         }
  200.     }
  201. }

  202. void mainface::on_set_alarm_clicked()
  203. {
  204.     wen1_alarm=ui->lineEdit->text();
  205.     shi1_alarm=ui->lineEdit_2->text();
  206.     wen2_alarm=ui->lineEdit_3->text();
  207.     shi2_alarm=ui->lineEdit_4->text();
  208.     is_alarm(1,0);
  209.     is_alarm(2,0);
  210. }

  211. void mainface::on_led11_control_clicked()
  212. {
  213.     if(led11->isLed())
  214.     {
  215.         led11->setLed(false);
  216.     }
  217.     else
  218.     {
  219.          led11->setLed(true);
  220.     }
  221.     sendmsg1();
  222. }

  223. void mainface::on_led12_control_clicked()
  224. {
  225.     if(led12->isLed())
  226.     {
  227.         led12->setLed(false);
  228.     }
  229.     else
  230.     {
  231.          led12->setLed(true);
  232.     }
  233.     sendmsg1();
  234. }

  235. void mainface::on_led21_control_clicked()
  236. {
  237.     if(led21->isLed())
  238.     {
  239.         led21->setLed(false);
  240.     }
  241.     else
  242.     {
  243.          led21->setLed(true);
  244.     }
  245.     sendmsg2();
  246. }

  247. void mainface::on_led22_control_clicked()
  248. {
  249.     if(led22->isLed())
  250.     {
  251.         led22->setLed(false);
  252.     }
  253.     else
  254.     {
  255.          led22->setLed(true);
  256.     }
  257.     sendmsg2();
  258. }

  259. void mainface::sendmsg1()
  260. {
  261.     QString data="1";
  262.     if(led11->isLed())
  263.     {
  264.         data.append("1");
  265.     }
  266.     else
  267.     {
  268.         data.append("0");
  269.     }

  270.     if(led12->isLed())
  271.     {
  272.         data.append("1");
  273.     }
  274.     else
  275.     {
  276.         data.append("0");
  277.     }
  278.     wifi2->sendmsg(data,wifi2->id1);
  279. }


  280. void mainface::sendmsg2()
  281. {
  282.     QString data="2";
  283.     if(led21->isLed())
  284.     {
  285.         data.append("1");
  286.     }
  287.     else
  288.     {
  289.         data.append("0");
  290.     }

  291.     if(led22->isLed())
  292.     {
  293.         data.append("1");
  294.     }
  295.     else
  296.     {
  297.         data.append("0");
  298.     }
  299.     wifi2->sendmsg(data,wifi2->id2);
  300. }

复制代码


软件调试:

   为了方便测试和这里首先最好设置开机自启,详细操作见帖子:【Rico Board试用体验】Qt应用移植到Rico Board测试并设置自启动这里主要是修改启动文件,让启动时开始执行QT应用,具体如下


然后重启Rico Board会看到开机后直接进入系统登录界面。

注:如果出现两个鼠标的问题,可以参考下前面帖子:【Rico Board试用体验】Qt开发中问题及解决方法小结测试结果:


图四 温室度采集子界面


   这里设置了2个方间的信息数据采集,当然也可以添加更多个,因为手头传感器显示,所以只显示了方间1有信息数据。从动态变化的数据中可以看到,方间1的温度为:湿度为


图五 家电开关控制子界面


   这部分主要是用来控制家电的开关,可以是空调,灯光,窗帘灯各种开关,另外也可以根据需要添加更多开关节点。


图七 报警阈值设置子界面


   设置这里主要是设置报警阈值。这里也是两个房间的,下面是设置中温度和湿度最大阈值,两个房间所以有四栏。超过则报警,显示为红色,正常情况下为绿色。

系统整体视图如下:


图八 系统视图

视频演示:

http://v.youku.com/v_show/id_XMTkzMjA4NDA2MA==.html?spm=a2hww.20023042.uerCenter.5!2~5~5!2~5~DL~DD~A.cQVl60&firsttime=203

若无法播放请点链接:基于QT的环境信息采集系统


试用总结:

   本次Rico Board主要是围绕基于Qt的环境信息采集系统进行的,期间因为一些事情,所以一直耽搁到现在才结项。在Qt项目开发中遇到了很多问题,比如无法编译、界面出现箭头拖动痕迹等。还好有网友和官方的帮助,除了wifi部分还在调试,其他部分最终基本上都已顺利完成。后面准备加上多媒体部分已经其他传感器的信息采集,另外结合网络实现天气等更多的信息,争取设计的更加完善。由于试用即将结束,所以根据自己2个多月的研究情况再次进行一个总结。后面附自己前面分享试用中分享的一些帖子如下(附件)。

  最后欢迎和大家一起学习共同进步!同时非常感谢米尔科技和电子发烧友论坛提供的此次试用机会!


附:
  • 【Rico Board试用体验】之完美初见
  • 【Rico Board试用体验】之系统上电体验
  • 【Rico Board试用体验】之配置交叉编译环境和工具
  • 【Rico Board试用体验】之编译触摸屏驱动Tslib
  • 【Rico Board试用体验】之编译并移植qt问题
  • 【Rico Board试用体验】之PC端配置IDE并测试
  • 【Rico Board试用体验】之系统登录对话框设计
  • 【Rico Board试用体验】Qt开发中问题及解决方法小结
  • 【Rico Board试用体验】Qt应用移植到Rico Board测试并设置自启动
  • 【Rico Board试用体验】之基于Qt的环境信息采集系统主界面设计
  • 【Rico Board试用体验】之基于Qt的环境信息采集系统完结篇


非常棒!

谢谢!

小编的界面做的真好看。

刚发现这个区,刚买了块板子~要是先看见这就好了

现在也不晚,一起学习!

小编开发的界面很强悍

厉害了我的哥~

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top