Benutzer-Werkzeuge

Webseiten-Werkzeuge


iot:innenraumthermometer:programmversion_0.1

Innenraumthermometer - Programmversion 0.1

Die Programmversion 0.1 enthält alle Grundfunktionen des Innenraumthermometers. Das Thermometer wacht alle zehn Minuten auf, misst Temperatur, Luftfeuchtigkeit, Luftdruck und die Batteriespannung, loggt sich in das WLAN ein, holt die aktuelle Zeit von einem NTP-Sever, stellt die Daten auf einem e-Paper-Display dar, sendet die Daten an OpenSenseMap und legt sich wieder für zehn Minuten schlafen. Die Zeit wird verwendet, um den Zeitpunkt der letzten Aktualisierung der Daten auf dem Display anzuzeigen.

// Innenraumthermometer
// Läuft auf einem Lolin D32 
// Misst Temperatur, Luftfeuchtigkeit und Luftdruck
// Zeigt die Daten auf einem E-Paper-Display an
// Sendet die Daten an OpenSenseMap

// Bibliotheken
#include <WiFi.h>
#include "time.h"
#include <Wire.h>
#include <SPI.h>  
#include <Adafruit_BME280.h>                      
#include <GxEPD.h>
#include <GxGDEH029A1/GxGDEH029A1.cpp>      // 2.9" b/w
#include <GxIO/GxIO_SPI/GxIO_SPI.cpp>
#include <GxIO/GxIO.cpp>
#include <U8g2_for_Adafruit_GFX.h>

/*
 * Anschluss des Waveshare 7,5 Zoll e-Paper Display an Lolin D32
 * DIN (blau):     Pin 23
 * CLK (gelb):     Pin 18
 * CS (orange):    Pin 5
 * DC (grün):      Pin 17
 * RST (weiß):     Pin 16
 * BUSY (violett): Pin 4
 */

// Base Class and path
GxIO_Class io(SPI, SS, 17, 16);
GxEPD_Class display(io, 16, 4);

Adafruit_BME280 bme; // I2C

U8G2_FOR_ADAFRUIT_GFX u8g2_for_adafruit_gfx;

uint64_t chipid; 

// WLAN SSDI und Passwort
const char* ssid       = "XXXXXXXXXXXXXX";         // Name des WLAN
const char* password   = "XXXXXXXXXXXXXXXXXXXX";   // Passwort des WLAN

// Opensensemap
//senseBox ID
#define SENSEBOX_ID "5b8105a27c5191001974d5ac"

//Sensor IDs
// Temperatur
#define temperatureSensorID "5b8105a27c5191001974d5ad"
// Luftfeuchtigkeit
#define humiditySensorID "5b81091f7c51910019757b79"
// Luftdruck
#define pressureSensorID "5b81091f7c51910019757b7a"
// Batteriespannung
#define voltageSensorID "5b811add7c5191001979373e"

char server[] = "ingress.opensensemap.org";

WiFiClient client;

const char* ntpServer = "pool.ntp.org";            // NTP Server Pool
const long  gmtOffset_sec = 3600;
const int   daylightOffset_sec = 3600;

float voltage;                                     // Spannung der Batterie

float temperature;                                 // Temperatur
float humidity;                                    // Luftfeuchtigkeit
float pressure;                                    // Luftdruck

#define uS_TO_S_FACTOR 1000000                     // Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  600                         // Time ESP32 will go to sleep (in seconds) */

RTC_DATA_ATTR int bootCount = 0;


void setup () {
  // Serielle Schnittstelle
  Serial.begin(115200);
  delay(1000); //Take some time to open up the Serial Monitor

  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) + " Seconds");

  // Chip ID 
  chipid = ESP.getEfuseMac();                      //The chip ID is essentially its MAC address(length: 6 bytes).
  Serial.printf("ESP32 Chip ID = %04X",(uint16_t)(chipid>>32));//print High 2 bytes
  Serial.printf("%08X\n",(uint32_t)chipid);//print Low 4bytes.

  // Initialisiert Wire
  Wire.begin(25, 26);           // SDA, SCL
      
  // e-Paper Display Waveshare 2,9 Zoll
  Serial.println();
  Serial.println("Setup Display");
  display.init(115200);                            // enable diagnostic output on Serial
  display.setRotation(3);                          // Displayinhalt um 90° nach rechts drehen
  Serial.println("Setup done");

  // Bindet die u8g2 Prozeduren in Adafruit GFX-Bibliothek ein
  u8g2_for_adafruit_gfx.begin(display);
  
  // BME280 initialisieren 
  bool status;
  status = bme.begin();  
  if (!status) {
      Serial.println("Could not find a valid BME280 sensor, check wiring!");
      while (1);
  }
  bme.setSampling(Adafruit_BME280::MODE_FORCED,
                    Adafruit_BME280::SAMPLING_X1, // temperature
                    Adafruit_BME280::SAMPLING_X1, // pressure
                    Adafruit_BME280::SAMPLING_X1, // humidity
                    Adafruit_BME280::FILTER_OFF   );
  
  // BME 280 abfragen 
  temperature = bme.readTemperature();
  humidity = bme.readHumidity();
  pressure = bme.readPressure() / 100.0F;
  
  // Verbindung zum WLAN Router aufbauen
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }
  Serial.println(" Connected!");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  
  // Aktuelle Zeit holen
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  Serial.print("Uhrzeit: "); printLocalTime();

  // Batteriespannung lesen
  voltage = analogRead(35) / 4096.0 * 7.445;            // Rechnerisch müsste der Faktor 7.445 sein
  Serial.print("Battery voltage: ");
  Serial.print(voltage);
  Serial.println(" volts");

  // Daten an Display senden
  display.fillScreen(GxEPD_WHITE);
  display.setTextColor(GxEPD_BLACK);                    // Systemschrift
  display.setFontMode(1);                               // u8g2 Fonts
  display.setBackgroundColor(GxEPD_WHITE);              // u8g2 Fonts
  display.setForegroundColor(GxEPD_BLACK);              // u8g2 Fonts


  // Temperatur
  display.setCursor(5, 16 );
  display.setFont(u8g2_font_helvB14_tf);
  display.print("Temperatur");

  display.setCursor(0, 100);  
  display.setFont(u8g2_font_logisoso58_tf);
  display.print(temperature, 1);

  display.setFont(u8g2_font_helvB12_tf);
  display.print("°C");

  // Luftfeuchtigkeit
  display.setCursor(180, 15);
  display.setFont(u8g2_font_helvB10_tf);
  display.print("Luftfeuchtigkeit");

  display.setCursor(180, 54);  
  display.setFont(u8g2_font_logisoso24_tf);
  display.print(humidity, 1);

  display.setFont(u8g2_font_helvB12_tf);
  display.print("% rH");

  // Luftdruck
  display.setCursor(180, 79);
  display.setFont(u8g2_font_helvB10_tf);
  display.print("Luftdruck");

  display.setCursor(180, 110);  
  display.setFont(u8g2_font_logisoso24_tf);
  display.print(pressure, 1);

  display.setFont(u8g2_font_helvB12_tf);
  display.print("hPa");

  // Aktualisierung
  display.setCursor(180, 128);
  display.setFont(u8g2_font_helvR08_tf);
  display.print("Aktualisiert: ");
  displayLocalTime();
  

  // Batteriespannung
  display.setCursor(0, 128);
  display.print(" Spannung: ");
  display.print(voltage);
  display.print(" Volt");

  
  display.update();


  // Daten an OpensenseMap senden
  Serial.print("connecting to ");
  Serial.println(server);

  // Use WiFiClient class to create TCP connections
  //WiFiClient client;
  const int port = 80;
  if (!client.connect(server, port)) {
    Serial.println("connection failed");
    return;
  }

  postFloatValue(temperature, 1, temperatureSensorID);
  postFloatValue(humidity, 1, humiditySensorID);
  postFloatValue(pressure, 1, pressureSensorID);
  postFloatValue(voltage, 1, voltageSensorID);
  
  // Schickt den ESP32 in den Tiefschlaf
  Serial.println("Going to sleep now");
  delay(100);
  esp_deep_sleep_start();

}


void loop() {

}

//######################################### Functions ##############################################

void printLocalTime() {
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.print("Failed to obtain time");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}

void displayLocalTime() {
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    display.print("--:--:--");
    return;
  }
  display.print(&timeinfo, "%H:%M:%S"); 
}

// Sendet die Daten an Opensensemap
void postFloatValue (float measurement, int digits, String sensorId) {
  //Float zu String konvertieren
  char obs[10];
  dtostrf(measurement, 5, digits, obs);
  //Json erstellen
  String jsonValue = "{\"value\":";
  jsonValue += obs;
  jsonValue += "}";
  //Mit OSeM Server verbinden und POST Operation durchführen
  Serial.println("-------------------------------------");
  Serial.print("Connectingto OSeM Server...");
  if (client.connect(server, 80)) {
    Serial.println("connected!");
    Serial.println("-------------------------------------");
    //HTTP Header aufbauen
    client.print("POST /boxes/"); client.print(SENSEBOX_ID); client.print("/"); client.print(sensorId); client.println(" HTTP/1.1");
    client.print("Host:");
    client.println(server);
    client.println("Content-Type: application/json");
    client.println("Connection: close");
    client.print("Content-Length: "); client.println(jsonValue.length());
    client.println();
    //Daten senden
    client.println(jsonValue);
    Serial.println(jsonValue);
  } else {
    Serial.println("failed!");
    Serial.println("-------------------------------------");
  }
  //Antwort von Server im seriellen Monitor anzeigen
  //waitForServerResponse();
}
iot/innenraumthermometer/programmversion_0.1.txt · Zuletzt geändert: 23.06.2024 10:01 von Frickelpiet