|
|
@@ -1,108 +1,185 @@
|
|
|
-/*
|
|
|
- bmp280_example.ino
|
|
|
- Example sketch for BMP280
|
|
|
+#include "Seeed_BMP280.h"
|
|
|
|
|
|
- Copyright (c) 2016 seeed technology inc.
|
|
|
- Website : www.seeedstudio.com
|
|
|
- Author : Lambor, CHN
|
|
|
- Create Time:
|
|
|
- Change Log : 2021/03/11 by @Kongduino
|
|
|
- Reworked example to display true altitude based on MSL
|
|
|
+// #define BMP280_DEBUG_PRINT
|
|
|
|
|
|
- The MIT License (MIT)
|
|
|
+bool BMP280::init(int i2c_addr) {
|
|
|
+ uint8_t chip_id = 0;
|
|
|
+ uint8_t retry = 0;
|
|
|
+ _devAddr = i2c_addr;
|
|
|
+ Wire.begin();
|
|
|
+ while ((retry++ < 5) && (chip_id != 0x58)) {
|
|
|
+ chip_id = bmp280Read8(BMP280_REG_CHIPID);
|
|
|
+#ifdef BMP280_DEBUG_PRINT
|
|
|
+ Serial.print("Read chip ID: ");
|
|
|
+ Serial.println(chip_id);
|
|
|
+#endif
|
|
|
+ delay(100);
|
|
|
+ }
|
|
|
+ dig_T1 = bmp280Read16LE(BMP280_REG_DIG_T1);
|
|
|
+ dig_T2 = bmp280ReadS16LE(BMP280_REG_DIG_T2);
|
|
|
+ dig_T3 = bmp280ReadS16LE(BMP280_REG_DIG_T3);
|
|
|
+ dig_P1 = bmp280Read16LE(BMP280_REG_DIG_P1);
|
|
|
+ dig_P2 = bmp280ReadS16LE(BMP280_REG_DIG_P2);
|
|
|
+ dig_P3 = bmp280ReadS16LE(BMP280_REG_DIG_P3);
|
|
|
+ dig_P4 = bmp280ReadS16LE(BMP280_REG_DIG_P4);
|
|
|
+ dig_P5 = bmp280ReadS16LE(BMP280_REG_DIG_P5);
|
|
|
+ dig_P6 = bmp280ReadS16LE(BMP280_REG_DIG_P6);
|
|
|
+ dig_P7 = bmp280ReadS16LE(BMP280_REG_DIG_P7);
|
|
|
+ dig_P8 = bmp280ReadS16LE(BMP280_REG_DIG_P8);
|
|
|
+ dig_P9 = bmp280ReadS16LE(BMP280_REG_DIG_P9);
|
|
|
+ writeRegister(BMP280_REG_CONTROL, 0x3F);
|
|
|
+ return true;
|
|
|
+}
|
|
|
|
|
|
- Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
- of this software and associated documentation files (the "Software"), to deal
|
|
|
- in the Software without restriction, including without limitation the rights
|
|
|
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
- copies of the Software, and to permit persons to whom the Software is
|
|
|
- furnished to do so, subject to the following conditions:
|
|
|
+float BMP280::getTemperature(void) {
|
|
|
+ int32_t var1, var2;
|
|
|
+ int32_t adc_T = bmp280Read24(BMP280_REG_TEMPDATA);
|
|
|
+ // Check if the last transport successed
|
|
|
+ if (!isTransport_OK) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ 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;
|
|
|
+ float T = (t_fine * 5 + 128) >> 8;
|
|
|
+ return T / 100;
|
|
|
+}
|
|
|
|
|
|
- The above copyright notice and this permission notice shall be included in
|
|
|
- all copies or substantial portions of the Software.
|
|
|
+uint32_t BMP280::getPressure(void) {
|
|
|
+ int64_t var1, var2, p;
|
|
|
+ // Call getTemperature to get t_fine
|
|
|
+ getTemperature();
|
|
|
+ // Check if the last transport successed
|
|
|
+ if (!isTransport_OK) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ int32_t adc_P = bmp280Read24(BMP280_REG_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 (uint32_t)p / 256;
|
|
|
+}
|
|
|
|
|
|
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
- THE SOFTWARE.
|
|
|
-*/
|
|
|
-#undef max
|
|
|
-#undef min
|
|
|
-#include <string>
|
|
|
+float BMP280::calcAltitude(float p0, float p1, float t) {
|
|
|
+ float C;
|
|
|
+ Serial.print("p0 = ");
|
|
|
+ Serial.println(p0);
|
|
|
+ Serial.print("p1 = ");
|
|
|
+ Serial.println(p1);
|
|
|
+ Serial.print("t = ");
|
|
|
+ Serial.println(t);
|
|
|
+ C = (p0 / p1);
|
|
|
+ Serial.print("C = ");
|
|
|
+ Serial.println(C);
|
|
|
+ C = pow(C, (1 / 5.25588)) - 1.0;
|
|
|
+ Serial.print("C = ");
|
|
|
+ Serial.println(C);
|
|
|
+ C = (C * (t + 273.15)) / 0.0065;
|
|
|
+ Serial.print("C = ");
|
|
|
+ Serial.println(C);
|
|
|
+ return C;
|
|
|
+}
|
|
|
|
|
|
-#include "Seeed_BMP280.h"
|
|
|
-#include <Wire.h>
|
|
|
-#include <ArduinoJson.h>
|
|
|
-// http://librarymanager/All#ArduinoJSON
|
|
|
+float BMP280::calcAltitude(float p0) {
|
|
|
+ if (!isTransport_OK) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ float t = getTemperature();
|
|
|
+ float p1 = getPressure();
|
|
|
+ return calcAltitude(p0, p1, t);
|
|
|
+}
|
|
|
|
|
|
-BMP280 bmp280;
|
|
|
-float MSL = 102009; // Mean Sea Level in Pa
|
|
|
-#define INTERVAL 2000
|
|
|
-double t0;
|
|
|
+uint8_t BMP280::bmp280Read8(uint8_t reg) {
|
|
|
+ Wire.beginTransmission(_devAddr);
|
|
|
+ Wire.write(reg);
|
|
|
+ Wire.endTransmission();
|
|
|
+ Wire.requestFrom(_devAddr, 1);
|
|
|
+ // return 0 if slave didn't response
|
|
|
+ if (Wire.available() < 1) {
|
|
|
+ isTransport_OK = false;
|
|
|
+ return 0;
|
|
|
+ } else if (isTransport_OK == false) {
|
|
|
+ isTransport_OK = true;
|
|
|
+ }
|
|
|
+ return Wire.read();
|
|
|
+}
|
|
|
|
|
|
-void setup() {
|
|
|
- Serial.begin(115200);
|
|
|
- delay(2000);
|
|
|
- Serial.println("\n\nBMP280 test");
|
|
|
- if (!bmp280.init()) {
|
|
|
- Serial.println("Device not connected or broken!");
|
|
|
- while (1);
|
|
|
+uint16_t BMP280::bmp280Read16(uint8_t reg) {
|
|
|
+ uint8_t msb, lsb;
|
|
|
+ Wire.beginTransmission(_devAddr);
|
|
|
+ Wire.write(reg);
|
|
|
+ Wire.endTransmission();
|
|
|
+ Wire.requestFrom(_devAddr, 2);
|
|
|
+ // return 0 if slave didn't response
|
|
|
+ if (Wire.available() < 2) {
|
|
|
+ isTransport_OK = false;
|
|
|
+ return 0;
|
|
|
+ } else {
|
|
|
+ isTransport_OK = true;
|
|
|
}
|
|
|
- t0 = millis();
|
|
|
+ msb = Wire.read();
|
|
|
+ lsb = Wire.read();
|
|
|
+ return (uint16_t) msb << 8 | lsb;
|
|
|
}
|
|
|
|
|
|
-void loop() {
|
|
|
- double t1 = millis();
|
|
|
- if (t1 - t0 > INTERVAL) {
|
|
|
- uint32_t pressure = bmp280.getPressure();
|
|
|
- //get and print temperatures
|
|
|
- Serial.print("Temp: ");
|
|
|
- Serial.print(bmp280.getTemperature());
|
|
|
- Serial.println(" *C");
|
|
|
- // Using "*C" as the unit for Celsius because the Arduino IDE doesn't support special symbols
|
|
|
+uint16_t BMP280::bmp280Read16LE(uint8_t reg) {
|
|
|
+ uint16_t data = bmp280Read16(reg);
|
|
|
+ return (data >> 8) | (data << 8);
|
|
|
+}
|
|
|
|
|
|
- //get and print atmospheric pressure data
|
|
|
- Serial.print("Pressure: ");
|
|
|
- Serial.print(pressure / 100.0);
|
|
|
- Serial.println(" HPa");
|
|
|
- Serial.print("MSL: ");
|
|
|
- Serial.print(MSL / 100.0);
|
|
|
- Serial.println(" HPa");
|
|
|
+int16_t BMP280::bmp280ReadS16(uint8_t reg) {
|
|
|
+ return (int16_t)bmp280Read16(reg);
|
|
|
+}
|
|
|
|
|
|
- //get and print altitude data
|
|
|
- // Pass MSL to the function
|
|
|
- Serial.print("Altitude: ");
|
|
|
- Serial.print(bmp280.calcAltitude(MSL));
|
|
|
- Serial.println(" m");
|
|
|
+int16_t BMP280::bmp280ReadS16LE(uint8_t reg) {
|
|
|
+ return (int16_t)bmp280Read16LE(reg);
|
|
|
+}
|
|
|
|
|
|
- Serial.println("\n");
|
|
|
- //add a line between output of different times.
|
|
|
- t0 = millis();
|
|
|
- }
|
|
|
- if (Serial.available()) {
|
|
|
- char mb[255];
|
|
|
- uint8_t ix = 0;
|
|
|
- while (Serial.available()) {
|
|
|
- mb[ix++] = Serial.read();
|
|
|
- }
|
|
|
- mb[ix] = 0;
|
|
|
- Serial.println("Incoming:");
|
|
|
- Serial.println(mb);
|
|
|
- StaticJsonDocument<200> doc;
|
|
|
- DeserializationError error = deserializeJson(doc, mb);
|
|
|
- // Pass a JSON packet to change current MSL. eg:
|
|
|
- // {"MSL":1021}
|
|
|
- if (!error) {
|
|
|
- float newMSL = doc["MSL"];
|
|
|
- Serial.print("New MSL: "); Serial.println(newMSL);
|
|
|
- if (newMSL > 0.0) {
|
|
|
- MSL = newMSL * 100;
|
|
|
- }
|
|
|
- } else {
|
|
|
- Serial.println("Parse error!");
|
|
|
+uint32_t BMP280::bmp280Read24(uint8_t reg) {
|
|
|
+ uint32_t data;
|
|
|
+ Wire.beginTransmission(_devAddr);
|
|
|
+ Wire.write(reg);
|
|
|
+ Wire.endTransmission();
|
|
|
+ Wire.requestFrom(_devAddr, 3);
|
|
|
+ // return 0 if slave didn't response
|
|
|
+ if (Wire.available() < 3) {
|
|
|
+ isTransport_OK = false;
|
|
|
+ return 0;
|
|
|
+ } else if (isTransport_OK == false) {
|
|
|
+ isTransport_OK = true;
|
|
|
+ if (!init(_devAddr)) {
|
|
|
+#ifdef BMP280_DEBUG_PRINT
|
|
|
+ Serial.println("Device not connected or broken!");
|
|
|
+#endif
|
|
|
}
|
|
|
}
|
|
|
+ data = Wire.read();
|
|
|
+ data <<= 8;
|
|
|
+ data |= Wire.read();
|
|
|
+ data <<= 8;
|
|
|
+ data |= Wire.read();
|
|
|
+ return data;
|
|
|
+}
|
|
|
+
|
|
|
+void BMP280::writeRegister(uint8_t reg, uint8_t val) {
|
|
|
+ Wire.beginTransmission(_devAddr); // start transmission to device
|
|
|
+ Wire.write(reg); // send register address
|
|
|
+ Wire.write(val); // send value to write
|
|
|
+ Wire.endTransmission(); // end transmission
|
|
|
}
|