forked from sbelectronics/tiny-bme280
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTinyBME280.cpp
More file actions
154 lines (140 loc) · 5.26 KB
/
TinyBME280.cpp
File metadata and controls
154 lines (140 loc) · 5.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/* TinyBME280 Library v2
David Johnson-Davies - www.technoblogy.com - 22nd June 2019
CC BY 4.0
Licensed under a Creative Commons Attribution 4.0 International license:
http://creativecommons.org/licenses/by/4.0/
*/
#include "TinyBME280.h"
int16_t T[4], P[10], H[7];
int32_t BME280t_fine;
int BME280address = 118;
int16_t read16 () {
uint8_t lo, hi;
lo = Wire.read(); hi = Wire.read();
return hi<<8 | lo;
}
int32_t read32 () {
uint8_t msb, lsb, xlsb;
msb = Wire.read(); lsb = Wire.read(); xlsb = Wire.read();
return (uint32_t)msb<<12 | (uint32_t)lsb<<4 | (xlsb>>4 & 0x0F);
}
// Can be called before BME280setup
void BME280setI2Caddress (uint8_t address) {
BME280address = address;
}
// Must be called once at start
void BME280setup (int mode) {
delay(2);
// Set the mode to Normal, no upsampling
Wire.beginTransmission(BME280address);
Wire.write(0xF2); // ctrl_hum
Wire.write(0b00000001);
Wire.write(0xF4); // ctrl_meas
Wire.write(0b00100100 | mode);
// Read the chip calibrations.
Wire.write(0x88);
Wire.endTransmission();
Wire.requestFrom(BME280address, 26);
for (int i=1; i<=3; i++) T[i] = read16(); // Temperature
for (int i=1; i<=9; i++) P[i] = read16(); // Pressure
Wire.read(); // Skip 0xA0
H[1] = (uint8_t)Wire.read(); // Humidity
//
Wire.beginTransmission(BME280address);
Wire.write(0xE1);
Wire.endTransmission();
Wire.requestFrom(BME280address, 7);
H[2] = read16();
H[3] = (uint8_t)Wire.read();
uint8_t e4 = Wire.read(); uint8_t e5 = Wire.read();
H[4] = ((int16_t)((e4 << 4) + (e5 & 0x0F)));
H[5] = ((int16_t)((Wire.read() << 4) + ((e5 >> 4) & 0x0F)));
H[6] = ((int8_t)Wire.read()); // 0xE7
// Read the temperature to set BME280t_fine
BME280temperature();
}
// Returns temperature in DegC, resolution is 0.01 DegC
// Output value of “5123” equals 51.23 DegC
int32_t BME280temperature () {
Wire.beginTransmission(BME280address);
Wire.write(0xFA);
Wire.endTransmission();
Wire.requestFrom(BME280address, 3);
int32_t adc = read32();
// Compensate
int32_t var1, var2, t;
var1 = ((((adc>>3) - ((int32_t)((uint16_t)T[1])<<1))) * ((int32_t)T[2])) >> 11;
var2 = ((((adc>>4) - ((int32_t)((uint16_t)T[1]))) * ((adc>>4) - ((int32_t)((uint16_t)T[1])))) >> 12);
var2 = (var2 * ((int32_t)T[3])) >> 14;
BME280t_fine = var1 + var2;
return (BME280t_fine*5+128)>>8;
}
// Returns pressure in Pa as unsigned 32 bit integer
// Output value of “96386” equals 96386 Pa = 963.86 hPa
uint32_t BME280pressure () {
Wire.beginTransmission(BME280address);
Wire.write(0xF7);
Wire.endTransmission();
Wire.requestFrom(BME280address, 3);
int32_t adc = read32();
// Compensate
int32_t var1, var2;
uint32_t p;
var1 = (((int32_t)BME280t_fine)>>1) - (int32_t)64000;
var2 = (((var1>>2) * (var1>>2)) >> 11 ) * ((int32_t)P[6]);
var2 = var2 + ((var1*((int32_t)P[5]))<<1);
var2 = (var2>>2) + (((int32_t)P[4])<<16);
var1 = (((P[3] * (((var1>>2) * (var1>>2)) >> 13 )) >> 3) + ((((int32_t)P[2]) * var1)>>1))>>18;
var1 = ((((32768+var1))*((int32_t)((uint16_t)P[1])))>>15);
if (var1 == 0) return 0;
p = (((uint32_t)(((int32_t)1048576) - adc) - (var2>>12)))*3125;
if (p < 0x80000000) p = (p << 1) / ((uint32_t)var1);
else p = (p / (uint32_t)var1) * 2;
var1 = (((int32_t)P[9]) * ((int32_t)(((p>>3) * (p>>3))>>13)))>>12;
var2 = (((int32_t)(p>>2)) * ((int32_t)P[8]))>>13;
p = (uint32_t)((int32_t)p + ((var1 + var2 + P[7]) >> 4));
return p;
}
// Humidity in %RH, resolution is 0.01%RH
// Output value of “4653” represents 46.53 %RH
uint32_t BME280humidity () {
Wire.beginTransmission(BME280address);
Wire.write(0xFD);
Wire.endTransmission();
Wire.requestFrom(BME280address, 2);
uint8_t hi = Wire.read(); uint8_t lo = Wire.read();
int32_t adc = (uint16_t)(hi<<8 | lo);
// Compensate
int32_t var1;
var1 = (BME280t_fine - ((int32_t)76800));
var1 = (((((adc << 14) - (((int32_t)H[4]) << 20) - (((int32_t)H[5]) * var1)) +
((int32_t)16384)) >> 15) * (((((((var1 * ((int32_t)H[6])) >> 10) * (((var1 *
((int32_t)H[3])) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) *
((int32_t)H[2]) + 8192) >> 14));
var1 = (var1 - (((((var1 >> 15) * (var1 >> 15)) >> 7) * ((int32_t)H[1])) >> 4));
var1 = (var1 < 0 ? 0 : var1);
var1 = (var1 > 419430400 ? 419430400 : var1);
return (uint32_t)((var1>>12)*25)>>8;
}
// Take a forced measurement.
// It's assumed the BME280 is in sleep mode. It'll be set to Forced mode, take
// the measurement, then automatically return to sleep mode after the measurement
// is complete.
void BME280ForceMeasurement () {
Wire.beginTransmission(BME280address);
Wire.write(0xF4); // ctrl_meas
Wire.write(0b00100101); // forced mode
Wire.endTransmission();
while (1) {
uint8_t x;
Wire.beginTransmission(BME280address);
Wire.write(0xF3); // status_Reg
Wire.endTransmission();
Wire.requestFrom(BME280address, 1);
x = Wire.read();
if ((x & 0x08) == 0) { // bit3, "measuring"
return;
}
delay(1);
}
}