esp32-env-monitor/esp32-env-monitor.ino

171 lines
4.3 KiB
Arduino
Raw Normal View History

2019-05-02 15:40:41 +02:00
#include <Arduino.h>
2019-05-02 16:27:48 +02:00
#include <Wire.h>
2019-05-02 15:40:41 +02:00
2019-05-02 15:06:21 +02:00
#include <WiFi.h>
#include "wifi_login.h"
2019-05-02 15:40:41 +02:00
#include <U8x8lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
2019-05-02 15:59:42 +02:00
#include <BME280I2C.h>
2019-05-02 16:27:48 +02:00
#include <Adafruit_SGP30.h>
2019-05-02 15:59:42 +02:00
2019-05-02 21:52:54 +02:00
U8X8_SSD1327_EA_W128128_4W_HW_SPI u8x8(/* cs=*/ 17, /* dc=*/ 3, /* reset=*/ 16);
2019-05-02 15:40:41 +02:00
2019-05-02 15:59:42 +02:00
BME280I2C bme; // Default : forced mode, standby time = 1000 ms
// Oversampling = pressure ×1, temperature ×1, humidity ×1, filter off,
2019-05-02 16:27:48 +02:00
Adafruit_SGP30 sgp;
2019-05-02 15:40:41 +02:00
// setup the terminal (U8X8LOG) and connect to u8g2 for automatic refresh of the display
// The size (width * height) depends on the display
#define U8LOG_WIDTH 16
#define U8LOG_HEIGHT 12
uint8_t u8log_buffer[U8LOG_WIDTH*U8LOG_HEIGHT];
U8X8LOG u8x8log;
2019-05-02 16:27:48 +02:00
/* return absolute humidity [mg/m^3] with approximation formula
* @param temperature [°C]
* @param humidity [%RH]
*/
uint32_t getAbsoluteHumidity(float temperature, float humidity) {
// approximation formula from Sensirion SGP30 Driver Integration chapter 3.15
const float absoluteHumidity = 216.7f * ((humidity / 100.0f) * 6.112f * exp((17.62f * temperature) / (243.12f + temperature)) / (273.15f + temperature)); // [g/m^3]
const uint32_t absoluteHumidityScaled = static_cast<uint32_t>(1000.0f * absoluteHumidity); // [mg/m^3]
return absoluteHumidityScaled;
}
2019-05-02 15:06:21 +02:00
void setup() {
2019-05-02 15:40:41 +02:00
//Init Display
u8x8.begin();
u8x8.setFont(u8x8_font_chroma48medium8_r);
u8x8log.begin(u8x8, U8LOG_WIDTH, U8LOG_HEIGHT, u8log_buffer);
u8x8log.setRedrawMode(0); // 0: Update screen with newline, 1: Update screen for every char
2019-05-02 15:06:21 +02:00
//Init wifi connection
WiFi.begin(ssid, password);
2019-05-02 15:40:41 +02:00
u8x8log.print("Connecting to SSID:\n");
u8x8log.print(ssid);
u8x8log.print("\n");
u8x8log.print("\n");
2019-05-02 15:06:21 +02:00
while (WiFi.status() != WL_CONNECTED) {
delay(500);
2019-05-02 15:40:41 +02:00
u8x8log.print(".");
2019-05-02 15:06:21 +02:00
}
2019-05-02 15:40:41 +02:00
u8x8log.print("\n");
u8x8log.print("WiFi connected\n");
u8x8log.print("IP address:\n");
u8x8log.println(WiFi.localIP());
u8x8log.print("\n");
u8x8log.print("\n");
2019-05-02 15:06:21 +02:00
2019-05-02 15:59:42 +02:00
//Init BME280 sensor
Wire.begin();
while(!bme.begin())
{
u8x8log.print("Could not find BME280 sensor!\n");
delay(1000);
}
switch(bme.chipModel())
{
case BME280::ChipModel_BME280:
u8x8log.print("Found BME280 sensor! Success.\n");
break;
case BME280::ChipModel_BMP280:
u8x8log.print("Found BMP280 sensor! No Humidity available.\n");
break;
default:
u8x8log.print("Found UNKNOWN sensor! Error!\n");
}
2019-05-02 16:27:48 +02:00
//Init SGP30 sensor
while(!sgp.begin())
{
u8x8log.print("Could not find SGP30 sensor!\n");
delay(1000);
}
u8x8log.print("Found SGP30 serial #");
u8x8log.print(sgp.serialnumber[0], HEX);
u8x8log.print(sgp.serialnumber[1], HEX);
u8x8log.print(sgp.serialnumber[2], HEX);
u8x8log.print("\n");
// If you have a baseline measurement from before you can assign it to start, to 'self-calibrate'
//sgp.setIAQBaseline(0x8E68, 0x8F41); // Will vary for each sensor!
2019-05-02 15:06:21 +02:00
}
2019-05-02 16:27:48 +02:00
int counter = 0;
2019-05-02 15:06:21 +02:00
void loop() {
2019-05-02 15:40:41 +02:00
//Clear screen
u8x8log.print("\f");
2019-05-02 15:59:42 +02:00
2019-05-02 16:27:48 +02:00
//Read Temperature, humidity and pressure
2019-05-02 15:59:42 +02:00
float temp(NAN), hum(NAN), pres(NAN);
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
bme.read(pres, temp, hum, tempUnit, presUnit);
2019-05-02 16:27:48 +02:00
//Read Air Quality
sgp.setHumidity(getAbsoluteHumidity(temp, hum));
if (! sgp.IAQmeasure()) {
u8x8log.print("Air Quality Measurement failed\n");
return;
}
2019-05-02 15:59:42 +02:00
u8x8log.print("Temp: ");
u8x8log.print(temp);
u8x8log.print("°"+ String(tempUnit == BME280::TempUnit_Celsius ? 'C' :'F'));
u8x8log.print("\nHumidity: ");
u8x8log.print(hum);
u8x8log.print("% RH");
u8x8log.print("\nPressure: ");
u8x8log.print(pres);
u8x8log.print("Pa\n");
2019-05-02 16:27:48 +02:00
u8x8log.print("TVOC ");
u8x8log.print(sgp.TVOC);
u8x8log.print(" ppb\n");
u8x8log.print("eCO2 ");
u8x8log.print(sgp.eCO2);
u8x8log.print(" ppm\n");
//Get Baseline readings every 30s
counter++;
if (counter == 30) {
counter = 0;
uint16_t TVOC_base, eCO2_base;
if (! sgp.getIAQBaseline(&eCO2_base, &TVOC_base)) {
u8x8log.print("Failed to get baseline readings\n");
return;
}
u8x8log.print("Baseline values: eCO2: 0x");
u8x8log.print(eCO2_base, HEX);
u8x8log.print(" & TVOC: 0x");
u8x8log.print(TVOC_base, HEX);
u8x8log.print("\n");
}
delay(1000);
2019-05-02 15:40:41 +02:00
2019-05-02 15:06:21 +02:00
}