Created
May 7, 2019 22:23
-
-
Save mntmn/7fad270e6327ea4cd2997dba14484b60 to your computer and use it in GitHub Desktop.
Kind of minimal BME680 temperature reader for Arduino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Wire.h> | |
#include <stdint.h> | |
#define ADDR 0x77 | |
#define addr_ctrl_meas 0x74 | |
#define addr_temp 0x22 | |
#define BME680_COEFF_ADDR1 0x89 | |
#define BME680_COEFF_ADDR2 0xe1 | |
#define BME680_COEFF_ADDR1_LEN 25 | |
#define BME680_COEFF_ADDR2_LEN 16 | |
#define BME680_T1_LSB_REG 33 | |
#define BME680_T1_MSB_REG 34 | |
#define BME680_T2_LSB_REG 1 | |
#define BME680_T2_MSB_REG 2 | |
#define BME680_T3_REG 3 | |
uint16_t t1; | |
int16_t t2; | |
int8_t t3; | |
// lifted from BOSCH code | |
int16_t calc_temperature(int32_t temp_adc, int32_t t1, int32_t t2, int32_t t3) | |
{ | |
int64_t var1; | |
int64_t var2; | |
int64_t var3; | |
int16_t calc_temp; | |
int32_t t_fine; | |
var1 = ((int32_t) temp_adc >> 3) - (t1 << 1); | |
var2 = (var1 * t2) >> 11; | |
var3 = ((var1 >> 1) * (var1 >> 1)) >> 12; | |
var3 = ((var3) * (t3 << 4)) >> 14; | |
t_fine = (var2 + var3); | |
calc_temp = (int16_t) (((t_fine * 5) + 128) >> 8); | |
return calc_temp; | |
} | |
byte calib_vals[BME680_COEFF_ADDR1_LEN+BME680_COEFF_ADDR2_LEN]; | |
int read_regs(byte* dest, byte reg, int len) { | |
Wire.beginTransmission(ADDR); | |
Wire.write(reg); | |
Wire.endTransmission(false); | |
Wire.requestFrom(ADDR,len); | |
for (int i=0; i<len; i++) { | |
uint32_t j=0; | |
while (!Wire.available()) { | |
// todo timeout | |
j++; | |
if (j>1000000) break; | |
} | |
dest[i] = Wire.read(); | |
} | |
return len; | |
} | |
byte reg = addr_temp; | |
void setup() | |
{ | |
Serial.begin(9600); | |
Wire.begin(); | |
delay(100); | |
// reset | |
for (int i=0; i<10; i++) { | |
Wire.beginTransmission(ADDR); | |
Wire.write(byte(0xb6)); | |
Wire.endTransmission(); | |
delay(100); | |
} | |
read_regs(calib_vals, BME680_COEFF_ADDR1, BME680_COEFF_ADDR1_LEN); | |
read_regs(calib_vals+BME680_COEFF_ADDR1_LEN, BME680_COEFF_ADDR2, BME680_COEFF_ADDR2_LEN); | |
t1 = (uint16_t) (((uint16_t)calib_vals[BME680_T1_MSB_REG]<<8)|(uint16_t)calib_vals[BME680_T1_LSB_REG]); | |
t2 = (int16_t) (((int16_t)calib_vals[BME680_T2_MSB_REG]<<8)|(int16_t)calib_vals[BME680_T2_LSB_REG]); | |
t3 = (int8_t) (calib_vals[BME680_T3_REG]); | |
} | |
uint8_t temp_raw[3]; | |
void loop() | |
{ | |
// trigger a measurement | |
Wire.beginTransmission(ADDR); | |
Wire.write(byte(addr_ctrl_meas)); | |
Wire.write(byte(1 | (2<<5) | (1<<2))); | |
Wire.endTransmission(); | |
delay(100); | |
read_regs(temp_raw, addr_temp, 3); | |
int32_t temp_raw2 = ((int32_t)temp_raw[0]<<12)|((int32_t)temp_raw[1]<<4); | |
int16_t temp = calc_temperature(temp_raw2, t1, t2, t3); | |
Serial.print("temp_raw: "); | |
Serial.print(temp_raw2); | |
Serial.print(" t1: "); | |
Serial.print(t1); | |
Serial.print(" t2: "); | |
Serial.print(t2); | |
Serial.print(" t3: "); | |
Serial.print(t3); | |
Serial.print("\r\n"); | |
Serial.print("temp: "); | |
Serial.print(temp); | |
Serial.print("\r\n"); | |
delay(100); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment