该系统主要以Zigbee为作为下位机链接对象,以Qt作为人机交互界面的设计,这里主要以Windows下开发Qt程序。

在Qt上的主要包括
(1)上位机与下位机之间的串口通信功能的实现;
(2)温度、湿度、甲烷含量数据的接收与显示;
(3)建立数据库;
(4)设置警报系统;
(5)建立用户注册与登录机制。

1、 串口通信功能与数据显示
在Qt中预设有与串口相关的板块serialport,该板块中封装多种与串口设置相关的类。通过对串口波特率、数据位、奇偶位、停止位、控制流等参数的设置,配置好与下位机的串口连接。代码如下图1:
//串口通信

QSerialPort *serial_1=new QSerialPort;
    foreach(const QSerialPortInfo &str,QSerialPortInfo::availablePorts ())
    {
        serial_1->setPort (str);//将获取到的串口赋给serial_1
        if(!serial_1->open (QIODevice::ReadWrite))//以读写方式打开
        {
          qDebug()<<"初始串口打开失败";
        }
        else
        {
            serial_1->close ();
        }
        serial=serial_1;
        if(!serial->open (QIODevice::ReadWrite))
        {
             QMessageBox::information (this,"错误","串口打开不成功");
             ui->label_focus->setText ("设备连接失败");
        }
        else
        {

    serial->setBaudRate (QSerialPort::Baud115200);//设置波特率为115200
    serial->setDataBits (QSerialPort::Data8);//设置数据位8位
    serial->setParity (QSerialPort::NoParity);//设置为没有奇偶校正位
    serial->setStopBits (QSerialPort::OneStop);//设置停止位数为1位
    serial->setFlowControl (QSerialPort::NoFlowControl);//设置控制流为无
    //QMessageBox::information (this,"提示","连接下位机成功");
    ui->label_focus->setText ("设备连接成功");
    }

}

过以上设置,我们可以实现电脑与ZigBee下位机的串口通信,由ZigBee下位机发通过串口发送检测到的数据到上位机(电脑),在使用Qt的开发的界面接收数据,然后截取并显示数据。进而做到温度、湿度、甲烷含量的数据接收与显示,反应出室内环境的实时情况。同时为了使用户更加直观的感受到温湿度、甲烷含量的程度变化,我们还将数据转化为了动态的曲线图表。而这里则用到了Qt的另一板块——charts。
这里插一句如何找到所有有效串口并返回到combox控件:

foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        QSerialPort serial;
        serial.setPort(info);
        ui->comboBox_com->addItem(serial.portName());
    }

2、 数据库与数据储存
利用Qt关于数据库的板块sql,该板块包括有与使用数据库功能的相关类,调用相关类实现数据库的连接、打开、储存的操作,这里我们根据本项目的需求量要求,选择了轻量化数据库SQLITE数据库。

this->db=QSqlDatabase::addDatabase ("QSQLITE");
    db.setDatabaseName ("abab.db");//与abab相连接
    bool ok;
    ok=db.open ();
    if(!ok)
    {
        qDebug()<<"数据库打开失败";
    }
    else
    {
        qDebug()<<"数据库打开成功";
    }

Qt界面接受在显示温湿度、甲烷含量数据的同时会按固定时间间隔来存储相关数据,便于用户查看并了解室内环境的过往情况(数据查询代码如图4)。在数据库中的储存方式上我们以时间对应数据的方式储存(数据储存代码如图3),并且为了方便查看与优化数据库的内存,数据量可以根据用户的想法设置,超过设置值,数据库会自动清空数据,然后重新储存新的数据。当然用户也能手动清空数据列表。

void Widget::save_data ()
{
    this->db=QSqlDatabase::addDatabase ("QSQLITE");//建立数据库链接
    db.setDatabaseName ("abab.db");//与abab相连接
    bool ok=true;
    ok=db.open ();
    if(!ok)
    {
        qDebug()<<"存储时数据库打开失败";
    }
    else
    {
        qDebug()<<"存储时数据库打开成功";
    }

    QDateTime curDatatime=QDateTime::currentDateTime ();
    QString time;
    time=curDatatime.toString ("yyyy-MM-dd hh:mm");

    QSqlQuery query;//用于储存数据
    query.prepare ("insert into detection_data(time,temperature,humidity,methane)"
                   "values(:time,:temperature,:humidity,:methane)");
    query.bindValue (":time",time);
    query.bindValue (":temperature",view.mid (0,2));
    query.bindValue (":humidity",view.mid (2,2));
/*****************改*********************/
    int change1;
    change1=view.mid(4,3).toInt ();
    change1=change1-30;
/***************************************/
    query.bindValue (":methane",change1);
    //query.bindValue (":methane",view.mid (4,3));
    bool ok_1 = true;
    ok=query.exec ();
    if(!ok_1)
    {
        qDebug()<<"数据添加失败";
    }
    else
    {
        qDebug()<<"数据添加成功";
    }

}

以下则是通过数据库查询注册的用户俩判断用户是否存在从而实现登录功能。

void log_in::on_pushButton_log_in_clicked()//点击登录转移到主要界面
{
    this->db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("abab.db");
    if(!db.open())
    {
        QMessageBox::warning(this,"错误","数据库打开失败");
        return ;
    }
    if(ui->lineEdit_username->text().isEmpty ()|ui->lineEdit_password->text ().isEmpty ())
    {
        QMessageBox::warning(this,"提示","用户名和密码不能为空!!!");
    }
    else
    {
        int a=0,b=0;
        QSqlQuery query("SELECT * FROM user_s");
              int fieldone = query.record().indexOf("name");
              int fieldtwo = query.record().indexOf("password");
              while (query.next()) {
                  if(ui->lineEdit_username->text ()== query.value(fieldone).toString()&&ui->lineEdit_password->text ()==query.value(fieldtwo).toString())
                  {
                      a=1;
                      break;
                  }
              }
              if(a)
              {
                  this->close();
                  Widget *Widget=new class Widget();
                  Widget->show();
                  db.close();
              }
              else {
                  QSqlQuery query("SELECT name FROM user");
                        while (query.next()) {
                            if(ui->lineEdit_username->text ()== query.value(0).toString())
                            {
                                b=1;
                                break;
                            }
                        }
                        if(b)
                        {
                            QMessageBox::information(this,"提示","密码错误");
                        }
                        else{
                            QMessageBox::information(this,"提示","该用户不存在,请先注册");
                        }
              }
    }
}

3、 警报系统与背景音乐
本系统除了具备检测室内环境的功能外,还具备警报系统。系统内部设置有针对温湿度、甲烷含量危险值的设定,若接收到的温度、甲烷含量、湿度超过或低于设定的危险值时,系统就会发出警报,提醒用户有危险出现。当危险解除时,警报也会随之解除。
此外,为了给用户营造一种温馨氛围,系统设置有在操作时播放的温馨背景音乐。当然用户爱听的话,也能手动关闭。(警报与背景音乐代码如图5)

void Widget::music()//背景音乐
{
    if(ui->pushButton_music->text ()=="开启音乐")
    {
       qDebug()<<"执行了";
       playlist->setPlaybackMode (QMediaPlaylist::CurrentItemInLoop);//循环播放当前项
       player->play ();
        ui->pushButton_music->setText ("关闭音乐");
    }
    else
    {
        qDebug()<<"暂停";
         player->stop();
         ui->pushButton_music->setText ("开启音乐");
    }
}

void Widget::alarm ()//警报声
{
    if(ui->pushButton_alarm->text ()=="关闭警报")
        {
        player_alarm->stop ();
        ui->pushButton_music->setText ("开启音乐");
        ui->pushButton_alarm->setText ("警报中");
        ui->pushButton_alarm->setEnabled (false);
        q=0;
        }
    else
    {
        q=1;
        ui->pushButton_alarm->setText ("关闭警报");
        ui->pushButton_alarm->setEnabled (true);
//        ui->pushButton_alarm->styleSheet ().clear ();
//        ui->pushButton_alarm->setStyleSheet ("image: url(:phono/in09.png;"
//                                             "font: 8pt '微软雅黑';"
//                                             "background-color: rgb(208, 208, 208);"
//                                             "background-image: url(:phono/in09.png);");
    }
}

4、用户注册与登录
本系统采用权限管理机制,只有通过系统注册账号后才能使用。初次使用者需要首先转入注册界面进行注册(用户注册功能代码如图6),获得账号后,返回登录界面输入注册的账号密码,进入操作主界面。
对于系统的登录功能,我们同样是采用建立数据库的方式完成的,注册账号即是加入新的用户信息到数据库,而登录即是在数据库中查找对应的注册数据,从而实现登录功能(用户登录功能代码如图7)。

void MainWindow::on_pushButton_register_clicked()
{
   int a = 1;
    if(ui->lineEdit_setUserName->text ().isEmpty ()|ui->lineEdit_setPassword->text ().isEmpty ()|ui->lineEdit_surePassword->text ().isEmpty ())
    {
        QMessageBox::warning(this,"警告","用户名和密码不能为空!!!");
    }
    else
    {
        if(ui->lineEdit_setPassword->text ()!=ui->lineEdit_surePassword->text ())
        {
            QMessageBox::warning(this,"警告","两次密码不一致!!");
        }
        else
        {
                if(!db.open())
                {
                    QMessageBox::warning(this,"错误","数据库打开失败");
                    return ;
                }

                else
                {

                  QSqlQuery  query("SELECT name FROM user_s");
                    while (query.next())
                    {
                        QString country = query.value(0).toString();
                        if(country==ui->lineEdit_setUserName->text ())
                        {
                            QMessageBox::information(this,"提示","该用户名已注册!");
                            a=0;
                            break;
                        }
                    }
                   if(a==1)
                   {
                        query.prepare("INSERT INTO user_s (name, password) "
                                      "VALUES (:name, :password)");
                        query.bindValue(":name", ui->lineEdit_setUserName->text ());
                        query.bindValue(":password", ui->lineEdit_setPassword->text ());
                        bool ok=query.exec();
                        if(ok)
                        {
                            QMessageBox::information(this,"提示","注册成功!");
                            this->db.close();
                        }
                        else
                        {
                            QMessageBox::information(this,"提示","注册失败!");
                            return;
                        }
                    }
                 }
             }
         }
  }

相关界面效果如下:

qt mqtt 智能家居 基于qt的智能家居系统_Zigbee


qt mqtt 智能家居 基于qt的智能家居系统_数据_02


qt mqtt 智能家居 基于qt的智能家居系统_Zigbee_03


以上是本人在Qt学习路上做过的一些设计中的一个,后续还会有更多关于Qt应用的更新,希望大家关注哦!!