Wetterstation v2
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

279 lines
7.7 KiB

/*
* Blink
* Turns on an LED on for one second,
* then off for one second, repeatedly.
*/
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <Wire.h>
#include <SPI.h>
#include <GxEPD2_BW.h>
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/Org_01.h>
#include "bitmaps/Bitmaps128x250.h"
#include <Adafruit_GFX.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME280.h"
#define ARDUINO_SAMD_VARIANT_COMPLIANCE
#include "SdsDustSensor.h"
#include "network/XD0OTA.h"
#include "network/XD0MQTT.h"
#include "icons.h"
static const char* TAG = "MAIN";
WiFiMulti wifiMulti;
GxEPD2_BW<GxEPD2_213_B72, GxEPD2_213_B72::HEIGHT> display(GxEPD2_213_B72(/*CS=SS*/ TFT_CS, /*DC=*/ TFT_DC, /*RST=*/ TFT_RST, /*BUSY=*/ -1)); // GDEH0213B72
Adafruit_BME280 bme; // I2C (also available: hardware SPI
//HardwareSerial Serial2(2);
SdsDustSensor sds(Serial2);
XD0OTA ota("esp32-weatherstation");
XD0MQTT mqtt;
uint32_t lastDisplayUpdate = 0;
void helloWorld()
{
const char HelloWorld[] = "IchbinsBens!";
//Serial.println("helloWorld");
display.setRotation(1);
display.setFont(&FreeMonoBold9pt7b);
display.setTextColor(GxEPD_BLACK);
int16_t tbx, tby; uint16_t tbw, tbh;
display.getTextBounds(HelloWorld, 0, 0, &tbx, &tby, &tbw, &tbh);
// center bounding box by transposition of origin:
uint16_t x = ((display.width() - tbw) / 2) - tbx;
uint16_t y = ((display.height() - tbh) / 2) - tby;
display.setFullWindow();
display.firstPage();
do
{
display.fillScreen(GxEPD_WHITE);
display.setCursor(x, y);
display.print(HelloWorld);
display.setCursor(5, display.height()-5);
display.setFont(&Org_01);
display.print(FW_VERSION);
}
while (display.nextPage());
//Serial.println("helloWorld done");
}
void displayIcoPartial(const uint8_t bitmap[], uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
display.setPartialWindow(x, y, w, h);
display.firstPage(); do {
display.drawInvertedBitmap(x, y, bitmap, w, h, GxEPD_BLACK);
} while (display.nextPage());
}
void getTime(char* ptr, size_t maxsize, const char* format) {
time_t now;
struct tm timeinfo;
time(&now); // update 'now' variable with current time
setenv("TZ", "CET-1CEST,M3.5.0/2,M10.5.0/3", 1);
tzset();
localtime_r(&now, &timeinfo);
strftime(ptr, maxsize, format, &timeinfo);
}
void printValues() {
#define SEALEVELPRESSURE_HPA (1013.25)
Serial.print("Temperature = ");
Serial.print(bme.readTemperature());
Serial.println(" *C");
Serial.print("Pressure = ");
Serial.print(bme.readPressure() / 100.0F);
Serial.println(" hPa");
Serial.print("Approx. Altitude = ");
Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
Serial.println(" m");
Serial.print("Humidity = ");
Serial.print(bme.readHumidity());
Serial.println(" %");
Serial.println();
}
/**
* \brief Setup function
*
* is run once on startup
*/
void setup()
{
Serial.begin(115200);
ESP_LOGD(TAG, "setup hardware and sensors");
// initialize LED digital pin as an output.
pinMode(LED_BUILTIN, OUTPUT);
// initialize e-paper display
SPI.begin(18, 19, 23, TFT_CS);
display.init();
#define BME_SDA 21
#define BME_SCL 22
Wire.begin(BME_SDA, BME_SCL);
if (!bme.begin()) {
ESP_LOGE(TAG, "Could not find a valid BME280 sensor, check wiring!");
}
/*
// Set up oversampling and filter initialization
bme.setTemperatureOversampling(BME680_OS_8X);
bme.setHumidityOversampling(BME680_OS_2X);
bme.setPressureOversampling(BME680_OS_4X);
bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
bme.setGasHeater(320, 150); // 320*C for 150 ms
*/
sds.begin();
display.clearScreen();
display.refresh();
ESP_LOGD(TAG, "displaying welcome screen");
helloWorld();
display.powerOff();
ESP_LOGD(TAG, "starting WiFi");
WiFi.setHostname("esp32-weatherstation");
wifiMulti.addAP(WIFI_SSID, WIFI_PASSWD);
wifiMulti.addAP(WIFI_SSID2, WIFI_PASSWD2);
Serial.println("Connecting Wifi...");
if(wifiMulti.run() == WL_CONNECTED) {
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
displayIcoPartial(ico_wifi16, display.width()-20, 0, ico_wifi16_width, ico_wifi16_height);
}
ESP_LOGD(TAG, "trying to fetch over-the-air update");
ota.update();
ESP_LOGD(TAG, "connecting to MQTT");
mqtt.begin();
ESP_LOGD(TAG, "setup done");
}
/**
* \brief Arduino main loop
*/
void loop()
{
ESP_LOGD(TAG, "loop()");
/* Do an e-paper display refresh every 2 minutes */
if (millis() - lastDisplayUpdate >= 2*60*1000) {
lastDisplayUpdate = millis();
display.setFullWindow();
display.setRotation(1);
display.firstPage();
do
{
display.fillScreen(GxEPD_WHITE);
display.setTextColor(GxEPD_BLACK);
display.setFont(&FreeSans9pt7b);
display.setTextWrap(false);
display.setCursor(0, 11);
display.println("ESP32-Wetterstation");
display.drawFastHLine(0, 14, display.width(), GxEPD_BLACK);
display.setCursor(0, 32);
display.print("Temperatur: ");
display.print(bme.readTemperature());
display.println(" *C");
display.print("Luftfeuchte: ");
display.print(bme.readHumidity());
display.println(" %");
display.print("Luftdruck:");
display.print(bme.readPressure() / 100.0F);
display.println(" hPa");
char timeStr[9];
getTime(timeStr, sizeof(timeStr), "%H:%M:%S");
display.setCursor(5, display.height()-5);
display.setFont(&Org_01);
display.print("Zeit: ");
display.println(timeStr);
}
while (display.nextPage());
display.powerOff();
/* send values MQTT */
String topic_temperature = String("thomas/sensor/") + ota.getMAC() + String("/temperature");
String topic_humidity = String("thomas/sensor/") + ota.getMAC() + String("/humidity");
String topic_pressure = String("thomas/sensor/") + ota.getMAC() + String("/pressure");
char temperature[8]; sprintf(temperature, "%.2f", bme.readTemperature());
char humidity[7]; sprintf(humidity, "%.2f", bme.readHumidity());
char pressure[8]; sprintf(pressure, "%.2f", bme.readPressure() / 100.0F);
mqtt.publish(topic_temperature.c_str(), temperature, sizeof(temperature));
mqtt.publish(topic_humidity.c_str(), humidity, sizeof(humidity));
mqtt.publish(topic_pressure.c_str(), pressure, sizeof(pressure));
}
/*
unsigned long endTime = bme.beginReading();
if (! bme.performReading()) {
ESP_LOGE(TAG, "BME680: Failed to perform reading :(");
return;
}
Serial.print("Temperature = "); Serial.print(bme.temperature); Serial.println(" *C");
display.print("Temperature: "); display.print(bme.temperature); display.println(" *C");
Serial.print("Pressure = "); Serial.print(bme.pressure / 100.0); Serial.println(" hPa");
display.print("Pressure: "); display.print(bme.pressure / 100); display.println(" hPa");
Serial.print("Humidity = "); Serial.print(bme.humidity); Serial.println(" %");
display.print("Humidity: "); display.print(bme.humidity); display.println(" %");
Serial.print("Gas = "); Serial.print(bme.gas_resistance / 1000.0); Serial.println(" KOhms");
display.print("Gas: "); display.print(bme.gas_resistance / 1000.0); display.println(" KOhms");
*/
PmResult pm = sds.readPm();
if (pm.isOk()) {
Serial.print("PM2.5 = ");
Serial.print(pm.pm25);
Serial.print(", PM10 = ");
Serial.println(pm.pm10);
// if you want to just print the measured values, you can use toString() method as well
Serial.println(pm.toString());
} else {
Serial.print("Could not read values from sensor, reason: ");
Serial.println(pm.statusToString());
}
printValues();
if(wifiMulti.run() != WL_CONNECTED) {
Serial.println("WiFi not connected!");
delay(1000);
}
delay(2000);
}