├── README.md ├── keywords.txt ├── examples └── bme280_simple │ └── bme280_simple.ino └── BME280_t.h /README.md: -------------------------------------------------------------------------------- 1 | # BME280_light 2 | 3 | Based on the work of reaper7 from ESP8266 board 4 | 5 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | BME280 KEYWORD1 2 | 3 | begin KEYWORD2 4 | refresh KEYWORD2 5 | 6 | BMP085_C LITERAL1 7 | BMP085_F LITERAL1 8 | 9 | temperature LITERAL2 10 | pressure LITERAL2 11 | humidity LITERAL2 12 | pressureToAltitude LITERAL2 13 | seaLevelForAltitude LITERAL2 14 | -------------------------------------------------------------------------------- /examples/bme280_simple/bme280_simple.ino: -------------------------------------------------------------------------------- 1 | //based on: 2 | // Adafruit Adafruit_BME280_Library 3 | // https://github.com/adafruit/Adafruit_BME280_Library 4 | //and 5 | // Astuder BMP085-template-library-Energia 6 | // https://github.com/astuder/BMP085-template-library-Energia 7 | //plus code for altitude and relative pressure 8 | //by r7 9 | 10 | #include // required by BME280 library 11 | #include // import BME280 template library 12 | 13 | #define ASCII_ESC 27 14 | 15 | #define MYALTITUDE 150.50 16 | 17 | char bufout[10]; 18 | 19 | BME280<> BMESensor; // instantiate sensor 20 | 21 | void setup() 22 | { 23 | Serial.begin(115200); // initialize serial 24 | Wire.begin(0,2); // initialize I2C that connects to sensor 25 | BMESensor.begin(); // initalize bme280 sensor 26 | } 27 | 28 | void loop() { 29 | BMESensor.refresh(); // read current sensor data 30 | sprintf(bufout,"%c[1;0H",ASCII_ESC); 31 | Serial.print(bufout); 32 | 33 | Serial.print("Temperature: "); 34 | Serial.print(BMESensor.temperature); // display temperature in Celsius 35 | Serial.println("C"); 36 | 37 | Serial.print("Humidity: "); 38 | Serial.print(BMESensor.humidity); // display humidity in % 39 | Serial.println("%"); 40 | 41 | Serial.print("Pressure: "); 42 | Serial.print(BMESensor.pressure / 100.0F); // display pressure in hPa 43 | Serial.println("hPa"); 44 | 45 | float relativepressure = BMESensor.seaLevelForAltitude(MYALTITUDE); 46 | Serial.print("RelPress: "); 47 | Serial.print(relativepressure / 100.0F); // display relative pressure in hPa for given altitude 48 | Serial.println("hPa"); 49 | 50 | Serial.print("Altitude: "); 51 | Serial.print(BMESensor.pressureToAltitude(relativepressure)); // display altitude in m for given pressure 52 | Serial.println("m"); 53 | 54 | delay(1000); // wait a while before next loop 55 | } 56 | -------------------------------------------------------------------------------- /BME280_t.h: -------------------------------------------------------------------------------- 1 | //based on: 2 | // Adafruit Adafruit_BME280_Library 3 | // https://github.com/adafruit/Adafruit_BME280_Library 4 | //and 5 | // Astuder BMP085-template-library-Energia 6 | // https://github.com/astuder/BMP085-template-library-Energia 7 | //plus code for altitude and relative pressure 8 | //by r7 9 | 10 | #ifndef BME280_T_h 11 | #define BME280_T_h 12 | 13 | #include 14 | #include 15 | 16 | //---------------------I2C ADDRESS--------------------------------------------------- 17 | #define BME280_ADDRESS (0x76) 18 | //---------------------REGISTERS----------------------------------------------------- 19 | enum 20 | { 21 | BME280_REGISTER_DIG_T1 = 0x88, 22 | BME280_REGISTER_DIG_T2 = 0x8A, 23 | BME280_REGISTER_DIG_T3 = 0x8C, 24 | 25 | BME280_REGISTER_DIG_P1 = 0x8E, 26 | BME280_REGISTER_DIG_P2 = 0x90, 27 | BME280_REGISTER_DIG_P3 = 0x92, 28 | BME280_REGISTER_DIG_P4 = 0x94, 29 | BME280_REGISTER_DIG_P5 = 0x96, 30 | BME280_REGISTER_DIG_P6 = 0x98, 31 | BME280_REGISTER_DIG_P7 = 0x9A, 32 | BME280_REGISTER_DIG_P8 = 0x9C, 33 | BME280_REGISTER_DIG_P9 = 0x9E, 34 | 35 | BME280_REGISTER_DIG_H1 = 0xA1, 36 | BME280_REGISTER_DIG_H2 = 0xE1, 37 | BME280_REGISTER_DIG_H3 = 0xE3, 38 | BME280_REGISTER_DIG_H4 = 0xE4, 39 | BME280_REGISTER_DIG_H5 = 0xE5, 40 | BME280_REGISTER_DIG_H6 = 0xE7, 41 | 42 | BME280_REGISTER_CHIPID = 0xD0, 43 | BME280_REGISTER_VERSION = 0xD1, 44 | BME280_REGISTER_SOFTRESET = 0xE0, 45 | 46 | BME280_REGISTER_CAL26 = 0xE1, // R calibration stored in 0xE1-0xF0 47 | 48 | BME280_REGISTER_CONTROLHUMID = 0xF2, 49 | BME280_REGISTER_CONTROL = 0xF4, 50 | BME280_REGISTER_CONFIG = 0xF5, 51 | BME280_REGISTER_PRESSUREDATA = 0xF7, 52 | BME280_REGISTER_TEMPDATA = 0xFA, 53 | BME280_REGISTER_HUMIDDATA = 0xFD, 54 | }; 55 | //---------------------CALIBRATION DATA---------------------------------------------- 56 | typedef struct 57 | { 58 | uint16_t dig_T1; 59 | int16_t dig_T2; 60 | int16_t dig_T3; 61 | 62 | uint16_t dig_P1; 63 | int16_t dig_P2; 64 | int16_t dig_P3; 65 | int16_t dig_P4; 66 | int16_t dig_P5; 67 | int16_t dig_P6; 68 | int16_t dig_P7; 69 | int16_t dig_P8; 70 | int16_t dig_P9; 71 | 72 | uint8_t dig_H1; 73 | int16_t dig_H2; 74 | uint8_t dig_H3; 75 | int16_t dig_H4; 76 | int16_t dig_H5; 77 | int8_t dig_H6; 78 | } bme280_calib_data; 79 | //---------------------TEMPERATURE UNITS---------------------------------------------- 80 | enum BME280_temp_t 81 | { 82 | BME280_C, 83 | BME280_F 84 | }; 85 | //---------------------TEMPLATE/STRUCTURE--------------------------------------------- 86 | template 88 | struct BME280 { 89 | 90 | private: 91 | 92 | bme280_calib_data _bme280_calib; 93 | 94 | //---------------Writes an 8 bit value over I2C 95 | void write8(byte reg, byte value) { 96 | Wire.beginTransmission((uint8_t)_i2caddr); 97 | Wire.write((uint8_t)reg); 98 | Wire.write((uint8_t)value); 99 | Wire.endTransmission(); 100 | } 101 | //---------------Reads an 8 bit value over I2C 102 | uint8_t read8(byte reg) { 103 | uint8_t value; 104 | 105 | Wire.beginTransmission((uint8_t)_i2caddr); 106 | Wire.write((uint8_t)reg); 107 | Wire.endTransmission(); 108 | Wire.requestFrom((uint8_t)_i2caddr, (byte)1); 109 | value = Wire.read(); 110 | Wire.endTransmission(); 111 | 112 | return value; 113 | }; 114 | //---------------Reads a 16 bit value over I2C 115 | uint16_t read16(byte reg) { 116 | uint16_t value; 117 | 118 | Wire.beginTransmission((uint8_t)_i2caddr); 119 | Wire.write((uint8_t)reg); 120 | Wire.endTransmission(); 121 | Wire.requestFrom((uint8_t)_i2caddr, (byte)2); 122 | value = (Wire.read() << 8) | Wire.read(); 123 | Wire.endTransmission(); 124 | 125 | return value; 126 | }; 127 | 128 | uint16_t read16_LE(byte reg) { 129 | uint16_t temp = read16(reg); 130 | 131 | return (temp >> 8) | (temp << 8); 132 | }; 133 | //---------------Reads a signed 16 bit value over I2C 134 | int16_t readS16(byte reg) { 135 | return (int16_t)read16(reg); 136 | }; 137 | 138 | int16_t readS16_LE(byte reg) { 139 | return (int16_t)read16_LE(reg); 140 | }; 141 | 142 | //---------------Reads the factory-set coefficients 143 | void readCoefficients(void) { 144 | _bme280_calib.dig_T1 = read16_LE(BME280_REGISTER_DIG_T1); 145 | _bme280_calib.dig_T2 = readS16_LE(BME280_REGISTER_DIG_T2); 146 | _bme280_calib.dig_T3 = readS16_LE(BME280_REGISTER_DIG_T3); 147 | 148 | _bme280_calib.dig_P1 = read16_LE(BME280_REGISTER_DIG_P1); 149 | _bme280_calib.dig_P2 = readS16_LE(BME280_REGISTER_DIG_P2); 150 | _bme280_calib.dig_P3 = readS16_LE(BME280_REGISTER_DIG_P3); 151 | _bme280_calib.dig_P4 = readS16_LE(BME280_REGISTER_DIG_P4); 152 | _bme280_calib.dig_P5 = readS16_LE(BME280_REGISTER_DIG_P5); 153 | _bme280_calib.dig_P6 = readS16_LE(BME280_REGISTER_DIG_P6); 154 | _bme280_calib.dig_P7 = readS16_LE(BME280_REGISTER_DIG_P7); 155 | _bme280_calib.dig_P8 = readS16_LE(BME280_REGISTER_DIG_P8); 156 | _bme280_calib.dig_P9 = readS16_LE(BME280_REGISTER_DIG_P9); 157 | 158 | _bme280_calib.dig_H1 = read8(BME280_REGISTER_DIG_H1); 159 | _bme280_calib.dig_H2 = readS16_LE(BME280_REGISTER_DIG_H2); 160 | _bme280_calib.dig_H3 = read8(BME280_REGISTER_DIG_H3); 161 | _bme280_calib.dig_H4 = (read8(BME280_REGISTER_DIG_H4) << 4) | (read8(BME280_REGISTER_DIG_H4+1) & 0xF); 162 | _bme280_calib.dig_H5 = (read8(BME280_REGISTER_DIG_H5+1) << 4) | (read8(BME280_REGISTER_DIG_H5) >> 4); 163 | _bme280_calib.dig_H6 = (int8_t)read8(BME280_REGISTER_DIG_H6); 164 | }; 165 | 166 | public: 167 | float temperature = 0; 168 | float pressure = 0; 169 | float humidity = 0; 170 | 171 | bool begin() { 172 | Wire.begin(); 173 | 174 | if (read8(BME280_REGISTER_CHIPID) != 0x60) 175 | return false; 176 | 177 | readCoefficients(); 178 | write8(BME280_REGISTER_CONTROLHUMID, 0x03); // Set before CONTROL (DS 5.4.3) 179 | write8(BME280_REGISTER_CONTROL, 0x3F); 180 | return true; 181 | }; 182 | 183 | void refresh() { 184 | //------------------temperature 185 | //int32_t var1, var2; 186 | 187 | int32_t adc_T = read16(BME280_REGISTER_TEMPDATA); 188 | adc_T <<= 8; 189 | adc_T |= read8(BME280_REGISTER_TEMPDATA+2); 190 | adc_T >>= 4; 191 | 192 | int32_t var1t = ((((adc_T>>3) - ((int32_t)_bme280_calib.dig_T1 <<1))) * 193 | ((int32_t)_bme280_calib.dig_T2)) >> 11; 194 | 195 | int32_t var2t = (((((adc_T>>4) - ((int32_t)_bme280_calib.dig_T1)) * 196 | ((adc_T>>4) - ((int32_t)_bme280_calib.dig_T1))) >> 12) * 197 | ((int32_t)_bme280_calib.dig_T3)) >> 14; 198 | 199 | int32_t t_fine = var1t + var2t; 200 | 201 | float T = (t_fine * 5 + 128) >> 8; 202 | temperature = T/100; 203 | 204 | //------------------pressure 205 | int64_t var1, var2, p; 206 | 207 | int32_t adc_P = read16(BME280_REGISTER_PRESSUREDATA); 208 | adc_P <<= 8; 209 | adc_P |= read8(BME280_REGISTER_PRESSUREDATA+2); 210 | adc_P >>= 4; 211 | 212 | var1 = ((int64_t)t_fine) - 128000; 213 | var2 = var1 * var1 * (int64_t)_bme280_calib.dig_P6; 214 | var2 = var2 + ((var1*(int64_t)_bme280_calib.dig_P5)<<17); 215 | var2 = var2 + (((int64_t)_bme280_calib.dig_P4)<<35); 216 | var1 = ((var1 * var1 * (int64_t)_bme280_calib.dig_P3)>>8) + 217 | ((var1 * (int64_t)_bme280_calib.dig_P2)<<12); 218 | var1 = (((((int64_t)1)<<47)+var1))*((int64_t)_bme280_calib.dig_P1)>>33; 219 | 220 | if (var1 == 0) { 221 | //return 0; // avoid exception caused by division by zero 222 | return; // avoid exception caused by division by zero 223 | } 224 | p = 1048576 - adc_P; 225 | p = (((p<<31) - var2)*3125) / var1; 226 | var1 = (((int64_t)_bme280_calib.dig_P9) * (p>>13) * (p>>13)) >> 25; 227 | var2 = (((int64_t)_bme280_calib.dig_P8) * p) >> 19; 228 | 229 | p = ((p + var1 + var2) >> 8) + (((int64_t)_bme280_calib.dig_P7)<<4); 230 | pressure = (float)p/256; 231 | 232 | //------------------humidity 233 | int32_t adc_H = read16(BME280_REGISTER_HUMIDDATA); 234 | 235 | int32_t v_x1_u32r; 236 | 237 | v_x1_u32r = (t_fine - ((int32_t)76800)); 238 | 239 | v_x1_u32r = (((((adc_H << 14) - (((int32_t)_bme280_calib.dig_H4) << 20) - 240 | (((int32_t)_bme280_calib.dig_H5) * v_x1_u32r)) + ((int32_t)16384)) >> 15) * 241 | (((((((v_x1_u32r * ((int32_t)_bme280_calib.dig_H6)) >> 10) * 242 | (((v_x1_u32r * ((int32_t)_bme280_calib.dig_H3)) >> 11) + ((int32_t)32768))) >> 10) + 243 | ((int32_t)2097152)) * ((int32_t)_bme280_calib.dig_H2) + 8192) >> 14)); 244 | 245 | v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * 246 | ((int32_t)_bme280_calib.dig_H1)) >> 4)); 247 | 248 | v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r; 249 | v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r; 250 | float h = (v_x1_u32r>>12); 251 | humidity = h / 1024.0; 252 | 253 | }; 254 | 255 | //float pressureToAltitude(float seaLevel, float atmospheric) { 256 | float pressureToAltitude(float seaLevel = 101325.00) { 257 | ////float atmospheric = pressure / 100.0F; //hPa 258 | //float atmospheric = pressure; //Pa 259 | //return 44330.0 * (1.0 - pow(atmospheric / seaLevel, 0.1903)); 260 | return 44330.0 * (1.0 - pow(pressure / seaLevel, 0.1903)); 261 | }; 262 | 263 | //float seaLevelForAltitude(float altitude = 150.50, float atmospheric) { 264 | float seaLevelForAltitude(float altitude = 150.50) { 265 | ////float atmospheric = pressure / 100.0F; //hPa 266 | //float atmospheric = pressure; //Pa 267 | //return pow((altitude/44330.0) + 1.0, 5.255F) * atmospheric; 268 | return pow((altitude / 44330.0) + 1.0, 5.255F) * pressure; 269 | }; 270 | 271 | }; 272 | #endif 273 | --------------------------------------------------------------------------------