基于北斗和4G_Cat1模组的华为云智慧物流开发05
基于北斗和4G_Cat1模组的华为云智慧物流开发05
本章主要做QT代码的分析,手把手教学做QT程序
先来分析一下目标效果,如下图所示
图中用不同的颜色标记了每种组件,并编了号。
1、QTextEdit,只不过是大小不一样而已
2、QLabel
3、QPushButton
4、QComboBox
分析完成,我们先新建一个工程,Base class选择QWidget,选qmake。其他工程名字没有要求随意即可。创建好之后如下图所示
接下来我们来做UI界面,双击打开widget.ui。用鼠标拖拽组件栏里的这四种组件,调整位置和大小。
这里在顶部添加一个标题,“智慧物流冷链运输”,调整字体大小为20。
接下来需要更改objectName,对应关系如下图所示。
图中漏了两个,定位方式后面“null”这个标签命名为locate_mode;卫星数量后“0”这个标签命名为satellite_number。其余的lable都是静态的所以就不需要改名了。
直接编译一下看看效果。
看起来比之前的好看一丢丢有没有觉得。
首先先把最简单的做了——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。湿度原理同上,这里便不在赘述。数据手册温湿度计算公式如下图所示
最后两行代码是把所得到的温湿度,传给对应的变量,在窗口进行显示。
那么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板上的效果吧!
总结:
本章讲述了如何对QT界面进行复刻,一步一步的写QT程序。详细的说明了温湿度数据采集数据转化的原理,并把代码做了分享。我觉得第一步做好了后面编程会很轻松。之所以写的比较细,是因为笔者也是初学者,这里请见谅,如果觉得写的太简单的请自动略过。
- 点赞
- 收藏
- 关注作者
评论(0)