2020-02-01

Esp8266 Windsensor TX23 als Arduino Tab.

TX23.ino

// ****************************************************************
// Sketch Esp8266 TX23 Windgeschwindigkeit- und Richtung Modular(Tab)
// Include FIFO Puffer for Hour, Day, Week
// created: Jens Fleischer, 2019-12-09
// last mod: Jens Fleischer, 2020-02-01
// For more information visit: https://fipsok.de
// ****************************************************************
// Hardware: Esp8266, TX23
// Braun (Schwarz) DATA an D2
// Red an Vcc
// Grün --
// Gelb an GND
// Software: Esp8266 Arduino Core 2.4.2 / 2.5.2 / 2.6.3
// Getestet auf: Nodemcu
/******************************************************************
  Copyright (c) 2019 Jens Fleischer. All rights reserved.

  This file is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.
  This file is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
*******************************************************************/
// Diese Version vom Windsensor sollte als Tab eingebunden werden.
// #include <WebServer.h> muss im Haupttab aufgerufen werden
// Die Funktionalität des ESP8266 Webservers ist erforderlich.
// Die Funktion "tx23();" muss im Setup aufgerufen werden.
// Zum speichern muss die Funktion "tx23Read();" im loop(); aufgerufen werden.
/**************************************************************************************/

#include <LaCrosse_TX23.h>                                            // https://github.com/egzumer/Arduino-LaCrosse-TX23-Library

LaCrosse_TX23 anemometer = LaCrosse_TX23(D2);                         // Pin anpassen

template <typename T, size_t size> T maxRead(T (&arr)[size]) {
  T maxValue {arr[0]};
  for (auto &value : arr) maxValue = max(maxValue, value);            // max Wert aus Array ermitteln
  return maxValue;
}

template <typename T, size_t size> T averageRead(T (&arr)[size]) {
  double average {0};
  for (auto &value : arr) average += static_cast<double>(value) / size;            // Durchschnitt aus Array berechnen
  return std::numeric_limits<T>::is_integer ? round(average) : average;
}

float fifoHour[60], fifoMaxHour[60], fifoDay[24], fifoMaxDay[24], fifoWeek[7], fifoMaxWeek[7];   // Fifo Puffer

void tx23() {                                                         // Funktionsaufruf "tx23();" muss im Setup eingebunden werden
  server.on("/tx23", []() {
    server.send(200, "application/json", tx23Read());
  });
}

const char* tx23Read() {                                              // Funktionsaufruf "tx23Read();" muss im Loop eingebunden werden
  static char buf[63];
  static bool correct {0};
  static float maxSpeed {0}, speedValue {0}, speed;
  static uint8_t numberOfValue {0}, indexHour {0}, indexDay {0}, indexWeek {0}; // Index Fifo Puffer
  static int32_t direction;
  static uint32_t letzteMillis {0}, letzteMillisMin {0};
  auto aktuelleMillis = millis();
  if (aktuelleMillis - letzteMillis >= 3e3) {                         // aller 3 Sekunden
    letzteMillis = aktuelleMillis;
    if ((correct = anemometer.read(speed, direction))) {              // Sensor auslesen
      maxSpeed = max(maxSpeed, speed);                                // max Wert ermitteln
      speedValue += speed;
      numberOfValue++;
    }
  }
  if (aktuelleMillis - letzteMillisMin >= 6e4) {                      // jede Minute
    letzteMillisMin = aktuelleMillis;
    fifoHour[indexHour] = speedValue / numberOfValue;                 // 60 min Puffer Durchschnitt übergeben
    fifoMaxHour[indexHour] = maxSpeed;                                // 60 min Puffer max Wert übergeben
    ++indexHour = indexHour % (sizeof fifoHour / sizeof fifoHour[0]); // 60 min Puffer Zeiger im Puffer vorrücken
    maxSpeed = 0;                                                     // maxSpeed zurücksetzen
    speedValue = 0;                                                   // Durchschnitt zurücksetzen
    numberOfValue = 0;                                                // Zähler zurücksetzen
    if (indexHour == 0) {
      ++indexDay = indexDay % (sizeof fifoDay / sizeof fifoDay[0]);         // 24 hour Puffer Zeiger im Puffer vorrücken
    }
    fifoDay[indexDay] = averageRead(fifoHour);                              // 24 hour Puffer Durchschnitt übergeben
    fifoMaxDay[indexDay] = maxRead(fifoMaxHour);                            // 24 hour Puffer max Wert übergeben
    if (indexHour == 0 && indexDay == 0) {
      const byte fifoSize = sizeof fifoWeek / sizeof fifoWeek[0];
      static byte fill {0};                                                 // In der ersten Woche das Array auffüllen
      if (fill < fifoSize) for (byte i = fill++; i < fifoSize; i++)fifoWeek[i] = averageRead(fifoDay);
      ++indexWeek = indexWeek % fifoSize;                                   // 7 day Puffer Zeiger im Puffer vorrücken
    }
    fifoWeek[indexWeek] = averageRead(fifoDay);                             // 7 day Puffer Durchschnitt übergeben
    fifoMaxWeek[indexWeek] = maxRead(fifoMaxDay);                           // 7 day Puffer max Wert übergeben
  }
  snprintf(buf, sizeof(buf), R"(["%d","%.1f","%.1f","%.1f","%.1f","%.1f","%.1f","%.1f"])",
           direction, speed, averageRead(fifoHour), maxRead(fifoMaxHour), averageRead(fifoDay), maxRead(fifoMaxDay), averageRead(fifoWeek), maxRead(fifoMaxWeek));
  return correct ? buf : "[\"nan\"]";
}

Zurück