This commit is contained in:
Your Name 2024-11-07 15:15:13 +08:00
commit cde3271e5a
7 changed files with 10465 additions and 0 deletions

10
CMakeLists.txt Normal file
View File

@ -0,0 +1,10 @@
cmake_minimum_required(VERSION 3.10)
project(BME280_Report)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_FLAGS "-O2 -li2c")
file(GLOB_RECURSE native_srcs src/*.cpp)
add_executable(${PROJECT_NAME} ${native_srcs})
target_link_libraries(${PROJECT_NAME} i2c)

3
readme.md Normal file
View File

@ -0,0 +1,3 @@
BME280 WebUI
==
A Simple WebUI

After

Width:  |  Height:  |  Size: 30 B

85
src/bme280.cpp Normal file
View File

@ -0,0 +1,85 @@
#include "bme280.h"
BME280::BME280(int gpioIdx){ //初始化设备
if ((fd = open(I2C_PATH, O_RDWR)) < 0) {
perror("无法打开I2C设备!");
return;
}
if (ioctl(fd, I2C_SLAVE, gpioIdx) < 0) {
perror("无法打开GPIO!");
close(fd);
return;
}
if (i2c_smbus_read_byte_data(fd, IDENT) != 0x60) {
perror("无法读取数据!");
close(fd);
return;
}
i2c_smbus_write_byte_data(fd, SOFT_RESET, 0xB6);
usleep(50000);
setCompensationParams(fd);
i2c_smbus_write_byte_data(fd, CTRL_HUM, 0x1);
i2c_smbus_write_byte_data(fd, CONFIG, 0);
i2c_smbus_write_byte_data(fd, CTRL_MEAS, 0x25);
}
bool BME280::ReadData(){
if ((i2c_smbus_read_byte_data(fd, 0xF3) & 0x9) != 0) {
printf("%s\n", "无法读取温度数据!");
return false;
}
i2c_smbus_read_i2c_block_data(fd, DATA_START_ADDR, DATA_LENGTH, dataBlock);
i2c_smbus_write_byte_data(fd, CTRL_MEAS, 0x25);
return true;
}
double BME280::GetTemp(){
return BME280_compensate_T_double((dataBlock[3] << 16 | dataBlock[4] << 8 | dataBlock[5]) >> 4);
}
double BME280::GetPressure(){
return BME280_compensate_P_double((dataBlock[0] << 16 | dataBlock[1] << 8 | dataBlock[2]) >> 4)/100.f;
}
double BME280::GetHumidity(){
return BME280_compensate_H_double(dataBlock[6] << 8 | dataBlock[7]);
}
int main() {
//初始化设备
BME280 b(0x76);
httplib::Server sv;
sv.Get("/", [&b](const httplib::Request &, httplib::Response &res) {
b.ReadData();
char text[1024]="Unk";
sprintf(text,"<html>"
"<head>"
"<meta charset=\"UTF-8\">"
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0,maximum-scale=1.0\">"
"<style>"
".card {"
"width: 300px;"
"padding: 16px;"
"border: 1px solid #ddd;"
"border-radius: 8px;"
"box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.1);"
"background-color: #fff;"
"font-family: Arial, sans-serif;"
"margin: 20px;"
"}"
".card p {"
"margin: 0;"
"margin-bottom: 10px;"
"}"
"</style>"
"</head>"
"<body>"
"<div class=\"card\">"
"<p>🌡温度: %.2f C<br/>💨气压: %.2f Pha<br/>💧湿度: %.2f %rH</p>"
"</div>"
"</body>"
"</html>"
,b.GetTemp(),b.GetPressure(),b.GetHumidity());
res.set_content(text, "text/html");
});
sv.listen("0.0.0.0", 1234);
return 0;
}

39
src/bme280.h Normal file
View File

@ -0,0 +1,39 @@
#ifndef __BME280_H
#define __BME280_H
#include <iostream>
#include <fcntl.h>
extern "C" {
#include <i2c/smbus.h>
#include <linux/i2c-dev.h>
}
#include <math.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "compensation.h"
#include "httplib.h"
#define I2C_PATH "/dev/i2c-1"
#define IDENT 0xD0
#define SOFT_RESET 0xE0
#define CTRL_HUM 0xF2
#define CTRL_MEAS 0xF4
#define CONFIG 0xF5
#define DATA_START_ADDR 0xF7
#define DATA_LENGTH 8
class BME280{
private:
int fd;
uint8_t dataBlock[8];
public:
BME280(int gpioIdx);
bool ReadData();
double GetTemp();
double GetPressure();
double GetHumidity();
};
#endif

121
src/compensation.cpp Normal file
View File

@ -0,0 +1,121 @@
#include "compensation.h"
extern "C" {
#include <i2c/smbus.h>
}
static int32_t t_fine = 0;
static uint16_t dig_T1 = 0;
static int16_t dig_T2 = 0;
static int16_t dig_T3 = 0;
static uint16_t dig_P1 = 0;
static int16_t dig_P2 = 0;
static int16_t dig_P3 = 0;
static int16_t dig_P4 = 0;
static int16_t dig_P5 = 0;
static int16_t dig_P6 = 0;
static int16_t dig_P7 = 0;
static int16_t dig_P8 = 0;
static int16_t dig_P9 = 0;
static uint8_t dig_H1 = 0;
static int16_t dig_H2 = 0;
static uint8_t dig_H3 = 0;
static int16_t dig_H4 = 0;
static int16_t dig_H5 = 0;
static int8_t dig_H6 = 0;
/* The following three compensation functions are reproduced from Appendix A: Section 8.1,
* Compensation formulas in double precision floating point, of the Bosch Sensortec technical
* datasheet.
*
* https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bme280-ds002.pdf
*
*/
/* Returns temperature in DegC, double precision. Output value of “51.23”
* equals 51.23 DegC. t_fine carries fine temperature as global value
*/
double BME280_compensate_T_double(int32_t adc_T) {
double var1, var2, T;
var1 = (((double)adc_T) / 16384.0 - ((double)dig_T1) / 1024.0) * ((double)dig_T2);
var2 = ((((double)adc_T) / 131072.0 - ((double)dig_T1) / 8192.0) *
(((double)adc_T) / 131072.0 - ((double)dig_T1) / 8192.0)) *
((double)dig_T3);
t_fine = (int32_t)(var1 + var2);
T = (var1 + var2) / 5120.0;
return T;
}
/* Returns pressure in Pa as double. Output value of “96386.2” equals 96386.2 Pa
* = 963.862 hPa
*/
double BME280_compensate_P_double(int32_t adc_P) {
double var1, var2, p;
var1 = ((double)t_fine / 2.0) - 64000.0;
var2 = var1 * var1 * ((double)dig_P6) / 32768.0;
var2 = var2 + var1 * ((double)dig_P5) * 2.0;
var2 = (var2 / 4.0) + (((double)dig_P4) * 65536.0);
var1 = (((double)dig_P3) * var1 * var1 / 524288.0 + ((double)dig_P2) * var1) / 524288.0;
var1 = (1.0 + var1 / 32768.0) * ((double)dig_P1);
/* avoid exception caused by division by zero */
if (var1 == 0.0) {
return 0;
}
p = 1048576.0 - (double)adc_P;
p = (p - (var2 / 4096.0)) * 6250.0 / var1;
var1 = ((double)dig_P9) * p * p / 2147483648.0;
var2 = p * ((double)dig_P8) / 32768.0;
p = p + (var1 + var2 + ((double)dig_P7)) / 16.0;
return p;
}
/* Returns humidity in %rH as as double. Output value of “46.332”
* represents 46.332 %rH
*/
double BME280_compensate_H_double(int32_t adc_H) {
double var_H;
var_H = (((double)t_fine) - 76800.0);
var_H = (adc_H - (((double)dig_H4) * 64.0 + ((double)dig_H5) / 16384.0 * var_H)) *
(((double)dig_H2) / 65536.0 *
(1.0 + ((double)dig_H6) / 67108864.0 * var_H *
(1.0 + ((double)dig_H3) / 67108864.0 * var_H)));
var_H = var_H * (1.0 - ((double)dig_H1) * var_H / 524288.0);
if (var_H > 100.0)
var_H = 100.0;
else if (var_H < 0.0)
var_H = 0.0;
return var_H;
}
/* Read calibration data and determine trimming parameters */
void setCompensationParams(int fd) {
uint8_t calData0[25];
uint8_t calData1[7];
/* read calibration data */
i2c_smbus_read_i2c_block_data(fd, CAL_DATA0_START_ADDR, CAL_DATA0_LENGTH, calData0);
i2c_smbus_read_i2c_block_data(fd, CAL_DATA1_START_ADDR, CAL_DATA1_LENGTH, calData1);
/* trimming parameters */
dig_T1 = calData0[1] << 8 | calData0[0];
dig_T2 = calData0[3] << 8 | calData0[2];
dig_T3 = calData0[5] << 8 | calData0[4];
dig_P1 = calData0[7] << 8 | calData0[6];
dig_P2 = calData0[9] << 8 | calData0[8];
dig_P3 = calData0[11] << 8 | calData0[10];
dig_P4 = calData0[13] << 8 | calData0[12];
dig_P5 = calData0[15] << 8 | calData0[14];
dig_P6 = calData0[17] << 8 | calData0[16];
dig_P7 = calData0[19] << 8 | calData0[18];
dig_P8 = calData0[21] << 8 | calData0[20];
dig_P9 = calData0[23] << 8 | calData0[22];
dig_H1 = calData0[24];
dig_H2 = calData1[1] << 8 | calData1[0];
dig_H3 = calData1[2];
dig_H4 = calData1[3] << 4 | (calData1[4] & 0xF);
dig_H5 = calData1[5] << 4 | (calData1[4] >> 4);
dig_H6 = calData1[6];
}

16
src/compensation.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef __COMPENSATION_H
#define __COMPENSATION_H
#include <stdint.h>
#define CAL_DATA0_START_ADDR 0x88
#define CAL_DATA0_LENGTH 25
#define CAL_DATA1_START_ADDR 0xE1
#define CAL_DATA1_LENGTH 7
double BME280_compensate_T_double(int32_t adc_T);
double BME280_compensate_P_double(int32_t adc_P);
double BME280_compensate_H_double(int32_t adc_H);
void setCompensationParams(int fd);
#endif

10191
src/httplib.h Normal file

File diff suppressed because it is too large Load Diff