基于北斗和4G_Cat1模组的华为云智慧物流开发05

举报
谢小康 发表于 2021/08/11 21:00:23 2021/08/11
【摘要】 基于北斗和4G_Cat1模组的华为云智慧物流开发05本章主要做QT代码的分析,手把手教学做QT程序先来分析一下目标效果,如下图所示图中用不同的颜色标记了每种组件,并编了号。 1、QTextEdit,只不过是大小不一样而已2、QLabel3、QPushButton4、QComboBox分析完成,我们先新建一个工程,Base class选择QWidget,选qmake。其他工程名字没有要求随意...

基于北斗和4G_Cat1模组的华为云智慧物流开发05

本章主要做QT代码的分析,手把手教学做QT程序
先来分析一下目标效果,如下图所示
image.png
图中用不同的颜色标记了每种组件,并编了号。
 1、QTextEdit,只不过是大小不一样而已
image.png

2、QLabel
image.png

3、QPushButton
image.png

4、QComboBox
image.png
分析完成,我们先新建一个工程,Base class选择QWidget,选qmake。其他工程名字没有要求随意即可。创建好之后如下图所示
image.png
接下来我们来做UI界面,双击打开widget.ui。用鼠标拖拽组件栏里的这四种组件,调整位置和大小。
这里在顶部添加一个标题,“智慧物流冷链运输”,调整字体大小为20。
接下来需要更改objectName,对应关系如下图所示。
image.png
图中漏了两个,定位方式后面“null”这个标签命名为locate_mode;卫星数量后“0”这个标签命名为satellite_number。其余的lable都是静态的所以就不需要改名了。
直接编译一下看看效果。
image.png
看起来比之前的好看一丢丢有没有觉得。
首先先把最简单的做了——SHT30温湿度传感器的采集并显示到QT应用界面中。
首先在widget.h中定义我们需要用到的槽函数,以及定义SHT30所需的定时器。

widget.h文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTimer>


QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
private slots:
    int SHT30_Init(void);
    int SHT30_Get_data(void);//定时获取SHT30数据
    int BH1750_Init(void);
    int BH1750_Get_data(void);//
private:
    Ui::Widget *ui;
    QTimer *SHT30_timer;
    QTimer *BH1750_timer;
};
#endif // WIDGET_H

widget.cpp文件

#include "widget.h"
#include "ui_widget.h"
#include<fcntl.h>
#include<sys/ioctl.h>
#include<unistd.h>


#define Address                                     0x44                  //SHT30地址
#define BH1750_Address                              0x23
#define I2C_RETRIES                                 0x0701
#define I2C_TIMEOUT                                 0x0702
#define I2C_SLAVE                                   0x0703                //IIC从器件的地址设置
#define I2C_BUS_MODE                                0x0780



int fd = -1;
double temperature;
double humidity;
double light;


Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //
     SHT30_timer = new QTimer(this);                                    //配置定时器
     BH1750_timer = new QTimer(this);
    //
     connect(SHT30_timer,SIGNAL(timeout()),this,SLOT(SHT30_Get_data()));//SHT30 数据采集定时任务
     connect(BH1750_timer,SIGNAL(timeout()),this,SLOT(BH1750_Get_data()));
    //
     //SHT30_Init();                                                      //SHT30 初始化
     SHT30_timer->start(1000);                                          //开启SHT30定时器
     //BH1750_Init();
     BH1750_timer->start(1000);
}



Widget::~Widget()
{
    delete ui;
}

//******************先做温湿度的数据读取与显示***********************
//SHT30 初始化函数
int Widget::SHT30_Init(void)
{

    fd  = open("/dev/i2c-0", O_RDWR);               // open file and enable read and  write
    if (fd < 0)
    {
        perror("Can't open /dev/SHT30 \n");       // open i2c dev file fail
        return - 1;
    }
    printf("open /dev/i2c-0 success !\n");
    if (ioctl(fd, I2C_SLAVE, Address) < 0)
    {
        // set i2c address
        printf("fail to set i2c device slave address!\n");
        ::close(fd);
        return - 1;
    }
    printf("set slave address to 0x%x success!\n", Address);
    return fd;
}
//获取SHT30温湿度数据
int Widget::SHT30_Get_data(void)
{
    SHT30_Init();
    quint8 buf[8] = {0};
    buf[0] = 0x2C;
    buf[1] = 0x0D;
    if ( write(fd, buf, 2) != 2 ) {
        perror("faile to write config.\n");
        return -1;
    }
    buf[0] = 0;
    buf[1] = 0;
    if ( read(fd, buf, 6) != 6 ) {
        perror("faile to read back configure data.\n");
        return -1;
    }
    // printf("SHT30---->: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x \n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
    temperature = ((float)((buf[0]<<8)+buf[1]))*175/65535-45;
    humidity = ((float)((buf[3]<<8)+buf[4]))*100/65535;
    printf("%f.%f\r\n",temperature,humidity);
    ui->temperature_text->setText(QString::number(temperature));
    ui->humidity_text->setText(QString::number(humidity));
    return  0;
}

//
int Widget::BH1750_Init(void)
{

    fd  = open("/dev/i2c-0", O_RDWR);               // open file and enable read and  write
    if (fd < 0)
    {
        perror("Can't open /dev/BH1750 \n");       // open i2c dev file fail
        return - 1;
    }
    printf("open /dev/i2c-0 success !\n");
    if (ioctl(fd, I2C_SLAVE, BH1750_Address) < 0)
    {
        // set i2c address
        printf("fail to set i2c device slave address!\n");
        ::close(fd);
        return - 1;
    }
    printf("set slave address to 0x%x success!\n", BH1750_Address);
    return fd;
}

int Widget::BH1750_Get_data(void)
{
    quint8 buf[3] = {0};
    BH1750_Init();
    buf[0] = 0x20;
    if (write(fd, buf, 1) != 1 )
    {
        perror("faile to write config.\n");
        return -1;
    }
    buf[0] = 0;
    if ( read(fd, buf, 2) != 2 ) {
        perror("faile to read back configure data.\n");
        return -1;
    }
    printf("BH1750---->: 0x%x 0x%x \n", buf[0], buf[1] );
   // temperature = ((float)((buf[0]<<8)+buf[1]))*175/65535-45;
   // humidity = ((float)((buf[3]<<8)+buf[4]))*100/65535;
    light = ((float)((buf[0]<<8)+buf[1]))/1.2;
    printf("%f\r\n",light);
    ui->Light_intensity_text->setText(QString::number(light));
    return  0;
}

这里我把两个文件里的代码分享出来了,我这里是把BH1750光照传感器也一同加上了,这里来分析代码。
首先我们以前就已经测试过BH1750与SHT30的IIC地址是分别是0x23和0x44。
来看初始化函数int Widget::SHT30_Init(void)
fd = open("/dev/i2c-0", O_RDWR);
//这里的i2c-0代表着I2C_1,
//O_RDWR表示打开文件并且可读可写
ioctl(fd, I2C_SLAVE, BH1750_Address) < 0 //设置从机地址
然后来看获取温湿度的值并显示的这个函数int Widget::SHT30_Get_data(void)
1、初始化STH30;
2、写入两个字节的数据0x2C和0x0D,设置SHT30工作模式为中速单次采集。
3、buf{}数组清零,用于从STH30读取6字节的数据

temperature = ((float)((buf[0]<<8)+buf[1]))*175/65535-45;
humidity = ((float)((buf[3]<<8)+buf[4]))*100/65535;

这里单纯分析温度,温度是两个字节的值,这里首先将第一个字节左移8位在和第二自己相加,将这个转化为float型的数据,此时这个值就是SHT30采集出来的原始值,根据手册进行转化,这里转化成摄氏度,所以是-45。湿度原理同上,这里便不在赘述。数据手册温湿度计算公式如下图所示
image.png
最后两行代码是把所得到的温湿度,传给对应的变量,在窗口进行显示。
那么QT是怎么来实现定时采集温湿度的呢?
下面就来关注一下,下面这两行代码

connect(SHT30_timer,SIGNAL(timeout()),this,SLOT(SHT30_Get_data()));//SHT30 数据采集定时任务
connect(BH1750_timer,SIGNAL(timeout()),this,SLOT(BH1750_Get_data()));

这里涉及到了QT的最精华的部分,那就是信号和槽。
这里当定时器SHT30_timer启动后时间溢出时,发出信号给SHT30_Get_data()这个函数,然后去执行相应的动作。这里connect相当于是把信号和动作连接起来。只要一有信号,就执行相应的动作。
BH1750光照传感器和SHT30类似,我这里就不再详细的展开说了,这里只说明一点,关于挂载在同一个IIC接口下的两个设备,每次读取数据的时候,都需要进行初始化,这点需要大家注意。
那好吧来看看下载到Linux板上的效果吧!
image.png
总结:
本章讲述了如何对QT界面进行复刻,一步一步的写QT程序。详细的说明了温湿度数据采集数据转化的原理,并把代码做了分享。我觉得第一步做好了后面编程会很轻松。之所以写的比较细,是因为笔者也是初学者,这里请见谅,如果觉得写的太简单的请自动略过。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。