temperature and humidity working !

This commit is contained in:
R.P.Clark 2023-09-18 04:54:42 +01:00
parent 32aedbbb13
commit 3fef485f97
6 changed files with 240 additions and 30 deletions

View File

@ -1,2 +1,2 @@
all: all:
gcc -O2 -std=c99 -Wall -Wextra main.c bme680.c i2c.c -o bme680 gcc -O2 -std=gnu99 -Wall -Wextra main.c bme680.c i2c.c -o bme680

View File

@ -1,2 +1,34 @@
# bme680 # bme680
test
Temperature OK, humidity OK, pressure a bit wonky. Not sure why !
```
$ ./bme680
61
par_t1: 26203
par_t2: 26519
par_t3: 3
par_p1: 35008
par_p2: 55252
par_p3: 88
par_p4: 9692
par_p5: 65334
par_p6: 30
par_p7: 24
par_p8: 65020
par_p9: 62067
par_p10: 30
par_h1: 794
par_h2: 4003
par_h3: 0
par_h4: 45
par_h5: 20
par_h6: 120
par_h7: 156
temperature: 22.8591 oC (floating-point)
temperature: 2286 oC (integer)
pressure: 146510 Pa (floating-point)
pressure: 60428 Pa (integer)
humidity: 639.392 (floating-point)
humidity: 639001 (integer)
```

123
bme680.c
View File

@ -1,4 +1,6 @@
#include "bme680.h" #include "bme680.h"
#include "i2c.h"
#include <stdio.h>
const double const_array1[16] = { const double const_array1[16] = {
1, 1,
@ -77,7 +79,7 @@ const int const_array2_int[16] = {
}; };
static double calc_temp_comp_1 ( uint32_t temp_adc , bme680_t *bme680) { double calc_temp_comp_1 ( uint32_t temp_adc , bme680_t *bme680) {
double var1, var2, temp_comp; double var1, var2, temp_comp;
bme680_calibration *cal; bme680_calibration *cal;
@ -96,7 +98,7 @@ static double calc_temp_comp_1 ( uint32_t temp_adc , bme680_t *bme680) {
return temp_comp; return temp_comp;
} }
static int calc_temp_comp_2 (uint32_t temp_adc, bme680_t *bme680) { int calc_temp_comp_2 (uint32_t temp_adc, bme680_t *bme680) {
int32_t var1, var2, var3, temp_comp; int32_t var1, var2, var3, temp_comp;
bme680_calibration *cal; bme680_calibration *cal;
@ -112,7 +114,7 @@ static int calc_temp_comp_2 (uint32_t temp_adc, bme680_t *bme680) {
return temp_comp; return temp_comp;
} }
static double calc_press_comp_1 ( uint32_t press_adc , bme680_t *bme680 ) { double calc_press_comp_1 ( uint32_t press_adc , bme680_t *bme680 ) {
double var1, var2, var3, press_comp; double var1, var2, var3, press_comp;
bme680_calibration *cal; bme680_calibration *cal;
@ -137,7 +139,7 @@ static double calc_press_comp_1 ( uint32_t press_adc , bme680_t *bme680 ) {
} }
static int calc_press_comp_2 ( uint32_t press_adc , bme680_t *bme680 ) { int calc_press_comp_2 ( uint32_t press_adc , bme680_t *bme680 ) {
uint32_t var1, var2, var3, press_comp; uint32_t var1, var2, var3, press_comp;
bme680_calibration *cal; bme680_calibration *cal;
@ -171,7 +173,7 @@ static int calc_press_comp_2 ( uint32_t press_adc , bme680_t *bme680 ) {
} }
static double calc_hum_comp_1 ( uint32_t hum_adc , bme680_t *bme680 ) { double calc_hum_comp_1 ( uint32_t hum_adc , bme680_t *bme680 ) {
double var1, var2, var3, var4, hum_comp; double var1, var2, var3, var4, hum_comp;
bme680_calibration *cal; bme680_calibration *cal;
@ -189,7 +191,7 @@ static double calc_hum_comp_1 ( uint32_t hum_adc , bme680_t *bme680 ) {
} }
static int calc_hum_comp_2 ( uint32_t hum_adc , bme680_t *bme680 ) { int calc_hum_comp_2 ( uint32_t hum_adc , bme680_t *bme680 ) {
uint32_t var1, var2, var3, var4, var5, var6, temp_scaled, hum_comp; uint32_t var1, var2, var3, var4, var5, var6, temp_scaled, hum_comp;
bme680_calibration *cal; bme680_calibration *cal;
@ -213,5 +215,114 @@ static int calc_hum_comp_2 ( uint32_t hum_adc , bme680_t *bme680 ) {
return hum_comp; return hum_comp;
} }
int bme680_calibrate ( int fd , bme680_calibration *cal ) {
uint8_t buffer[3] = {0, 0 ,0};
int err = 0;
// start with temp params
err |= i2c_read_reg(fd, 0xE9, 2, buffer);
cal->par_t1 = (buffer[1] << 8) | buffer[0];
err |= i2c_read_reg(fd, 0x8A, 2, buffer);
cal->par_t2 = (buffer[1] << 8) | buffer[0];
err |= i2c_read_reg(fd, 0x8C, 1, buffer);
cal->par_t3 = buffer[0];
// pressure
err |= i2c_read_reg(fd, 0x8E, 2, buffer);
cal->par_p1 = (buffer[1] << 8) | buffer[0];
err |= i2c_read_reg(fd, 0x90, 2 , buffer);
cal->par_p2 = (buffer[1] << 8) | buffer[0];
err |= i2c_read_reg(fd, 0x92, 1, buffer);
cal->par_p3 = buffer[0];
err |= i2c_read_reg(fd, 0x94, 2, buffer);
cal->par_p4 = (buffer[1] << 8) | buffer[0];
err |= i2c_read_reg(fd, 0x96, 2, buffer);
cal->par_p5 = (buffer[1] << 8) | buffer[0];
err |= i2c_read_reg(fd, 0x99, 1, buffer);
cal->par_p6 = buffer[0];
err |= i2c_read_reg(fd, 0x98, 1, buffer); // strange order
cal->par_p7 = buffer[0];
err |= i2c_read_reg(fd, 0x9C, 2, buffer);
cal->par_p8 = (buffer[1] << 8) | buffer[0];
err |= i2c_read_reg(fd, 0x9E, 2, buffer);
cal->par_p9 = (buffer[1] << 8) | buffer[0];
err |= i2c_read_reg(fd, 0xA0, 1, buffer);
cal->par_p10 = buffer[0];
// humidity
err |= i2c_read_reg(fd, 0xE2, 2, buffer);
cal->par_h1 = (buffer[1] << 4) | (buffer[0] & 0xF);
err |= i2c_read_reg(fd, 0xE1, 2, buffer);
cal->par_h2 = (buffer[1] << 4) | ((buffer[0] >> 4) & 0xF);
err |= i2c_read_reg(fd, 0xE4, 1, buffer);
cal->par_h3 = buffer[0];
err |= i2c_read_reg(fd, 0xE5, 1, buffer);
cal->par_h4 = buffer[0];
err |= i2c_read_reg(fd, 0xE6, 1, buffer);
cal->par_h5 = buffer[0];
err |= i2c_read_reg(fd, 0xE7, 1, buffer);
cal->par_h6 = buffer[0];
err |= i2c_read_reg(fd, 0xE8, 1, buffer);
cal->par_h7 = buffer[0];
// gas
err |= i2c_read_reg(fd, 0xED, 1, buffer);
cal->par_g1 = buffer[0];
err |= i2c_read_reg(fd, 0xEB, 2, buffer);
cal->par_g2 = (buffer[1] << 8) | buffer[0];
err |= i2c_read_reg(fd, 0xEE, 1, buffer);
cal->par_g2 = buffer[0];
// todo more
return err;
}
void print_calibration ( bme680_calibration *cal ) {
printf("par_t1: %d\n", cal->par_t1);
printf("par_t2: %d\n", cal->par_t2);
printf("par_t3: %d\n", cal->par_t3);
printf("par_p1: %d\n", cal->par_p1);
printf("par_p2: %d\n", cal->par_p2);
printf("par_p3: %d\n", cal->par_p3);
printf("par_p4: %d\n", cal->par_p4);
printf("par_p5: %d\n", cal->par_p5);
printf("par_p6: %d\n", cal->par_p6);
printf("par_p7: %d\n", cal->par_p7);
printf("par_p8: %d\n", cal->par_p8);
printf("par_p9: %d\n", cal->par_p9);
printf("par_p10: %d\n", cal->par_p10);
printf("par_h1: %d\n", cal->par_h1);
printf("par_h2: %d\n", cal->par_h2);
printf("par_h3: %d\n", cal->par_h3);
printf("par_h4: %d\n", cal->par_h4);
printf("par_h5: %d\n", cal->par_h5);
printf("par_h6: %d\n", cal->par_h6);
printf("par_h7: %d\n", cal->par_h7);
}

View File

@ -46,3 +46,16 @@ typedef struct {
bme680_calibration cal; bme680_calibration cal;
} bme680_t; } bme680_t;
void print_calibration(bme680_calibration *);
int bme680_calibrate(int, bme680_calibration *);
int calc_hum_comp_2(uint32_t, bme680_t *);
double calc_hum_comp_1(uint32_t, bme680_t *);
int calc_press_comp_2(uint32_t, bme680_t *);
double calc_press_comp_1(uint32_t, bme680_t *);
int calc_temp_comp_2(uint32_t, bme680_t *);
double calc_temp_comp_1(uint32_t, bme680_t*);

22
i2c.c
View File

@ -7,9 +7,6 @@
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#define MY_DEVICE "/dev/i2c-1"
#define MY_DEVICE_ADDRESS 0x77
int i2c_init(const char *dev, uint8_t addr) { int i2c_init(const char *dev, uint8_t addr) {
int fd = -1; int fd = -1;
@ -56,22 +53,3 @@ int i2c_write_reg(int fd, uint8_t reg, uint8_t value) {
return 0; return 0;
} }
int main2(void) {
int res;
uint8_t cmd_buf[2] = {0x00, 0x00};
int fd = i2c_init(MY_DEVICE, MY_DEVICE_ADDRESS);
if (i2c_read_reg(fd, 0xD0, 1, (uint8_t *)&res) != 0) {
fprintf(stderr, "ddd\n");
}
printf("%X\n", res);
printf("%X\n", i2c_read_reg2(fd, 0xD0));
close(fd);
return 0;
}

76
main.c
View File

@ -1,6 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include "bme680.h" #include "bme680.h"
#include "i2c.h" #include "i2c.h"
#include <unistd.h>
#define DEVICE "/dev/i2c-1" #define DEVICE "/dev/i2c-1"
#define ADDRESS 0x77 #define ADDRESS 0x77
@ -8,8 +9,83 @@
int main(){ int main(){
int fd = i2c_init(DEVICE, ADDRESS); int fd = i2c_init(DEVICE, ADDRESS);
bme680_t bme680;
printf("%X\n", i2c_read_reg2(fd, 0xD0)); printf("%X\n", i2c_read_reg2(fd, 0xD0));
if (bme680_calibrate(fd, &bme680.cal) != 0) {
fprintf(stderr, "error bme680 calibration\n");
} else {
print_calibration(&bme680.cal);
}
//1. write osrs fields to diff regs
uint8_t ctrl_meas, ctrl_hum;
uint8_t osrs_t, osrs_p, osrs_h, ctrl_mode;
osrs_t = osrs_p = osrs_h = 0b011;
ctrl_mode = 0;
ctrl_meas = (osrs_t << 5) | (osrs_p << 2) | ctrl_mode;
ctrl_hum = osrs_h;
i2c_write_reg(fd, 0x74, ctrl_meas);
i2c_write_reg(fd, 0x72, ctrl_hum);
// set filter mode
uint8_t filter_reg = 0b101 << 2;
i2c_write_reg(fd, 0x75, filter_reg);
// todo gas stuff
// resend ctrl_meas but with ctrl_mode set to 0b01 in it, then it should work
ctrl_meas |= 1;
i2c_write_reg(fd, 0x74, ctrl_meas);
// poll reg `meas_status_0 bit 5. It will be 0 when all scheduled conversions are done.
uint8_t qq;
while ((qq = i2c_read_reg2(fd, 0x1D)) >> 4) {
usleep(2000); // 2 ms
}
// now read the temp/press/hum adc and convert in order.
uint32_t temp_adc, press_adc, hum_adc;
uint8_t buffer[3];
i2c_read_reg(fd, 0x22, 3, buffer);
temp_adc = (buffer[0] << 12) | (buffer[1] << 4) | (buffer[2] >> 4);
i2c_read_reg(fd, 0x1F, 3, buffer);
press_adc = (buffer[0] << 12) | (buffer[1] << 4) | (buffer[2] >> 4);
i2c_read_reg(fd, 0x25, 2, buffer);
hum_adc = (buffer[0] << 8) | buffer[1];
// adc readings are only 20-bit when the IIR filter is enabled, otherwise
// the size depends on the oversample settings (osrs_X).
double temperature = calc_temp_comp_1 ( temp_adc , &bme680 );
printf("temperature: %g oC (floating-point)\n", temperature);
int temperature2 = calc_temp_comp_2 (temp_adc, &bme680 );
printf("temperature: %d oC (integer)\n", temperature2);
double pressure = calc_press_comp_1 ( press_adc , &bme680 );
printf("pressure: %g Pa (floating-point)\n", pressure);
int pressure2 = calc_press_comp_2 (press_adc , &bme680 );
printf("pressure: %d Pa (integer)\n", pressure2);
double humidity = calc_hum_comp_1 ( hum_adc, &bme680 );
printf("humidity: %g (floating-point)\n", humidity);
int humidity2 = calc_hum_comp_2 ( hum_adc, &bme680 );
printf("humidity: %d (integer)\n", humidity2);
close(fd); close(fd);
return 0; return 0;