Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

Meine Projekte

Mein Server

  • Hardware

My projects

  • Autarkic weather station
  • Display

My server

  • Hardware
autarkic_weather_station

Autarkic weather station

North/East weather station

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
}
autarkic_weather_station.txt · Zuletzt geändert: 2025/01/21 14:02 von Mel

Seiten-Werkzeuge