Windsensor TX20 mit ESP8266

Update am 28.05.2018 (Rot gekennzeichnet)

Heute nochmal was zum Thema Hausautomatisierung bzw. Messung von Umweltdaten.

Von Homematic gibt es eine komplette Wetterstation die wahrscheinlich ohne größeres Zutun in meine bestehende FHEM-Installation integriert werden kann. Allerdings ist das Ding recht teuer und schaut dafür noch nach viel Plastik aus. Auf der Suche nach einem günstigeren Windsensor bin ich über den TechnoLine TX20 gestolpert (auch Plastik, aber weniger und preislich günstiger). Diesen gibt es ab 30€ im Netz. Allerdings ist der Sensor zum kabelgebundenen Anschluss an eine Wetterstation gedacht (z.B. WS 2300, WS 2307, WS 2350).

Ich wollte meinen zukünftigen Windsensor aber irgendwie kabellos in meine bestehende Infrastruktur integrieren, entweder per Funk oder per WLAN. Da ich noch ein paar ESP8266 von der letzten China-Bestellung im Keller liegen hatte, habe ich mich auf die Suche nach der Anbindung des TX20 Windsensors an den ESP8266 gemacht. Im ersten Schritt half die folgende Webseite wo der Kollege aus Neuseeland viel Arbeit in die Auswertung des Kommunikationsprotokoll des TX20 gesteckt hat:

La Crosse TX20 Anemometer Communication Protocol

Die Integration des oben herausgefundenen Protokolls des TX20 für den ESP8266 ist auf folgender Webseite zu finden: http://fabrizio.zellini.org/decoding-la-crosse-tx20-anemometer-with-arduino. Das Beispielscript von dieser Seite kann man direkt mittels Arduino IDE auf den ESP8266 laden. Wie das funktioniert und was sonst noch so beim ESP zu beachten ist, findet man unter anderem in diesem Heise-Artikel.

In dem Beispielscript fehlte für meine Zwecke nur noch die WLAN-Funktionalität und eine komfortable Möglichkeit an die Messdaten für die weitere Nutzung zu gelangen. Das unten stehende angepasste Script ermöglicht beides. Aber zuerst ein paar Worte über die Anpassungen:

Integration von WLAN

Die Zugangsdaten für ein bestehendes WLAN werden fest im Code eingegeben. Der ESP verbindet sich mit diesem ein paar Sekunden nach Anschluss der Betriebsspannung. Die Konfiguration der WLAN-Zugangsdaten über einen vom ESP erstellten Access Point (AP) ist noch nicht implementiert (siehe Todo).

Zugriff auf Messdaten

Ich hatte drei Möglichkeiten zum Zugriff auf die Messdaten implementiert. Im Beispielscript sind alle Möglichkeiten aktiv. Das Script sollte also entsprechend des genutzten Zugriffes auf die Messdaten angepasst werden.

1. Webseite

Darstellung der Webseite nur im alten Script!

Zum einen stellt der ESP8266 nun eine einfache Webseite zur Verfügung. Neben der Windgeschwindigkeit und der Windrichtung werden auch noch verschiedene andere Daten des ESP8266 ausgelesen und dargestellt. Unter anderem auch die Betriebsspannung des Mikrocontrollers welche beim Betrieb mit Batterien auf deren Zustand zurück schließen lässt. Die Seite einfach im Webbrowser mittels IP oder Hostnamen des ESP8266 öffnen.

2. JSON

Implementierung von JSON nur im alten Script!

Um die Daten einfacher automatisiert weiter verarbeiten zu können, wird beim Anhängen von /json an die URL ein JSON-String zurück geliefert. Dieser schaut wie folgt aus:

{“Windgeschwindigkeit”:61,”Windrichtung”:2}

Mit PHP funktioniert das Auswerten des JSON-Strings wie folgt. Solch ein Script könnte z.B. zeitgesteuert per Cronjob aufgerufen werden und die extrahierten Daten in eine Datenbank schreiben oder anderweitig darauf reagieren.

[cclN_php]
$windrichtung=$json_ergebnis->Windrichtung;

// hier kann die weitere Verarbeitung der Daten erfolgen…
?>
[/cclN_php]

 

3. Scriptaufruf durch den ESP8266

Die beiden oberen Varianten bedürfen einen aktiven Aufruf durch einen Client (Webbrowser) oder den Aufruf der Webseite durch ein Script. Nachteil dieser Variante ist, das der ESP immer aktiv sein muss da er den Zeitpunkt der Abfrage nicht kennt. Um Strom zu sparen ist eine aktive Datenübermittlung durch den ESP vorteilhafter. D.h der ESP kann in definierten Intervallen messen, die Daten übermitteln und sich wieder schlafen legen. Die aktive Übermittlung der Daten wird durch den Aufruf einer Webseite (die auf einem Server hinterlegt ist) durch den ESP realisiert. Der entsprechende Host (Zeile 8) und URL (Zeile 235) sind im Programm für den ESP fest hinterlegt.

Hier ein beispielhaftes PHP-Script welches auf einem Webserver liegt und durch den ESP aufgerufen wird, die Daten auswertet und diese dann in eine Textdatei auf dem Server schreibt:

Update am 28.05.2018 (nur für neues ESP-Script mit Boe-Funktion)

<?php
//*************************
// Uebergebene Daten des
// ESP-Aufrufes auslesen
//*************************
$windgeschwindigkeit=$_GET["windgeschwindigkeit"];
$windgeschwindigkeit=$windgeschwindigkeit/10*3.6;
$windrichtung=$_GET["windrichtung"];
$boe=$_GET["boe"];
$boe=$boe/10*3.6;
$vcc=$_GET["vcc"];

//*************************
// Werte in Datei schreiben
//*************************
$datum = date("d.m.Y H:i");
$handle = fopen ('tmp/wind.txt', 'a');
fwrite ($handle, $datum.",".$windgeschwindigkeit.",".$windrichtung.",".$boe.",".$vcc."\n");
fclose ($handle);
?>

 

Hier nun das Programm für den ESP8266

Update am 28.05.2018 mit Boe-Funktion und ohne eigene Webseite & ohne JSON

#include <ESP8266WiFi.h>
#include <WiFiManager.h>

#define DEBUG true

// WLAN Zugangsdaten
const char* ssid      = "<ssid_eingeben>";
const char* password  = "<passwort_eingeben>";
// Host wo Daten hingesendet werden soll
const char* datahost  = "<ip_des_hosts>";

unsigned long previousMillis = 0;
const long interval = 600000; // 600000ms = 10 Minuten Intervall

WiFiServer server(80);
ADC_MODE(ADC_VCC);

const byte DATAPIN=2;
volatile boolean TX20IncomingData = false;

unsigned char chk;
unsigned char sa,sb,sd,se;
unsigned int sc,sf,pin;
String tx20RawDataS = "";

int boe=0;
// Zaehlerfür Mittelwert
int counter=0;
long summe=0;
float mittelw=0;
String mittelw2string = "";

void isTX20Rising() {
  if (!TX20IncomingData) {
    TX20IncomingData = true;
  }
}


// Verbindung zum WLAN aufbauen
void verbinden() {
  if(DEBUG) {
    delay(10);
    Serial.println("");
    Serial.print(F("Verbinde zu WLAN-Netzwerk '"));
    Serial.print(ssid);
    Serial.print("' ");
  }
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
 
  if(DEBUG) {
    Serial.println(F("-> Verbunden"));  
    Serial.print(F("IP-Adresse: "));
    Serial.print(WiFi.localIP());
    Serial.println("");
  }
  //sendData();
}


void setup() {
  boe=0;
  pinMode(DATAPIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(DATAPIN), isTX20Rising, RISING);
  Serial.begin(115200);
  delay(10);
  
  Serial.println();
  Serial.println();
  
  verbinden();
}


boolean readTX20() {
  int bitcount=0;
  
  sa=sb=sd=se=0;
  sc=0;sf=0;
  tx20RawDataS = "";

  for (bitcount=41; bitcount>0; bitcount--) {
    pin = (digitalRead(DATAPIN));
    if (!pin) {
      tx20RawDataS += "1";      
    } else {
      tx20RawDataS += "0";      
    }
    if ((bitcount==41-4) || (bitcount==41-8) || (bitcount==41-20)  || (bitcount==41-24)  || (bitcount==41-28)) {
      tx20RawDataS += " ";
    }      
    if (bitcount > 41-5){
      // start, inverted
      sa = (sa<<1)|(pin^1);
    } else
    if (bitcount > 41-5-4){
      // wind dir, inverted
      sb = sb>>1 | ((pin^1)<<3);
    } else
    if (bitcount > 41-5-4-12){
      // windspeed, inverted
      sc = sc>>1 | ((pin^1)<<11);
    } else
    if (bitcount > 41-5-4-12-4){
      // checksum, inverted
      sd = sd>>1 | ((pin^1)<<3);
    } else 
    if (bitcount > 41-5-4-12-4-4){
      // wind dir
      se = se>>1 | (pin<<3);
    } else {
      // windspeed
      sf = sf>>1 | (pin<<11);
    } 
        
    delayMicroseconds(1200);    
  }
  chk= ( sb + (sc&0xf) + ((sc>>4)&0xf) + ((sc>>8)&0xf) );chk&=0xf;
  delayMicroseconds(2000);
  TX20IncomingData = false;  

  if (sa==4 && sb==se && sc==sf && sd==chk){      
    return true;
  } else {
    return false;      
  }
}


void loop() {

  if (TX20IncomingData) {

    char a[90];
    boolean validData = readTX20();
    Serial.println(tx20RawDataS);
    sprintf(a, "ID: %d\t%d\n", sa, B00100);
    Serial.write (a);
    sprintf(a, "Windrichtung: %d\t%d\n", sb, se);
    Serial.write (a);
    sprintf(a, "Windgeschwindigkeit: %d\t%d\n", sc, sf);
    Serial.write (a);

    // #################################################################
    // boe feststellen
    // Speichert den Maximalwert eines Messzyklus in der variablen boe
    // #################################################################
    if (sc>boe){
      boe=sc;
    }
    if (boe>1000){
      boe=0;
    }
    Serial.write("Windboe= ");
    Serial.println(boe);
    
    // 4095 im eeprom ??
    if (sc>1000){
      sc=0;
    }
    
    // #####################################################
    // Zur Mittelwertberechnung durchschnittlichen 
    // Windgeschwindigkeit während des Messzyklus
    // 8 Messwerte pro Minute
    // #####################################################
    counter = counter +1;
    Serial.write("Messinterval= ");
    Serial.println(counter);
    summe=summe+sc;
    float mittelw = summe/counter;
    
    mittelw2string = String(mittelw);
    Serial.write("Summe aller Messwerte = ");
    Serial.println(summe);
    Serial.write("Mittelwert= ");
    Serial.println(mittelw2string);
      
    sprintf(a, "Pruefsumme: %d\t%d\n", sd, chk);
    Serial.write (a);
    if (validData){
      Serial.println("OK");
    } else {
      Serial.println("Fehler");
    }
    Serial.println("");

  }  

  unsigned long currentMillis = millis();   
  if(currentMillis - previousMillis >= interval) 
  {
    previousMillis = currentMillis;
    sendData();
    counter=0;
    summe=0;
    boe=0;
  }
  
}


// Verbindung zu Host herstellen und Sensordaten übermitteln
void sendData() 
{
  Serial.println("");
  Serial.print(F("Verbinde zu '"));
  Serial.print(datahost);
  Serial.print("'");
   
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(datahost, httpPort)) {
    Serial.println(F(" Fehler beim Verbinden zum Host"));
    return;
  }

  // Batteriespannung auslesen
  float vcc = ESP.getVcc() / 1000.0;

 
  String url = "/umwelt/windsensor.php";
  url += "?windgeschwindigkeit=";
  url += mittelw2string;
  url += "&windrichtung=";
  url += sb;
  url += "&boe=";
  url += boe;
  url += "&vcc=";
  url += vcc;

  Serial.println("");
  Serial.print("URL-Anfrage: ");
  Serial.println(url);
   
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + datahost + "\r\n" + 
               "Connection: close\r\n\r\n");
  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      Serial.println("[Client Timeout]");
      client.stop();
      return;
    }
  }
   
  // Lese alle Daten aus der Antwort des Servers
  while(client.available()){
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }
  Serial.println("");
  Serial.print(F("Verbindung zu '"));
  Serial.print(datahost);
  Serial.println(F("' beendet."));
}

 

Altes Script:

#include <ESP8266WiFi.h>
#include <WiFiManager.h>


// WLAN Zugangsdaten
const char* ssid      = "<ssid>";
const char* password  = "<passwort>";
// Host wo Daten hingesendet werden soll
const char* datahost  = "<ip_des_hosts>";


unsigned long previousMillis = 0;  
//const long interval = 30000;       // 30sek Interval beim Senden
const long interval = 60000;       // 1min Interval beim Senden


WiFiServer server(80);
ADC_MODE(ADC_VCC);

const byte DATAPIN=2;
volatile boolean TX20IncomingData = false;

unsigned char chk;
unsigned char sa,sb,sd,se;
unsigned int sc,sf, pin;
String tx20RawDataS = "";

int boe=0;
int counter=0;
long summe=0;
float mittelw=0;
String mittelw2string = "";


void isTX20Rising() {
  if (!TX20IncomingData) {
    TX20IncomingData = true;
  }  
}

void setup() {
  //boe=0;
  pinMode(DATAPIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(DATAPIN), isTX20Rising, RISING);
  Serial.begin(115200);
  delay(10);
  
  Serial.println();
  Serial.println();

  Serial.println("Los geht es...");
  Serial.println();

  WiFiManager wifiManager;

  // AP deaktivieren
  WiFi.softAPdisconnect();
  WiFi.disconnect();
  WiFi.mode(WIFI_STA);
  delay(100);
  
  Serial.print("Verbindung zu... ");
  Serial.println(ssid);  
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi verbunden");
  server.begin();
  Serial.println("Server gestartet");
  Serial.println(WiFi.localIP());
}

boolean readTX20() {
    int bitcount=0;
    
    sa=sb=sd=se=0;
    sc=0;sf=0;
    tx20RawDataS = "";

    for (bitcount=41; bitcount>0; bitcount--) {
      pin = (digitalRead(DATAPIN));
      if (!pin) {
        tx20RawDataS += "1";      
      } else {
        tx20RawDataS += "0";      
      }
      if ((bitcount==41-4) || (bitcount==41-8) || (bitcount==41-20)  || (bitcount==41-24)  || (bitcount==41-28)) {
        tx20RawDataS += " ";
      }      
      if (bitcount > 41-5){
        // start, inverted
        sa = (sa<<1)|(pin^1);
      } else
      if (bitcount > 41-5-4){
        // wind dir, inverted
        sb = sb>>1 | ((pin^1)<<3);
      } else
      if (bitcount > 41-5-4-12){
        // windspeed, inverted
        sc = sc>>1 | ((pin^1)<<11);
      } else
      if (bitcount > 41-5-4-12-4){
        // checksum, inverted
        sd = sd>>1 | ((pin^1)<<3);
      } else 
      if (bitcount > 41-5-4-12-4-4){
        // wind dir
        se = se>>1 | (pin<<3);
      } else {
        // windspeed
        sf = sf>>1 | (pin<<11);
      } 
          
      delayMicroseconds(1200);    
    }
    chk= ( sb + (sc&0xf) + ((sc>>4)&0xf) + ((sc>>8)&0xf) );chk&=0xf;
    delayMicroseconds(2000);  // just in case
    TX20IncomingData = false;  

    if (sa==4 && sb==se && sc==sf && sd==chk){      
      return true;
    } else {
      return false;      
    }
}

void loop() {
 
  if (TX20IncomingData) {
    char a[90];
    boolean validData = readTX20();
    Serial.println(tx20RawDataS);
    sprintf(a, "ID: %d\t%d\n", sa, B00100);
    Serial.write (a);
    sprintf(a, "Windrichtung: %d\t%d\n", sb, se);
    Serial.write (a);
    sprintf(a, "Windgeschwindigkeit: %d\t%d\n", sc, sf);
    Serial.write (a);
    
    // #################################################################
    // Boe feststellen
    // Speichert den Maximalwert eines Messzyklus in der variablen boe
    // #################################################################
    if (sc>boe){
      boe=sc;
    }
    if (boe>1000){
      boe=0;
    }
    Serial.write("Windboe= ");
    Serial.println(boe);
    
    // 4095 im eeprom ??
    if (sc>1000){
      sc=0;
    }

    // ############################################################
    // Mittelwertberechnung 
    // Durchschnittliche Windgeschwindigkeit während des Messzyklus
    // 8 Messwerte pro Minute
    // ############################################################
    counter = counter +1;
    Serial.write("Messinterval= ");
    Serial.println(counter);
    summe=summe+sc;
    float mittelw = summe/counter;
    
    mittelw2string = String(mittelw);
    Serial.write("summe aller Messwerte = ");
    Serial.println(summe);
    Serial.write("Mittelwert= ");
    Serial.println(mittelw2string);


    sprintf(a, "Pruefsumme: %d\t%d\n", sd, chk);
    Serial.write (a);
    if (sd=chk){      
      Serial.println("OK");
    } else {
      Serial.println("Fehler");
      
    }
    Serial.println("");


    // Pruefen ob sich ein Client verbunden hat
    WiFiClient client = server.available();
    if (!client) {
      return;
    }
    
    // Warten bis der Client Daten sendet
    Serial.println("neuer Client");
    while(!client.available()){
      delay(1);
    }

    // Lese die erste Zeile der Anfrage
    String req = client.readStringUntil('\r');
    Serial.println(req);
    client.flush();

    // WIFI Signalstaerke auslesen
    long rssi = WiFi.RSSI();
    Serial.print("RSSI:");
    Serial.println(rssi);

    // Batteriespannung auslesen
    float vcc = ESP.getVcc() / 1000.0;


    // Webseite aufrufen um Sensordaten zu übergeben
    unsigned long currentMillis = millis();  
    if(currentMillis - previousMillis >= interval && sc >= 5000) 
    {
      previousMillis = currentMillis;
      sendData();
    }

    
    // Anfrage beantworten
    int val;
    String content;
    if (req.indexOf("/json") != -1) {
      // Sensordaten als JSON zurueck liefern
      // http://<url_zum_esp>/json
      Serial.println("JSON");
      content = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n";
      content += "{\"Windgeschwindigkeit\":";
      content += sc;
      content += ",\"Mittelwert\":";
      content += mittelw2string;
      content += ",\"Boe\":";
      content += boe;
      content += ",\"Windrichtung\":";
      content += sb;
      content += "}\n";
    } else {
      // Sensordaten als Webseite anzeigen
      Serial.println("HTML");
      content = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html><head><title>Windsensor</title></head><body style=\"font-family:verdana;\">\r\n";
      content += "<p style='font-size:18px;font-weight:bold;'>Windsensor</p><br>";
      content += "<table>";
      content += "<tr><td>Windgeschwindigkeit (aktuell)</td><td>";
      content += sc;
      content += "</td></tr><tr><td>Windgeschwindigkeit (Mittelwert)</td><td>";
      content += mittelw2string;
      content += "</td></tr><tr><td>Windgeschwindigkeit (Boe)</td><td>";
      content += boe;
      content += "</td></tr><tr><td>Windrichtung</td><td>";
      content += sb;
      content += "</td></tr>";
      content += "<tr><td><br></td><td></td></tr>";
      content += "<tr><td>WIFI-Signal</td><td>";
      content += rssi;
      content += " dBm</td>";
      content += "<tr><td>Signal Qualit&auml;t</td><td>";
      content += 2 * (rssi + 100);
      content += "%</td></tr>";
      content += "<tr><td>Batteriespannung</td><td>";
      content += vcc;
      content += " V</td></tr>";
      content += "</table>";
      content += "</body></html>\n";
    }
   
    // Senden der Antwort zum Webserver
    client.print(content);
    delay(1);
    Serial.println("Client Verbindung beendet");
    
  }
  
}

// Verbindung zu Server herstellen und Sensordaten übermitteln
void sendData() 
{
  
  if ( WiFi.status() != WL_CONNECTED ) {
    Serial.println ("kein connect –> reconnect");
  
    Serial.print("Verbinden zu ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
      WiFi.hostname("ESP-wind");
      delay(500);
      Serial.print(".");
    }
  }


  
  Serial.println("");
  Serial.print(F("Verbinde zu '"));
  Serial.print(datahost);
  Serial.print("'");
   
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(datahost, httpPort)) {
    Serial.println(F(" Fehler beim verbinden zum Host"));
    return;
  }
 
  String url = "/umwelt/windsensor.php";
  url += "?windgeschwindigkeit=";
  url += sc;
  url += "&windrichtung=";
  url += sb;
 
  Serial.print("URL-Anfrage: ");
  Serial.println(url);
   
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + datahost + "\r\n" + 
               "Connection: close\r\n\r\n");
  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      Serial.println("[Client Timeout]");
      client.stop();
      return;
    }
  }
   
  // Read all the lines of the reply from server and print them to Serial
  while(client.available()){
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }
  Serial.println("");
  Serial.print(F("Verbindung zu '"));
  Serial.print(datahost);
  Serial.println(F("' beendet."));
}

 

Die vom Sensor ausgelesenen Werte müssen noch “konvertiert” werden. Auf der Seite von John ist eine entsprechende Tabelle zur Umwandlung der 15 nummerischen Werte für die Windrichtung in deren “Himmelsrichtungen”, als auch die Einheit der Windgeschwindigkeit zu finden.

Aufbau

Anstatt einer Freiluftverdrahtung habe ich diesmal eine kleine Platine zur Aufnahme des ESP, einer Steckerleiste für den FTDI (oder für den Batteriehalter) sowie den Anschluss des Windsensors gelötet. Aktuell hängt es noch an der “langen Leine” durchs geschlossene Fenster, später soll die Platine aber in ein Kistchen in die Nähe des Sensors. Der Jumper setzt den GPIO_0 zum programmieren des ESP auf Masse. WICHTIG: Das FTDI muss 3,3V unterstützen da der ESP keine 5V verträgt.

Das Ganze dann nochmal von unten…

…und der schematische Aufbau zum Anschluss des FTDI an den ESP

Der Anschluss des Windsensors ist wie folgt (den ursprünglichen Western-Stecker am Windsensor habe ich abgeschnitten):

Anschluss Windsensor
GelbMasse (GND)
GrünMasse (DTR)
Rot3,3V (Vcc)
SchwarzGPIO_2 (TxD)

Ist der grüne Anschluss (DTR) auf Masse gelegt, sendet der Sensor alle zwei Sekunden Daten. Das kann bzgl. des Stromverbrauchs und dem Ansatz unter Punkt 3) evtl. noch auf einen GPIO des ESP gelegt werden.

Wofür das Ganze?

Weil es Spaß gemacht hat! Einen wirklichen Einsatz für den Windsensor habe ich noch nicht. Eigentlich war das nur die Gelegenheit, etwas mit dem ESP experimentieren zu können. Vielleicht steuere ich damit später mal die aktuell noch nicht vorhandene Markise oder ich weiß wie stark der Wind war, wenn nochmal unser Sonnenschirm von einer Windhose zerstückelt wird.

Probleme

  • Wenn die Betriebsspannung sinkt bzw. nicht genug Strom geliefert wird (z.B. beim Betrieb an Batterien), sind die Messdaten nicht korrekt (Prüfsumme falsch)

Todo

  • Sensor schlafen legen
  • Mit Batterieversorgung experimentieren
  • Update mittels OTA
  • WLAN-Konfig über Access Point (AP), dann Station (STA) einrichten
  • Konfiguration des URL zur aktiven Übergabe der Daten über Webseite

 

53 Gedanken zu „Windsensor TX20 mit ESP8266

  • 3. Juli 2017 um 20:44 Uhr
    Permalink

    hallo,
    ich bin gerade durch deinen Heizungsbeitrag (Viesmann darstellung auf Website) auf diesen Projekt gestossen und vielen Dank für die Erläuterung!
    ich habe heute zufällig erstmals von dem ESP8266 gehört und gelesen (in anderem zusammenhang) und habe deshalb gleich drauf geklickt! 🙂

    ich möchte bei uns messen wie stark der Wind ist um herauszufinden ob es sich lohnt ein kleines Windrad aufzubauen, daher ist dein Ansatz sehr gut für mich (weil er kostengünstig und digital auswertbar ist).

    ich setze z.B. als Hausautomationsoberfläche “Openhab” ein, wo sich viele Geräte unter einer Oberfläche “zusammenfinden” können und per sogenannten Rules verarbeitet werden können.
    Dort gibt es auch eine REST-API, welches es ermöglicht externe Daten in die Variablen (ITEMS genannt) einspielen kann. Ich werde sobald möglich mal deinen Ansatz versuchen aufzunehmen und in mein Openhab zu bringen.

    Ich bin gerade dabei die Viessmann Heizung darein zu bringen…

    Also weiter so! 🙂
    Liebe Grüße

    Antwort
  • 8. Oktober 2017 um 18:45 Uhr
    Permalink

    Hallo,
    ich nochmal…
    ich habe jetzt einen ESP8266 (D1 mini) und den TX20 da.
    Ich kam soweit das ich den Wemos D1 mini per Arduino (v 1.8.5) beschreiben kann (wie im Heise Beitrag konnte ich Blink Schreiben und ausführen).
    Aber wenn ich dein Script kompilieren möchte bricht er 3x ab mit den Fehler:
    error: expected ‘;’ before ‘Windgeschwindigkeit’
    Zeile 180: content += “{“Windgeschwindigkeit”:”;
    error: expected ‘;’ before ‘Windrichtung’
    Zeile 182: content += “,”Windrichtung”:”;
    error: expected ‘;’ before ‘font’
    Zeile 188: content = “HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n\r\nWindsensor\r\n”;

    Wenn ich die 3 Zeile mit // auskommentiere komme keine Fehler, er kompiliert und läd auch hoch, aber im D1 mini geschieht einfach nichts (ich sehe in der FritzBox keinen WLAN-Connect, beim einschalten blinkt kurz die LED)

    Ich komme nicht weiter, ggf. kannst du mir helfen?
    Im Kontakt habe ich meine E-Mailadresse eingetragen.
    Ich würde mich über eine kurze Nachricht freuen! 🙂
    Vielen Dank!

    Antwort
    • 12. Oktober 2017 um 16:43 Uhr
      Permalink

      Oh man ,sorry… Anscheinend war mein WLAN Passwort einfach zu sicher wegen Sonderzeichen, testweise im Gäste WLAN mit niedrigstem Passwort standard angemeldet und schwups konnte sich der ESP verbinden und ich die Website aufrufen.
      Danke für die tolle Idee und Umsetzung! Super Projekt

      Antwort
      • 6. Dezember 2017 um 16:01 Uhr
        Permalink

        hallo
        habe die gleichen fehlermeldungen wie oliver
        habe noch keinen windsensor dran
        im serial terminal sehe ich wifi connected und die ip
        kann die ip im browser nicht connecten
        benötige da einen tipp
        gruß
        meinolf

        Antwort
        • 6. Dezember 2017 um 16:11 Uhr
          Permalink

          Hallo Meinolf,

          vermutlich ist das Problem der fehlende Sensor. Im Code kommt irgendwann die “if (TX20IncomingData)”-Abfrage.
          D.h. dort wird nur reingesprungen wenn auch Daten vom Sensor kommen. Innerhalb dieser if-Abfrage wird die kleine Webseite zusammen gebaut und die Daten an den Client gesendet.

          Gruß
          Chris

          Antwort
  • 3. Januar 2018 um 12:15 Uhr
    Permalink

    Hallo,

    vielen Dank für die Anleitung. Meine Basisstation ist leider defekt und so habe ich den Windsensor über.
    Ich habe ein NodeMCU V3 Board gekauft und die IDE von Arduino (V1.8.5) auf meinem Windows Rechner installiert. Wenn ich nun des Sketch kompilieren möchte, bekomme ich die Meldung, dass er die Bibliothek nicht finden kann.
    Woher bekomme ich diese Bibliothek?

    Grüße
    Markus

    Antwort
    • 3. Januar 2018 um 16:33 Uhr
      Permalink

      Hallo Markus,

      meinst Du die beiden Bibliotheken #include ESP8266WiFi.h und WiFiManager.h?
      Ui, das ist schon lange her wo ich die eingebunden habe…

      Das sollte aber hier -> https://github.com/tzapu/WiFiManager zu finden sein.
      Dort ist auch die Einbindung in die Arduino IDE erklärt.

      Gruß
      Chris

      Antwort
  • 5. Januar 2018 um 19:45 Uhr
    Permalink

    Hallo
    läuft jetzt bei mir. Ich habe den sketch so erweitert das ich die durchschnittliche windgeschwindigkeit und die max geschwindigkeit ( also boe ) in 10 minuten ermittele.
    und alle 10 min schicke ich es zu einem raspi in eine mysql datenbank
    scheint bis jetzt stabil zu laufen

    danke für die Anregung

    Antwort
    • 5. Januar 2018 um 20:33 Uhr
      Permalink

      Hallo, kannst du den Sketch mal zusenden? Danke!

      Antwort
      • 8. Januar 2018 um 19:13 Uhr
        Permalink

        Ich übermittele an den raspi die momentane windgeswchwindigkeit, boe , windmittel, summe aller messwerte im interval , zahl der messungen, und richtung

        die summe und die zahl der messungen dienten mir zur überprüfung ob er richtig rechnet.
        könnt ihr ja rausschmeissen

        #include
        #include
        #include

        // WLAN Zugangsdaten
        const char* ssid = “xxxxxxxxxxxxxxx”;
        const char* password = “xxxxxxxxxxxxxxx”;
        // Host wo Daten hingesendet werden soll
        const char* datahost = “192.168.xxx.xxx”;

        unsigned long previousMillis = 0;
        const long interval = 600000; // 600000ms = 10 Minuten Intervall
        // const long interval = 300000; // 300000ms = 5 Minuten Intervall
        // const long interval = 60000; // 1min intervall

        WiFiServer server(80);
        ADC_MODE(ADC_VCC);

        const byte DATAPIN=2;
        volatile boolean TX20IncomingData = false;

        unsigned char chk;
        unsigned char sa,sb,sd,se;
        unsigned int sc,sf,pin;
        String tx20RawDataS = “”;

        int boe=0;
        // counter für mittelwert
        int counter=0;
        long summe=0;
        float mittelw=0;
        String mittelw2string = “” ;

        void isTX20Rising() {
        if (!TX20IncomingData) {
        TX20IncomingData = true;
        }
        }

        void setup() {
        boe=0;
        pinMode(DATAPIN, INPUT);
        attachInterrupt(digitalPinToInterrupt(DATAPIN), isTX20Rising, RISING);
        Serial.begin(115200);
        delay(10);

        Serial.println();
        Serial.println();

        WiFiManager wifiManager;

        // AP deaktivieren
        WiFi.softAPdisconnect();
        WiFi.disconnect();
        WiFi.mode(WIFI_STA);
        delay(100);

        Serial.print(“Connecting to “);
        Serial.println(ssid);
        WiFi.begin(ssid, password);
        while (WiFi.status() != WL_CONNECTED) {
        WiFi.hostname(“ESP-wind”);
        delay(500);
        Serial.print(“.”);
        }

        Serial.println(“”);
        Serial.println(“WiFi connected”);
        // server.begin();
        Serial.println(“Server started”);
        Serial.println(WiFi.localIP());
        }

        boolean readTX20() {
        int bitcount=0;

        sa=sb=sd=se=0;
        sc=0;sf=0;
        tx20RawDataS = “”;

        for (bitcount=41; bitcount>0; bitcount–) {
        pin = (digitalRead(DATAPIN));
        if (!pin) {
        tx20RawDataS += “1”;
        } else {
        tx20RawDataS += “0”;
        }
        if ((bitcount==41-4) || (bitcount==41-8) || (bitcount==41-20) || (bitcount==41-24) || (bitcount==41-28)) {
        tx20RawDataS += ” “;
        }
        if (bitcount > 41-5){
        // start, inverted
        sa = (sa< 41-5-4){
        // wind dir, inverted
        sb = sb>>1 | ((pin^1)< 41-5-4-12){
        // windspeed, inverted
        sc = sc>>1 | ((pin^1)< 41-5-4-12-4){
        // checksum, inverted
        sd = sd>>1 | ((pin^1)< 41-5-4-12-4-4){
        // wind dir
        se = se>>1 | (pin<>1 | (pin<>4)&0xf) + ((sc>>8)&0xf) );chk&=0xf;
        delayMicroseconds(2000); // just in case
        TX20IncomingData = false;

        if (sa==4 && sb==se && sc==sf && sd==chk){
        return true;
        } else {
        return false;
        }
        }

        void loop() {

        if (TX20IncomingData) {

        char a[90];
        boolean validData = readTX20();
        Serial.println(tx20RawDataS);
        sprintf(a, “ID: %d\t%d\n”, sa, B00100);
        Serial.write (a);
        sprintf(a, “Windrichtung: %d\t%d\n”, sb, se);
        Serial.write (a);
        sprintf(a, “Windgeschwindigkeit: %d\t%d\n”, sc, sf);
        Serial.write (a);

        // #################################################################
        // boe feststellen
        // speichert den maximalwert eines Messzyklus in der variablen boe
        // #################################################################
        if (sc>boe){
        boe=sc;
        }
        if (boe>1000){
        boe=0;
        }
        Serial.write(“Windboe= “);
        Serial.println(boe);

        // 4095 im eeprom ??
        if (sc>1000){
        sc=0;
        }

        // #####################################################
        // zur mittelwertberechnung
        // durchschnittlichen windgeschwindigkeit während des messzyklus
        // 8 messwerte pro minute
        // #####################################################
        counter = counter +1;
        Serial.write(“Messinterval= “);
        Serial.println(counter);
        summe=summe+sc;
        float mittelw = summe/counter;

        mittelw2string = String(mittelw);
        Serial.write(“summe aller Messwerte = “);
        Serial.println(summe);
        Serial.write(“Mittelwert= “);
        Serial.println(mittelw2string);

        // sendData();

        sprintf(a, “Pruefsumme: %d\t%d\n”, sd, chk);
        Serial.write (a);
        if (validData){
        Serial.println(“OK”);
        } else {
        Serial.println(“Fehler”);

        }
        Serial.println(“”);

        // #########################################################
        // “externe” Webseite aufrufen um Sensordaten zu übergeben
        // #####################################################
        // reconnect
        if ( WiFi.status() != WL_CONNECTED ) {
        Serial.println (“kein connect –> reconnect”);

        Serial.print(“Connecting to “);
        Serial.println(ssid);
        WiFi.begin(ssid, password);
        while (WiFi.status() != WL_CONNECTED) {
        WiFi.hostname(“ESP-wind”);
        delay(500);
        Serial.print(“.”);
        }

        }

        unsigned long currentMillis = millis();

        // ester übermittelter messwert = fehlerhaft sc = 4095

        if(currentMillis – previousMillis >= interval && sc 5000) {
        Serial.println(“[Client Timeout]”);
        client.stop();
        return;
        }
        }

        while(client.available()){
        String line = client.readStringUntil(‘\r’);
        Serial.print(line);
        }
        Serial.println(“”);
        Serial.print(F(“Verbindung zu ‘”));
        Serial.print(datahost);
        Serial.println(F(“‘ beendet.”));
        }

        Antwort
        • 12. Januar 2018 um 16:21 Uhr
          Permalink

          Hi Meinolf,

          vielen Dank für das Script. Werde es am Wochenende mal testen.

          Gruß
          Chris

          Antwort
    • 5. Januar 2018 um 21:10 Uhr
      Permalink

      Hallo Meinolf,

      schön zu hören das es jetzt funktioniert. Dein Idee mach absolut Sinn! Der aktuelle Wert sagt nicht wirklich was aus. Würdest Du deinen Sketch teilen?

      Gruß
      Chris

      Antwort
  • 8. Januar 2018 um 11:46 Uhr
    Permalink

    Hallo Chris,
    klar kann ich das weitergeben. Muss ich erst noch den source entmüllen .
    Da steht noch jede Menge auskommentiertes unnützes Zeug drin.

    Meinolf

    Antwort
  • 8. Januar 2018 um 20:37 Uhr
    Permalink

    Cool, werde ich morgen mal ausprobieren.
    Nur eine Frage, wie visualisierst du die Daten?
    Ich möchte die Werte auch in meine MySQL datenbank schreiben und dann her Highcharts visualiseren.
    Aber die Werte wie sie da rauskommen müssen ja erst mit einer Tabelle auf m/s umgerechnet werden bzw. auf Windrichtumg. Kann das nicht der ESP machen und dann nur die ‘umgerechneten’ Werte übertragen?
    (Macht doch Sinn oder?)

    Antwort
      • 17. Januar 2018 um 15:47 Uhr
        Permalink

        Hallo Oliver
        das geht jetzt bei mir auch mit highcharts und der windrose.
        schick mir mal deine emailadresse . ich möchte den link nicht öffentlich machen
        gruß
        meinolf

        Antwort
        • 18. Januar 2018 um 14:37 Uhr
          Permalink

          hast du die Werte die du reinschreibst schon im sketch mit der Tabelle geändert oder Schreibst du die TX20 “Rohdaten”?
          Danke und Gruß
          Oliver

          Antwort
    • 12. Januar 2018 um 13:09 Uhr
      Permalink

      das kannst du auch im php script machen welches die daten in die mysql schreibt
      aber im prinzip kann das auch der esp. werden dann aber alles fliesskomma operationen.
      wenn du die umrechnung vor der übertragung auf den server vornimmst denke ich unproblematisch. in der messschleife .. weiss ich nicht
      visualisieren mache ich mit googlecharts .
      highcharts sieht auch toll aus. wenn du da resultate hast kannste dich mal melden

      meinolf

      Antwort
  • 5. Mai 2018 um 17:27 Uhr
    Permalink

    hallo diefenbecker,
    Ich bin sehr von dem Thema Hausautomatisierung und Sensor Datenerfassung mittels dem esp8266 angesteckt worden. Jetzt bin ich gerade dabei eine Wetterstation aufzubauen. Habe da auch diese Anleitung durchgeführt. Du hast in deinem Text stehen dass du den Windsensor an der “langen Leine” liegen hattest. Heißt das dass du die komplette Länge des original Anschlusskabels verwendet hattest? Das habe ich nämlich so gemacht und ich bekomme keine Sensordaten. Ich dachte mir es könnte an der länger liegen. Im Netz steht das S bei one-wire Sensoren keine Längenbeschränkung geben soll. Somit möchte ich das ausschließen. Kann natürlich sein dass es auch ein Fehler im Sketch ist. Ich habe nämlich die ganzen Web Geschichten herausgenommen. Wäre für eine Antwort sehr dankbar.

    Antwort
    • 5. Mai 2018 um 17:28 Uhr
      Permalink

      Entschuldigung ich muss mich korrigieren es gibt natürlich an der Längenbeschränkung bei one wire Sensoren. 150 Meter

      Antwort
    • 8. Mai 2018 um 18:16 Uhr
      Permalink

      Hallo,

      ich hab das original Kabel verwendet ohne zu kürzen (ausser das ich den Westernstecker kurz abgeschnitten habe).
      Schicke Dir mal einen neuen Sketch zum Testen…

      Gruß
      Chris

      Antwort
  • 28. Mai 2018 um 06:23 Uhr
    Permalink

    Hi,
    besten Dank erst mal für die Arbeit. Ich versuche gerade, meinen TX 20 ans Laufen zu bekommen. Allerdings gab es schon beim übersetzen Schwierigkeiten.
    Meiner Meinung nach fehlen hier einige Backslashes – auch der Compiler ist dieser Meinung und gab folgerichtig Fehler aus. Ich gebe hier meine Korrekturen an, es sollte kein Problem sien die stellen im Code zu finden:

    content += “{\”Windgeschwindigkeit\”:”;

    content += “,\”Windrichtung\”:”;


    content = “HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n\r\nWindsensor\r\n”;

    Mich wundert, dass das noch keinem aufgefallen ist (vermutlich habe ich’s überlesen)…
    Ciao
    jürgen

    Antwort
    • 28. Mai 2018 um 17:33 Uhr
      Permalink

      Hallo Jürgen,

      gern geschehen und vielen Dank für die Spende. Habe mich sehr gefreut!
      Der Quellcode ist wahrscheinlich durch den Editor von WordPress zerhackt worden. Mit dem stehe ich Kriegsfuss.
      Ich habe das nochmal neu gemacht und dabei eine andere, aktuellere Version des Quellcodes eingestellt (und den Alten zusätzlich).
      Die neue Version basiert auf dem Eintrag von meinolf aus den Kommentaren.

      Gruß
      Chris

      Antwort
      • 28. Mai 2018 um 19:24 Uhr
        Permalink

        Hi Chris,
        ich werde es morgen früh nochmal probieren. Ich habe allerdings noch andere Probleme (nach einiger Zeit hängt sich der ESP auf und nix geht mehr). Aber da muss ich erst mal etwas Forschung betreiben, um vernünftige Fehlermeldungen machen zu können.
        Ciao
        Jürgen

        Antwort
      • 29. Mai 2018 um 05:17 Uhr
        Permalink

        Das Skript läuft jetzt seit 2 Stunden ohne Probleme. Super!
        Ich werde es jetzt für meine Zwecke anpassen. Wenn ich meine, es kommt was Interessantes für die Allgemeinheit heraus, schicke ich es Dir (z.B. eine “Beruhigungspille” für die Windrichtung in Form einer speziellen Mittelwertfunktion oder dgl.). Im Augenblick herrscht hier allerdings Windstille…

        Antwort
      • 29. Mai 2018 um 10:18 Uhr
        Permalink

        So, einen hab ich noch: Die Werte für die Windrichtung waren bei mir sehr merkwürdig…
        Ich hatte noch im Hinterkopf, dass irgendwo im weiten Netz jemand die Verzögerungszeit von 1200 auf 1220 uSec geändert hatte und dass das Problem damit verschwand. So auch hier:
        delayMicroseconds(1200); –>> delayMicroseconds(1220);
        in der Funktion readTX20()

        und schon geht’s.
        Vielleicht ist das ein Wert den man weiter oben, gut sichtbar, konfigurierbar machen sollte. Ich bin mir nicht sicher , wovon der genaue Wert abhängig ist. Er scheint ja bei anderen mit 1200 uSec richtig gewesen zu sein.

        Ciao & Danke nochmal
        Jürgen

        Antwort
  • 3. Juni 2018 um 05:24 Uhr
    Permalink

    Nee, hab noch einen 🙂
    In der Funktion sendData() wird beim Zusammenbau der URL sc für die Windrichtung verwendet. Meiner Meinung nach müsste dort sb verwendet werden.
    Der Fluch der bösen Tat… (glob. Variable) 🙂
    Ciao
    Jürgen

    Antwort
    • 4. Juni 2018 um 19:40 Uhr
      Permalink

      Hi Jürgen,

      da hast Du recht! Ich hab es geändert.

      Gruß
      Chris

      Antwort
  • 12. August 2018 um 10:53 Uhr
    Permalink

    Ich glaube ich komm da nicht ganz mit mit der ganzen Technik und Programmierung der Wetterstation. Ich dachte mir ich kauf einRaspberry undinstalliere das Betriebssystem Steck an gpio4 pin zb data TXD und häng ein 868 MHZ Funk empfängermodul drann. Dann Installiere ich Weewex. und lade die daten auf Weather Underground hoch. Aber es fängt ja schon bei der Python Programmierung und datenausgabe der Scrip t s an. Schde für die Investition und die Technoline Wetterstation. Werde Jetzt eine Wetterstation PCE FCS 20 anschaffen mit usb anschluß. Bei der bekomme ich das besser zum laufen. Oder Verkauft mir jemand die Micro SD Karte mit Fertiger Konfigurierter Software für mein PI und anleitung Trau mich fast nicht mehr was zufragen. Wenn mann davon keine ahnung hat sollte mann die finger weg lassen. Auch wenn mann gerne eine Eigene Wetterstation hätte.

    Antwort
    • 23. August 2018 um 15:25 Uhr
      Permalink

      @Michael Schneider

      Hallo
      Das ganze ist ein Projekt um den ESP8266 Mikrocontroller – steht ja auch da oben. Was soll das ganze mit dem Raspberry Pi zu tun haben? Ich meine, man kann doch wenigstens mal lesen, oder? Und wenn man keinerlei Erfahrung und Ahnung von der Materie hat – Finger von lassen. Oder aber: lernen, wie es geht. Mach dich schlau über den ESP8266, kaufe dir ein Board damit und lerne mit Arduino IDE zu programmieren.

      Antwort
  • 11. September 2018 um 20:23 Uhr
    Permalink

    Hallo Christopher,
    ich baue mir gerade eine eigene Wetterstation mit dem ESP12E (alias Lua Lolin V3). Das klappt soweit alles. Nun habe ich die o.g. Sites eingehend studiert und mir den zum La Crosse Aneometer kompatiblen Technoline TX20 gekauft. Jetzt stehe ich aber vor einem Problem. Ich habe alles so beschaltet wie bei jhon.geek.nz u.ä. angeheben und den Code von ihm zu Testzwecken auf den ESP geladen. Das Anemometer liefert auch die Windrichtung und der CRC ist immer OK, jedoch bleibt die Windgeschwindigkeit immer 0. Hast Du eine Idee, was das sein kann? Spannung am TX20 sind 3,3V und nicht 5. DataPin ist D6 und nicht D2. Auf D2 liegen bei mir die I2C-Sensoren.
    Über eine bloße Anregung würde ich mich schon freuen!
    Herzliche Grüße.
    Christian

    Antwort
    • 5. April 2019 um 23:00 Uhr
      Permalink

      Hallo Christian,

      Konntest du das Problem lösen?

      Ich habe mit Tasmota und einem Wemos D1 auch das Problem.

      Antwort
      • 5. Oktober 2019 um 19:12 Uhr
        Permalink

        Ja ich konnte das Problem lösen. Der erworbene TX20 hatte einen internen Defekt, den der Hersteller bestätigt hat. Ich habe umgehend einen neuen erhalten.

        Antwort
        • 14. Oktober 2019 um 19:24 Uhr
          Permalink

          Hast du zufällig noch die Originalbeschaltung des RJ11 Steckers?

          Antwort
          • 16. Oktober 2019 um 15:41 Uhr
            Permalink

            Ich glaube so:
            1->Braun
            2->Rot
            3->Grün
            4->Gelb

            Von der Kabelseite Richtung Steckerkontakte geschaut von Links nach Rechts gezählt.

            Aber ohne Gewähr da ich den abgeschnittenen Stecker nicht mehr habe…

            Gruß
            Chris

  • 13. September 2018 um 18:20 Uhr
    Permalink

    hi,
    super artikel, vielen dank! habs gleich nachgebaut und läuf, bin begeistert. bei mir sendet er die daten direkt an fhem.

    zwei fragen habe ich allerdings:
    1) bei mir ist valuddata immer false, trotzdem erscheinen die daten sinnvoll. validdata wird im skript ja auch nicht verwendet (vermurlich deswegen?). ist das bei euch auch der fall? woran liegt es?
    2) ich habe alle paar tage mal morgens ein ausreisser bei der boe (und nur bei dem wert). selbst bei windstille ist dann auf einmal ein wert mit 80 dazwischen. habt ihr das auch? ich weiss noch nicht, ob es falsche daten sind (check validdata wird ja nicht verwendet, könnte also theoretisch durch noise auf der leitung kommen, aber warum dann jr bei dem wert?) oder ob ein vogel gegen den sensor kommt oder so….

    Antwort
  • 7. April 2019 um 17:38 Uhr
    Permalink

    Hallo Christian,

    Hast du das Problem beheben können?

    Habe ebenfalls das Problem, das die Geschwindigkeit auf 0 bleibt.

    Antwort
    • 9. Mai 2019 um 20:54 Uhr
      Permalink

      Hallo,

      für die NodeMCU (und andere ESP) Besessenen 😉

      Sollte der Chip sich jedes Mal neustarten, hilft es, den ISR Befehl (2. Argument in der attachInterrupt function) in das IRAM zu laden.
      aus readTX20() { … wird dann ICACHE_RAM_ATTR readTX20() { …

      Bei mir ist die Geschwindigkeit übrigens auch 0 … konnte das jemand lösen?

      Antwort
      • 12. Mai 2019 um 08:50 Uhr
        Permalink

        Hallo Christoph,

        danke für den Tip! Werde ich testen und ggf. in ein neues BIN einbauen.

        Gruß
        Chris

        Antwort
  • 9. Mai 2019 um 09:50 Uhr
    Permalink

    Hi,

    ich versuche, das Skript auf einem NodeMCU V2 ans Laufen zu bekommen. Einbinden sämtlicher libs und Kompilieren klappt problemlos.

    Dann aber spuckt der serielle output das hier aus:
    10:46:25.562 -> ets Jan 8 2013,rst cause:2, boot mode:(3,6)
    10:46:25.562 ->
    10:46:25.562 -> load 0x4010f000, len 1384, room 16
    10:46:25.562 -> tail 8
    10:46:25.562 -> chksum 0x2d
    10:46:25.562 -> csum 0x2d
    10:46:25.562 -> v0dd6549c
    10:46:25.562 -> ~ld

    Erst dachte ich (mit Verweis auf , es wäre ein Pin, der den Reset immer wieder triggert (RST Cause 2), aber einige Seiten im Netz sagen, RST cause 2 sei “Processor internal physical address or data error during instruction fetch”.

    Kommt jemandem das bekannt vor und dieser jemand hat einen heißen Tipp?

    Ansonsten wie immer eine sehr umfangreiche und gründlich beschriebene Doku 🙂 Vielen Dank dafür.

    Antwort
    • 22. Mai 2019 um 12:15 Uhr
      Permalink

      Hallo!

      Hatte den selben Fehler. Installiere eine ältere Bibliothek für das Board (Ich glaube ich bin von 2.3.0 auf 2.2.0 zurückgegangen)!

      Gruß
      Thomas

      Antwort
      • 3. Oktober 2019 um 01:45 Uhr
        Permalink

        Hallo Thomas,

        könntest du deine Config bitte posten? Bei mir bleibst die Geschwindigkeit leider weiterhin auf 0.

        Antwort
  • 26. Mai 2019 um 16:23 Uhr
    Permalink

    Hallo,
    bin gerade dabei das ganze nachzubauen, habe aber eine Frage zu den Variablen, bzw. den Werten derer, kannst du / irgendwer mir vllt erklären wofür der Variablenname steht, und was die Werte die drin stehen bedeuten und in welchen Einheiten diese sind?
    Weshalb gibt es zwei Werte je für Windrichtung und -geschwindigkeit?
    Prinzipiell geht es mir darum die Werte in die tatsächliche Windrichtung und km/h umzurechnen.

    Danke schon mal 🙂

    unsigned char chk;
    unsigned char sa,sb,sd,se;
    unsigned int sc,sf,pin;
    String tx20RawDataS = “”;

    Meine Ausgabe:

    00100 0010 000000000000 0001 0110 111111111111
    ID: 4 4
    Windrichtung: 4 9
    Windgeschwindigkeit: 0 0

    Antwort
    • 3. Juni 2019 um 17:06 Uhr
      Permalink

      Hallo Merlin,

      die Windrichtung ist “sb” und die Windgeschwindigkeit is “sc”. Ich hätte hier ein Script in einer Beta-Version die verschiedene Verbesserungen analog der Zisternenmessung Füllstandsmessung der Zisterne mittels ESP8266 (NodeMCU) und Ultraschallsensor implementiert hat (OTA, Konfigseite, AP, …) wo auch die Windrichtung umgerechnet wird und die Windgeschwindikeit gemittelt wird.
      Falls Interesse zum Testen bitte melden.

      Hier ein Schnipsel des Codes für die berechnung des Mittelwertes und der Windrichtung.

      //**********************************************
      // Sensordaten auslesen
      //**********************************************
      void sensordaten() {
      if (TX20IncomingData) {

      char a[90];
      boolean validData = readTX20();
      Serial.println(tx20RawDataS);

      if (validData){
      sprintf(a, “ID: %d\t%d\n”, sa, B00100);
      Serial.write (a);
      sprintf(a, “Windrichtung: %d\t%d\n”, sb, se);
      Serial.write (a);
      sprintf(a, “Windgeschwindigkeit: %d\t%d\n”, sc, sf);
      Serial.write (a);

      // #################################################################
      // Speichert den Maximalwert eines Messzyklus in der Variablen boe
      // #################################################################
      if (sc>boe){
      boe=sc;
      }
      if (boe>1000){
      boe=0;
      }
      if (sc>1000){
      sc=0;
      }

      // #####################################################
      // Zur Mittelwertberechnung durchschnittlichen
      // Windgeschwindigkeit während des Messzyklus
      // 8 messwerte pro Minute
      // #####################################################

      counter = counter +1;
      Serial.write(“Messinterval= “);
      Serial.println(counter);
      summe=summe+sc;
      float mittelw = summe/counter;
      mittelw2string = String(mittelw);
      windrichtung=sb;
      switch (sb) {
      case 0:
      windrichtung=”N”;
      break;
      case 1:
      windrichtung=”NNO”;
      break;
      case 2:
      windrichtung=”NO”;
      break;
      case 3:
      windrichtung=”ONO”;
      break;
      case 4:
      windrichtung=”O”;
      break;
      case 5:
      windrichtung=”OSO”;
      break;
      case 6:
      windrichtung=”SO”;
      break;
      case 7:
      windrichtung=”SSE”;
      break;
      case 8:
      windrichtung=”S”;
      break;
      case 9:
      windrichtung=”SSW”;
      break;
      case 10:
      windrichtung=”SW”;
      break;
      case 11:
      windrichtung=”WSW”;
      break;
      case 12:
      windrichtung=”W”;
      break;
      case 13:
      windrichtung=”WNW”;
      break;
      case 14:
      windrichtung=”NW”;
      break;
      case 15:
      windrichtung=”NNW”;
      break;
      }

      Serial.write(“Summe aller Messwerte = “);
      Serial.println(summe);
      Serial.write(“Mittelwert: “);
      Serial.println(mittelw2string);
      Serial.write(“Windboe: “);
      Serial.println(boe);
      Serial.write(“Windrichtung: “);
      Serial.println(windrichtung);
      }

      sprintf(a, “Pruefsumme: %d\t%d\n”, sd, chk);
      Serial.write (a);
      if (validData){
      Serial.println(“OK”);
      } else {
      Serial.println(“Fehler”);
      }
      Serial.println(“”);
      }

      }

      Gruß
      Chris

      Antwort
  • 21. Juni 2019 um 14:19 Uhr
    Permalink

    Hallo,
    mittlerweile gibt es die Technoline TX20 so gut wie nicht mehr.
    Meine Frage, wenn man das Projekt mit dem Technoline TX23 umsätzt, müsste dann viel an Quellcode geändert werden oder sind die Rohdaten ggf. identisch?
    MfG Paradox

    Antwort
    • 22. Juni 2019 um 09:55 Uhr
      Permalink

      Hallo,

      laut einigen Foren sollten der TX20 und TX23 (und auch der TX31) Baugleich sein.
      Somit sollte sich auch am Protokoll nichts geändert haben.
      Mit Gewissheit kann ich es aber nicht sagen.

      Gruß
      Chris

      Antwort
  • 25. Dezember 2019 um 17:28 Uhr
    Permalink

    Hallo, konnte das schon jemand testen ob der TX23 funktioniert? Danke und Gruß Martin

    Antwort
    • 26. Dezember 2019 um 18:33 Uhr
      Permalink

      Hallo Martin,

      nee, hab ich noch nicht getestet. Ich vermute aber, dass beide (TX20 & TX23) die gleiche “Sprache” sprechen und dass es funktionieren sollte.

      Gruß
      Chris

      Antwort
    • 17. Januar 2020 um 16:49 Uhr
      Permalink

      Hallo Martin,

      Habe mir ein Technoline tx23 besorgt und leider kein erfolg gehabt, ich bekomme keinerlei Daten. Folgende Pins wurden verwendet: Rot -> VCC, schwarz -> TX, gelb -> GND

      Antwort
  • 16. April 2022 um 22:17 Uhr
    Permalink

    Moin 🙂 sehr detailliertes und interessantes Projekt. Ich bin derzeit noch auf der Suche das ganze offline und autark zu betreiben. Hat jemand schon Erfahrung damit? Die Idee: eine Solarzelle soll permanent einen LiPo laden und dieser soll den ESP8266 betreiben. Dann soll der esp seine stündlichen Messwerte auf eine sd Karte schreiben. An dem Ort wo ich den Wind messen will ist leider derzeit noch kein Strom geschweige denn wlan. Habt ihr da Ideen?

    Antwort
    • 23. April 2022 um 08:46 Uhr
      Permalink

      Hallo Martin,

      daas ginge bestimmt. Ich bin nur aaktuell leider Land unter.
      Kannst Du selbst programmieren? Dann können wir evtl. mal zusammen schauen.

      Gruß
      Chris

      Antwort

Schreibe einen Kommentar zu Jürgen Grete Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert