Benutzer-Werkzeuge

Webseiten-Werkzeuge


autarke_wetterstation

Autarke Wetterstation

Wetterstation Nord/Ost

Warum Autark, ne nicht wegen den Strompreisen, so viel hat der Raspberry Pi Pico nicht gefuttert. Nein die Ameisen sind schuld. An dem Pi Pico hatte ich einen DS18B20. Also langes Kabel, zum Fenster raus. An einer Pflanzstange befestigt, denn an der Hausmauer hätte es falsche Ergebnisse geliefert. Die Ameisen fanden das interessant und sind dem Weg bis in die Wohnung gefolgt. Also kam die Idee für eine Autarke Wetterstation auf und weil Temperatur alleine bissel Langweilig ist ;-)

Also Recherchiert was man dafür benötigt. Natürlich gab es keine Gesamt Lösung, ich musste mir aus mehreren Projekten das eigene zusammen Basteln. Zu Beginn dann auch mit zu hohem Stromverbrauch durch die Komponenten und weil 5 V auf 3,3 V mittels Spannungsregler herunter geregelt wurde.
Nach weiterem Recherchieren und überlegen, bin ich nun auf die Aktuelle Variante gekommen. Dies ist keine Anleitung die Vorschreibt wie es geht, Verbbesserungspotenzial gibt es bestimmt, aber ich will mal aufzeigen wie ich das jetzt für mich gelöst habe.
Ich verlinke die Teil, Ihr solltet aber die Preise vorher vergleichen!

Teileliste

BME280 Barometrischer Sensor für Temperatur, Luftfeuchtigkeit und Luftdruck Als Sensor für Temperatur und Luftfeuchtigkeit habe ich den BME280 ausgewählt













D1 mini (links) und D1 mini lite (rechts) von obenD1 mini (links) und D1 mini lite (rechts) von unten Als Herz bzw. Hirn habe ich den D1 mini ausgewählt. Ich meine der D1 mini lite verbraucht weniger, gesicherte Infos habe ich keine gefunden. Funktionieren tut es mit beiden.
Achtung: ich habe bei meiner letzten Bestellung bei berrybase.de leider nicht den D1 mini lite mit dem ESP8285 bekommen, sondern den D1 mini mit ESP8266. Kontrolliert also die Platinen, bevor Ihr sie aus der Antistatischen Verpackung heraus nehmt, wenn diese nicht Wieder verschließbar ist.








Prototyping Shield für D1 Mini Das Prototyping Shield für D1 Mini nutze ich, da ich vom Solar-Power-Management-Modul die 3,3 V und GND, sowie die 3,3 V und GND vom BME280 am D1 mini anschließen muss. Später mehr.











Solar Power Management Module ist für 6V~24V Solarmodule Ich hatte erst das Solar Power Manager Module (D) von Waveshare genutzt, da dieses aber nur 5 V ausgeben kann, die ich mit Spannungsregler oder vom D1 mini selbst herunter regeln muss, habe ich mich umgeschaut und das Solar-Power-Management-Modul von Waveshare gefunden. Das kann direkt 3,3 V ausgeben.










Lithium Ionen Batterie Pack ICR18650 3.7V 4400mAh mit JST-PHR-2 Stecker Bei der Batterie bin ich dann von einer 18650 mit 3400mAh auf ein Lithium Ionen Batterie Pack ICR18650 3.7V 4400mAh mit JST-PHR-2 Stecker gewechselt. Die Zellen sind parallel geschaltet und mit einer Schutzschaltung punktverschweißt, die einen Überspannungs-, Unterspannungs- und Überstromschutz bietet. Lieber etwas zu viel Strom wie zu wenig ;-) Später mehr.





Solar Panel (6V 5W) Solar Panel (6V 5W) von Waveshare um die Batterie aufzuladen. Das Panel lädt übrigens schon bei Tageslicht.












Wasserdichte AnschlussdoseWasserdichte Anschlussdose, irgendwo muss die Elektrik und der Akku ja unter gebracht werden.








TFA-Dostmann Wetterschutzgehäuse für AußensenderTFA-Dostmann Wetterschutzgehäuse für Außensender den der BME280 darf kein direktes Wasser abbekommen.











Weitere Teile:


Für die Wetterstation Nord/Ost habe ich noch folgendes benötigt zum aufstellen:

  • Sonnenschirm Ständer (Stahlplatte mit 27 kg)
  • 1¾ Zoll Wasserrohr, 1 x 2 m + 1 x 60 cm


Weiter Dinge die Nötig sind:


Was man gebrauchen kann, aber nicht zwingend nötig ist:


Aufbau

Gestell Wetterstation Nord/OstWetterstation Nord/OstNun habe ich mir als erstes überlegt, wie man die ganzen Teile zusammen bekommt. Dafür habe ich nachgelesen, in welchem Winkel das Solar Panel am besten aufgestellt werden soll. Bei fest stehenden Solar Panel wird ein Winkel von 30° - 35° angeraten.
Somit hatte ich schon einmal 3 Werte um ein Dreieck zu berechnen. Die Länge des Solar Panel mit 23 cm (Seite c), der Winkel mit 35° (Winkel β) und der Winkel γ mit 90°.
So kam ich für a auf 18,84 cm und für b auf 13,19. Da nun das Alu Rohr nur auf den Millimeter genau, und nicht auf Zehntel Millimter, geschnitten wird und ich noch die Verbinder mit einrechnen musste, entschied ich mich für a = 17 cm mit Verbinder 18,35 cm, b = 11,5 cm mit Verbinder 12,75 cm.
Das führt dann zu einem Winkel β von 34,79°.
Die Querstreben, an denen das Lochband befestigt wird, sind je 14 cm lang. Die Strebe an dem die Wetterschutzhülle befestigt wird ist 15 cm lang. Auf den Bildern ist das Gestell der Wetterstion die auf der Nord/Ost Seite steht zu sehen.
Für die Süd/West Seite habe ich aufgrund der Befestigungsmöglichkeit das Gestell etwas anders aufgebaut.





Gestell Wetterstation Süd/WestWetterstation Süd/West Da ich auf der Süd/West Seite kein Sonnenschirm Ständer und Wasserrohr benötige um die Wetterstation zu befestigen, habe ich das Gestell verändert. Um den Sensor so weit wie möglich vom Gebäude weg zu bekommen, habe ich die Stange für die Wetterschutzhülle vor das Solar Panel gesetzt. Die Verbindungsstange ist 35 cm lang. Bilder kann ich dazu noch keine zeigen, da Aktuell der Balkon, wo die Wetterstation aufgestellt wird, Renoviert wird. Die füge ich dann ein, sobald der Balkon fertig ist.








Solar Panel mit LochbandSolar Panel mit Lochband und Box Das Solar Panel hat auf der Rückseite Löcher im Rahmen. Diese habe ich genutzt und daran Lochband befestigt. Das Lochband habe ich dann an den Freien Enden am Alu Gestell befestigt. Die Löcher der Wasserdichten Anschlussdose haben leider nicht auf den Abstand der Löcher im Solar Panel gepasst. Ich habe die Dose dann einfach mit Kabelbindern am Lochband befestigt.
Die Anschlussdose hatte keine Löcher für die Kabelverschraubung, diese habe ich mit einem Stufenbohrer hinein gemacht. Das schwierigste hier war den Stecker des Solar Panel durch den Reduzierdichteinsatz zu bekommen. Hier hat mir Seife geholfen, aber keine Flüssig Seife, sondern ein Stück feste Seife. Den Stecker an der Dicksten Stelle damit eingerieben, bissel drücken und schieben und flutsch war der Stecker durch ^_^










Wetterschutzhülle mit BME280 Für den Anschluss des Sensors habe ich mir eine Steuerleitung 4 x 0.14 mm² geholt, da ich nicht mit 4 einzelnen Kabeln arbeiten wollte. Hier muss man aufpassen, das Kabel sollte man zuerst durch den Boden der Wetterschutzhülle ziehen, weder der 1×4 noch die zwei 1×2 Dupont Stecker passt durch das Loch. Ich habe dann einfach das Kabel mit 2 Kabelbindern befestigt. Und die Wetterschutzhülle habe ich auch mit Kabelbindern am Gestell befestigt.











Elektronik

So kommen wir zur Verbindung der Elektronik. Ja das Bild enhält nicht die Original Teile, diese habe ich in Fritzing nicht gefunden. Aber um mal ein Übersicht zu sehen, reicht das doch ;-)

Bauplan Elektrik Der BME280 muss mit dem D1 mini verbunden werden.
VIN > 3V3
GND > GND
SCL > D1
SDA > D2

Der D1 mini muss mit dem Solar Power Management Module verbunden werden.
3V3 > 3V3
GND > GND

Das Solar Panel und das Lithium Ionen Batterie Pack müssen mit dem Solar Power Management Module verbunden werden.
Stecker vom Solar Panel > SOLAR IN
Stecker vom Lithium Ionen Batterie Pack > Battery 3.7V

Und für den Deep Sleep müssen wir folgende Pins am D1 mini miteinander Verbinden.
RST > D0





Prototyping Shield mit StiftenPrototyping Shield RückseiteSo hier haben wir nun das Problem das gleich zwei 3V3 und GND am D1 mini benötigt werden. Da der aber nur je einen zur Verfügung hat, behelfen wir uns mit dem Prototyping Shield. Darauf habe ich 6 Stifte einer 2x 40-polig, RM 2,54, gewinkelt Stiftleiste gelötet. Die kann man leicht von den 40 Stück abtrennen. Dadurch habe ich dann drei 3V3 Pins und 3 GND Pins. Man muss aber die Pins auf der Rückseite mit einem Draht verbinden, da die Platine keine Verbindungen hat. Da reicht dann so ein Fest Kern Draht 0.13 mm² aus.









Kabel mit Dupont Stecker Das Kabel habe ich selbst angefertigt, mit Draht Fest Kern 0.13 mm² und Dupont Stecker. Damit kann man sich Kabel und Stecker so zusammen setzt, wie man es braucht. Ich empfehle hier eine Dupont Crimpzange zu nutzen, es geht zwar auch ohne und mit einer Feinzange, aber ich finde die Dupont Crimpzange liefert bessere Ergebnisse.





BME280 mit Dupont Stecker Beim BME280 habe ich einen 1×4 Stecker an die Steuerleitung gemacht, da die Pins ja schön nebeneinander liegen.












BME Anschlüsse in der Box Auf der Seite die in der Box ist, habe ich zwei 1×2 Stecker an die Steuerleitung angebracht. Hier habe ich 3V3 und GND zu einem Stecker sowie SCL und SDA zu einem Stecker zusammen geführt. 3V3 und GND liegen ja am Prototyping Shield direkt nebeneinander. SCL und SDA kommen am D1 mini ja auf D1 und D2, die auch direkt nebeneinander liegen.







Alles Komponenten zusammen gesteckt So sieht das ganze dann aus, wenn alles verbunden ist.















Wasserdichte Box mit der Elerktrik darin Und so sieht das in der Box aus.








Löten

Ich möchte mal hier über meine Erfahrung mit dem Löten berichten.
Die Lötstation habe ich mir gekauft, weil es mit dem günstigen Gerät nicht geklappt hatte. HÄtte ich mir Wahrscheinlich sparen können, aber bereut habe ich es trotzdem nicht. Das es mit der neuen Lötstation auch erst nicht funktionierte, habe ich mir auf einem Discord Server mal Hilfe geholt. Die meisten Artikel zum Thema „Tipps zum löten“ haben mir nicht wirklich geholfen. Die meist genannten Temperaturen haben bei mir das Lot nicht schmelzen lassen.
Durch nachfragen beim Discord Server habe ich erfahren das bei Lot ohne Blei 350°C genutzt werden und bei Lot mit Blei meistens mit 285 bis 300°C.
Als es auch damit nicht so recht klappen wollte, fragte ich weiter nach und erfuhr das der Durchmesser des Lötdraht nicht zum Durchmesser der Lötspitze passt. Lötspitze 0,4 mm, Lötdraht mit 1 mm funktioniert nicht, weil der zu dicke Lötdraht zu viel Wärme weg nimmt.
Also immer drauf achten das Durchmesser des Lötdrahtes zur Lötspitze passt.
Ich habe mir also einen Lötdraht mit 0,3 mm und Blei besorgt und konnte so mit einer Temperatur von 300°C arbeiten.


Hier mal das was ich im Discord als Info bekommen habe:
M: Moin,
Bin kein Experte im löten, daher kein richtige Ahnung davon.
Ich habe eine Lötstation von Weller.
Die Lötspitze ist 0,4 mm dick.
Der Lötdraht ist 1 mm dick und es steht 227°C drauf.
Aber das Lot schmilzt nicht bei 227°C.
Bei 300°C funktioniert es mal und mal nicht, scheinbar wird die Spitze nicht gleichmäßig heiß oder der Lötdraht ist zu dick für eine so dünne Spitze?
Auf wie viel Grad muss man den Lötkolben stellen?
S: Ich nehme meistens 350-380°C , manchmal auch mehr wenn die Leiterplatte eine gute Masseanbindung hat, denn dann ist auch die Wärmeableitung besser.
M: OK ich glaub das ist für den D1 mini und den BMP280 etwas zu viel 😅
Naja ich hab das bleihaltige Lot in 0,3 mm bestellt, denke damit dürfte ich besser zurecht kommen
S: 350° geht eigentlich immer für sowas, weniger nehme ich nie
M: Naja wenn das Lot aber früher schmilzt, wäre wärmer ja nicht so gut 😅
Ich teste es einfach an einem Probe Stück, dann werde ich ja sehen was funktioniert
S: bedenke, es muss nicht nur das Lot schmelzen sondern auch die Stelle erhitzt werden, die du löten willst. Da braucht du immer mehr Temperatur, als auf dem Zinn steht. Je nach Padgröße und Kupferanbindung kann das bei bleifreien Lot bis zu 420° sein. Ich würde behaupten beim D1 mini machste 350° bleifrei und 285-300° verbleit. Dem Bauteil ist das relativ egal. Das wird meist im Reflow Ofen mehr gestresst, da die Wärme viel länger appliziert wird.
M: Ok, danke für den Tipp, dann Versuche ich das so und lag mit 300 beim ersten Versuch gar nicht Mal so daneben.
S: ne für verbleit sind 300° sehr gut, für bleifrei etwas mehr. wenn du die Möglichkeit hast verbleites zu löten, dann nimm verbleites. Da werden die Lötstellen nicht so spröde.
M: Ja werde ich sobald es da ist und Notfalls bestelle ich die beiden Teile nochmal wenn die ersten nicht funktionieren. So teuer sind die ja nicht.
S: du wirst dir recht schwer tun, ein Bauteil durch Hitze sterben zu lassen. Vorher verdampft eher das Lötpad der Leiterplatte
M: Ok, gut zu wissen, hatte schon Angst das ich es kaputt mache 😅
S: also ich habs noch nicht geschafft ein Bauteil kaputt zu löten in fast 40 Jahren Elektronikbastelei


Programm

Damit der D1 Mini nun die Werte des BME280 abfragen und per MQTT an den Broker auf meinem Server schicken kann, brauchen wir ein kleines Programm.
Dieses habe ich über die Arduino IDE auf den D1 mini aufgespielt.
Wenn Ihr die Arduino IDE installiert habt, müsst hier noch folgendes machen, bevor Ihr das Programm auf den D1 mini hochladen könnt:

Unter
Datei > Voreinstellungen > Zusätzliche Boardverwalter-URLs:
diie folgenden URLs eintragen, nur 1 URL je Zeile!
https://dl.espressif.com/dl/package_esp32_index.json
http://arduino.esp8266.com/stable/package_esp8266com_index.json

Unter
Werkzeuge > Boardverwalter
folgendes eingeben: esp8266
und das Paket esp8266 by ESP8266 Community installieren

Unter
Werkzeuge > Bibliotheken verwalten
folgendes suchen und installieren:

  • BME280
    • BME280 by Tyler Glenn
  • PubSubClient
    • PubSubClient by Nick O'Leary
  • SimpleTimer
    • SimpleTimer by Alexander Kiryanenko



Werkzeuge > Board > ESP8266 Boards
Generic ESP8266 Modul (das ist D1 mini)
Generic ESP8285 Modul (das ist D1 mini lite)

Werkzeuge > Port
Da müsst Ihr selbst schauen, da ich das ganze unter Linux gemacht habe hatte ich hier: /dev/ttyS0
Bei Windows soll das COM sein.
Anleitung D1 mini in Arduino IDE einrichten.


Original Code

//v004 MQTT conservatory weather station
////Code originally based on https://www.home-assistant.io/blog/2015/10/11/measure-temperature-with-esp8266-and-report-to-mqtt/
//
//Hardware:
//Wemos D1 mini, BME280 sensor wired as I2C, Raspberry Pi 3 node red and moquitto MQTT server.
//
//Description:
//BME temp, humidity and pressure readings are published to the MQTT server (also printed to serial).
//Heartbeat RSSI value of device gets sent to MQTT broker, node red can light a Blynk LED/colour text (if online/offline)
//BME280 wiring - 3V to Vcc / Gnd to Gnd / D1 to SCL / D2 to SDA
//
//Changelog:
//v002 added deep sleep (first attempt)
//v003 added battery voltage monitoring
//v004 testing battery life improvements (removed serial prints)
//


#include <ESP8266WiFi.h>
#include <Wire.h>
#include <PubSubClient.h>
#include <BME280I2C.h>
#include <SimpleTimer.h>

#define wifi_ssid ""
#define wifi_password ""

#define mqtt_server ""
#define mqtt_user ""
#define mqtt_password ""

#define temperature_topic "house/consv/sensor/temperature"
#define humidity_topic "house/consv/sensor/humidity"
#define pressure_topic "house/consv/sensor/pressure"
#define heartbeat_topic "house/consv/sensor/heartbeat" //for heartbeat
#define freeram_topic "house/consv/sensor/freeram" // send device free ram
#define battery_topic "house/consv/sensor/battery" // send battery voltage

WiFiClient espClient;
PubSubClient client(espClient);

BME280I2C bme;    // Default : forced mode, standby time = 1000 ms
// Oversampling = pressure ×1, temperature ×1, humidity ×1, filter off,

long rssi; // setup variable for RSSI heartbeat value
char *client_id = "Wemos_no_1_MQTT";  //  MQTT Client ID


//Setup variables for later
float temp;
int hum;
int pres;


void setup() {
  
  // Connect D0 to RST to wake up
  pinMode(D0, WAKEUP_PULLUP);

  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);

  while (!Serial) {} // Wait

  Wire.begin();

  while (!bme.begin())
  {
    Serial.println("Could not find BME280 sensor!");
    delay(500);
  }

  // bme.chipID(); // Deprecated. See chipModel().
  switch (bme.chipModel())
  {
    case BME280::ChipModel_BME280:
      Serial.println("Found BME280 sensor! Success.");
      break;
    case BME280::ChipModel_BMP280:
      Serial.println("Found BMP280 sensor! No Humidity available.");
      break;
    default:
      Serial.println("Found UNKNOWN sensor! Error!");
  }
  
  reconnect();  //connect to MQTT server
  heartbeat(); // publish RSSI value as heartbeat
  sendSensor(); //publish sensor readings
  battery();  // read battery level

  delay(500); //delay to allow for MQTT messages to be published
  
  ESP.deepSleep(10 * 1000000);  // 10 seconds
  
}




void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(wifi_ssid);

  WiFi.begin(wifi_ssid, wifi_password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}


void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    // If you do not want to use a username and password, change next line to
    // if (client.connect("ESP8266Client")) {
    if (client.connect(client_id, mqtt_user, mqtt_password)) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 1 seconds");
      // Wait 1 seconds before retrying
      delay(1000);
    }
  }
}



void heartbeat()  // function for heartbeat check
{
  Serial.print("RSSI:");
  Serial.println(WiFi.RSSI());
  client.publish(heartbeat_topic, String(WiFi.RSSI()).c_str(), true);
  client.publish(freeram_topic, String(ESP.getFreeHeap()).c_str(), true);
}



void sendSensor() // function to send sensor readings to MQTT
{
  //read latest values
  temp = bme.temp();
  hum = bme.hum();
  pres = bme.pres();

  if (isnan(temp)) {
    Serial.println("Error reading temperature!");
  }
  else
  {
    Serial.print("Temperature: ");
    Serial.println(String(temp).c_str());
    client.publish(temperature_topic, String(temp , 1).c_str(), true);
  }

  if (isnan(temp)) {
    Serial.println("Error reading humidity!");
  }
  else
  {
    Serial.print("Humidity: ");
    Serial.println(String(hum).c_str());
    client.publish(humidity_topic, String(hum).c_str(), true);
  }

  if (isnan(pres)) {
    Serial.println("Error reading pressure!");
  }
  else
  {
    Serial.print("Pressure: ");
    Serial.println(String(pres / 100).c_str());
    client.publish(pressure_topic, String(pres / 100).c_str(), true);
  }
}



void battery()
{
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);   
   // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 4.5V):
  float voltage = sensorValue * (3.3 / 1024.0) * 3.0;
  // send out the value you read:
  Serial.print("Voltage: ");
  Serial.println(voltage);
  client.publish(battery_topic, String(voltage).c_str(), true);
}

void loop(){}



So sieht mein Code aus.

Ich habe für mich die SSID des WLAN + Passwort gesetzt. Die IP des MQTT Servers eingetragen. heartbeat_topic, freeram_topic, battery_topic entfernt. Und die ESP.deepSleep auf 900 gesetzt, da nur alle 15 Minuten ausgelesen und gesendet werden soll.

//v004 MQTT conservatory weather station
////Code originally based on https://www.home-assistant.io/blog/2015/10/11/measure-temperature-with-esp8266-and-report-to-mqtt/
//
//Hardware:
//Wemos D1 mini, BME280 sensor wired as I2C, Raspberry Pi 3 node red and moquitto MQTT server.
//
//Description:
//BME temp, humidity and pressure readings are published to the MQTT server (also printed to serial).
//Heartbeat RSSI value of device gets sent to MQTT broker, node red can light a Blynk LED/colour text (if online/offline)
//BME280 wiring - 3V to Vcc / Gnd to Gnd / D1 to SCL / D2 to SDA
//
//Changelog:
//v002 added deep sleep (first attempt)
//v003 added battery voltage monitoring
//v004 testing battery life improvements (removed serial prints)
//


#include <ESP8266WiFi.h>
#include <Wire.h>
#include <PubSubClient.h>
#include <BME280I2C.h>
#include <SimpleTimer.h>

#define wifi_ssid "SSID"
#define wifi_password "PASSWORD"

#define mqtt_server "SERVER"
#define mqtt_user ""
#define mqtt_password ""

#define temperature_topic "temperatureNO"
#define humidity_topic "humidityNO"
#define pressure_topic "pressureNO"
#define battery_topic "batteryNO"

WiFiClient espClient;
PubSubClient client(espClient);

BME280I2C bme;    // Default : forced mode, standby time = 1000 ms
// Oversampling = pressure ×1, temperature ×1, humidity ×1, filter off,


//Setup variables for later
float temp;
float hum;
float pres;


void setup() {

  // Connect D0 to RST to wake up
  pinMode(16, WAKEUP_PULLUP);

  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);

  while (!Serial) {} // Wait

  Wire.begin();

  while (!bme.begin())
  {
    Serial.println("Could not find BME280 sensor!");
    delay(500);
  }

  // bme.chipID(); // Deprecated. See chipModel().
  switch (bme.chipModel())
  {
    case BME280::ChipModel_BME280:
      Serial.println("Found BME280 sensor! Success.");
      break;
    case BME280::ChipModel_BMP280:
      Serial.println("Found BMP280 sensor! No Humidity available.");
      break;
    default:
      Serial.println("Found UNKNOWN sensor! Error!");
  }

  reconnect();  //connect to MQTT server
  sendSensor(); //publish sensor readings

  delay(500); //delay to allow for MQTT messages to be published

  ESP.deepSleep(900 * 1000000); //900 Sekunden = 15 Minuten

}


void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(wifi_ssid);

  WiFi.begin(wifi_ssid, wifi_password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}


void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    // If you do not want to use a username and password, change next line to
    // if (client.connect("ESP8266Client")) {
    if (client.connect("ESP8266Client")) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 1 seconds");
      // Wait 1 seconds before retrying
      delay(1000);
    }
  }
}


void sendSensor() // function to send sensor readings to MQTT
{
  //read latest values
  temp = bme.temp();
  hum = bme.hum();
  pres = bme.pres();

  if (isnan(temp)) {
    Serial.println("Error reading temperature!");
  }
  else
  {
    Serial.print("Temperature: ");
    Serial.println(String(temp).c_str());
    client.publish(temperature_topic, String(temp , 1).c_str(), true);
  }

  if (isnan(temp)) {
    Serial.println("Error reading humidity!");
  }
  else
  {
    Serial.print("Humidity: ");
    Serial.println(String(hum).c_str());
    client.publish(humidity_topic, String(hum).c_str(), true);
  }

  if (isnan(pres)) {
    Serial.println("Error reading pressure!");
  }
  else
  {
    Serial.print("Pressure: ");
    Serial.println(String(pres).c_str());
    client.publish(pressure_topic, String(pres).c_str(), true);
  }
}

void battery()
{
  // read the input on analog pin A0:
  int sensorValue = analogRead(17);   
   // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 4.5V):
  float voltage = 4.16 * (sensorValue/1023.0);
  // send out the value you read:
  Serial.print("Voltage: ");
  Serial.println(voltage);
  client.publish(battery_topic, String(voltage).c_str(), true);
}

void loop() {}

Node Red Display

Und so lasse ich die Daten mit Node Red auf einem Display anzeigen. Aktuell sind für SW nur Temperatur verfügbar, da dort noch der Pi Pico mit dem DS18B20 läuft, bis eben die Renovierung fertig ist. Dann wird unter NO das gleiche angezeigt nur mit SW und eben den Werten des Sensors auf der Süd/West Seite.
Ansicht auf dem Display

Relais zum trennen des Solar Panel bei Temperaturen unter 5°C

Da man den Akku unter 0°C nicht aufladen soll, hab ich mir überlegt das Solar Panel mittels eines Relais zu trennen, wenn die Temperatur unter 5°C fällt.

Dazu hab ich gesucht und folgendes Relais gefunden: Signal-Relais, 3 V DC, 3 A, 2 CO, AZ832P2-2C-3DE. Gefunden habe ich es durch dieses Video bistabiles Relais am ESP - schalten ohne standby.

Hier der Schaltplan wie ich es angeschlossen habe.

Schaltplan für die Wettertstatiion mit Relais

Das ganze habe ich auf eine kleine Fertige Platine gesetzt.

Zuerst setze ich den Status für Pin 12 = true und 13 = false, denn die Grundstellung des Relais ist RESET. Also so als wenn man auf Pin 12 Strom gegeben hätte.

#include <EEPROM.h>

const int relaisPin13 = 13;
const int relaisPin12 = 12;

// EEPROM Speicheradressen für den Status der Relais
int status13Addr = 0;
int status12Addr = 1;

void setup() {
  Serial.begin(115200);

  // Relais-Pins als Ausgang definieren
  pinMode(relaisPin13, OUTPUT);
  pinMode(relaisPin12, OUTPUT);

  // Relais-Pins auf LOW setzen, um sicherzustellen, dass sie zu Beginn in OFF sind
  digitalWrite(relaisPin13, LOW);  
  digitalWrite(relaisPin12, LOW); 

  // EEPROM initialisieren
  EEPROM.begin(512);

  // Setze den Status für Relais 13 und Relais 12 im EEPROM
  writeEEPROMBoolean(status13Addr, false); // Relais 13 Status auf "false" (OFF)
  writeEEPROMBoolean(status12Addr, true);  // Relais 12 Status auf "true" (ON)
  
  // Stromstoß für Relais 13 (OFF)
  digitalWrite(relaisPin13, HIGH);  // Relais 13 einschalten (kurzer Impuls)
  delay(1000);                      // 1 Sekunde Stromstoß
  digitalWrite(relaisPin13, LOW);   // Relais 13 wieder ausschalten

  // Stromstoß für Relais 12 (ON)
  digitalWrite(relaisPin12, HIGH);  // Relais 12 einschalten (kurzer Impuls)
  delay(1000);                      // 1 Sekunde Stromstoß
  digitalWrite(relaisPin12, LOW);   // Relais 12 wieder ausschalten

  delay(60000); // 1 Minute warten, damit du die Ausgabe sehen kannst
}

void loop() {
  // Hauptloop bleibt leer
}

// Funktion zum Schreiben eines booleschen Wertes ins EEPROM
void writeEEPROMBoolean(int address, bool value) {
  EEPROM.write(address, value ? 1 : 0); // true wird als 1 und false als 0 gespeichert
  EEPROM.commit();
}

Und so sieht nun mein Code für die Wetterstation aus.

#include <ESP8266WiFi.h>
#include <Wire.h>
#include <PubSubClient.h>
#include <BME280I2C.h>
#include <EEPROM.h>

// Konstanten und Variablen
const char* ssid = "SSID";           // WiFi SSID
const char* password = "PASSWORD";   // WiFi Passwort
const char* mqttServer = "SERVER_IP";  // MQTT Server IP

// Pin-Definitionen
const int batteryPin = 17;           // Pin für die Batteriespannung
const int wakeUpPin = 16;            // Wakeup-Pin D0 (GPIO16)
const int relaisPin13 = 13;          // Relais für Pin 13
const int relaisPin12 = 12;          // Relais für Pin 12

// EEPROM Speicherpositionen für die Relaisstatus
int status13Addr = 0;  // Speicheradresse für Relais 13 Status
int status12Addr = 1;   // Speicheradresse für Relais 12 Status

// MQTT und Sensor-Objekte
WiFiClient espClient;
PubSubClient client(espClient);
BME280I2C bme;  // BME280 Sensor-Objekt

void setup() {
  Serial.begin(115200);
  pinMode(wakeUpPin, WAKEUP_PULLUP);
  Wire.begin();

  // Relais-Pins als Ausgang definieren
  pinMode(relaisPin13, OUTPUT);
  pinMode(relaisPin12, OUTPUT);
  
  // Relais Pins auf LOW setzen, damit sie beim Start ausgeschaltet sind
  digitalWrite(relaisPin13, LOW);
  digitalWrite(relaisPin12, LOW);
  Serial.println("Relais initialisiert auf LOW");

  // EEPROM initialisieren
  EEPROM.begin(512);  // 512 ist die maximale Größe des EEPROM auf ESP8266
  Serial.println("EEPROM initialisiert");

  setup_wifi();            // WiFi-Verbindung einrichten
  setup_mqtt();            // MQTT-Server einrichten
  setup_bme280();          // BME280-Sensor einrichten
  send_data();             // Daten sammeln und senden
  steuereRelais();         // Relaissteuerung auf Basis der Temperatur

  ESP.deepSleep(15 * 60 * 1000000); // Geht in den Deep Sleep-Modus
  Serial.println("Deep Sleep aktiviert");
}

void setup_wifi() {
  Serial.print("Verbindung zum WiFi...");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500); // Warte, bis die Verbindung hergestellt wird
  }
  Serial.println("WiFi connected");
}

void setup_mqtt() {
  client.setServer(mqttServer, 1883); // MQTT-Server einstellen
  Serial.println("MQTT Server eingestellt");
  reconnect();  // Sicherstellen, dass der Client verbunden ist
}

void reconnect() {
  Serial.println("Verbindung zum MQTT Broker wird hergestellt...");
  while (!client.connected()) {
    if (client.connect("SuedWest")) {
      Serial.println("Connected to MQTT Broker");
    } else {
      delay(1000); // Versucht alle 1 Sekunde, sich zu verbinden
      Serial.print(".");
    }
  }
}

void setup_bme280() {
  Serial.println("BME280 Sensor wird initialisiert...");
  while (!bme.begin()) {
    delay(500); // Verzögerung, wenn der Sensor nicht gefunden wird
  }
  switch (bme.chipModel()) {
    case BME280::ChipModel_BME280:
      Serial.println("BME280 sensor detected");
      break;
    case BME280::ChipModel_BMP280:
      Serial.println("BMP280 sensor detected (no humidity)");
      break;
    default:
      Serial.println("Unknown sensor detected!");
  }
}

void send_data() {
  // Sensorwerte ablesen
  float temperature = bme.temp();
  float humidity = round(bme.hum() * 100.0) / 100.0; // Runden auf 2 Dezimalstellen
  float pressure = round(bme.pres() * 100.0) / 100.0; // Runden auf 2 Dezimalstellen

  Serial.print("Temperatur: ");
  Serial.println(temperature);  // Ausgabe der Temperatur

  Serial.print("Luftfeuchtigkeit: ");
  Serial.println(humidity);  // Ausgabe der Luftfeuchtigkeit

  Serial.print("Luftdruck: ");
  Serial.println(pressure);  // Ausgabe des Luftdrucks

  // Batteriespannung ablesen
  pinMode(batteryPin, INPUT);
  uint16_t sensorValue = analogRead(batteryPin);
  float voltage = sensorValue / 1023.0;
  float battery = round((voltage / 100 * (470 + 320)) * 100.0) / 100.0; // Batterie runden auf 2 Dezimalstellen

  Serial.print("Batteriespannung: ");
  Serial.println(battery);  // Ausgabe der Batteriespannung

  // Relais-Status aus EEPROM lesen
  bool status13 = readEEPROMBoolean(status13Addr);  // Relais 13 Status aus EEPROM lesen
  bool status12 = readEEPROMBoolean(status12Addr);  // Relais 12 Status aus EEPROM lesen

  // JSON-Daten erstellen
  String json = "{\"SuedWest\":{\"temperature\":" + String(temperature) +
                ",\"humidity\":" + String(humidity) + 
                ",\"pressure\":" + String(pressure) +
                ",\"battery\":" + String(battery) + 
                ",\"RelaisStatus\":{\"Relais13\":" + String(status13 ? "true" : "false") + 
                ",\"Relais12\":" + String(status12 ? "true" : "false") + "}}}";

  // MQTT-Nachricht senden
  client.publish("Weather", json.c_str(), true);
  Serial.println("Data sent to MQTT Broker");
}

void writeEEPROMBoolean(int address, bool value) {
  EEPROM.write(address, value ? 1 : 0); // true wird als 1 und false als 0 gespeichert
  EEPROM.commit();
}

bool readEEPROMBoolean(int address) {
  return EEPROM.read(address) == 1;  // true, wenn 1, sonst false
}

void steuereRelais() {
  // Temperatur direkt abrufen, um sicherzustellen, dass der aktuelle Wert verwendet wird
  float currentTemperature = bme.temp();
  Serial.print("Aktuelle Temperatur: ");
  Serial.println(currentTemperature);  // Ausgabe der aktuellen Temperatur

  // Relais 13 steuern, wenn die Temperatur < 5.00 ist und der Status 13 = false
  if (currentTemperature < 5.00) {
    bool status13 = readEEPROMBoolean(status13Addr);
    Serial.print("Relais 13 Status: ");
    Serial.println(status13 ? "true" : "false");  // Ausgabe des aktuellen Status von Relais 13

    if (!status13) {
      Serial.println("Relais 13 wird eingeschaltet...");  // Debug-Ausgabe vor dem Schalten
      digitalWrite(relaisPin13, HIGH);  // Relais 13 schalten
      writeEEPROMBoolean(status13Addr, true);    // Status 13 auf true setzen
      writeEEPROMBoolean(status12Addr, false);   // Status 12 auf false setzen
      delay(1000);  // Relais für kurze Zeit eingeschaltet lassen (Stromstoß)
      digitalWrite(relaisPin13, LOW);   // Relais 13 ausschalten
      Serial.println("Relais 13 wurde ausgeschaltet.");  // Debug-Ausgabe nach dem Ausschalten
    } else {
      Serial.println("Relais 13 ist bereits eingeschaltet.");  // Wenn der Status bereits auf true ist
    }
  } 
  
  // Relais 12 steuern, wenn die Temperatur > 5.01 ist und der Status 12 = false
  else if (currentTemperature > 5.01) {
    bool status12 = readEEPROMBoolean(status12Addr);
    Serial.print("Relais 12 Status: ");
    Serial.println(status12 ? "true" : "false");  // Ausgabe des aktuellen Status von Relais 12

    if (!status12) {
      Serial.println("Relais 12 wird eingeschaltet...");  // Debug-Ausgabe vor dem Schalten
      digitalWrite(relaisPin12, HIGH);  // Relais 12 schalten
      writeEEPROMBoolean(status12Addr, true);    // Status 12 auf true setzen
      writeEEPROMBoolean(status13Addr, false);   // Status 13 auf false setzen
      delay(1000);  // Relais für kurze Zeit eingeschaltet lassen (Stromstoß)
      digitalWrite(relaisPin12, LOW);   // Relais 12 ausschalten
      Serial.println("Relais 12 wurde ausgeschaltet.");  // Debug-Ausgabe nach dem Ausschalten
    } else {
      Serial.println("Relais 12 ist bereits eingeschaltet.");  // Wenn der Status bereits auf true ist
    }
  } else {
    Serial.println("Keine Temperaturbedingung erfüllt. Keine Relaissteuerung.");
  }
}

void loop() {
  // Der Hauptloop bleibt leer, da der ESP8266 im Deep Sleep-Modus ist
}
autarke_wetterstation.txt · Zuletzt geändert: 2025/01/19 13:55 von Mel

Seiten-Werkzeuge