Esp pobiera dane z innych esp i wysyła na serwery aqi.eco i weathercloud

SOYER
Posts: 1186
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry

Post

Cześć, były prośyb to wklejam tu szkic z mojego esp8266, o którym była mowa min w tym wątku:
viewtopic.php?t=16100
Generalnie do tego urządzenia mam podpięty tylko czujnik ds18 który mierzy temperaturę w słońcu, dht22 mierzący temp i wilgotność w kuchni, czujnik deszczu i czujnik wiatru.
Jako, że chciałem przedstawiać odczyty czujników na stronie www, zainteresowałem się serwisami aqi.eco i weathercloud.
Na starcie serwis aqi przegrał, bo tam każde urządzenie wysyłające musi przesyłać też dane z czujnika jakości powietrza. U mnie to odpadało bo za komplet odczytów odpowiada kilka esp. Na jednym mam PMS5003, na kolejnym zewnętrzną wilgotność i ciśnienie z BME(P)280, temperaturę chciałem wziąć tą przy gruncie do wyświetlenia, więc kolejny esp tym razem esp32, no i wreszcie ten esp od wiatru, deszczu.
Więc uznałem, że będę przesyłał na weathercloud.
Po wgryzieniu się w temat, opisywany też tutaj:
https://forbot.pl/forum/topic/24726-dar ... /#comments
oraz tutaj, ale o tym później:
viewtopic.php?t=14698&start=200
okazało się, że na weathercloud owszem można wysyłać na jedno konto dane z kilku urządzeń ale żeby wyświetlać dane z czujnika jakości powietrza trzeba wykupić plan za prawie 50 euro rocznie.
W międzyczasie narodził się pomysł by pobierać potrzebne dane z clouda Supli na jedno esp, a następnie całą paczkę wysyłać na aqi i weatherclouda. Tak też zrobiłem w tym szkicu.
Pobieram przez linki bezpośrednie aktualny stan interesujących mnie czujników, dodaję odczyty z wiatru i deszczu i wysyłam na serwery www.
Dodatkowo dla weatherclouda liczę jeszcze jakieś indeky ciepła, punkt rosy i temperaturę odczuwalną.
Po wymianie kilku maili z Tomkiem od aqi.eco, któremu bardzo dziękuję za pomoc w zaznajomieniu się z aqi i wychwycenie kilku błędów, udało mi się go namówić na dodanie do aqi.eco wyświetlanie prędkości wiatru i ilości opadów. Wszystko macie w szkicu.
Ostatnia sprawa, wyszedł babol z opadami deszczu w KPOP , a dokładnie z odpowiednim ich wyświetlaniem na wykresach Supli. Okazało się, że wykresy w Supli dla mniejszej rozdzielczości danych niż minutowa, uśredniają odczyty. Czyli jeśli wysyłamy dane np przez godzinę, ale tylko w jednym przesyle był pomiar deszczu większy niż zero, to na wykresach będzie to uśrednione dla godziny/ilość zapisów. Czyli wykres godzinowy, dzienny będzie pokazywał bzdury dla odczytu ilości opadów, jedynie wykres minutowy pokazuje prawdę. Teoretycznie da się to podobno jakoś obejść modyfikując kod KLOPa, lub modyfikując kod ImpulseCounter, tak by do każdego impulsu dało się przypisać ilość mniejszą niż 1, ale ja nie potrafię. Może kolega @klew coś podziała. Póki co zostawiam dla odczytu deszczu KPOPa, pamiętając o tym by przeglądając wykresy mieć ustawiony tryb minutowy.
Poniżej szkic, napisany w prosty sposób, na pewno można by go jeszcze bardziej zrobić czytelnym, ale jak pisałem powstawał w sposób ewolucyjny. Komentarzy w szkicu mało, jakby coś było nieczytelne to pytajcie. Wszelkie "xxx" wiadomo do wypełnienia Waszymi unikalnymi danymi.

Code: Select all

#include <SuplaDevice.h>
#include <Timers.h>
#include <supla/sensor/DHT.h>
#include <supla/sensor/DS18B20.h>
#include <supla/network/esp_wifi.h>
#include <supla/sensor/general_purpose_measurement.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>

String jsonBuffer;

  Supla::ESPWifi wifi("xxx", "xxx);

char server [] = "https://api.weathercloud.net";
char IDKryry [] = "xxx";
char KeyKryry [] = "xxx";
  
#define dsPin 14 //D5
#define dhtPin 5 //D1
#define windPin 12 //D6
#define rainPin 2  //D4

Timer minuta;
Timer sekund1;
Timer sekund6;
Timer minut10;

int rai=0;
bool r=0;
float mmM2=0;
int WCpressure = 0;
int WChumidity = 0;
int WCgruntTemp = 0;
int WCpm25 = 0;
int WCpm10 = 0;
int WCpm1 = 0;
int WCaverage_kmh = 0;
float punkt_rosy;           // dew point (C)
float heatIndex;
float t_odczuwal; 
#define c1 (-42.379)
#define c2 (2.04901523)
#define c3 (10.14333127)
#define c4 (-0.22475541)
#define c5 (-0.00683783)
#define c6 (-0.05481717)
#define c7 (0.00122874)
#define c8 (0.00085282)
#define c9 (-0.00000199)

volatile int half_revolutions_time = 2; //Utworzenie zmiennej połowa pełnego obrotu (half revolutions)
volatile int rpm = 0;
unsigned long static  last_event = 0;
unsigned long static last_event1 = 0;
int sample = 0;
float moment_kmh;
float temp_kmh;
float correct_moment_kmh;
float average_kmh;
float pressure =0;
float gruntTemp =0;

Supla::Sensor::GeneralPurposeMeasurement *moment_wind = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *average_wind = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *rain = nullptr;

void ICACHE_RAM_ATTR rn(){// wektor przerwania deszczomierza
  unsigned long static last_event1 = 0;
  if (millis() - last_event1 < 50) {   //debouncing
    return;
  }
  rai++;
  last_event1 = millis();
}
 void ICACHE_RAM_ATTR rpm_fan() { //funkcja rpm_fan
  if (millis() - last_event < 5) {   //debouncing
    return;
  }
  half_revolutions_time = (millis() - last_event);
  last_event = millis();
}
void temporaryRPM(){
    noInterrupts(); 
    if((last_event + 2000) < millis()){    
     rpm=0;
     moment_kmh = 0;
     correct_moment_kmh = 0;
    }
    else{ 
      rpm = (30000 / half_revolutions_time) ;
      moment_kmh = 6.28 * 0.075 * rpm/60.0 * 3.6;// pi x promień czujnika x rpm/60s x ms->km/h
      if(moment_kmh < 10){
        correct_moment_kmh = moment_kmh * 2.8;
      }
      else if((moment_kmh >= 10) && (moment_kmh < 25)){
        correct_moment_kmh = moment_kmh * 2.7;
      }
      else if(moment_kmh >= 25){
        correct_moment_kmh = moment_kmh * 2.8;
      }
    } 
    if(sekund6.available()){
      temp_kmh = temp_kmh + correct_moment_kmh;
      sample++;
      sekund6.restart();
     }
    if(sample==10){
      average_kmh = temp_kmh / 10; 
      temp_kmh = 0;
      sample=0;
      sekund6.restart();
    }
   interrupts() ; //Przywróć przerwania
}

void setup() {
  Serial.begin(9600);
   // Replace the falowing GUID with value that you can retrieve from https://www.supla.org/arduino/get-guid
  char GUID[SUPLA_GUID_SIZE] = {xxx};

  // Replace the following AUTHKEY with value that you can retrieve from: https://www.supla.org/arduino/get-authkey
  char AUTHKEY[SUPLA_AUTHKEY_SIZE] = {xxx};
    new Supla::Sensor::DS18B20(dsPin);
    new Supla::Sensor::DHT(dhtPin, DHT22);
    moment_wind = new Supla::Sensor::GeneralPurposeMeasurement();
    average_wind = new Supla::Sensor::GeneralPurposeMeasurement();
    rain = new Supla::Sensor::GeneralPurposeMeasurement();   
    pinMode(windPin,INPUT_PULLUP);
    pinMode(rainPin,INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(rainPin), rn, RISING); 
    attachInterrupt(digitalPinToInterrupt(windPin), rpm_fan, FALLING);
    minuta.begin(59999);
    sekund6.begin(6000);
    sekund1.begin(1000);
    minut10.begin(610000);
    last_event = millis();
    last_event1 = millis();
       SuplaDevice.begin(GUID,              // Global Unique Identifier 
                    "sxxx.supla.org",  // SUPLA server address
                    "xxx",   // Email address used to login to Supla Cloud
                    AUTHKEY);          // Authorization key
}

void loop() {
    SuplaDevice.iterate();
    temporaryRPM();
    sendToAll();
}

void sendToAll(){
    if(sekund1.available()){  
      moment_wind->setValue(correct_moment_kmh);
      sekund1.restart();
    }
    if(minuta.available()){  
      average_wind->setValue(average_kmh);
      minuta.restart();
    }
    if(minut10.available()){
      mmM2=rai*0.15; // dwa przerwnia na jedną kolebkę, więc 0.15
      rain->setValue(mmM2);
      rai=0;
      weathercloud(); 
      minut10.restart();
    }
}
void weathercloud(){
  int WCmmM2 = mmM2 *10;

  ///////////////////////////////////////////////////////////////////////////////
  WCaverage_kmh = (average_kmh * 10) / 3.6; //km/h->m/s
  String serverPathPM_pm1 = "https://svrxx.supla.org/direct/xxx/xxx/read?format=json";
  String serverPathPM_pm25 = "https://svrxx.supla.org/direct/xxx/xxxx/read?format=json";
  String serverPathPM_pm10 = "https://svrxx.supla.org/direct/xxx/xxx/read?format=json";
  String serverPathGRUNT_temp = "https://svrxx.supla.org/direct/xxx/xxx/read?format=json";
  String serverPathZEW_press = "https://svrxx.supla.org/direct/xxx/xxx/read?format=json"; 
  String serverPathZEW_hum = "https://svrxx.supla.org/direct/xxx/xxxxread?format=json";

punkt_rosy = (dewPoint(gruntTemp, WChumidity))*10;
heatindex();
windchill();

  String serverPathWC = String(server) + "/v01/set/wid/" + String(IDKryry) + "/key/" + String(KeyKryry) 
  + "/temp/" + String(WCgruntTemp) + "/hum/" + String(WChumidity) 
  + "/bar/" + String(WCpressure) + "/wspd/" + String(WCaverage_kmh) + "/heat/" + String(heatIndex)
  + "/rainrate/" + String(WCmmM2) + "/dew/" + String(punkt_rosy) + "/chill/" + String(t_odczuwal);
  // + "/pm25/" + String(WCpm25) + "/pm10/" + String(WCpm10);
  
  
String serverPath_aqi = "https://api.aqi.eco/update/xxx"; 
      jsonBuffer = httpGET_PM_pm1(serverPathPM_pm1.c_str());
      jsonBuffer = httpGET_PM_pm25(serverPathPM_pm25.c_str());
      jsonBuffer = httpGET_PM_pm10(serverPathPM_pm10.c_str());
      jsonBuffer = httpGET_GRUNT_temp(serverPathGRUNT_temp.c_str());
      jsonBuffer = httpGET_ZEW_hum(serverPathZEW_hum.c_str());
      jsonBuffer = httpGET_ZEW_press(serverPathZEW_press.c_str());
      jsonBuffer = httpGETWC(serverPathWC.c_str());
      jsonBuffer = httpPOSTaqi(serverPath_aqi.c_str());
      
      Serial.println(jsonBuffer);
}
String httpGET_PM_pm1(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    WCpm1 = doc["value"]; 
    Serial.print("pm1:  ");
    Serial.println(WCpm1);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_PM_pm25(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    WCpm25 = doc["value"]; 
    Serial.print("pm2,5:  ");
    Serial.println(WCpm25);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_PM_pm10(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    WCpm10 = doc["value"]; 
    Serial.print("pm10:  ");
    Serial.println(WCpm10);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_GRUNT_temp(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    gruntTemp = doc["temperature"]; 
    if(gruntTemp > -273){
      WCgruntTemp = gruntTemp *10;
    }
    Serial.print("tempGrunt:  ");
    Serial.println(gruntTemp);
    Serial.print("tempGruntWC:  ");
    Serial.println(WCgruntTemp);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_ZEW_hum(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    WChumidity = doc["humidity"]; 
    Serial.print("humidityZewWC:  ");
    Serial.println(WChumidity);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_ZEW_press(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);  
    pressure = doc["value"]; 
    WCpressure = pressure *10;
    Serial.print("pressureWC:  ");
    Serial.println(WCpressure);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGETWC(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpPOSTaqi(const char* serverName) {
float AQIpressure = pressure*100;
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  http1.addHeader("Content-Type", "application/json");
  int httpResponseCode = http1.POST("{\"esp8266id\": \"123123123\",\"sensordatavalues\":[{\"value_type\":\"PMS_P0\",\"value\":" + String(WCpm1) + "},{\"value_type\":\"PMS_P2\",\"value\":" + String(WCpm25) + "}, {\"value_type\":\"PMS_P1\",\"value\":" + String(WCpm10) + "},{\"value_type\":\"BME280_temperature\",\"value\":" + String(gruntTemp) + "},{\"value_type\":\"BME280_humidity\",\"value\":" + String(WChumidity) + "},{\"value_type\":\"wind_speed\",\"value\":" + String(WCaverage_kmh) + "},{\"value_type\":\"rainfall\",\"value\":" + String(mmM2) + "},{\"value_type\":\"BME280_pressure\",\"value\":" + String(AQIpressure) + "}]}");

  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
double dewPoint(double tempc_min, double humidity){
  
        double RATIO = 373.15 / (273.15 + tempc_min);  // RATIO was originally named A0, possibly confusing in Arduino context
        double SUM = -7.90298 * (RATIO - 1);
        SUM += 5.02808 * log10(RATIO);
        SUM += -1.3816e-7 * (pow(10, (11.344 * (1 - 1/RATIO ))) - 1) ;
        SUM += 8.1328e-3 * (pow(10, (-3.49149 * (RATIO - 1))) - 1) ;
        SUM += log10(1013.246);
        double VP = pow(10, SUM - 3) * humidity;
        double T = log(VP/0.61078);   // temp var
        return (241.88 * T) / (17.558 - T);
}
void heatindex(){
  float temp_f = (gruntTemp*1.8)+32;
if (temp_f > 80.0)   //The heat index only works for temperatures  above 80°F 
{
  float heat_f = c1+c2*(temp_f)+c3*(WChumidity)+c4*(temp_f)*(WChumidity)+c5*(pow(temp_f,2))+c6*(pow(WChumidity,2))+c7*(pow(temp_f, 2))*(WChumidity)+c8*(temp_f)*(pow(WChumidity, 2))+c9*(pow(temp_f, 2))*(pow(WChumidity, 2));
  heatIndex = ((heat_f - 32)*5/9)*10;  //  converting to C and x10 to WC
  }
  else
{
  heatIndex = gruntTemp*10;
}
}
void windchill(){
float temp_f = (gruntTemp*1.8)+32;

if ((temp_f <50.0) && (average_kmh > 3.6)) //The wind chill only works for temperatures  below 50°F and wind speed above 3 mph. (10°C , 1 m/s)

{
 float chill_f =35.74+0.6215*temp_f-35.75*pow(average_kmh,0.16)+0.4275*temp_f*pow(average_kmh,0.16);
 t_odczuwal = ((chill_f - 32)*5/9)*10;  //  converting to C
}

else
{
  t_odczuwal = gruntTemp*10;
}
}
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
SOYER
Posts: 1186
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry

Post

Cały dzień dzisiaj walczyłem z pomiarami deszczu. Weathercloud wymaga danych sumujących ostatnią godzinę i ostatnią dobę.
Wklejam poniższy kod to implementujący.
Walczę jeszcze o zapisywanie danych do pamięci, by w razie resetu nie utracić danych zebranych z przerwań, a nie obrobionych jeszcze i niewysłanych na serwery. Tu licze na pomoc szanownych forumowiczów obeznanych z supla storage. Jak w wybranym momencie zapisać do pamięci wybraną zmienną.
Najważniejsza zmiana: dwa kanały odpowiadające za wyświetlanie opadów deszczu (za1h i za 24h) są teraz KLOPami, a nie KPOPami.

Code: Select all

#include <SuplaDevice.h>
#include <Timers.h>
#include <supla/sensor/DHT.h>
#include <supla/sensor/DS18B20.h>
#include <supla/network/esp_wifi.h>
#include <supla/sensor/general_purpose_measurement.h>
#include <supla/sensor/general_purpose_meter.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <supla/clock/clock.h> //int suplaClock.getYear(); getMonth(); getDay(); getDayOfWeek();1 - Sunday, 2 - Monday getHour(); getMin(); getSec();
#include <supla/storage/eeprom.h>
#include <EEPROM.h>

String jsonBuffer;

  Supla::ESPWifi wifi("xxx", "xx");

char server [] = "https://api.weathercloud.net";
char IDKryry [] = "xxx";
char KeyKryry [] = "xxx";
  
#define dsPin 14 //D5
#define dhtPin 5 //D1
#define windPin 12 //D6
#define rainPin 2  //D4

Timer minuta;
Timer sekund1;
Timer sekund6;
Timer minut10;

int rai1h=0;
int rai24h=0;
bool r=0;
float mm1h=0;
float mm24h=0;
int WCpressure = 0;
int WChumidity = 0;
int WCgruntTemp = 0;
int WCpm25 = 0;
int WCpm10 = 0;
int WCpm1 = 0;
int WCaverage_kmh = 0;
float punkt_rosy;           // dew point (C)
float heatIndex;
float t_odczuwal; 
#define c1 (-42.379)
#define c2 (2.04901523)
#define c3 (10.14333127)
#define c4 (-0.22475541)
#define c5 (-0.00683783)
#define c6 (-0.05481717)
#define c7 (0.00122874)
#define c8 (0.00085282)
#define c9 (-0.00000199)

volatile int half_revolutions_time = 2; //Utworzenie zmiennej połowa pełnego obrotu (half revolutions)
volatile int rpm = 0;
unsigned long static  last_event = 0;
unsigned long static last_event1 = 0;
int sample = 0;
float moment_kmh;
float temp_kmh;
float correct_moment_kmh;
float average_kmh;
float pressure =0;
float gruntTemp =0;

Supla::Sensor::GeneralPurposeMeasurement *moment_wind = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *average_wind = nullptr;
Supla::Sensor::GeneralPurposeMeter *rain1h = nullptr;
Supla::Sensor::GeneralPurposeMeter *rain24h = nullptr;
Supla::Clock clock1;
Supla::Eeprom eeprom(100);

void ICACHE_RAM_ATTR rn(){// wektor przerwania deszczomierza
  unsigned long static last_event1 = 0;
  if (millis() - last_event1 < 50) {   //debouncing
    return;
  }
  rai1h++;
  EEPROM.write(1, rai1h);
  rai24h++;
  EEPROM.write(2, rai24h);
  last_event1 = millis();
}
 void ICACHE_RAM_ATTR rpm_fan() { //funkcja rpm_fan
  if (millis() - last_event < 5) {   //debouncing
    return;
  }
  half_revolutions_time = (millis() - last_event);
  last_event = millis();
}
void temporaryRPM(){
    noInterrupts(); 
    if((last_event + 2000) < millis()){    
     rpm=0;
     moment_kmh = 0;
     correct_moment_kmh = 0;
    }
    else{ 
      rpm = (30000 / half_revolutions_time) ;
      moment_kmh = 6.28 * 0.075 * rpm/60.0 * 3.6;// pi x promień czujnika x rpm/60s x ms->km/h
      if(moment_kmh < 10){
        correct_moment_kmh = moment_kmh * 2.8;
      }
      else if((moment_kmh >= 10) && (moment_kmh < 25)){
        correct_moment_kmh = moment_kmh * 2.7;
      }
      else if(moment_kmh >= 25){
        correct_moment_kmh = moment_kmh * 2.8;
      }
    } 
    if(sekund6.available()){
      temp_kmh = temp_kmh + correct_moment_kmh;
      sample++;
      sekund6.restart();
     }
    if(sample==10){
      average_kmh = temp_kmh / 10; 
      temp_kmh = 0;
      sample=0;
      sekund6.restart();
    }
   interrupts() ; //Przywróć przerwania
}

void setup() {
  Serial.begin(9600);
   // Replace the falowing GUID with value that you can retrieve from https://www.supla.org/arduino/get-guid
  char GUID[SUPLA_GUID_SIZE] = {xx};

  // Replace the following AUTHKEY with value that you can retrieve from: https://www.supla.org/arduino/get-authkey
  char AUTHKEY[SUPLA_AUTHKEY_SIZE] = {xx};
    new Supla::Sensor::DS18B20(dsPin);
    new Supla::Sensor::DHT(dhtPin, DHT22);
    moment_wind = new Supla::Sensor::GeneralPurposeMeasurement();
    average_wind = new Supla::Sensor::GeneralPurposeMeasurement();
    rain1h = new Supla::Sensor::GeneralPurposeMeter();
    rain24h = new Supla::Sensor::GeneralPurposeMeter();
    auto clock1 = SuplaDevice.getClock();
  rai1h=EEPROM.read(1);
  rai24h=EEPROM.read(2);
  Serial.println("EEPROM Rain value");
  Serial.print("rai1h VALUE FROM EEPROM:  ");
  Serial.print(rai1h);
  Serial.println(" mm");
  Serial.print("rai24h VALUE FROM EEPROM:  ");
  Serial.print(rai24h);
  Serial.println(" mm");
    pinMode(windPin,INPUT_PULLUP);
    pinMode(rainPin,INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(rainPin), rn, RISING); 
    attachInterrupt(digitalPinToInterrupt(windPin), rpm_fan, FALLING);
    minuta.begin(59999);
    sekund6.begin(6000);
    sekund1.begin(1000);
    minut10.begin(600001);
    last_event = millis();
    last_event1 = millis();
 
       SuplaDevice.begin(GUID,              // Global Unique Identifier 
                    "sxx.supla.org",  // SUPLA server address
                    "xx.pl",   // Email address used to login to Supla Cloud
                    AUTHKEY);          // Authorization key
}

void loop() {
    SuplaDevice.iterate();
    temporaryRPM();
    sendToAll();
}

void sendToAll(){
    if(sekund1.available()){  
      moment_wind->setValue(correct_moment_kmh);
      sekund1.restart();
    }
    if(minuta.available()){ 
      Serial.print("rai1h:  ");
      Serial.print(rai1h);
      Serial.println(" mm");
      Serial.print("rai24h:  ");
      Serial.print(rai24h);
      Serial.println(" mm");
      noInterrupts(); 
      if(clock1.getMin()==59){
        rai1h=0;
        EEPROM.write(1, rai1h);
        Serial.println("Reset Hourly Rain");
      }
      if((clock1.getHour()==23) && (clock1.getMin()==59)){
        rai1h=0;
        rai24h=0;
        EEPROM.write(1, rai1h);
        EEPROM.write(2, rai24h);
        Serial.println("Reset Hourly Rain");
        Serial.println("Reset Daily Rain");
      }
      average_wind->setValue(average_kmh);
      mm1h=rai1h*0.15; // dwa przerwnia na jedną kolebkę, więc 0.15
      mm24h=rai24h*0.15;
      rain1h->setValue(mm1h);
      rain24h->setValue(mm24h);
      minuta.restart();
      interrupts();
    }
    if(minut10.available()){
      weathercloud(); 
      minut10.restart();
    }
}
void weathercloud(){
  int WCmm1h = mm1h *10;
  int WCmm24h = mm24h *10;

  ///////////////////////////////////////////////////////////////////////////////
  WCaverage_kmh = (average_kmh * 10) / 3.6; //km/h->m/s
  String serverPathPM_pm1 = "https://svrxx.supla.org/direct/x/xx/read?format=json";
  String serverPathPM_pm25 = "https://svrxx.supla.org/direct/x/xx/read?format=json";
  String serverPathPM_pm10 = "https://svrxx.supla.org/direct/x/9xx/read?format=json";
  String serverPathGRUNT_temp = "https://svrxx.supla.org/direct/x/xx/read?format=json";
  String serverPathZEW_press = "https://svrxx.supla.org/direct/x/x/read?format=json"; 
  String serverPathZEW_hum = "https://svxx.supla.org/direct/x/x/read?format=json";

punkt_rosy = (dewPoint(gruntTemp, WChumidity))*10;
heatindex();
windchill();

  String serverPathWC = String(server) + "/v01/set/wid/" + String(IDKryry) + "/key/" + String(KeyKryry) 
  + "/temp/" + String(WCgruntTemp) + "/hum/" + String(WChumidity) 
  + "/bar/" + String(WCpressure) + "/wspd/" + String(WCaverage_kmh) + "/heat/" + String(heatIndex)
  + "/rainrate/" + String(WCmm1h) + "/dew/" + "/rain/" + String(WCmm24h) + "/dew/" 
  + String(punkt_rosy) + "/chill/" + String(t_odczuwal);
  // + "/pm25/" + String(WCpm25) + "/pm10/" + String(WCpm10);
  
  
String serverPath_aqi = "https://api.aqi.eco/update/xxxxx"; 
      jsonBuffer = httpGET_PM_pm1(serverPathPM_pm1.c_str());
      jsonBuffer = httpGET_PM_pm25(serverPathPM_pm25.c_str());
      jsonBuffer = httpGET_PM_pm10(serverPathPM_pm10.c_str());
      jsonBuffer = httpGET_GRUNT_temp(serverPathGRUNT_temp.c_str());
      jsonBuffer = httpGET_ZEW_hum(serverPathZEW_hum.c_str());
      jsonBuffer = httpGET_ZEW_press(serverPathZEW_press.c_str());
      jsonBuffer = httpGETWC(serverPathWC.c_str());
      jsonBuffer = httpPOSTaqi(serverPath_aqi.c_str());
      
      Serial.println(jsonBuffer);
}
String httpGET_PM_pm1(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    WCpm1 = doc["value"]; 
    Serial.print("pm1:  ");
    Serial.println(WCpm1);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_PM_pm25(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    WCpm25 = doc["value"]; 
    Serial.print("pm2,5:  ");
    Serial.println(WCpm25);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_PM_pm10(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    WCpm10 = doc["value"]; 
    Serial.print("pm10:  ");
    Serial.println(WCpm10);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_GRUNT_temp(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    gruntTemp = doc["temperature"]; 
    if(gruntTemp > -273){
      WCgruntTemp = gruntTemp *10;
    }
    Serial.print("tempGrunt:  ");
    Serial.println(gruntTemp);
    Serial.print("tempGruntWC:  ");
    Serial.println(WCgruntTemp);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_ZEW_hum(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    WChumidity = doc["humidity"]; 
    Serial.print("humidityZewWC:  ");
    Serial.println(WChumidity);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_ZEW_press(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);  
    pressure = doc["value"]; 
    WCpressure = pressure *10;
    Serial.print("pressureWC:  ");
    Serial.println(WCpressure);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGETWC(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpPOSTaqi(const char* serverName) {
float AQIpressure = pressure*100;
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  http1.addHeader("Content-Type", "application/json");
  int httpResponseCode = http1.POST("{\"esp8266id\": \"123123123\",\"sensordatavalues\":[{\"value_type\":\"PMS_P0\",\"value\":" + String(WCpm1) + "},{\"value_type\":\"PMS_P2\",\"value\":" + String(WCpm25) + "}, {\"value_type\":\"PMS_P1\",\"value\":" + String(WCpm10) + "},{\"value_type\":\"BME280_temperature\",\"value\":" + String(gruntTemp) + "},{\"value_type\":\"BME280_humidity\",\"value\":" + String(WChumidity) + "},{\"value_type\":\"wind_speed\",\"value\":" + String(WCaverage_kmh) + "},{\"value_type\":\"rainfall\",\"value\":" + String(mm24h) + "},{\"value_type\":\"BME280_pressure\",\"value\":" + String(AQIpressure) + "}]}");

  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
double dewPoint(double tempc_min, double humidity){
  
        double RATIO = 373.15 / (273.15 + tempc_min);  // RATIO was originally named A0, possibly confusing in Arduino context
        double SUM = -7.90298 * (RATIO - 1);
        SUM += 5.02808 * log10(RATIO);
        SUM += -1.3816e-7 * (pow(10, (11.344 * (1 - 1/RATIO ))) - 1) ;
        SUM += 8.1328e-3 * (pow(10, (-3.49149 * (RATIO - 1))) - 1) ;
        SUM += log10(1013.246);
        double VP = pow(10, SUM - 3) * humidity;
        double T = log(VP/0.61078);   // temp var
        return (241.88 * T) / (17.558 - T);
}
void heatindex(){
  float temp_f = (gruntTemp*1.8)+32;
if (temp_f > 80.0)   //The heat index only works for temperatures  above 80°F 
{
  float heat_f = c1+c2*(temp_f)+c3*(WChumidity)+c4*(temp_f)*(WChumidity)+c5*(pow(temp_f,2))+c6*(pow(WChumidity,2))+c7*(pow(temp_f, 2))*(WChumidity)+c8*(temp_f)*(pow(WChumidity, 2))+c9*(pow(temp_f, 2))*(pow(WChumidity, 2));
  heatIndex = ((heat_f - 32)*5/9)*10;  //  converting to C and x10 to WC
  }
  else
{
  heatIndex = gruntTemp*10;
}
}
void windchill(){
float temp_f = (gruntTemp*1.8)+32;

if ((temp_f <50.0) && (average_kmh > 3.6)) //The wind chill only works for temperatures  below 50°F and wind speed above 3 mph. (10°C , 1 m/s)

{
 float chill_f =35.74+0.6215*temp_f-35.75*pow(average_kmh,0.16)+0.4275*temp_f*pow(average_kmh,0.16);
 t_odczuwal = ((chill_f - 32)*5/9)*10;  //  converting to C
}

else
{
  t_odczuwal = gruntTemp*10;
}
}
EDIT: edytowałem przed chwilą szkic powyżej, zapisuje w odpowiednim czasie zmienne odpowiedzialne za opady deszczu do eepromu. Czyta je przy ewentualnym resecie esp.
Dziękuję @klew i @lukfud za pomoc.
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
SOYER
Posts: 1186
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry

Post

Cześć, kolejne poprawki w szkicu. Poprawione wysyłanie danych na weathercloud dotyczące wiatru, teraz wysyłamy prędkość chwilową, średnią z ostatnich 10min i wreszcie porywy wiatru czyli najwyższą prędkość chwilową z ostatnich 10 minut.
Jest też nowa funkcja zapisywania do pamięci stanu licznika KLOP, zaimplementowana w ostatnim wydaniu Supla Device. Plus oczywiście to wszystko co we wcześniejszych wpisach.

Code: Select all

#include <SuplaDevice.h>
#include <Timers.h>
#include <supla/sensor/DHT.h>
#include <supla/sensor/DS18B20.h>
#include <supla/network/esp_wifi.h>
#include <supla/sensor/general_purpose_measurement.h>
#include <supla/sensor/general_purpose_meter.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <supla/clock/clock.h> //int suplaClock.getYear(); getMonth(); getDay(); getDayOfWeek();1 - Sunday, 2 - Monday getHour(); getMin(); getSec();
#include <supla/storage/eeprom.h>
#include <EEPROM.h>

String jsonBuffer;

  Supla::ESPWifi wifi("xx", "xx");

char server [] = "https://api.weathercloud.net";
char IDKryry [] = "xx";
char KeyKryry [] = "xx";
  
#define dsPin 14 //D5
#define dhtPin 5 //D1
#define windPin 12 //D6
#define rainPin 2  //D4

Timer minuta;
Timer sekund1;
Timer sekund6;
Timer minut10;

int rai1h=0;
int rai24h=0;
bool r=0;
float mm1h=0;
float mm24h=0;
int WCpressure = 0;
int WChumidity = 0;
int WCgruntTemp = 0;
int WCpm25 = 0;
int WCpm10 = 0;
int WCpm1 = 0;
int WCaverage_kmh = 0;
int WCporyw_kmh = 0;
int WCmoment_kmh = 0;
float punkt_rosy;           // dew point (C)
float heatIndex;
float t_odczuwal; 
#define c1 (-42.379)
#define c2 (2.04901523)
#define c3 (10.14333127)
#define c4 (-0.22475541)
#define c5 (-0.00683783)
#define c6 (-0.05481717)
#define c7 (0.00122874)
#define c8 (0.00085282)
#define c9 (-0.00000199)

volatile int half_revolutions_time = 2; //Utworzenie zmiennej połowa pełnego obrotu (half revolutions)
volatile int rpm = 0;
unsigned long static  last_event = 0;
unsigned long static last_event1 = 0;
int sample = 0;
float moment_kmh;
float poryw_kmh;
float temp_kmh;
float correct_moment_kmh;
float average_kmh;
float pressure =0;
float gruntTemp =0;

Supla::Sensor::GeneralPurposeMeasurement *moment_wind = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *average_wind = nullptr;
Supla::Sensor::GeneralPurposeMeter *rain1h = nullptr;
Supla::Sensor::GeneralPurposeMeter *rain24h = nullptr;
Supla::Clock clock1;
Supla::Eeprom eeprom(100);

void ICACHE_RAM_ATTR rn(){// wektor przerwania deszczomierza
  unsigned long static last_event1 = 0;
  if (millis() - last_event1 < 50) {   //debouncing
    return;
  }
  rai1h++;
  EEPROM.write(1, rai1h);
  rai24h++;
  EEPROM.write(2, rai24h);
  last_event1 = millis();
}
 void ICACHE_RAM_ATTR rpm_fan() { //funkcja rpm_fan
  if (millis() - last_event < 5) {   //debouncing
    return;
  }
  half_revolutions_time = (millis() - last_event);
  last_event = millis();
}
void temporaryRPM(){
    noInterrupts(); 
    if((last_event + 2000) < millis()){    
     rpm=0;
     moment_kmh = 0;
     correct_moment_kmh = 0;
    }
    else{ 
      rpm = (30000 / half_revolutions_time) ;
      moment_kmh = 6.28 * 0.075 * rpm/60.0 * 3.6;// pi x promień czujnika x rpm/60s x ms->km/h
      if(moment_kmh < 10){
        correct_moment_kmh = moment_kmh * 2.8; //prędkość chwilowa po korekcie
      }
      else if((moment_kmh >= 10) && (moment_kmh < 25)){
        correct_moment_kmh = moment_kmh * 2.7;
      }
      else if(moment_kmh >= 25){
        correct_moment_kmh = moment_kmh * 2.8;
      }
    } 
    if(sekund6.available()){
      temp_kmh = temp_kmh + correct_moment_kmh;
      sample++;
      if(poryw_kmh < correct_moment_kmh){
        poryw_kmh = correct_moment_kmh;
      }
      sekund6.restart();
     }
    if(sample==100){// 100 x 6 sek = 10min
      average_kmh = temp_kmh / 100; 
      temp_kmh = 0;
      sample=0;
      WCporyw_kmh=(poryw_kmh*10)/3.6;// poryw z 10min pomnozony razy 10dla WC i /3.6(m/s)
      poryw_kmh=0;
      WCaverage_kmh = (average_kmh * 10) / 3.6; //km/h->m/s
      WCmoment_kmh = (correct_moment_kmh*10)/3.6;
      sekund6.restart();
    }
   interrupts() ; //Przywróć przerwania
}

void setup() {
  Serial.begin(9600);
  //EEPROM.begin(32);
   // Replace the falowing GUID with value that you can retrieve from https://www.supla.org/arduino/get-guid
  char GUID[SUPLA_GUID_SIZE] = {xx};

  // Replace the following AUTHKEY with value that you can retrieve from: https://www.supla.org/arduino/get-authkey
  char AUTHKEY[SUPLA_AUTHKEY_SIZE] = {xx};
    new Supla::Sensor::DS18B20(dsPin);
    new Supla::Sensor::DHT(dhtPin, DHT22);
    moment_wind = new Supla::Sensor::GeneralPurposeMeasurement();
    average_wind = new Supla::Sensor::GeneralPurposeMeasurement();
    rain1h = new Supla::Sensor::GeneralPurposeMeter();
    rain24h = new Supla::Sensor::GeneralPurposeMeter();
    auto clock1 = SuplaDevice.getClock();
    rain24h->setKeepStateInStorage(true);
  rai1h=EEPROM.read(1);
  rai24h=EEPROM.read(2);
  Serial.println("EEPROM Rain value");
  Serial.print("rai1h VALUE FROM EEPROM:  ");
  Serial.print(rai1h);
  Serial.println(" mm");
  Serial.print("rai24h VALUE FROM EEPROM:  ");
  Serial.print(rai24h);
  Serial.println(" mm");
    pinMode(windPin,INPUT_PULLUP);
    pinMode(rainPin,INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(rainPin), rn, RISING); 
    attachInterrupt(digitalPinToInterrupt(windPin), rpm_fan, FALLING);
    minuta.begin(59999);
    sekund6.begin(6000);
    sekund1.begin(1000);
    minut10.begin(600001);
    last_event = millis();
    last_event1 = millis();
 
       SuplaDevice.begin(GUID,              // Global Unique Identifier 
                    "xx.supla.org",  // SUPLA server address
                    "xx@wp.pl",   // Email address used to login to Supla Cloud
                    AUTHKEY);          // Authorization key
}

void loop() {
    SuplaDevice.iterate();
    temporaryRPM();
    sendToAll();
}

void sendToAll(){
    if(sekund1.available()){  
      moment_wind->setValue(correct_moment_kmh);
      sekund1.restart();
    }
    if(minuta.available()){ 
      Serial.print("rai1h:  ");
      Serial.print(rai1h);
      Serial.println(" mm");
      Serial.print("rai24h:  ");
      Serial.print(rai24h);
      Serial.println(" mm");
      noInterrupts(); 
      if(clock1.getMin()==59){
        rai1h=0;
        EEPROM.write(1, rai1h);
        Serial.println("Reset Hourly Rain");
      }
      if((clock1.getHour()==23) && (clock1.getMin()==59)){
        rai1h=0;
        rai24h=0;
        EEPROM.write(1, rai1h);
        EEPROM.write(2, rai24h);
        Serial.println("Reset Hourly Rain");
        Serial.println("Reset Daily Rain");
      }
      average_wind->setValue(average_kmh);
      mm1h=rai1h*0.15; // dwa przerwnia na jedną kolebkę, więc 0.15
      mm24h=rai24h*0.15;
      rain1h->setValue(mm1h);
      rain24h->setValue(mm24h);
      minuta.restart();
      interrupts();
    }
    if(minut10.available()){
      weathercloud(); 
      minut10.restart();
    }
}
void weathercloud(){
  int WCmm1h = mm1h *10;
  int WCmm24h = mm24h *10;

  ///////////////////////////////////////////////////////////////////////////////
  String serverPathPM_pm1 = "https://svrxx.supla.org/direct/xx/xx/read?format=json";
  String serverPathPM_pm25 = "https://svrxx.supla.org/direct/xx/xx/read?format=json";
  String serverPathPM_pm10 = "https://svrxx.supla.org/direct/xx/xx/read?format=json";
  String serverPathGRUNT_temp = "https://svrxx.supla.org/direct/xx/xxr/read?format=json";
  String serverPathZEW_press = "https://svrxx.supla.org/direct/xx/xx/read?format=json"; 
  String serverPathZEW_hum = "https://svrxx.supla.org/direct/xx/xx/read?format=json";

punkt_rosy = (dewPoint(gruntTemp, WChumidity))*10;
heatindex();
windchill();

  String serverPathWC = String(server) + "/v01/set/wid/" + String(IDKryry) + "/key/" + String(KeyKryry) 
  + "/temp/" + String(WCgruntTemp) + "/hum/" + String(WChumidity) 
  + "/bar/" + String(WCpressure) + "/wspdavg/" + String(WCaverage_kmh) + "/wspdhi/" + String(WCporyw_kmh) 
  + "/wspd/" + String(WCmoment_kmh) + "/heat/" + String(heatIndex)
  + "/rainrate/" + String(WCmm1h) + "/dew/" + "/rain/" + String(WCmm24h) + "/dew/" 
  + String(punkt_rosy) + "/chill/" + String(t_odczuwal);
  // + "/pm25/" + String(WCpm25) + "/pm10/" + String(WCpm10);
  
  
String serverPath_aqi = "https://api.aqi.eco/update/xx"; 
      jsonBuffer = httpGET_PM_pm1(serverPathPM_pm1.c_str());
      jsonBuffer = httpGET_PM_pm25(serverPathPM_pm25.c_str());
      jsonBuffer = httpGET_PM_pm10(serverPathPM_pm10.c_str());
      jsonBuffer = httpGET_GRUNT_temp(serverPathGRUNT_temp.c_str());
      jsonBuffer = httpGET_ZEW_hum(serverPathZEW_hum.c_str());
      jsonBuffer = httpGET_ZEW_press(serverPathZEW_press.c_str());
      jsonBuffer = httpGETWC(serverPathWC.c_str());
      jsonBuffer = httpPOSTaqi(serverPath_aqi.c_str());
      
      Serial.println(jsonBuffer);
}
String httpGET_PM_pm1(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    WCpm1 = doc["value"]; 
    Serial.print("pm1:  ");
    Serial.println(WCpm1);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_PM_pm25(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    WCpm25 = doc["value"]; 
    Serial.print("pm2,5:  ");
    Serial.println(WCpm25);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_PM_pm10(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    WCpm10 = doc["value"]; 
    Serial.print("pm10:  ");
    Serial.println(WCpm10);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_GRUNT_temp(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    gruntTemp = doc["temperature"]; 
    if(gruntTemp > -273){
      WCgruntTemp = gruntTemp *10;
    }
    Serial.print("tempGrunt:  ");
    Serial.println(gruntTemp);
    Serial.print("tempGruntWC:  ");
    Serial.println(WCgruntTemp);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_ZEW_hum(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    WChumidity = doc["humidity"]; 
    Serial.print("humidityZewWC:  ");
    Serial.println(WChumidity);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_ZEW_press(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);  
    pressure = doc["value"]; 
    WCpressure = pressure *10;
    Serial.print("pressureWC:  ");
    Serial.println(WCpressure);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGETWC(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpPOSTaqi(const char* serverName) {
  
float AQIpressure = pressure*100;
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  http1.addHeader("Content-Type", "application/json");
  int httpResponseCode = http1.POST("{\"esp8266id\": \"123123123\",\"sensordatavalues\":[{\"value_type\":\"PMS_P0\",\"value\":" + String(WCpm1) + "},{\"value_type\":\"PMS_P2\",\"value\":" + String(WCpm25) + "}, {\"value_type\":\"PMS_P1\",\"value\":" + String(WCpm10) + "},{\"value_type\":\"BME280_temperature\",\"value\":" + String(gruntTemp) + "},{\"value_type\":\"BME280_humidity\",\"value\":" + String(WChumidity) + "},{\"value_type\":\"wind_speed\",\"value\":" + String(average_kmh) + "},{\"value_type\":\"rainfall\",\"value\":" + String(mm24h) + "},{\"value_type\":\"BME280_pressure\",\"value\":" + String(AQIpressure) + "}]}");

  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
double dewPoint(double tempc_min, double humidity){ //punkt rosy
  
        double RATIO = 373.15 / (273.15 + tempc_min);  // RATIO was originally named A0, possibly confusing in Arduino context
        double SUM = -7.90298 * (RATIO - 1);
        SUM += 5.02808 * log10(RATIO);
        SUM += -1.3816e-7 * (pow(10, (11.344 * (1 - 1/RATIO ))) - 1) ;
        SUM += 8.1328e-3 * (pow(10, (-3.49149 * (RATIO - 1))) - 1) ;
        SUM += log10(1013.246);
        double VP = pow(10, SUM - 3) * humidity;
        double T = log(VP/0.61078);   // temp var
        return (241.88 * T) / (17.558 - T);
}
void heatindex(){  //indeks ciepła
  float temp_f = (gruntTemp*1.8)+32;
if (temp_f > 80.0)   //The heat index only works for temperatures  above 80°F 
{
  float heat_f = c1+c2*(temp_f)+c3*(WChumidity)+c4*(temp_f)*(WChumidity)+c5*(pow(temp_f,2))+c6*(pow(WChumidity,2))+c7*(pow(temp_f, 2))*(WChumidity)+c8*(temp_f)*(pow(WChumidity, 2))+c9*(pow(temp_f, 2))*(pow(WChumidity, 2));
  heatIndex = ((heat_f - 32)*5/9)*10;  //  converting to C and x10 to WC
  }
  else
{
  heatIndex = gruntTemp*10;
}
}
void windchill(){   // temperatura odczuwalna
float temp_f = (gruntTemp*1.8)+32;

if ((temp_f <50.0) && (average_kmh > 3.6)) //The wind chill only works for temperatures  below 50°F and wind speed above 3 mph. (10°C , 1 m/s)

{
 float chill_f =35.74+0.6215*temp_f-35.75*pow(average_kmh,0.16)+0.4275*temp_f*pow(average_kmh,0.16);
 t_odczuwal = ((chill_f - 32)*5/9)*10;  //  converting to C
}

else
{
  t_odczuwal = gruntTemp*10;
}
}
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
SOYER
Posts: 1186
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry

Post

Kolejna poprawiona wersja, poprawiłem/naprawiłem zapis do eepromu dodając funkcję EEPROM.commit() i rezygnując z suplowego :->setKeepStateInStorage(true);, dodatkowo dodałem zapis do pamięci średniej prędkości wiatru, oraz trochę przebudowałem ten szkic.

Code: Select all

#include <SuplaDevice.h>
#include <Timers.h>
#include <supla/sensor/DHT.h>
#include <supla/sensor/DS18B20.h>
#include <supla/network/esp_wifi.h>
#include <supla/sensor/general_purpose_measurement.h>
#include <supla/sensor/general_purpose_meter.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <supla/clock/clock.h> //int suplaClock.getYear(); getMonth(); getDay(); getDayOfWeek();1 - Sunday, 2 - Monday getHour(); getMin(); getSec();
#include <supla/storage/eeprom.h>
#include <EEPROM.h>

String jsonBuffer;

  Supla::ESPWifi wifi("xx");

char server [] = "https://api.weathercloud.net";
char IDKryry [] = "x";
char KeyKryry [] = "x";
  
#define dsPin 14 //D5
#define dhtPin 5 //D1
#define windPin 12 //D6
#define rainPin 2  //D4

Timer minuta;
Timer sekund1;
Timer sekund6;

int rai1h=0;
int rai24h=0;
bool r=0;
float mm1h=0;
float mm24h=0;
int WCpressure = 0;
int WChumidity = 0;
int WCgruntTemp = 0;
int WCpm25 = 0;
int WCpm10 = 0;
int WCpm1 = 0;
int WCaverage_kmh = 0;
int WCporyw_kmh = 0;
int WCmoment_kmh = 0;
float punkt_rosy;           // dew point (C)
float heatIndex;
float t_odczuwal; 
#define c1 (-42.379)
#define c2 (2.04901523)
#define c3 (10.14333127)
#define c4 (-0.22475541)
#define c5 (-0.00683783)
#define c6 (-0.05481717)
#define c7 (0.00122874)
#define c8 (0.00085282)
#define c9 (-0.00000199)

volatile int half_revolutions_time = 2; //Utworzenie zmiennej połowa pełnego obrotu (half revolutions)
volatile int rpm = 0;
unsigned long static  last_event = 0;
unsigned long static last_event1 = 0;
int sample = 0;
float moment_kmh;
float poryw_kmh;
float temp_kmh;
float correct_moment_kmh;
float average_kmh;
float pressure =0;
float gruntTemp =0;

Supla::Sensor::GeneralPurposeMeasurement *moment_wind = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *average_wind = nullptr;
Supla::Sensor::GeneralPurposeMeter *rain1h = nullptr;
Supla::Sensor::GeneralPurposeMeter *rain24h = nullptr;
Supla::Clock clock1;
Supla::Eeprom eeprom(100);
///////////////////////////////////////////////////////////////////////////////////////////////////////

void weathercloud(){
  int WCmm1h = mm1h *10;
  int WCmm24h = mm24h *10;

  String serverPathPM_pm1 = "https://svrx.supla.org/direct/x/x74/read?format=json";
  String serverPathPM_pm25 = "https://svrx.supla.org/direct/x/x/read?format=json";
  String serverPathPM_pm10 = "https://svrx.supla.org/direct/x/x/read?format=json";
  String serverPathGRUNT_temp = "https://svrx.supla.org/direct/x/x/read?format=json";
  String serverPathZEW_press = "https://svrx.supla.org/direct/x/x/read?format=json"; 
  String serverPathZEW_hum = "https://svrx.supla.org/direct/x/x/read?format=json";

punkt_rosy = (dewPoint(gruntTemp, WChumidity))*10;
heatindex();
windchill();

  String serverPathWC = String(server) + "/v01/set/wid/" + String(IDKryry) + "/key/" + String(KeyKryry) 
  + "/temp/" + String(WCgruntTemp) + "/hum/" + String(WChumidity) 
  + "/bar/" + String(WCpressure) + "/wspdavg/" + String(WCaverage_kmh) + "/wspdhi/" + String(WCporyw_kmh) 
  + "/wspd/" + String(WCmoment_kmh) + "/heat/" + String(heatIndex)
  + "/rainrate/" + String(WCmm1h) + "/dew/" + "/rain/" + String(WCmm24h) + "/dew/" 
  + String(punkt_rosy) + "/chill/" + String(t_odczuwal);
  // + "/pm25/" + String(WCpm25) + "/pm10/" + String(WCpm10);
  
  
String serverPath_aqi = "https://api.aqi.eco/update/xx"; 
      jsonBuffer = httpGET_PM_pm1(serverPathPM_pm1.c_str());
      jsonBuffer = httpGET_PM_pm25(serverPathPM_pm25.c_str());
      jsonBuffer = httpGET_PM_pm10(serverPathPM_pm10.c_str());
      jsonBuffer = httpGET_GRUNT_temp(serverPathGRUNT_temp.c_str());
      jsonBuffer = httpGET_ZEW_hum(serverPathZEW_hum.c_str());
      jsonBuffer = httpGET_ZEW_press(serverPathZEW_press.c_str());
      jsonBuffer = httpGETWC(serverPathWC.c_str());
      jsonBuffer = httpPOSTaqi(serverPath_aqi.c_str());
      
      Serial.println(jsonBuffer);
}
String httpGET_PM_pm1(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    WCpm1 = doc["value"]; 
    Serial.print("pm1:  ");
    Serial.println(WCpm1);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_PM_pm25(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    WCpm25 = doc["value"]; 
    Serial.print("pm2,5:  ");
    Serial.println(WCpm25);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_PM_pm10(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    WCpm10 = doc["value"]; 
    Serial.print("pm10:  ");
    Serial.println(WCpm10);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_GRUNT_temp(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    gruntTemp = doc["temperature"]; 
    if(gruntTemp > -273){
      WCgruntTemp = gruntTemp *10;
    }
    Serial.print("tempGrunt:  ");
    Serial.println(gruntTemp);
    Serial.print("tempGruntWC:  ");
    Serial.println(WCgruntTemp);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_ZEW_hum(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    WChumidity = doc["humidity"]; 
    Serial.print("humidityZewWC:  ");
    Serial.println(WChumidity);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_ZEW_press(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);  
    pressure = doc["value"]; 
    WCpressure = pressure *10;
    Serial.print("pressureWC:  ");
    Serial.println(WCpressure);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGETWC(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpPOSTaqi(const char* serverName) {
  
float AQIpressure = pressure*100;
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  http1.addHeader("Content-Type", "application/json");
  int httpResponseCode = http1.POST("{\"esp8266id\": \"123123123\",\"sensordatavalues\":[{\"value_type\":\"PMS_P0\",\"value\":" + String(WCpm1) + "},{\"value_type\":\"PMS_P2\",\"value\":" + String(WCpm25) + "}, {\"value_type\":\"PMS_P1\",\"value\":" + String(WCpm10) + "},{\"value_type\":\"BME280_temperature\",\"value\":" + String(gruntTemp) + "},{\"value_type\":\"BME280_humidity\",\"value\":" + String(WChumidity) + "},{\"value_type\":\"wind_speed\",\"value\":" + String(average_kmh) + "},{\"value_type\":\"rainfall\",\"value\":" + String(mm24h) + "},{\"value_type\":\"BME280_pressure\",\"value\":" + String(AQIpressure) + "}]}");

  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
double dewPoint(double tempc_min, double humidity){    //punkt rosy
  
        double RATIO = 373.15 / (273.15 + tempc_min);  // RATIO was originally named A0, possibly confusing in Arduino context
        double SUM = -7.90298 * (RATIO - 1);
        SUM += 5.02808 * log10(RATIO);
        SUM += -1.3816e-7 * (pow(10, (11.344 * (1 - 1/RATIO ))) - 1) ;
        SUM += 8.1328e-3 * (pow(10, (-3.49149 * (RATIO - 1))) - 1) ;
        SUM += log10(1013.246);
        double VP = pow(10, SUM - 3) * humidity;
        double T = log(VP/0.61078);   // temp var
        return (241.88 * T) / (17.558 - T);
}
void heatindex(){ // indeks ciepła
  float temp_f = (gruntTemp*1.8)+32;// stopnie C->F
if (temp_f > 80.0)   //The heat index only works for temperatures  above 80°F 
{
  float heat_f = c1+c2*(temp_f)+c3*(WChumidity)+c4*(temp_f)*(WChumidity)+c5*(pow(temp_f,2))+c6*(pow(WChumidity,2))+c7*(pow(temp_f, 2))*(WChumidity)+c8*(temp_f)*(pow(WChumidity, 2))+c9*(pow(temp_f, 2))*(pow(WChumidity, 2));
  heatIndex = ((heat_f - 32)*5/9)*10;  //  converting to C and x10 to WC
  }
  else
{
  heatIndex = gruntTemp*10;
}
}
void windchill(){    //temperatura odczuwalna
float temp_f = (gruntTemp*1.8)+32;    // stopnie C->F

if ((temp_f <50.0) && (average_kmh > 3.6)) //The wind chill only works for temperatures  below 50°F and wind speed above 3 mph. (10°C , 1 m/s)

{
 float chill_f =35.74+0.6215*temp_f-35.75*pow(average_kmh,0.16)+0.4275*temp_f*pow(average_kmh,0.16);
 t_odczuwal = ((chill_f - 32)*5/9)*10;  //  converting to C
}

else
{
  t_odczuwal = gruntTemp*10;
}
}

void ICACHE_RAM_ATTR rn(){// wektor przerwania deszczomierza
  unsigned long static last_event1 = 0;
  if (millis() - last_event1 < 50) {   //debouncing
    return;
  }
  rai1h++;
  EEPROM.write(1, rai1h);
  rai24h++;
  EEPROM.write(2, rai24h);
  last_event1 = millis();
  EEPROM.commit(); //zapis z RAM do eeprom
}
 void ICACHE_RAM_ATTR rpm_fan() { //funkcja rpm_fan
  if (millis() - last_event < 5) {   //debouncing
    return;
  }
  half_revolutions_time = (millis() - last_event);
  last_event = millis();
}
void count_and_send(){
    noInterrupts(); 
    if((last_event + 2000) < millis()){    
     rpm=0;
     moment_kmh = 0;
     correct_moment_kmh = 0;
    }
    else{ 
      rpm = (30000 / half_revolutions_time) ;
      moment_kmh = 6.28 * 0.075 * rpm/60.0 * 3.6;// pi x promień czujnika x rpm/60s x ms->km/h
      if(moment_kmh < 10){
        correct_moment_kmh = moment_kmh * 2.8; //prędkość chwilowa po korekcie
      }
      else if((moment_kmh >= 10) && (moment_kmh < 25)){
        correct_moment_kmh = moment_kmh * 2.7;
      }
      else if(moment_kmh >= 25){
        correct_moment_kmh = moment_kmh * 2.8;
      }
    } 
    interrupts() ;
    if(sekund1.available()){  
      moment_wind->setValue(correct_moment_kmh);
      if(poryw_kmh < correct_moment_kmh){
        poryw_kmh = correct_moment_kmh;
      }
      sekund1.restart();
    }
    if(sekund6.available()){
      temp_kmh = temp_kmh + correct_moment_kmh; //temp_kmh narastająca zmienna przez 10min
      sample++;
      sekund6.restart();
     }
    if(sample==100){// 100 x 6 sek = 10min
      noInterrupts(); 
      average_kmh = temp_kmh / 100; //średnia prędkość wiatru policzona ze 100 próbek
      temp_kmh = 0;
      sample=0;
      WCporyw_kmh=(poryw_kmh*10)/3.6;// poryw z 10min pomnozony razy 10dla WC i /3.6(m/s)dla weathercloud
      poryw_kmh=0;
      WCaverage_kmh = (average_kmh * 10) / 3.6; //km/h->m/s dla weathercloud
      WCmoment_kmh = (correct_moment_kmh*10)/3.6;//dla weathercloud
      average_wind->setValue(average_kmh);
      EEPROM.write(3, average_kmh);
      EEPROM.commit(); //zapis z RAM do eeprom
      interrupts() ; //Przywróć przerwania
      mm1h=rai1h*0.15; // dwa przerwnia na jedną kolebkę, więc 0.15
      mm24h=rai24h*0.15;
      rain1h->setValue(mm1h);
      rain24h->setValue(mm24h);
      weathercloud();
      sekund6.restart();
    }
}

void setup() {
  Serial.begin(9600);
  EEPROM.begin(32);
  delay(10);
   // Replace the falowing GUID with value that you can retrieve from https://www.supla.org/arduino/get-guid
  char GUID[SUPLA_GUID_SIZE] = {x};

  // Replace the following AUTHKEY with value that you can retrieve from: https://www.supla.org/arduino/get-authkey
  char AUTHKEY[SUPLA_AUTHKEY_SIZE] = {x};
    new Supla::Sensor::DS18B20(dsPin);
    new Supla::Sensor::DHT(dhtPin, DHT22);
    moment_wind = new Supla::Sensor::GeneralPurposeMeasurement();
    average_wind = new Supla::Sensor::GeneralPurposeMeasurement();
    rain1h = new Supla::Sensor::GeneralPurposeMeter();
    rain24h = new Supla::Sensor::GeneralPurposeMeter();
    auto clock1 = SuplaDevice.getClock();
  rai1h=EEPROM.read(1);
  rai24h=EEPROM.read(2);
  mm1h=rai1h*0.15; // dwa przerwnia na jedną kolebkę, więc 0.15
  mm24h=rai24h*0.15;
  rain1h->setValue(mm1h);
  rain24h->setValue(mm24h);
  average_kmh=EEPROM.read(3);
  average_wind->setValue(average_kmh);
  Serial.println("EEPROM Rain value");
  Serial.print("rai1h VALUE FROM EEPROM:  ");
  Serial.print(rai1h);
  Serial.println(" mm");
  Serial.print("rai24h VALUE FROM EEPROM:  ");
  Serial.print(rai24h);
  Serial.println(" mm");
  Serial.print("average_kmh VALUE FROM EEPROM:  ");
  Serial.print(average_kmh);
  Serial.println(" km/h");
    pinMode(windPin,INPUT_PULLUP);
    pinMode(rainPin,INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(rainPin), rn, RISING); 
    attachInterrupt(digitalPinToInterrupt(windPin), rpm_fan, FALLING);
    minuta.begin(59999);
    sekund6.begin(6001);
    sekund1.begin(1000);
    last_event = millis();
    last_event1 = millis();
 
       SuplaDevice.begin(GUID,              // Global Unique Identifier 
                    "svrx.supla.org",  // SUPLA server address
                    "x@wp.pl",   // Email address used to login to Supla Cloud
                    AUTHKEY);          // Authorization key
}

void loop() {
    SuplaDevice.iterate();
    count_and_send();
    midnight();
}

void midnight(){
    if(minuta.available()){ 
      if(clock1.getMin()==59){
        rai1h=0;
        EEPROM.write(1, rai1h);
        EEPROM.commit(); //zapis z RAM do eeprom
        Serial.println("Reset Hourly Rain");
      }
      if((clock1.getHour()==23) && (clock1.getMin()==59)){
        rai1h=0;
        rai24h=0;
        EEPROM.write(1, rai1h);
        EEPROM.write(2, rai24h);
        EEPROM.commit(); //zapis z RAM do eeprom
        Serial.println("Reset Hourly Rain");
        Serial.println("Reset Daily Rain");
      }
      minuta.restart();
    }   
}
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603

Return to “Projekty użytkowników”