<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Windsensor &#8211; bubuxblog</title>
	<atom:link href="https://www.bubuxblog.de/tag/windsensor/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.bubuxblog.de</link>
	<description></description>
	<lastBuildDate>Mon, 04 Jun 2018 18:38:17 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>
	<item>
		<title>Windsensor TX20 mit ESP8266</title>
		<link>https://www.bubuxblog.de/windsensor-tx20-mit-esp8266/</link>
					<comments>https://www.bubuxblog.de/windsensor-tx20-mit-esp8266/#comments</comments>
		
		<dc:creator><![CDATA[diefenbecker]]></dc:creator>
		<pubDate>Fri, 05 May 2017 17:38:56 +0000</pubDate>
				<category><![CDATA[Eigenbau]]></category>
		<category><![CDATA[ESP8266]]></category>
		<category><![CDATA[Heimautomatisierung]]></category>
		<category><![CDATA[Hausautomatisierung]]></category>
		<category><![CDATA[TX20]]></category>
		<category><![CDATA[Windsensor]]></category>
		<guid isPermaLink="false">http://blog.bubux.de/?p=1372</guid>

					<description><![CDATA[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 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><strong><span style="color: #ff0000;">Update am 28.05.2018 (Rot gekennzeichnet)<br />
</span></strong></p>
<p>Heute nochmal was zum Thema Hausautomatisierung bzw. Messung von Umweltdaten.</p>
<p>Von Homematic gibt es eine komplette <a href="http://www.eq-3.de/produkte/homematic/wetter-und-umwelt/hm-wds100-c6-o-2.html" target="_blank" rel="noopener noreferrer">Wetterstation</a> die wahrscheinlich ohne größeres Zutun in meine bestehende <a href="http://blog.bubux.de/raspberry-pi-heimautomatisierung-mit-coc-und-fhem/" target="_blank" rel="noopener noreferrer">FHEM-Installation</a> 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).</p>
<p><a href="http://blog.bubux.de/wp-content/uploads/2017/04/20170423_115418.jpg"><img fetchpriority="high" decoding="async" class="alignnone size-large wp-image-1395" src="http://blog.bubux.de/wp-content/uploads/2017/04/20170423_115418-1024x576.jpg" alt="" width="768" height="432" srcset="https://www.bubuxblog.de/wp-content/uploads/2017/04/20170423_115418-1024x576.jpg 1024w, https://www.bubuxblog.de/wp-content/uploads/2017/04/20170423_115418-300x169.jpg 300w, https://www.bubuxblog.de/wp-content/uploads/2017/04/20170423_115418-768x432.jpg 768w" sizes="(max-width: 768px) 100vw, 768px" /></a></p>
<p><span id="more-1372"></span></p>
<p>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 <a href="https://de.wikipedia.org/wiki/ESP8266" target="_blank" rel="noopener noreferrer">ESP8266</a> 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:</p>
<blockquote class="wp-embedded-content" data-secret="dd9KLPMdqS"><p><a href="https://www.john.geek.nz/2011/07/la-crosse-tx20-anemometer-communication-protocol/">La Crosse TX20 Anemometer Communication Protocol</a></p></blockquote>
<p><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted"  src="https://www.john.geek.nz/2011/07/la-crosse-tx20-anemometer-communication-protocol/embed/#?secret=dd9KLPMdqS" data-secret="dd9KLPMdqS" width="600" height="338" title="&#8220;La Crosse TX20 Anemometer Communication Protocol&#8221; &#8212; john.geek.nz" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe></p>
<p>Die Integration des oben herausgefundenen Protokolls des TX20 für den ESP8266 ist auf folgender Webseite zu finden: <a href="http://fabrizio.zellini.org/decoding-la-crosse-tx20-anemometer-with-arduino" target="_blank" rel="noopener noreferrer">http://fabrizio.zellini.org/decoding-la-crosse-tx20-anemometer-with-arduino</a>. Das Beispielscript von dieser Seite kann man direkt mittels <a href="https://www.arduino.cc/" target="_blank" rel="noopener noreferrer">Arduino IDE</a> auf den ESP8266 laden. Wie das funktioniert und was sonst noch so beim ESP zu beachten ist, findet man unter anderem in diesem <a href="https://www.heise.de/developer/artikel/Arduino-goes-ESP8266-3240085.html" target="_blank" rel="noopener noreferrer">Heise-Artikel</a>.</p>
<p>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:</p>
<h2>Integration von WLAN</h2>
<p>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).</p>
<h2>Zugriff auf Messdaten</h2>
<p>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.</p>
<h3>1. Webseite</h3>
<p><strong><span style="color: #ff0000;">Darstellung der Webseite nur im alten Script!</span></strong></p>
<p>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.</p>
<p><a href="http://blog.bubux.de/wp-content/uploads/2017/04/windsensor_webseite.png"><img decoding="async" class="alignnone wp-image-1377" src="http://blog.bubux.de/wp-content/uploads/2017/04/windsensor_webseite-300x200.png" alt="" width="458" height="305" srcset="https://www.bubuxblog.de/wp-content/uploads/2017/04/windsensor_webseite-300x200.png 300w, https://www.bubuxblog.de/wp-content/uploads/2017/04/windsensor_webseite-768x512.png 768w, https://www.bubuxblog.de/wp-content/uploads/2017/04/windsensor_webseite.png 940w" sizes="(max-width: 458px) 100vw, 458px" /></a></p>
<h3>2. JSON</h3>
<p><strong><span style="color: #ff0000;">Implementierung von JSON nur im alten Script!</span></strong></p>
<p>Um die Daten einfacher automatisiert weiter verarbeiten zu können, wird beim Anhängen von <em>/json</em> an die URL ein JSON-String zurück geliefert. Dieser schaut wie folgt aus:</p>
<p><i>{&#8222;Windgeschwindigkeit&#8220;:61,&#8220;Windrichtung&#8220;:2}</i></p>
<p>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.</p>
<p>[cclN_php]<br />
<!--?php $json = file_get_contents('http://esp8266-windsensor/json'); $json_ergebnis=json_decode($json); $windgeschwindigkeit=$json_ergebnis-&gt;Windgeschwindigkeit;&lt;br ?--> $windrichtung=$json_ergebnis-&gt;Windrichtung;</p>
<p>// hier kann die weitere Verarbeitung der Daten erfolgen&#8230;<br />
?&gt;<br />
[/cclN_php]</p>
<p>&nbsp;</p>
<h3>3. Scriptaufruf durch den ESP8266</h3>
<p>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.</p>
<p>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:</p>
<p><span style="color: #ff0000;"><strong>Update am 28.05.2018 (nur für neues ESP-Script mit Boe-Funktion)<br />
</strong></span></p>
<pre class="lang:php decode:true">&lt;?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);
?&gt;</pre>
<p>&nbsp;</p>
<h2>Hier nun das Programm für den ESP8266</h2>
<p><span style="color: #ff0000;"><strong>Update am 28.05.2018 mit Boe-Funktion und ohne eigene Webseite &amp; ohne JSON<br />
</strong></span></p>
<pre class="height-set:true height:700 toolbar:1 lang:c decode:true ">#include &lt;ESP8266WiFi.h&gt;
#include &lt;WiFiManager.h&gt;

#define DEBUG true

// WLAN Zugangsdaten
const char* ssid      = "&lt;ssid_eingeben&gt;";
const char* password  = "&lt;passwort_eingeben&gt;";
// Host wo Daten hingesendet werden soll
const char* datahost  = "&lt;ip_des_hosts&gt;";

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("-&gt; 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&gt;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 &gt; 41-5){
      // start, inverted
      sa = (sa&lt;&lt;1)|(pin^1);
    } else
    if (bitcount &gt; 41-5-4){
      // wind dir, inverted
      sb = sb&gt;&gt;1 | ((pin^1)&lt;&lt;3);
    } else
    if (bitcount &gt; 41-5-4-12){
      // windspeed, inverted
      sc = sc&gt;&gt;1 | ((pin^1)&lt;&lt;11);
    } else
    if (bitcount &gt; 41-5-4-12-4){
      // checksum, inverted
      sd = sd&gt;&gt;1 | ((pin^1)&lt;&lt;3);
    } else 
    if (bitcount &gt; 41-5-4-12-4-4){
      // wind dir
      se = se&gt;&gt;1 | (pin&lt;&lt;3);
    } else {
      // windspeed
      sf = sf&gt;&gt;1 | (pin&lt;&lt;11);
    } 
        
    delayMicroseconds(1200);    
  }
  chk= ( sb + (sc&amp;0xf) + ((sc&gt;&gt;4)&amp;0xf) + ((sc&gt;&gt;8)&amp;0xf) );chk&amp;=0xf;
  delayMicroseconds(2000);
  TX20IncomingData = false;  

  if (sa==4 &amp;&amp; sb==se &amp;&amp; sc==sf &amp;&amp; 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&gt;boe){
      boe=sc;
    }
    if (boe&gt;1000){
      boe=0;
    }
    Serial.write("Windboe= ");
    Serial.println(boe);
    
    // 4095 im eeprom ??
    if (sc&gt;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 &gt;= 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 += "&amp;windrichtung=";
  url += sb;
  url += "&amp;boe=";
  url += boe;
  url += "&amp;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 &gt; 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."));
}</pre>
<p>&nbsp;</p>
<p><strong>Altes Script:</strong></p>
<pre class="height-set:true height:200 toolbar:1 lang:default decode:true">#include &lt;ESP8266WiFi.h&gt;
#include &lt;WiFiManager.h&gt;


// WLAN Zugangsdaten
const char* ssid      = "&lt;ssid&gt;";
const char* password  = "&lt;passwort&gt;";
// Host wo Daten hingesendet werden soll
const char* datahost  = "&lt;ip_des_hosts&gt;";


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&gt;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 &gt; 41-5){
        // start, inverted
        sa = (sa&lt;&lt;1)|(pin^1);
      } else
      if (bitcount &gt; 41-5-4){
        // wind dir, inverted
        sb = sb&gt;&gt;1 | ((pin^1)&lt;&lt;3);
      } else
      if (bitcount &gt; 41-5-4-12){
        // windspeed, inverted
        sc = sc&gt;&gt;1 | ((pin^1)&lt;&lt;11);
      } else
      if (bitcount &gt; 41-5-4-12-4){
        // checksum, inverted
        sd = sd&gt;&gt;1 | ((pin^1)&lt;&lt;3);
      } else 
      if (bitcount &gt; 41-5-4-12-4-4){
        // wind dir
        se = se&gt;&gt;1 | (pin&lt;&lt;3);
      } else {
        // windspeed
        sf = sf&gt;&gt;1 | (pin&lt;&lt;11);
      } 
          
      delayMicroseconds(1200);    
    }
    chk= ( sb + (sc&amp;0xf) + ((sc&gt;&gt;4)&amp;0xf) + ((sc&gt;&gt;8)&amp;0xf) );chk&amp;=0xf;
    delayMicroseconds(2000);  // just in case
    TX20IncomingData = false;  

    if (sa==4 &amp;&amp; sb==se &amp;&amp; sc==sf &amp;&amp; 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&gt;boe){
      boe=sc;
    }
    if (boe&gt;1000){
      boe=0;
    }
    Serial.write("Windboe= ");
    Serial.println(boe);
    
    // 4095 im eeprom ??
    if (sc&gt;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 &gt;= interval &amp;&amp; sc &gt;= 5000) 
    {
      previousMillis = currentMillis;
      sendData();
    }

    
    // Anfrage beantworten
    int val;
    String content;
    if (req.indexOf("/json") != -1) {
      // Sensordaten als JSON zurueck liefern
      // http://&lt;url_zum_esp&gt;/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&lt;!DOCTYPE HTML&gt;\r\n&lt;html&gt;&lt;head&gt;&lt;title&gt;Windsensor&lt;/title&gt;&lt;/head&gt;&lt;body style=\"font-family:verdana;\"&gt;\r\n";
      content += "&lt;p style='font-size:18px;font-weight:bold;'&gt;Windsensor&lt;/p&gt;&lt;br&gt;";
      content += "&lt;table&gt;";
      content += "&lt;tr&gt;&lt;td&gt;Windgeschwindigkeit (aktuell)&lt;/td&gt;&lt;td&gt;";
      content += sc;
      content += "&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Windgeschwindigkeit (Mittelwert)&lt;/td&gt;&lt;td&gt;";
      content += mittelw2string;
      content += "&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Windgeschwindigkeit (Boe)&lt;/td&gt;&lt;td&gt;";
      content += boe;
      content += "&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Windrichtung&lt;/td&gt;&lt;td&gt;";
      content += sb;
      content += "&lt;/td&gt;&lt;/tr&gt;";
      content += "&lt;tr&gt;&lt;td&gt;&lt;br&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;";
      content += "&lt;tr&gt;&lt;td&gt;WIFI-Signal&lt;/td&gt;&lt;td&gt;";
      content += rssi;
      content += " dBm&lt;/td&gt;";
      content += "&lt;tr&gt;&lt;td&gt;Signal Qualit&amp;auml;t&lt;/td&gt;&lt;td&gt;";
      content += 2 * (rssi + 100);
      content += "%&lt;/td&gt;&lt;/tr&gt;";
      content += "&lt;tr&gt;&lt;td&gt;Batteriespannung&lt;/td&gt;&lt;td&gt;";
      content += vcc;
      content += " V&lt;/td&gt;&lt;/tr&gt;";
      content += "&lt;/table&gt;";
      content += "&lt;/body&gt;&lt;/html&gt;\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 –&gt; 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 += "&amp;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 &gt; 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."));
}</pre>
<p>&nbsp;</p>
<p>Die vom Sensor ausgelesenen Werte müssen noch &#8222;konvertiert&#8220; werden. Auf der Seite von <a href="https://www.john.geek.nz/2011/07/la-crosse-tx20-anemometer-communication-protocol/" target="_blank" rel="noopener">John</a> ist eine entsprechende Tabelle zur Umwandlung der 15 nummerischen Werte für die Windrichtung in deren &#8222;Himmelsrichtungen&#8220;, als auch die Einheit der Windgeschwindigkeit zu finden.</p>
<h2>Aufbau</h2>
<p>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 &#8222;langen Leine&#8220; 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.</p>
<p><a href="http://blog.bubux.de/wp-content/uploads/2017/04/20170423_115317.jpg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-1397" src="http://blog.bubux.de/wp-content/uploads/2017/04/20170423_115317-1024x576.jpg" alt="" width="768" height="432" srcset="https://www.bubuxblog.de/wp-content/uploads/2017/04/20170423_115317-1024x576.jpg 1024w, https://www.bubuxblog.de/wp-content/uploads/2017/04/20170423_115317-300x169.jpg 300w, https://www.bubuxblog.de/wp-content/uploads/2017/04/20170423_115317-768x432.jpg 768w" sizes="auto, (max-width: 768px) 100vw, 768px" /></a></p>
<p>Das Ganze dann nochmal von unten&#8230;</p>
<p><a href="http://blog.bubux.de/wp-content/uploads/2017/04/20170423_115331.jpg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-1396" src="http://blog.bubux.de/wp-content/uploads/2017/04/20170423_115331-1024x576.jpg" alt="" width="768" height="432" srcset="https://www.bubuxblog.de/wp-content/uploads/2017/04/20170423_115331-1024x576.jpg 1024w, https://www.bubuxblog.de/wp-content/uploads/2017/04/20170423_115331-300x169.jpg 300w, https://www.bubuxblog.de/wp-content/uploads/2017/04/20170423_115331-768x432.jpg 768w" sizes="auto, (max-width: 768px) 100vw, 768px" /></a></p>
<p>&#8230;und der schematische Aufbau zum Anschluss des FTDI an den ESP</p>
<p><a href="http://blog.bubux.de/wp-content/uploads/2017/04/esp_ftdi.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-1402" src="http://blog.bubux.de/wp-content/uploads/2017/04/esp_ftdi.png" alt="" width="640" height="555" srcset="https://www.bubuxblog.de/wp-content/uploads/2017/04/esp_ftdi.png 640w, https://www.bubuxblog.de/wp-content/uploads/2017/04/esp_ftdi-300x260.png 300w" sizes="auto, (max-width: 640px) 100vw, 640px" /></a></p>
<p>Der Anschluss des Windsensors ist wie folgt (den ursprünglichen Western-Stecker am Windsensor habe ich abgeschnitten):</p>

<table id="tablepress-3" class="tablepress tablepress-id-3">
<thead>
<tr class="row-1">
	<th class="column-1">Anschluss Windsensor</th><td class="column-2"></td>
</tr>
</thead>
<tbody class="row-striping row-hover">
<tr class="row-2">
	<td class="column-1">Gelb</td><td class="column-2">Masse (GND)</td>
</tr>
<tr class="row-3">
	<td class="column-1">Grün</td><td class="column-2">Masse (DTR)</td>
</tr>
<tr class="row-4">
	<td class="column-1">Rot</td><td class="column-2">3,3V (Vcc)</td>
</tr>
<tr class="row-5">
	<td class="column-1">Schwarz</td><td class="column-2">GPIO_2 (TxD)</td>
</tr>
</tbody>
</table>

<p>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.</p>
<h2>Wofür das Ganze?</h2>
<p>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.</p>
<p><a href="http://blog.bubux.de/wp-content/uploads/2017/05/20140810_192933.jpg"><img loading="lazy" decoding="async" class="alignnone wp-image-1576 size-thumbnail" src="http://blog.bubux.de/wp-content/uploads/2017/05/20140810_192933-150x150.jpg" alt="" width="150" height="150"></a></p>
<h2>Probleme</h2>
<ul>
<li>Wenn die Betriebsspannung sinkt bzw. nicht genug Strom geliefert wird (z.B. beim Betrieb an Batterien), sind die Messdaten nicht korrekt (Prüfsumme falsch)</li>
</ul>
<h2>Todo</h2>
<ul>
<li>Sensor schlafen legen</li>
<li>Mit Batterieversorgung experimentieren</li>
<li>Update mittels <a href="https://esp8266.github.io/Arduino/versions/2.0.0/doc/ota_updates/ota_updates.html" target="_blank" rel="noopener noreferrer">OTA</a></li>
<li>WLAN-Konfig über Access Point (AP), dann Station (STA) einrichten</li>
<li>Konfiguration des URL zur aktiven Übergabe der Daten über Webseite</li>
</ul>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.bubuxblog.de/windsensor-tx20-mit-esp8266/feed/</wfw:commentRss>
			<slash:comments>53</slash:comments>
		
		
			</item>
	</channel>
</rss>
