Mein Server
- Hardware
- Autarkic weather station
- Display
My server
- Hardware
Mein Server
My server
Why self-sufficient, not because of the electricity prices, the Raspberry Pi Pico didn't eat that much. No, the ants are to blame. I had a DS18B20 on the Pi Pico. So long cable, out of the window. Attached to a planting pole, because it would have given false results on the house wall. The ants found it interesting and followed the path into the apartment. So the idea for a self-sufficient weather station came up and because temperature alone is a bit boring
So I researched what I needed for it. Of course there was no complete solution, I had to put together my own from several projects. At the beginning, the power consumption was too high due to the components and because 5 V was regulated down to 3.3 V using a voltage regulator.
After further research and consideration, I have now come up with the current variant. This is not a manual that prescribes how to do it, there is certainly potential for improvement, but I want to show how I have now solved this for myself.
I'm linking the part, but you should compare the prices beforehand
#include <ESP8266WiFi.h> #include <Wire.h> #include <PubSubClient.h> #include <BME280I2C.h> #include <EEPROM.h> // Constants and variables const char* ssid = "SSID"; // WiFi SSID const char* password = "PASSWORD"; // WiFi Passwort const char* mqttServer = "SERVER_IP"; // MQTT Server IP // Pin definitions const int batteryPin = 17; // Pin for the battery voltage (A0) const int wakeUpPin = 16; // Wakeup-Pin D0 (GPIO16) const int relayPin13 = 13; // relay for Pin 13 const int relayPin12 = 12; // relay for Pin 12 // EEPROM memory positions for the relay status int status13Addr = 0; // Memory address for relay 13 Status int status12Addr = 1; // Memory address for relay 12 Status // MQTT and sensor objects WiFiClient espClient; PubSubClient client(espClient); BME280I2C bme; // BME280 Sensor object void setup() { Serial.begin(115200); pinMode(wakeUpPin, WAKEUP_PULLUP); Wire.begin(); // Define relay pins as output pinMode(relayPin13, OUTPUT); pinMode(relayPin12, OUTPUT); // Set relay pins to LOW so that they are switched off at startup digitalWrite(relayPin13, LOW); digitalWrite(relayPin12, LOW); Serial.println("relay initialisiert auf LOW"); // Initialize EEPROM EEPROM.begin(512); // 512 is the maximum size of the EEPROM on ESP8266 Serial.println("EEPROM initialized"); setup_wifi(); // Set up WiFi connection setup_mqtt(); // Set up the MQTT server setup_bme280(); // Setting up the BME280 sensor send_data(); // Collect and send data relay_control(); // Relay control based on temperature ESP.deepSleep(15 * 60 * 1000000); // Goes into deep sleep mode } void setup_wifi() { Serial.print("Connection to WiFi..."); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); // Wait until the connection is established } Serial.println("WiFi connected"); } void setup_mqtt() { client.setServer(mqttServer, 1883); // Setting the MQTT server Serial.println("MQTT server discontinued"); reconnect(); // Ensure that the client is connected } void reconnect() { Serial.println("Connection to the MQTT broker is established..."); while (!client.connected()) { if (client.connect("SouthWest")) { Serial.println("Connected to MQTT Broker"); } else { delay(1000); // Attempts to connect every 1 second Serial.print("."); } } } void setup_bme280() { Serial.println("BME280 sensor is initialized..."); while (!bme.begin()) { delay(500); // Delay if the sensor is not found } 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() { // Read sensor values float temperature = bme.temp(); float humidity = round(bme.hum() * 100.0) / 100.0; // Round to 2 decimal places float pressure = round(bme.pres() * 100.0) / 100.0; // Round to 2 decimal places Serial.print("Temperature: "); Serial.println(temperature); // Temperature output Serial.print("Humidity: "); Serial.println(humidity); // Humidity output Serial.print("Air Pressure: "); Serial.println(pressure); // Output of the air pressure // Reading the battery voltage pinMode(batteryPin, INPUT); uint16_t sensorValue = analogRead(batteryPin); float voltage = sensorValue / 1023.0; float battery = round((voltage / 100 * (470 + 320)) * 100.0) / 100.0; // Round battery to 2 decimal places Serial.print("Battery voltage: "); Serial.println(battery); // Output of the battery voltage // Read relay status from EEPROM bool status13 = readEEPROMBoolean(status13Addr); // Relay 13 Read status from EEPROM bool status12 = readEEPROMBoolean(status12Addr); // Relay 12 Read status from EEPROM // Create JSON data String json = "{\"SouthWest\":{\"temperature\":" + String(temperature) + ",\"humidity\":" + String(humidity) + ",\"pressure\":" + String(pressure) + ",\"battery\":" + String(battery) + ",\"relayStatus\":{\"relay13\":" + String(status13 ? "true" : "false") + ",\"relay12\":" + String(status12 ? "true" : "false") + "}}}"; // Send MQTT message 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 is saved as 1 and false as 0 EEPROM.commit(); } bool readEEPROMBoolean(int address) { return EEPROM.read(address) == 1; // true if 1, otherwise false } void relay_control() { // Retrieve temperature directly to ensure that the current value is used float currentTemperature = bme.temp(); Serial.print("Current temperature: "); Serial.println(currentTemperature); // Output of the current temperature // Control relay 13 if the temperature is < 5.00 and the status 13 = false if (currentTemperature < 5.00) { bool status13 = readEEPROMBoolean(status13Addr); Serial.print("relay 13 Status: "); Serial.println(status13 ? "true" : "false"); // Output of the current status of relay 13 if (!status13) { Serial.println("Relay 13 is switched on..."); // Debug output before switching digitalWrite(relayPin13, HIGH); // Switch relay 13 writeEEPROMBoolean(status13Addr, true); // Set status 13 to true writeEEPROMBoolean(status12Addr, false); // Set status 12 to false delay(1000); // Leave relay switched on for 1 second (current surge) digitalWrite(relayPin13, LOW); // Switch off relay 13 Serial.println("Relay 13 was switched off."); // Debug output after switching off } else { Serial.println("Relay 13 is already switched on."); // If the status is already set to true } } // Control relay 12 if the temperature is > 5.01 and the status 12 = false else if (currentTemperature > 5.01) { bool status12 = readEEPROMBoolean(status12Addr); Serial.print("relay 12 Status: "); Serial.println(status12 ? "true" : "false"); // Output of the current status of relay 12 if (!status12) { Serial.println("Relay 12 is switched on..."); // Debug output before switching digitalWrite(relayPin12, HIGH); // Switch relay 12 writeEEPROMBoolean(status12Addr, true); // Set status 12 to true writeEEPROMBoolean(status13Addr, false); // Set status 13 to false delay(1000); // Leave relay switched on for 1 second (current surge) digitalWrite(relayPin12, LOW); // Switch off relay 12 Serial.println("Relay 12 was switched off."); // Debug output after switching off } else { Serial.println("Relay 12 is already switched on."); // If the status is already set to true } } else { Serial.println("No temperature condition fulfilled. No relay control."); } } void loop() { // The main loop remains empty because the ESP8266 is in deep sleep mode }