BMP280 MS5611 added

This commit is contained in:
Myk 2024-04-13 01:03:37 +03:00
parent 54285dd721
commit 258fa0097d
9 changed files with 294 additions and 29 deletions

View File

@ -24,8 +24,16 @@ make flash
In the event of TVOC issues, inspections should be carried out to find
the root cause of the problem and address it as exposure to the VOCs
may harm health. Indoor VOC levels up to 350 ppb are
acceptable. However they should not exceed 500ppb. CO2 ppm range of
450 to 2000 ppm (parts per million).
acceptable. However they should not exceed 500ppb.
400 ppm: average outdoor air level.
4001,000 ppm: typical level found in occupied spaces with good air exchange.
1,0002,000 ppm: level associated with complaints of drowsiness and poor air.
2,0005,000 ppm: level associated with headaches, sleepiness, and stagnant, stale, stuffy air. Poor concentration, loss of attention, increased heart rate and slight nausea may also be present.
5,000 ppm: this indicates unusual air conditions where high levels of other gases could also be present. Toxicity or oxygen deprivation could occur. This is the permissible exposure limit for daily workplace exposures.
40,000 ppm: this level is immediately harmful due to oxygen deprivation.
#+END_EXAMPLE
*** Particulate matter
+ PM1 :: are extremely fine particulates with a diameter of fewer than 1 microns.
@ -38,7 +46,7 @@ In gneral I want the stack to be pluggable as much as possible. The current scop
+ [X] Thermometer - provided by HDC1080
+ [X] Humidity sensor - provided by HDC1080
+ [-] Particulate matter
- [ ] PM2.5 - i'd to start with it
- [ ] PM2.5 - PS3003 acuired
- [ ] PM10
- [ ] PM1 - I might need it to indoor mod
+ [ ] Preasure sensor

21
include/BMP280Sensor.h Normal file
View File

@ -0,0 +1,21 @@
// BMP280Sensor.h
#ifndef BMP280SENSOR_H
#define BMP280SENSOR_H
#define BMP280_ADDR (0x76)
#define SEALEVELPRESSURE_HPA (1013.25)
#include <Adafruit_BME280.h>
class BMP280Sensor {
public:
BMP280Sensor(uint8_t address = BMP280_ADDR); // Constructor
void init();
void read_values(float* temperature, float* humidity, float* pressure, float* altitude);
private:
uint8_t _address; // BMP280 wake pin
Adafruit_BME280 bmp280; // BMP280 object
};
#endif // BMP280SENSOR_H

View File

@ -4,7 +4,7 @@
#define CCS811SENSOR_H
#define CCS811_WAK 23
#include "ccs811.h" // Include CCS811 library
#include <ccs811.h> // Include CCS811 library
class CCS811Sensor {
public:

19
include/MS5611Sensor.h Normal file
View File

@ -0,0 +1,19 @@
// MS5611Sensor.h
#ifndef MS5611SENSOR_H
#define MS5611SENSOR_H
#include <MS5611.h>
class MS5611Sensor {
public:
MS5611Sensor(); // Constructor
void init(); // Initialize without temperature and humidity
void read_values(double* temperature, double* preasure, double* altitude);
private:
uint8_t _address; // MS5611 I2C address
MS5611 ms5611; // MS5611 object
};
#endif // MS5611SENSOR_H

View File

@ -15,7 +15,9 @@ framework = arduino
lib_deps =
maarten-pennings/CCS811@^12.0.0
closedcube/ClosedCube HDC1080@^1.3.2
https://github.com/me-no-dev/ESPAsyncWebServer.git#master
https://github.com/me-no-dev/ESPAsyncWebServer.git#master
https://github.com/jarzebski/Arduino-MS5611
adafruit/Adafruit BME280 Library
monitor_speed = 115200
monitor_filters = default, log2file
extra_scripts = populate_static.py

View File

@ -1,14 +1,19 @@
#include "ESPAsyncWebServer.h"
#include <WiFi.h>
#include <Wire.h>
#include <time.h>
// Sensors
#include "HDC1080Sensor.h"
#include "CCS811Sensor.h"
#include <time.h>
#include "MS5611Sensor.h"
#include "BMP280Sensor.h"
//#include "src/ESPinfluxdb.h" // https://github.com/hwwong/ESP_influxdb // 14.04.2019
#include "http_static.h" // HTTP pages and JSON request templates
// ********************** Config **********************
// DeepSleep time send data every 60 seconds
// DeepSleep time send data every 60 seconds
const int sleepTimeS = 60;
// WiFi Config
@ -24,19 +29,64 @@ struct tm timeinfo;
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
// Globals for HDC1080
// Globals for HDC1080 :: Temp/Humidity
HDC1080Sensor HDC1080_sensors;
double hdc1080_temp, hdc1080_humidity;
bool hdc1080_err;
// Globals for CCS811
// Globals for CCS811 :: eTVOC/eCO2
CCS811Sensor CCS811_sensors;
uint16_t eco2, etvoc, errstat, raw;
uint16_t ccs811_eco2, ccs811_etvoc, ccs811_errstat, ccs811_raw;
// Globals for MS5611 :: Pressure/Altitude
MS5611Sensor MS5611_sensors;
double ms5611_temp, ms5611_pressure, ms5611_altitude;
// Globals for BMP280 :: Temp/Hum/Pressure
BMP280Sensor BMP280_sensors;
float bmp280_temp, bmp280_humidity, bmp280_pressure, bmp280_altitude;
// loop cycle
#define workCycle 60 //seconds
// ******************** Config End ********************
void scanI2CDevices() {
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for (address = 1; address < 127; address++) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.print("I2C device found at address 0x");
if (address < 16) {
Serial.print("0");
}
Serial.print(address, HEX);
Serial.println(" !");
nDevices++;
} else if (error == 4) {
Serial.print("Unknown error at address 0x");
if (address < 16) {
Serial.print("0");
}
Serial.println(address, HEX);
}
}
if (nDevices == 0) {
Serial.println("No I2C devices found\n");
} else {
Serial.println("done\n");
}
}
// ---------- HDC1080 ----------
String readHDC1080Temperature() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
if (isnan(hdc1080_temp)) {
@ -58,7 +108,8 @@ String readHDC1080Humidity() {
return String(hdc1080_humidity);
}
}
// ---------- End HDC1080 ----------
// ---------- CCS11 ----------
String processCCS811Error(err_t errstat) {
if ( errstat == CCS811_ERRSTAT_OK_NODATA ) {
Serial.println("CCS811: waiting for (new) data");
@ -74,20 +125,100 @@ String processCCS811Error(err_t errstat) {
}
String readCCS811TVOC() {
if( errstat==CCS811_ERRSTAT_OK ){
return String(etvoc);
if( ccs811_errstat==CCS811_ERRSTAT_OK ){
return String(ccs811_etvoc);
} else {
return processCCS811Error(errstat);
return processCCS811Error(ccs811_errstat);
}
}
String readCCS811ECO2() {
if( errstat==CCS811_ERRSTAT_OK ){
return String(eco2);
if( ccs811_errstat==CCS811_ERRSTAT_OK ){
return String(ccs811_eco2);
} else {
return processCCS811Error(errstat);
return processCCS811Error(ccs811_errstat);
}
}
// ---------- End CCS11 ----------
// ---------- MS5611 ----------
String readMS5611Temperature() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
if (isnan(ms5611_temp)) {
Serial.println("Failed to read from MS5611 sensor!");
return "--";
}
else {
return String(ms5611_temp);
}
}
String readMS5611Pressure() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
if (isnan(ms5611_pressure)) {
Serial.println("Failed to read from MS5611 sensor!");
return "--";
}
else {
return String(ms5611_temp);
}
}
String readMS5611Altitude() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
if (isnan(ms5611_altitude)) {
Serial.println("Failed to read from MS5611 sensor!");
return "--";
}
else {
return String(ms5611_altitude);
}
}
// ---------- End MS5611 ----------
// ---------- BMP280 ----------
String readBMP280Temperature() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
if (isnan(bmp280_temp)) {
Serial.println("Failed to read from BMP280 sensor!");
return "--";
}
else {
return String(bmp280_temp);
}
}
String readBMP280Humidity() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
if (isnan(bmp280_humidity)) {
Serial.println("Failed to read from BMP280 sensor!");
return "--";
}
else {
return String(bmp280_humidity);
}
}
String readBMP280Pressure() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
if (isnan(bmp280_pressure)) {
Serial.println("Failed to read from BMP280 sensor!");
return "--";
}
else {
return String(bmp280_pressure);
}
}
String readBMP280Altitude() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
if (isnan(bmp280_altitude)) {
Serial.println("Failed to read from BMP280 sensor!");
return "--";
}
else {
return String(bmp280_altitude);
}
}
// ---------- End BMP280 ----------
String formatISO8601() {
char timestamp[20]; // Buffer for timestamp
@ -163,17 +294,22 @@ void setup()
HDC1080_sensors.init();
// eCO2 and eTVOC, temp and humidity needed to adjust values
CCS811_sensors.init(&hdc1080_temp, &hdc1080_humidity);
// Todo add pointer to temp, we might allight Altimeter by another sens
// MS5611_sensors.init();
// humidity, temperature, pressure and altitude
BMP280_sensors.init();
// Pages and JSONs
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", http_static::index_html, processor);
});
// Deprecated
server.on("/api/sensors.json", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", http_static::sensor_things_resp, processor);
});
// lightweight named endpoints
// DEPRECATED lightweight named endpoints
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", readHDC1080Temperature().c_str());
});
@ -187,6 +323,19 @@ void setup()
request->send_P(200, "text/plain", readCCS811ECO2().c_str());
});
// For prometheus scrapping. to be deprecated as well
server.on("/metrics", HTTP_GET, [](AsyncWebServerRequest *request) {
String response = "hdc1080_temperature " + String(readHDC1080Temperature()) + "\n";
response += "hdc1080_humidity " + String(readHDC1080Humidity()) + "\n";
response += "ccs811_tvoc " + String(readCCS811TVOC()) + "\n";
response += "ccs811_eco2 " + String(readCCS811ECO2()) + "\n";
response += "bmp280_temperature " + String(readBMP280Temperature()) + "\n";
response += "bmp280_humidity " + String(readBMP280Humidity()) + "\n";
response += "bmp280_pressure " + String(readBMP280Pressure()) + "\n";
response += "bmp280_altitude " + String(readBMP280Altitude()) + "\n";
request->send(200, "text/plain", response);
});
// Start server
server.begin();
}
@ -202,16 +351,27 @@ void loop()
Serial.println("Failed to obtain time");
return;
}
scanI2CDevices();
Serial.print(&timeinfo, "[%M-%d-%Y--%H:%M:%S]: ");
HDC1080_sensors.read_values(&hdc1080_temp, &hdc1080_humidity, &hdc1080_err);
CCS811_sensors.read_values(&eco2, &etvoc, &errstat, &raw);
CCS811_sensors.read_values(&ccs811_eco2, &ccs811_etvoc, &ccs811_errstat, &ccs811_raw);
BMP280_sensors.read_values(&bmp280_temp, &bmp280_humidity, &bmp280_pressure, &bmp280_altitude);
Serial.print("H="); Serial.print(readHDC1080Temperature()); Serial.print(" °C ");
Serial.print("T="); Serial.print(readHDC1080Humidity()); Serial.print(" % ");
Serial.print("eco2="); Serial.print(readCCS811ECO2()); Serial.print(" ppm ");
Serial.print("etvoc="); Serial.print(readCCS811TVOC()); Serial.print(" ppb ");
Serial.print("T=");
Serial.print(readHDC1080Temperature());
Serial.print(" / ");
Serial.print(readBMP280Temperature());
Serial.print(" °C ");
Serial.print("H=");
Serial.print(readHDC1080Humidity());
Serial.print(" / ");
Serial.print(readBMP280Humidity());
Serial.print(" % ");
Serial.print("eco2="); Serial.print(readCCS811ECO2()); Serial.print(" ppm ");
Serial.print("etvoc="); Serial.print(readCCS811TVOC()); Serial.print(" ppb ");
Serial.print("pressure="); Serial.print(readBMP280Pressure()); Serial.print(" Pa ");
Serial.print("alt="); Serial.print(readBMP280Altitude()); Serial.print(" m ");
Serial.println("");
// Wait
delay(workCycle*1000);

View File

@ -0,0 +1,30 @@
// BMP280Sensor.cpp
#include "BMP280Sensor.h"
BMP280Sensor::BMP280Sensor(uint8_t address) : _address(address) {
// Constructor sets the address
}
void BMP280Sensor::init() {
// Enable BMP280
bool ok = bmp280.begin(_address);
/* weather monitoring settings from driver lib */
bmp280.setSampling(Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1, // temperature
Adafruit_BME280::SAMPLING_X1, // pressure
Adafruit_BME280::SAMPLING_X1, // humidity
Adafruit_BME280::FILTER_OFF );
}
void BMP280Sensor::read_values(float* temperature, float* humidity, float* pressure, float* altitude) {
// Only needed in forced mode! In normal mode, you can remove the next line.
bmp280.takeForcedMeasurement(); // has no effect in normal mode
if (humidity) *humidity = bmp280.readHumidity();
if (temperature) *temperature = bmp280.readTemperature();
if (pressure) *pressure = bmp280.readPressure() / 100.0F;
if (altitude) *altitude = bmp280.readAltitude(SEALEVELPRESSURE_HPA);
}

View File

@ -0,0 +1,25 @@
// MS5611Sensor.cpp
#include "MS5611Sensor.h"
// Initialize MS5611 sensor
// Ultra high resolution: MS5611_ULTRA_HIGH_RES
// (default) High resolution: MS5611_HIGH_RES
// Standard: MS5611_STANDARD
// Low power: MS5611_LOW_POWER
// Ultra low power: MS5611_ULTRA_LOW_POWER
MS5611Sensor::MS5611Sensor() {
// Constructor - No need to do anything here
}
void MS5611Sensor::init() {
ms5611.begin(MS5611_ULTRA_HIGH_RES);
}
void MS5611Sensor::read_values(double* temperature, double* preasure, double* altitude) {
if (temperature) *temperature = ms5611.readTemperature(true);
if (preasure) *preasure = ms5611.readPressure(true);
if (altitude) *altitude = ms5611.getAltitude(*preasure); // second arg double seaLevelPressure = 101325
}

View File

@ -19,7 +19,7 @@
"definition": "http://www.qudt.org/qudt/owl/1.0.0/quantity/Instances.html#Temperature"
},
"Sensor": {
"name": "Temperature Sensor",
"name": "temperature",
"description": "Sensor for measuring temperature"
},
"Observations": [
@ -43,7 +43,7 @@
"definition": "http://www.qudt.org/qudt/owl/1.0.0/quantity/Instances.html#RelativeHumidity"
},
"Sensor": {
"name": "Humidity Sensor",
"name": "humidity",
"description": "Sensor for measuring humidity"
},
"Observations": [
@ -67,7 +67,7 @@
"definition": "http://www.qudt.org/qudt/owl/1.0.0/quantity/Instances.html#TotalVolatileOrganicCompounds"
},
"Sensor": {
"name": "TVOC Sensor",
"name": "etcov",
"description": "Sensor for measuring Total Volatile Organic Compounds"
},
"Observations": [
@ -91,7 +91,7 @@
"definition": "http://www.qudt.org/qudt/owl/1.0.0/quantity/Instances.html#CarbonDioxideConcentration"
},
"Sensor": {
"name": "eCO2 Sensor",
"name": "eco2",
"description": "Sensor for measuring Equivalent Carbon Dioxide"
},
"Observations": [