M5Paper and BME280 Sensor
-
Because the BME280 library didn't want to work with the M5Paper Wire1 I2c connection, I changed the routines so that they now work.
The adjustment now works for M5Stack, the M5Paper and for the Core2.
I post the complete code here, because I cannot upload a zip file.
he whole consists of:- M5Paper_BME280.uno
- BME280.h
- BME280_routines
1. M5Paper_BME280.uno
/* * BME280 Sensor (Temperature,Pressure, and Humidity) * Is working now also for M5Paper, and testest on all M5Stack devices * Rewritten by J.Kromhout (NL) * Version 1.0 * Date : 24-02-2021 * * Todo: Beter input for smapling etc. * Making the routine universal for BME280 and BMP280 */ #include <M5EPD.h> #include <Wire.h> #include "BME280.h" /* definition file */ double p,t,h; /* pressure,temperature and humidity */ void setup() { M5.begin(); Wire1.begin(25,32); /* start Wire1 on M5Paper */ getBME280(&Wire1, &t, &p, &h); /* get messurment*/ Serial.println("-------------------------"); Serial.printf("Temperature : %6.1f °C\n", t); Serial.printf("Barometer : %6.1f hPa\n", p); Serial.printf("Humidity : %6.1f %%\n", h); Serial.println("-------------------------"); } void loop() { // put your main code here, to run repeatedly: } void getBME280(TwoWire *theWire, double *t, double *p, double *h) { _i2c = theWire; /* check of BME280 is avilable */ uint8_t value = read8(0xD0); if (value == 0x60) Serial.println("BME280 found"); else { Serial.println("No BME280 found! Check your device........"); while(true); } reset_BME280(); // Reset BME280 write8(BME280_REGISTER_CONTROLHUMID,(uint8_t)0x01); // Select control humidity register write8(BME280_REGISTER_CONTROL, (uint8_t)0x27); // Select control measurement register write8(BME280_REGISTER_CONFIG, (uint8_t)0xA0); // Select config register readCoefficients(); // Read coefficients from BME280 *t = get_Temperature(); // Get temperature *p = get_Pressure()/100.0; // Get pressure *h = get_Humidity(); // Get Humidity }2. BME280.h
#define BME280_ADDRESS 0x77 /* Primary I2C Address */ TwoWire *_i2c; uint8_t _i2caddr = BME280_ADDRESS; int32_t t_fine; /* tempory variable */ /* calibration data, need for calculation */ uint16_t dig_T1; int16_t dig_T2; int16_t dig_T3; uint16_t dig_P1; int16_t dig_P2; int16_t dig_P3; int16_t dig_P4; int16_t dig_P5; int16_t dig_P6; int16_t dig_P7; int16_t dig_P8; int16_t dig_P9; uint8_t dig_H1; int16_t dig_H2; uint8_t dig_H3; int16_t dig_H4; int16_t dig_H5; int8_t dig_H6; /* Calibrate registers addresses */ #define BME280_REGISTER_DIG_T1 0x88 #define BME280_REGISTER_DIG_T2 0x8A #define BME280_REGISTER_DIG_T3 0x8C #define BME280_REGISTER_DIG_P1 0x8E #define BME280_REGISTER_DIG_P2 0x90 #define BME280_REGISTER_DIG_P3 0x92 #define BME280_REGISTER_DIG_P4 0x94 #define BME280_REGISTER_DIG_P5 0x96 #define BME280_REGISTER_DIG_P6 0x98 #define BME280_REGISTER_DIG_P7 0x9A #define BME280_REGISTER_DIG_P8 0x9C #define BME280_REGISTER_DIG_P9 0x9E #define BME280_REGISTER_DIG_H1 0xA1 #define BME280_REGISTER_DIG_H2 0xE1 #define BME280_REGISTER_DIG_H3 0xE3 #define BME280_REGISTER_DIG_H4 0xE4 #define BME280_REGISTER_DIG_H5 0xE5 #define BME280_REGISTER_DIG_H6 0xE7 /* ontrol registers */ #define BME280_REGISTER_CHIPID 0xD0 #define BME280_REGISTER_VERSION 0xD1 #define BME280_REGISTER_SOFTRESET 0xE0 #define BME280_REGISTER_CAL26 0xE1 #define BME280_REGISTER_CONTROLHUMID 0xF2 #define BME280_REGISTER_STATUS 0xF3 #define BME280_REGISTER_CONTROL 0xF4 #define BME280_REGISTER_CONFIG 0xF5 #define BME280_REGISTER_PRESSUREDATA 0xF7 #define BME280_REGISTER_TEMPDATA 0xFA #define BME280_REGISTER_HUMIDDATA 0xFD3. BME280_routines
uint8_t read8(byte reg) { uint8_t value; _i2c->beginTransmission((uint8_t)BME280_ADDRESS); _i2c->write((uint8_t)reg); _i2c->endTransmission(); _i2c->requestFrom((uint8_t)BME280_ADDRESS,(uint8_t)1); value = _i2c->read(); return value; } void write8(byte reg , byte value) { _i2c->beginTransmission((uint8_t)BME280_ADDRESS); _i2c->write((uint8_t)reg); _i2c->write((uint8_t)value); _i2c->endTransmission(); } uint16_t read16(byte reg) { uint16_t value; _i2c->beginTransmission((uint8_t) BME280_ADDRESS); _i2c->write((uint8_t)reg); _i2c->endTransmission(); _i2c->requestFrom((uint8_t)BME280_ADDRESS,(uint8_t)2); value = (_i2c->read() << 8) | _i2c->read(); return value; } uint32_t read24(byte reg) { uint32_t value; _i2c->beginTransmission((uint8_t)BME280_ADDRESS); _i2c->write((uint8_t)reg); _i2c->endTransmission(); _i2c->requestFrom((uint8_t)BME280_ADDRESS,(uint8_t)3); value = _i2c->read(); value <<= 8; value |= _i2c->read(); value <<= 8; value |= _i2c->read(); return value; } uint16_t read16_LE(byte reg) { uint16_t temp = read16(reg); return (temp >> 8) | (temp << 8); } int16_t readS16(byte reg) { return (int16_t) read16(reg); } int16_t readS16_LE(byte reg) { return (int16_t) read16_LE(reg); } void readCoefficients() { dig_T1 = read16_LE(BME280_REGISTER_DIG_T1); dig_T2 = readS16_LE(BME280_REGISTER_DIG_T2); dig_T3 = readS16_LE(BME280_REGISTER_DIG_T3); dig_P1 = read16_LE(BME280_REGISTER_DIG_P1); dig_P2 = readS16_LE(BME280_REGISTER_DIG_P2); dig_P3 = readS16_LE(BME280_REGISTER_DIG_P3); dig_P4 = readS16_LE(BME280_REGISTER_DIG_P4); dig_P5 = readS16_LE(BME280_REGISTER_DIG_P5); dig_P6 = readS16_LE(BME280_REGISTER_DIG_P6); dig_P7 = readS16_LE(BME280_REGISTER_DIG_P7); dig_P8 = readS16_LE(BME280_REGISTER_DIG_P8); dig_P9 = readS16_LE(BME280_REGISTER_DIG_P9); dig_H1 = read8(BME280_REGISTER_DIG_H1); dig_H2 = readS16_LE(BME280_REGISTER_DIG_H2); dig_H3 = read8(BME280_REGISTER_DIG_H3); dig_H4 = ((int8_t)read8(BME280_REGISTER_DIG_H4) << 4) | (read8(BME280_REGISTER_DIG_H4 + 1) & 0xF); dig_H5 = ((int8_t)read8(BME280_REGISTER_DIG_H5 + 1) << 4) | (read8(BME280_REGISTER_DIG_H5) >> 4); dig_H6 = (int8_t)read8(BME280_REGISTER_DIG_H6); } double get_Temperature() { int32_t var1, var2; int32_t adc_T = read24(BME280_REGISTER_TEMPDATA); adc_T >>= 4; var1 = ((((adc_T >> 3) - ((int32_t)dig_T1 << 1))) * ((int32_t)dig_T2)) >> 11; var2 = (((((adc_T >> 4) - ((int32_t)dig_T1)) * ((adc_T >> 4) - ((int32_t)dig_T1))) >> 12) * ((int32_t)dig_T3)) >> 14; t_fine = var1 + var2; double T = (t_fine * 5 + 128) >> 8; return T / 100; } double get_Pressure() { int64_t var1, var2, p; // Must be done first to get the t_fine variable set up get_Temperature(); int32_t adc_P = read24(BME280_REGISTER_PRESSUREDATA); adc_P >>= 4; var1 = ((int64_t)t_fine) - 128000; var2 = var1 * var1 * (int64_t)dig_P6; var2 = var2 + ((var1 * (int64_t)dig_P5) << 17); var2 = var2 + (((int64_t)dig_P4) << 35); var1 = ((var1 * var1 * (int64_t)dig_P3) >> 8) + ((var1 * (int64_t)dig_P2) << 12); var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)dig_P1) >> 33; if (var1 == 0) { return 0; // avoid exception caused by division by zero } p = 1048576 - adc_P; p = (((p << 31) - var2) * 3125) / var1; var1 = (((int64_t)dig_P9) * (p >> 13) * (p >> 13)) >> 25; var2 = (((int64_t)dig_P8) * p) >> 19; p = ((p + var1 + var2) >> 8) + (((int64_t)dig_P7) << 4); return (double)p / 256; } double get_Humidity(void) { get_Temperature(); // must be done first to get t_fine int32_t adc_H = read16(BME280_REGISTER_HUMIDDATA); if (adc_H == 0x8000) // value in case humidity measurement was disabled return NAN; int32_t v_x1_u32r; v_x1_u32r = (t_fine - ((int32_t)76800)); v_x1_u32r = (((((adc_H << 14) - (((int32_t)dig_H4) << 20) - (((int32_t)dig_H5) * v_x1_u32r)) + ((int32_t)16384)) >> 15) * (((((((v_x1_u32r * ((int32_t)dig_H6)) >> 10) * (((v_x1_u32r * ((int32_t)dig_H3)) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) * ((int32_t)dig_H2) + 8192) >> 14)); v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((int32_t)dig_H1)) >> 4)); v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r; v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r; double h = (v_x1_u32r >> 12); return h / 1024.0; } void reset_BME280() { write8(BME280_REGISTER_SOFTRESET , (uint8_t)0xB6); }Have fun with it. Let us know when there are improvements.
Cheers,Jan
-
Make an improvement in the main call routine. The return value of getBME280 is a boolean.
now it is possible to check whether a BME280 is connected correctly.bool getBME280(TwoWire *theWire, double *t, double *p, double *h) { _i2c = theWire; /* check of BME280 is avilable */ uint8_t value = read8(0xD0); if (value == 0x60) // BME280 detected { reset_BME280(); // Reset BME280 write8(BME280_REGISTER_CONTROLHUMID,(uint8_t)0x01); // Select control humidity register write8(BME280_REGISTER_CONTROL, (uint8_t)0x27); // Select control measurement register write8(BME280_REGISTER_CONFIG, (uint8_t)0xA0); // Select config register readCoefficients(); // Read coefficients from BME280 *t = get_Temperature(); // Get temperature *p = get_Pressure()/100.0; // Get pressure *h = get_Humidity(); // Get Humidity return true; } else { return false; // No BME280 detected } }Cheers,
Jan
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login