My first weather station

Your project looks awesome, but I don’t have hardware to build it.
So I just like to contribute somehow, hopefully I’ll build it later, by modifying your code, posted by @magnum1795, as follows.

It’s compiled OK. Hopefully it’ll run OK as well.

Note
It’s currently written for ESP32, to use Blynk_WM library, SSL as well as local Blynk Server.
Please change the following #define’s (to true or false) to suit your application

#define USE_BLYNK_WM          true
#define USE_SSL               false
#define USE_LOCAL_SERVER      true

The code

#ifndef ESP32
#error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
#endif

#define BLYNK_PRINT Serial

#define USE_BLYNK_WM          true
#define USE_SSL               false
#define USE_LOCAL_SERVER      true

#if USE_SSL
  #include <WiFiClientSecure.h>
#else
  #include <WiFiClient.h>
#endif
  
#if USE_BLYNK_WM

  // Not use #define USE_SPIFFS  => using EEPROM for configuration data in WiFiManager
  // #define USE_SPIFFS    false => using EEPROM for configuration data in WiFiManager
  // #define USE_SPIFFS    true  => using SPIFFS for configuration data in WiFiManager
  // Be sure to define USE_SPIFFS before #include <BlynkSimpleEsp8266_WM.h>
  
  //#define USE_SPIFFS                  true
  #define USE_SPIFFS                  false
  
  #if (!USE_SPIFFS)
    // EEPROM_SIZE must be <= 4096 and >= CONFIG_DATA_SIZE (currently 172 bytes)
    #define EEPROM_SIZE    (4 * 1024)
    // EEPROM_START + CONFIG_DATA_SIZE must be <= EEPROM_SIZE
    #define EEPROM_START   2048
  #endif
  
  // Force some params in Blynk, only valid for library version 1.0.1 and later
  #define TIMEOUT_RECONNECT_WIFI                    10000L
  #define RESET_IF_CONFIG_TIMEOUT                   true
  #define CONFIG_TIMEOUT_RETRYTIMES_BEFORE_RESET    5
  // Those above #define's must be placed before #include <BlynkSimpleEsp8266_WM.h>
   
  #if USE_SSL
    #include <BlynkSimpleEsp32_SSL_WM.h>          // https://github.com/khoih-prog/Blynk_WM
  #else
    #include <BlynkSimpleEsp32_WM.h>              // https://github.com/khoih-prog/Blynk_WM
  #endif
  
#else
  #if USE_SSL
    #include <BlynkSimpleEsp32_SSL.h>
    #define BLYNK_SERVER_HARDWARE_PORT    9443    // blynk server SSL port
  #else
    #include <BlynkSimpleEsp32.h>
    #define BLYNK_SERVER_HARDWARE_PORT    8080    // blynk server port
  #endif

  char ssid[]   = ""; // wifi SSID
  char pass[]   = ""; // wifi password

  #if USE_LOCAL_SERVER
    char auth[]   = "";                     // Local Blynk server token
    char server[] = "accout.duckdns.org";   // blynk server
  #else
    char auth[]   = "";                     //Cloud Blynk server token
    char server[] = "blynk-cloud.com";      // Cloud Blynk server
  #endif

#endif
#include <WidgetRTC.h>

#include <WiFi.h>
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <BME280I2C.h>                //https://github.com/finitespace/BME280/tree/master/src
#include <Wire.h>

BME280I2C bme;

#define uS_TO_S_FACTOR      1000000
#define TIME_TO_SLEEP       600                       //set deep sleep time (in seconds)

#define COUNT_PERIOD        5000                      // measure interval (ms)
#define RAIN_COUNT_PERIOD   ( 24L * 3600L * 1000L )   // One day

// 50ms debouncing time
#define DEBOUNCE_TIME       50

#define RADIUS            (90.0f)         // in mm
#define PIxRADIUS         (PI * 90.0)
#define RAIN_AMOUNT       (0.3f)          // Precipitation

#define VOLT_DETECTION_PIN    34  // voltage detection pin number
#define RAIN_GAUGE_PIN        14  // Rain pin number
#define WIND_SPEED_PIN        35  // wind speed pin number
#define UV_INDEX_PIN          36  // UV Index detection pin number
#define WIND_DIRECTION_PIN    39  // Wind direction pin number

#define BLYNK_VPIN_WIND_DIRECTION       V1
#define BLYNK_VPIN_TEMP                 V2
#define BLYNK_VPIN_WIND_SPEED           V3
#define BLYNK_VPIN_HUMID                V4
#define BLYNK_VPIN_RAIN_AMOUNT          V5
#define BLYNK_VPIN_PRESSURE             V6
#define BLYNK_VPIN_HALL_SENSOR          V7
#define BLYNK_VPIN_WIND_DIRECTION_BIN   V8
#define BLYNK_VPIN_CPU_TEMP1            V9
#define BLYNK_VPIN_CPU_TEMP2            V10
#define BLYNK_VPIN_BATT_VOLT            V11
#define BLYNK_VPIN_UV_INDEX             V12
#define BLYNK_VPIN_DEW_POINT1           V13
#define BLYNK_VPIN_DEW_POINT2           V14
#define BLYNK_VPIN_RSSI1                V15
#define BLYNK_VPIN_RSSI2                V16

//int delaytime         = 2000;     // Time between samples (miliseconds)

int Wdir              = 0;
int measurement       = 0;
int pinValue          = 1;

unsigned int Sample   = 0; // Sample number
unsigned int RPM      = 0; // Revolutions per minute

float windSpeedMetrePerSec    = 0; // Wind speed (m/s)
float windSpeedKmPerHr        = 0; // Wind speed (km/h)


float voltage                 = (((float)analogRead(VOLT_DETECTION_PIN) * (3.3 / 4095)) * 2) + 0.24; // battery voltage
float UVIndex                 = ((float)analogRead(UV_INDEX_PIN) * (3.3 / 4095)) * 10; // UV Index GUVA-S12SD
float windDirection           = ((float)analogRead(WIND_DIRECTION_PIN)); // Wind direction

volatile unsigned int counter  = 0; // magnet counter for sensor
volatile unsigned int currentCount;
volatile float totalAmount     = 0;
volatile float currRainAmount;
volatile long startTime;
volatile bool windDataReady = false;
volatile bool rainDataReady = false;

#ifdef __cplusplus
extern "C" {
#endif
uint8_t temprature_sens_read();
#ifdef __cplusplus
}
#endif

uint8_t temprature_sens_read();
BlynkTimer timer;
WidgetRTC  rtc;

BLYNK_CONNECTED()
{
  rtc.begin();
  Blynk.syncAll();
}

void IRAM_ATTR RainSensor();
void IRAM_ATTR WindSpeedSensor();

void setup()
{
  // Debug console
  pinMode(RAIN_GAUGE_PIN, INPUT);
  pinMode(WIND_SPEED_PIN, INPUT);
  pinMode(WIND_DIRECTION_PIN, INPUT);
  pinMode(UV_INDEX_PIN, INPUT);
  pinMode(VOLT_DETECTION_PIN, INPUT);

  float windDirection = ((float)analogRead(WIND_DIRECTION_PIN));

  Serial.begin(115200);
  
  #if USE_BLYNK_WM
    Blynk.begin("ESP32-Weather-Station");
  #else
    WiFi.mode(WIFI_STA);
    Blynk.connectWiFi(ssid, pass);
    Blynk.config(auth, server, BLYNK_SERVER_HARDWARE_PORT);
    Blynk.connect();
  #endif

  ArduinoOTA.setHostname("Weather-Station");
  ArduinoOTA.begin();

  Blynk.setProperty(BLYNK_VPIN_WIND_DIRECTION, "rotation", Wdir);

  Wire.begin();
  while (!bme.begin()) //start BME 280
  {
    Serial.println("Could not find BMP280 sensor!");
    delay(1000);
  }

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

  timer.setInterval(300000L, sendSensor);
  Sample++;

  timer.setInterval(500L, measureAll);

  attachInterrupt(digitalPinToInterrupt(WIND_SPEED_PIN), WindSpeedSensor, RISING);
  attachInterrupt(digitalPinToInterrupt(RAIN_GAUGE_PIN), RainSensor,  RISING);
  // start timing
  startTime = millis();
}

void loop()
{
  Blynk.run(); //start the Blynk sketch
  timer.run(); //start the timer
  ArduinoOTA.handle();
}

void measureAll()
{
  WindDir();
  RainCalc();
  WindVelocity();
}

void sendSensor()
{
  static float temp(NAN), hum(NAN), pres(NAN);
  static float voltage; // battery voltage
  static float UVIndex; // UV Index
  static float windDirection; // Szélirány
  static double gamma; // calculate dewpoint
  static double dp; // calculate dewpoint
  static long rssi; // read signal strength

  measurement = hallRead();
  
  BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);  // read BME 280
  BME280::PresUnit presUnit(BME280::PresUnit_hPa);      // read BME 280
  bme.read(pres, temp, hum, tempUnit, presUnit);        // read BME 280

  voltage       = (((float)analogRead(VOLT_DETECTION_PIN) * (3.3 / 4095)) * 2) + 0.24; // battery voltage
  UVIndex       = ((float)analogRead(UV_INDEX_PIN) * (3.3 / 4095)) * 10; // UV Index
  windDirection = ((float)analogRead(WIND_DIRECTION_PIN)); // Szélirány

  gamma         = log(hum / 100) + ((17.62 * temp) / (243.5 + temp));   // calculate dewpoint
  dp            = 243 * gamma / (17.62 - gamma);                        // calculate dewpoint

  rssi          = WiFi.RSSI();                                    

  Blynk.setProperty(BLYNK_VPIN_WIND_DIRECTION, "rotation", Wdir);                             // image rotating to wind direction
  Blynk.virtualWrite(BLYNK_VPIN_WIND_DIRECTION, 1);
  Blynk.virtualWrite(BLYNK_VPIN_TEMP,               temp);                                    //temperature
  Blynk.virtualWrite(BLYNK_VPIN_WIND_SPEED,         windSpeedKmPerHr);                        //Wind speed
  Blynk.virtualWrite(BLYNK_VPIN_HUMID,              hum);                                     //humidity
  Blynk.virtualWrite(BLYNK_VPIN_RAIN_AMOUNT,        totalAmount);                             //Rain amount
  Blynk.virtualWrite(BLYNK_VPIN_PRESSURE,           pres);                                    //pressure
  Blynk.virtualWrite(BLYNK_VPIN_HALL_SENSOR,        measurement);                             //hallsensor
  Blynk.virtualWrite(BLYNK_VPIN_WIND_DIRECTION_BIN, windDirection);                           //Wind direction binary (test function)
  Blynk.virtualWrite(BLYNK_VPIN_CPU_TEMP1,          (temprature_sens_read() - 32) / 1.8);     //CPU Temp
  Blynk.virtualWrite(BLYNK_VPIN_CPU_TEMP2,          (temprature_sens_read() - 32) / 1.8);     //CPU Temp
  Blynk.virtualWrite(BLYNK_VPIN_BATT_VOLT,          voltage);                                 //Battery Voltage
  Blynk.virtualWrite(BLYNK_VPIN_UV_INDEX,           UVIndex);                                 //UV index
  Blynk.virtualWrite(BLYNK_VPIN_DEW_POINT1,         dp);                                      //Dew point
  Blynk.virtualWrite(BLYNK_VPIN_DEW_POINT2,         dp);                                      //Dew point
  Blynk.virtualWrite(BLYNK_VPIN_RSSI1,              rssi);                                    //rssi
  Blynk.virtualWrite(BLYNK_VPIN_RSSI2,              rssi);                                    //rssi

  // Serial.println("Sleeping now !);
  // delay(500);
  // esp_sleep_enable_timer_wakeup((uint64_t)TIME_TO_SLEEP * uS_TO_S_FACTOR); //set deepsleep time
  // esp_deep_sleep_start(); //deepsleep start
  // delay(100);
}

void WindDir()
{
  float windDirection = ((float)analogRead(WIND_DIRECTION_PIN));
  
  if (windDirection < 190)
    Wdir = 270;       // W
  else if (windDirection < 420)
    Wdir = 315;       // NW
  else if (windDirection < 700)
    Wdir = 292.5;     // W-NW
  else if (windDirection < 900)
    Wdir = 0;         // N
  else if (windDirection < 1300)
    Wdir = 337.5;     // N-NW
  else if (windDirection < 1500)
    Wdir = 225;       // SW
  else if (windDirection < 1600)
    Wdir = 247.5;     // W-SW
  else if (windDirection < 2250)
    Wdir = 45;        // NE
  else if (windDirection < 2400)
    Wdir = 22.5;      // N-NE
  else if (windDirection < 2900)
    Wdir = 180;       // S
  else if (windDirection < 3100)
    Wdir = 202.5;     // S-SW
  else if (windDirection < 3400)
    Wdir = 135;       // SE
  else if (windDirection < 3600)
    Wdir = 157.5;     // S-SE
  else if (windDirection < 3840)
    Wdir = 90;        // E
  else if (windDirection < 3950)
    Wdir = 67, 5;     // E-NE
  else if (windDirection < 4095)
    Wdir = 112.5;     // E-SE
  else
    Wdir = 0;         // N

  Blynk.setProperty(BLYNK_VPIN_WIND_DIRECTION, "rotation", Wdir);       // image rotating to wind direction
  Blynk.virtualWrite(BLYNK_VPIN_WIND_DIRECTION, 1);                     // image number
  Blynk.virtualWrite(BLYNK_VPIN_WIND_DIRECTION_BIN, windDirection);     // wind direction binary (test function)
}

bool dayStart = false;

void RainCalc()
{
  static float totalRainAmount;
  
  // Reset within 10s after boot or at around beginning of every day (12AM), have 60 s to do
  if ( !dayStart && ( (millis() < 10000 ) || ( (hour() == 0) && (minute() == 0) ) ) )
  {
    dayStart      = true;

    noInterrupts();
    totalAmount   = 0;   
    interrupts();
  }

  // Prepare for next day at 1AM
  if ( dayStart && (hour() == 1) )
  {
     dayStart = false; 
  }

  noInterrupts();
  totalRainAmount = totalAmount;
  interrupts();
  
  Blynk.virtualWrite(BLYNK_VPIN_RAIN_AMOUNT, totalRainAmount); // Rain amount
}

void IRAM_ATTR RainSensor() 
{
  static long lastMillis = 0;
  static long currMillis;

  currMillis = millis();
  
  if (currMillis >= lastMillis + DEBOUNCE_TIME)
  {
    totalAmount += RAIN_AMOUNT;
    lastMillis  = currMillis;
  }
}

void WindVelocity() 
{
  if (windDataReady)
  {
    noInterrupts();
    // COUNT_PERIOD = 5000 = 5s
    windDataReady = false;
    //RPM = ((currentCount) * 60) / (COUNT_PERIOD / 1000);          // Calculate revolutions per minute (RPM)
    RPM = ( currentCount * 12 );                                    
    interrupts();
    
    //windSpeedKmPerHr = ((4 * PIxRADIUS * RPM) / 60) / 1000;       // Calculate wind speed on m/s
    windSpeedMetrePerSec = (RPM * PIxRADIUS) / 15000;               
  
    windSpeedKmPerHr = windSpeedMetrePerSec * 3.6;                  // Calculate wind speed on km/h
    Blynk.virtualWrite(BLYNK_VPIN_WIND_SPEED, windSpeedKmPerHr);    // Wind speed sending
  }
}

void IRAM_ATTR WindSpeedSensor() 
{
  static long lastMillis = 0;
  static long currMillis;

  currMillis = millis();
  
  if (currMillis >= lastMillis + DEBOUNCE_TIME)
  {
    counter++;
    lastMillis = currMillis;
  
    if (currMillis >= startTime + COUNT_PERIOD )
    {
      startTime     = currMillis;
      currentCount  = counter;
      counter       = 0;
      windDataReady = true;
    }
  }
}

Please let us know if it’s running OK.
Regards,

1 Like