之基于Qt的环境信息采集系统设计(结项篇)
基于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对象的一个槽函数相连接,所以会转到该事件进行执行。同时也有可能是点击按键事件,每个按键都对应一个槽函数,当点击该案件时就会转到该按键对应的槽函数去执行相应的处理。
项目工程代码:
- #include "dialog.h"
- #include "ui_dialog.h"
- #include "./keyboard/keyboard.h"
- Dialog::Dialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::Dialog)
- {
- setWindowFlags(Qt::FramelessWindowHint);
- setAttribute(Qt::WA_TranslucentBackground);
- ui->setupUi(this);
- lineEditkeyboard = new Keyboard();
- connect(ui->lineEdit ,SIGNAL(selectionChanged()),this ,SLOT(open_keyboard_lineEdit()));
- connect(ui->lineEdit_2,SIGNAL(selectionChanged()),this ,SLOT(open_keyboard_lineEdit()));
- }
- Dialog::~Dialog()
- {
- delete ui;
- }
- void Dialog::open_keyboard_lineEdit()
- {
- QLineEdit *line = (QLineEdit *)sender();
- lineEditkeyboard->setLineEdit(line);
- lineEditkeyboard->show();
- }
- void Dialog::on_pushButton_clicked()
- {
- if(this->ui->lineEdit->text().trimmed()== tr("zdl") &&
- this->ui->lineEdit_2->text().trimmed()==tr("935520"))
- {
- accept();
- }
- else
- {
- QTextCodec::setCodecForTr( QTextCodec::codecForName("GBK") );
- QMessageBox::warning(this,tr("Warning"),tr("username and password are wrong!"),QMessageBox::Yes);
- this->ui->lineEdit->clear();
- this->ui->lineEdit_2->clear();
- this->ui->lineEdit->setFocus();
- }
- }
- void Dialog::on_pushButton_2_clicked()
- {
- this->ui->lineEdit->clear();
- this->ui->lineEdit_2->clear();
- this->ui->lineEdit->setFocus();
- }
- #include "mainface.h"
- #include "ui_mainface.h"
- #include "wendu/qcw_meter.h"
- #include"./wifi/Wifi.h"
- #include "./keyboard/keyboard.h"
- mainface::mainface(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::mainface)
- {
- ui->setupUi(this);
- wifi_init();
- initData();
- enviroment_init();
- keyboard_init();
- time_init();
- alarm_init();
- led_init();
- }
- mainface::~mainface()
- {
- delete ui;
- }
- void mainface::open_keyboard_lineEdit()
- {
- QLineEdit *line = (QLineEdit *)sender();
- lineEditkeyboard->setLineEdit(line);
- lineEditkeyboard->show();
- }
- void mainface::initData()
- {
- setWindowFlags(Qt::FramelessWindowHint);
- setAttribute(Qt::WA_TranslucentBackground);
- m_vecBtn.push_back(ui->environment);
- m_vecBtn.push_back(ui->control);
- m_vecBtn.push_back(ui->music);
- m_vecBtn.push_back(ui->option);
- m_vecBtn.push_back(ui->set);
- for (int i = 0; i != m_vecBtn.size(); ++i)
- {
- ///功能选择键只有一个被选中;
- m_vecBtn[i]->setCheckable(true);
- m_vecBtn[i]->setAutoExclusive(true);
- }
- }
- void mainface::setCurrentWidget()
- {
- for (int i = 0; i != m_vecBtn.size(); ++i)
- {
- if ( m_vecBtn[i]->isChecked() )
- {
- ui->stackedWidget->setCurrentIndex(i);
- }
- }
- }
- void mainface::on_environment_clicked()
- {
- setCurrentWidget();
- }
- void mainface::on_control_clicked()
- {
- setCurrentWidget();
- }
- void mainface::on_music_clicked()
- {
- setCurrentWidget();
- }
- void mainface::on_option_clicked()
- {
- setCurrentWidget();
- }
- void mainface::on_set_clicked()
- {
- setCurrentWidget();
- }
- void mainface::enviroment_init()
- {
- wendu1=new QcwMeter(ui->temp);
- shidu1=new QcwMeter(ui->shidu);
- shidu1->setUnits("%");
- wendu1->setMinValue(0);
- wendu1->setMaxValue(40);
- shidu1->setMinValue(0);
- shidu1->setMaxValue(80);
- wendu2=new QcwMeter(ui->temp_2);
- shidu2=new QcwMeter(ui->shidu_2);
- shidu2->setUnits("%");
- wendu2->setMinValue(0);
- wendu2->setMaxValue(40);
- shidu2->setMinValue(0);
- shidu2->setMaxValue(80);
- }
- void mainface::wifi_init()
- {
- wifi2=new Wifi();
- wifi2->openserver();
- QObject::connect(wifi2,SIGNAL(readyRead(QString)),this,SLOT(DataComing(QString)),Qt::QueuedConnection);
- }
- void mainface::keyboard_init()
- {
- lineEditkeyboard = new Keyboard();
- connect(ui->lineEdit ,SIGNAL(selectionChanged()),this ,SLOT(open_keyboard_lineEdit()));
- connect(ui->lineEdit_2 ,SIGNAL(selectionChanged()),this ,SLOT(open_keyboard_lineEdit()));
- connect(ui->lineEdit_3 ,SIGNAL(selectionChanged()),this ,SLOT(open_keyboard_lineEdit()));
- connect(ui->lineEdit_4,SIGNAL(selectionChanged()),this ,SLOT(open_keyboard_lineEdit()));
- }
- void mainface::time_init()
- {
- ui->lcdNumber->setNumDigits(8); //显示格式 hh:mm:ss
- ui->lcdNumber->setSegmentStyle(QLCDNumber::Flat); //设置时间显示字体
- ui->lcdNumber->display(QTime::currentTime().toString("hh:mm:ss"));
- timer = new QTimer();
- QObject::connect(timer,SIGNAL(timeout()),this,SLOT(chTime()));
- timer->start(1000);
- }
- void mainface::alarm_init()
- {
- alarm1=new QcwIndicatorLamp(ui->alarm);
- alarm2=new QcwIndicatorLamp(ui->alarm_2);
- wen1_alarm="100";
- shi1_alarm="100";
- wen2_alarm="100";
- shi2_alarm="100";
- }
- void mainface::led_init()
- {
- led11=new Led(ui->widget);
- led12=new Led(ui->widget_3);
- led21=new Led(ui->widget_2);
- led22=new Led(ui->widget_4);
- }
- void mainface::chTime()
- {
- QTime time = QTime::currentTime();
- QString text = time.toString("hh:mm:ss");
- ui->lcdNumber->display(text);
- }
- void mainface::DataComing(QString buf)
- {
- int id=buf.mid(0,1).toInt();
- QString wen,shi,yanwu,led1,led2;
- wen=buf.mid(1,3);
- shi=buf.mid(4,3);
- yanwu=buf.mid(7,1);
- if(id==1)
- {
- wendu1->setValue(wen.toDouble()/10);
- shidu1->setValue(shi.toDouble()/10);
- }
- if(id==2)
- {
- wendu2->setValue(wen.toDouble()/10);
- shidu2->setValue(shi.toDouble()/10);
- }
- is_alarm(id,yanwu.toInt());
- if(wifi2->idflag==1)
- {
- wifi2->idflag=0;
- wifi2->SendData("AT+RST\r");
- wifi2->id1="";
- wifi2->id2="";
- //sleep(5);
- wifi2->openserver();
- }
- }
- void mainface::is_alarm(int id,int yanwu)
- {
- if(id==1)
- {
- if(yanwu==1||wendu1->value()>wen1_alarm.toDouble()||shidu1->value()>shi1_alarm.toDouble())
- {
- if(alarm1->isAlarm()==false)
- {
- alarm1->setAlarm(true);
- }
- }
- else
- {
- if(alarm1->isAlarm()==true)
- {
- alarm1->setAlarm(false);
- }
- }
- }
- if(id==2)
- {
- if(yanwu==1||wendu2->value()>wen2_alarm.toDouble()||shidu2->value()>shi2_alarm.toDouble())
- {
- if(alarm2->isAlarm()==false)
- {
- alarm2->setAlarm(true);
- }
- }
- else
- {
- if(alarm2->isAlarm()==true)
- {
- alarm2->setAlarm(false);
- }
- }
- }
- }
- void mainface::on_set_alarm_clicked()
- {
- wen1_alarm=ui->lineEdit->text();
- shi1_alarm=ui->lineEdit_2->text();
- wen2_alarm=ui->lineEdit_3->text();
- shi2_alarm=ui->lineEdit_4->text();
- is_alarm(1,0);
- is_alarm(2,0);
- }
- void mainface::on_led11_control_clicked()
- {
- if(led11->isLed())
- {
- led11->setLed(false);
- }
- else
- {
- led11->setLed(true);
- }
- sendmsg1();
- }
- void mainface::on_led12_control_clicked()
- {
- if(led12->isLed())
- {
- led12->setLed(false);
- }
- else
- {
- led12->setLed(true);
- }
- sendmsg1();
- }
- void mainface::on_led21_control_clicked()
- {
- if(led21->isLed())
- {
- led21->setLed(false);
- }
- else
- {
- led21->setLed(true);
- }
- sendmsg2();
- }
- void mainface::on_led22_control_clicked()
- {
- if(led22->isLed())
- {
- led22->setLed(false);
- }
- else
- {
- led22->setLed(true);
- }
- sendmsg2();
- }
- void mainface::sendmsg1()
- {
- QString data="1";
- if(led11->isLed())
- {
- data.append("1");
- }
- else
- {
- data.append("0");
- }
- if(led12->isLed())
- {
- data.append("1");
- }
- else
- {
- data.append("0");
- }
- wifi2->sendmsg(data,wifi2->id1);
- }
- void mainface::sendmsg2()
- {
- QString data="2";
- if(led21->isLed())
- {
- data.append("1");
- }
- else
- {
- data.append("0");
- }
- if(led22->isLed())
- {
- data.append("1");
- }
- else
- {
- data.append("0");
- }
- wifi2->sendmsg(data,wifi2->id2);
- }
软件调试:
为了方便测试和这里首先最好设置开机自启,详细操作见帖子:【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的环境信息采集系统完结篇
非常棒!
谢谢!
小编的界面做的真好看。
刚发现这个区,刚买了块板子~要是先看见这就好了
现在也不晚,一起学习!
赞
小编开发的界面很强悍
厉害了我的哥~