树莓派开发笔记(八):GPIO口的I2C使用(BME280三合一传感器:温度、湿度、气压测量)
若该文为原创文章,未经允许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/79775665
各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中...(点击传送门)
树莓派开发专栏(点击传送门)
上一篇:《树莓派开发笔记(七):GPIO口的SPI使用(BME280三合一传感器:测量温度、湿度、气压、海拔高度) 》
下一篇:《树莓派开发笔记(九):CSI口的摄像头拍照(同样适用USB摄像头)》
前话
前面介绍了SPI的使用,本章节我们开发GPIO口的I2C使用,同样适用BME280三合一传感器,采集气压、温度、适度,计算海拔高度。
Demo:GPIO口的I2C通讯
I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。
主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件.在总线上主和从、发和收的关系不是恒定的,而取决于此时数据传送方向:
- 如果主机要发送数据给从器件,则主机首先寻址从器件,然后主动发送数据至从器件,最后由主机终止数据传送;
- 如果主机要接收从器件的数据,则主机器件寻址从器件.然后主机接收从器件发送的数据,最后由主机终止接收过程。在这种情况下,主机主要是负责产生定时时钟和终止数据传送。
BME280
BME280是一款集成温度、湿度、气压,三位一体的环境传感器。具有高精度,多功能,小尺寸等特点,如下图:
BME280模块,设备地址默认为0x77。下面是读取数据的指令,数据的读出是从0xf7到0xfc读做(温度和压力)或从0xf7到0xfe(温度、压力、湿度等)数据以无符号形式读出。
制指令集,如下图:
读取数据指令集,分为压力,温度,适度,如下图:
开启I2C接口
sudo raspi-config
按照下图步骤选取
然后重启。
查看系统是否启动i2c,如下图:
电路原理图
检测I2C设备是否在线
我们按照图纸连接好后,使用三方查看设备是否在线来判断设备是否正常连接。
sudo apt-get install i2c-tools
sudo i2cdetect -y 1
注意:笔者对传感器不连接电源进行测试,只连接通讯的I2C线和GND(断开VCC),使用该指令也检测不到,但是程序用wiring库却可以读到,具体原因可能是供电不足(不接VCC也供电但低于3.3V)和指令检测方式的我呢提,笔者没有细究。总之,为保持硬件稳定,需要让指令检测到才算可靠。
关键代码
初始化代码
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);_bme280.initPressureTemperatureMode();_bme280.initHumidity();startTimer(1000);
}
每隔1s读取数据
void MainWindow::timerEvent(QTimerEvent *event)
{ui->label_i2cP->setText(QString("%1 Pa").arg(_bme280.getPressure()));ui->label_i2cT->setText(QString("%1 ℃").arg(_bme280.getTemperatureC()));ui->label_i2cH->setText(QString("%1 %").arg(_bme280.getHumidity()));ui->label_i2cA->setText(QString("%1 m").arg(_bme280.getAltitudeMeters()));
}
模块代码
bme280.h
#ifndef BME280_H
#define BME280_H
#include <QObject>
#include "i2c.h"
//Register names:
#define BME280_DIG_T1_LSB_REG 0x88
#define BME280_DIG_T1_MSB_REG 0x89
#define BME280_DIG_T2_LSB_REG 0x8A
#define BME280_DIG_T2_MSB_REG 0x8B
#define BME280_DIG_T3_LSB_REG 0x8C
#define BME280_DIG_T3_MSB_REG 0x8D
#define BME280_DIG_P1_LSB_REG 0x8E
#define BME280_DIG_P1_MSB_REG 0x8F
#define BME280_DIG_P2_LSB_REG 0x90
#define BME280_DIG_P2_MSB_REG 0x91
#define BME280_DIG_P3_LSB_REG 0x92
#define BME280_DIG_P3_MSB_REG 0x93
#define BME280_DIG_P4_LSB_REG 0x94
#define BME280_DIG_P4_MSB_REG 0x95
#define BME280_DIG_P5_LSB_REG 0x96
#define BME280_DIG_P5_MSB_REG 0x97
#define BME280_DIG_P6_LSB_REG 0x98
#define BME280_DIG_P6_MSB_REG 0x99
#define BME280_DIG_P7_LSB_REG 0x9A
#define BME280_DIG_P7_MSB_REG 0x9B
#define BME280_DIG_P8_LSB_REG 0x9C
#define BME280_DIG_P8_MSB_REG 0x9D
#define BME280_DIG_P9_LSB_REG 0x9E
#define BME280_DIG_P9_MSB_REG 0x9F
#define BME280_DIG_H1_REG 0xA1
#define BME280_CHIP_ID_REG 0xD0 //Chip ID Online value is 0x60 all the time
#define BME280_RST_REG 0xE0 //Softreset Reg
#define BME280_DIG_H2_LSB_REG 0xE1
#define BME280_DIG_H2_MSB_REG 0xE2
#define BME280_DIG_H3_REG 0xE3
#define BME280_DIG_H4_MSB_REG 0xE4
#define BME280_DIG_H4_LSB_REG 0xE5
#define BME280_DIG_H5_MSB_REG 0xE6
#define BME280_DIG_H6_REG 0xE7
#define BME280_CTRL_HUMIDITY_REG 0xF2 //Ctrl Humidity Reg
#define BME280_STAT_REG 0xF3 //Status Reg
#define BME280_CTRL_MEAS_REG 0xF4 //Ctrl Measure Reg
#define BME280_CONFIG_REG 0xF5 //Configuration Reg
#define BME280_PRESSURE_MSB_REG 0xF7 //Pressure MSB
#define BME280_PRESSURE_LSB_REG 0xF8 //Pressure LSB
#define BME280_PRESSURE_XLSB_REG 0xF9 //Pressure XLSB
#define BME280_TEMPERATURE_MSB_REG 0xFA //Temperature MSB
#define BME280_TEMPERATURE_LSB_REG 0xFB //Temperature LSB
#define BME280_TEMPERATURE_XLSB_REG 0xFC //Temperature XLSB
#define BME280_HUMIDITY_MSB_REG 0xFD //Humidity MSB
#define BME280_HUMIDITY_LSB_REG 0xFE //Humidity LSB
class BME280 : public QObject
{Q_OBJECT
public:enum PRESSURE_OVERSAMPLING{PRESSURE_OVERSAMPLING_SKIPPED = 0x00,PRESSURE_OVERSAMPLING_PLUS_ONE = 0x01,PRESSURE_OVERSAMPLING_PLUS_TWO = 0x02,PRESSURE_OVERSAMPLING_PLUS_FOUR = 0x03,PRESSURE_OVERSAMPLING_PLUS_EIGHT = 0x04,PRESSURE_OVERSAMPLING_PLUS_SIXTEEN = 0x05};enum TEMPERATURE_OVERSAMPLING{TEMPERATURE_OVERSAMPLING_SKIPPED = 0x00,TEMPERATURE_OVERSAMPLING_PLUS_ONE = 0x01,TEMPERATURE_OVERSAMPLING_PLUS_TWO = 0x02,TEMPERATURE_OVERSAMPLING_PLUS_FOUR = 0x03,TEMPERATURE_OVERSAMPLING_PLUS_EIGHT = 0x04,TEMPERATURE_OVERSAMPLING_PLUS_SIXTEEN = 0x05};enum MODE_OF_PRESSURE_TEMPERATUR{MODE_OF_PRESSURE_TEMPERATUR_SLEEP = 0x00,MODE_OF_PRESSURE_TEMPERATUR_FORCED = 0x01,MODE_OF_PRESSURE_TEMPERATUR_MORMAL = 0x03};enum HUMIDITY_OVERSAMPLING{HUMIDITY_OVERSAMPLING_SKIPPED = 0x00,HUMIDITY_OVERSAMPLING_PLUS_ONE = 0x01,HUMIDITY_OVERSAMPLING_PLUS_TWO = 0x02,HUMIDITY_OVERSAMPLING_PLUS_FOUR = 0x03,HUMIDITY_OVERSAMPLING_PLUS_EIGHT = 0x04,HUMIDITY_OVERSAMPLING_PLUS_SIXTEEN = 0x05};struct Calibration{uint16_t dig_T1;int16_t dig_T2;int16_t dig_T3;uint16_t dig_P1;int16_t dig_P2;int16_t dig_P3;int16_t dig_P4;int16_t dig_P5;int16_t dig_P6;int16_t dig_P7;int16_t dig_P8;int16_t dig_P9;uint8_t dig_H1;int16_t dig_H2;uint8_t dig_H3;int16_t dig_H4;int16_t dig_H5;uint8_t dig_H6;};public:explicit BME280(int devId = 0x77, QObject *parent = 0);bool isOnline();void initPressureTemperatureMode(PRESSURE_OVERSAMPLING p = PRESSURE_OVERSAMPLING_PLUS_ONE,TEMPERATURE_OVERSAMPLING t = TEMPERATURE_OVERSAMPLING_PLUS_ONE,MODE_OF_PRESSURE_TEMPERATUR m = MODE_OF_PRESSURE_TEMPERATUR_MORMAL);void initHumidity(HUMIDITY_OVERSAMPLING h = HUMIDITY_OVERSAMPLING_PLUS_ONE);void reset();
public slots:float getTemperatureC();float getTemperatureF();float getPressure();float getHumidity();float getAltitudeMeters();float getAltitudeFeet();
private:I2c _i2c;int _devId;Calibration _calibration;int32_t _tFine;
};
#endif // BME280_H
bme280.cpp
#include "bme280.h"
#include <QDebug>
BME280::BME280(int devId, QObject *parent): QObject(parent),_devId(devId)
{_i2c.open(devId);…
}
bool BME280::isOnline()
{// according to 0xD0 "id", value is 0x60return _i2c.readData(BME280_CHIP_ID_REG) == 0x60;
}
void BME280::initPressureTemperatureMode(BME280::PRESSURE_OVERSAMPLING p, BME280::TEMPERATURE_OVERSAMPLING t, BME280::MODE_OF_PRESSURE_TEMPERATUR m)
{uchar uc;…_i2c.writeData(BME280_CTRL_MEAS_REG, uc);_i2c.readData(BME280_CTRL_MEAS_REG);…
}void BME280::initHumidity(BME280::HUMIDITY_OVERSAMPLING h)
{uchar uc;…_i2c.writeData(BME280_CTRL_HUMIDITY_REG, uc);
}void BME280::reset()
{_i2c.writeData(BME280_RST_REG, 0xB6);
}float BME280::getTemperatureC()
{…int32_t adc_T = ((uint32_t)_i2c.readData(BME280_TEMPERATURE_MSB_REG) << 12) | ((uint32_t)_i2c.readData(BME280_TEMPERATURE_LSB_REG) << 4) | ((_i2c.readData(BME280_TEMPERATURE_XLSB_REG) >> 4) & 0x0F);…float output = (_tFine * 5 + 128) >> 8;output = output / 100;return output;
}float BME280::getTemperatureF()
{float output = getTemperatureC();output = (output * 9) / 5 + 32;return output;
}float BME280::getPressure()
{…int32_t adc_P = ((uint32_t)_i2c.readData(BME280_PRESSURE_MSB_REG) << 12) | ((uint32_t)_i2c.readData(BME280_PRESSURE_LSB_REG) << 4) | ((_i2c.readData(BME280_PRESSURE_XLSB_REG) >> 4) & 0x0F);int64_t var1, var2, p_acc;…p_acc = p_acc >> 8; // /256return (float)p_acc;
}float BME280::getHumidity()
{…int32_t adc_H = ((uint32_t)_i2c.readData(BME280_HUMIDITY_MSB_REG) << 8) | ((uint32_t)_i2c.readData(BME280_HUMIDITY_LSB_REG));int32_t var1;…return (float)((var1>>12) >> 10);
}float BME280::getAltitudeMeters()
{float heightOutput = 0;…return heightOutput;
}
float BME280::getAltitudeFeet()
{float heightOutput = 0;heightOutput = getAltitudeMeters() * 3.28084;return heightOutput;
}
I2C模块代码
i2c.h
#ifndef I2C_H
#define I2C_H
#include <QObject>
#include <QByteArray>
class I2c : public QObject
{Q_OBJECT
public:explicit I2c(QObject *parent = 0);
signals:
public slots:bool open(uchar addr);void writeData(int reg, uchar data);uchar readData(int reg);
private:int _fd;
};
#endif // I2C_H
i2c.cpp
#include "i2c.h"
#include "wiringPi.h"
#include "wiringPiI2C.h"
#include <QDebug>
#include <QByteArray>I2c::I2c(QObject *parent) : QObject(parent)
{wiringPiSetup();_fd = 0;
}
bool I2c::open(uchar addr)
{
_fd = wiringPiI2CSetup(addr);
…
}void I2c::writeData(int reg, uchar data)
{…ret = wiringPiI2CWriteReg8(_fd, reg, data);
}
uchar I2c::readData(int reg)
{…data = wiringPiI2CReadReg8(_fd, reg);…
}
运行效果
办公室正常效果(笔者在十多层,差不多吧95m左右的水平高度)
哈10s的气(主要是t,h)
放到特定环境挤压空气一下(主要是p)
上一篇:《树莓派开发笔记(七):GPIO口的SPI使用(BME280三合一传感器:测量温度、湿度、气压、海拔高度) 》
下一篇:《树莓派开发笔记(九):CSI口的摄像头拍照(同样适用USB摄像头)》
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/79775665
树莓派开发笔记(八):GPIO口的I2C使用(BME280三合一传感器:温度、湿度、气压测量)相关推荐
- 树莓派开发笔记(九):基于CSI口的摄像头拍照程序(同样适用USB摄像头)
若该文为原创文章,未经允许不得转载 原博主博客地址:https://blog.csdn.net/qq21497936 原博主博客导航:https://blog.csdn.net/qq21497936/ ...
- GPIO口模拟I2C操作
/* 作者:天空 日期:2014.5.12 功能:利用GPIO口模拟I2C总线,对传感器寄存器读取数据 注意:如果需要移植些文件到其他设 ...
- 树莓派开发笔记(五):GPIO引脚介绍和GPIO的输入输出使用(驱动LED灯、检测按键)
若该文为原创文章,未经允许不得转载 原博主博客地址:https://blog.csdn.net/qq21497936 原博主博客导航:https://blog.csdn.net/qq21497936/ ...
- 树莓派开发笔记(十四):入手研华ADVANTECH工控树莓派UNO-220套件(三):使用研发自带系统测试rtc、gpio、232和485套件接口
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/124754769 红胖子(红模仿)的博文大全:开发技术集 ...
- 全志H6方案板香橙派OrangePi 3开发板26pin GPIO口测试
wiringOP 已适配 Orange Pi 3 开发板,使用 wiringOP 可以测试 GPIO.I2C.UART 和 SPI 的功能,下文先介绍26pin GPIO口测试 测试前先安装wirin ...
- 树莓派开发笔记(十七):树莓派4B+上Qt多用户连接操作Mysql数据库同步(单条数据悲观锁)
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/125188715 红胖子(红模仿)的博文大全:开发技术集 ...
- 树莓派开发笔记(十一):蓝牙的使用,BlueZ协议(双树莓探测rssi并通过蓝牙互传获取的rssi信号强度)
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://blog.csdn.net/qq21497936/article/details/110940484 长期持续带来更多项目与技术分 ...
- 3399使用GPIO口模拟i2c升级NT68411
RK3399使用GPIO口模拟i2c升级NT68411固件 sda = gpio_to_desc(129); //GPIO4_A1 scl = gpio_to_desc(130); //GPIO4_A ...
- 树莓派android摄像头驱动开发,树莓派开发笔记(九):基于CSI口的摄像头拍照程序(同样适用USB摄像头)...
前话 前面开发完GPIO口的功能,还剩下2个接口,一个是摄像头,一个是显示屏.本篇我们开发一个基于CSI接口的摄像头拍照程序. Demo:摄像头CSI的拍照程序 树莓派摄像头 笔者买的不是USB网络摄 ...
- 启明云端分享|ESP32学习笔记参考GPIO口操作
提示:作为Espressif(乐鑫科技)大中华区合作伙伴及sigmastar(厦门星宸)VAD合作伙伴,我们不仅用心整理了你在开发过程中可能会遇到的问题以及快速上手的简明教程供开发小伙伴参考.同时也用 ...
最新文章
- PDF编辑工具——PDF Desktop Converter 4 Professional
- js map遍历 修改对象里面的值_js中那些方法不改变原来的数组对象
- 为CEDIT添加有颜色的边框
- C++类构造函数初始化列表及初始化成员变量的误区
- sql 数据库维护索引_SQL索引维护
- NodeJS + Sequelize + Mysql + Vue + Bootstrap
- 盘点俄罗斯大神写的几款软件,你用过几个?最后1个是我的童年
- Unity实现多旋翼无人机的模拟飞行(物理引擎)
- msdn windows server 按电源事件api_微博评论是如何设计的?曾说能抗8位明星同时出轨,但遇大事件屡屡挂掉!...
- java工具类_16 个超级实用的 Java 工具类
- 从新电脑开始构建FATE环境,图文并茂
- Git版本管理工具使用知识汇总
- 微信小程序-批量地图标记
- 人工智能+名片,我们看到了营销圈中的“阿尔法
- 微信公众号开发及运营(一)
- 将 C++ 对象暴露给 QML
- 计算机和互联网的英语演讲,英语演讲---关于互联网
- Arduino+DHT11温湿度传感器+12864oled显示温湿度
- 核心系统粗放型向集约型转变--(一)BI+DW
- 浅谈雷达与其火灾探测功能