Bau und Entwicklung der Raspberry Wetterstation

 

 

Alles begann mit dem Kauf meiner WS2000 im Jahr 2003 bei Conrad Elektronik. Diese brachte bereits einen Temperatur/Feuchtesensor, einen Regensensor und einen Windsensor mit. Sie wurde auf dem umgebenden Grundstück unseres frisch gebauten Haus aufgestellt und dank dem WS7000-13 PC-Funkinterface welches nicht ausgelesene Daten in einen Ringspeicher speichert, konnten alle Daten lückenlos gespeichert und beliebig am Computer ausgelesen werden. 2005 wurde die Wetterstation durch eine WS2500 ergänzt. Hier war der Helligkeitssensor neu, aus dessen Werten die verwendete Software WsWin von Werner Krenn, sogar die Sonnenscheindauer und Einstrahlungsleistung/m² berechnen konnte. Es gingen einige Jahre ins Land und die Station wurde beständig um Sensoren erweitert. So dauerte es nicht lange, bis Bodentemperatursensoren dazu kamen, wie auch Temperatursensoren in verschiedenen Höhen zwischen 0 und 2m. 2008 dann die Hiobsbotschaft. ELV stellt die Produktion der WS2xxx Reihe ein. Es gab immer seltener Restposten zu ergattern, zu immer höheren Preisen. In Wetterforen kam die schnell die Frage auf, warum gerade ein Wetterstationsmodell, welches so gut auf die Bedürfnisse von Hobbymeteorologen zugeschnitten ist, unbedingt aus dem Programm genommen werden muss. Denn inzwischen haben sich im hobbymeteorologichen Sektor die Kombisensoren verbreitet, wo oft Wind, Regen und Temperatursensor in eine Einheit verbaut sind. Im meteorologischen Sinne sehr unsinnig, da nach WMO-Norm der Wind in 10m und die Lufttemperatur in 2m Höhe gemessen wird. Der Regensensor hingegen ist so anzubringen, dass er stabil steht und kein Spritzwasser vom Boden abbekommt. Des weiteren darf er nicht im Windschatten umliegender Gebäude stehen, weswegen er häufig auf einem kurzen Holzpfahl auf der Wetterwiese platziert wird. All dies macht ein Kombisensor unmöglich, da man sich für einen Sensor entscheiden muss, den man Normgerecht unter bringt, die übrigen Sensoren liefern entsprechend falsche Werte. Auch die Vantage Wetterstationen kamen nicht in Betracht, da diese von ihren Anschaffungskosten her schlicht zu wuchtig für meine Verhältnisse waren. 2010 dann noch einmal ein kleiner Lichtblick. ELV gab seine für Garantiefälle gelagerten Ersatzgeräte zum Verkauf frei. Somit wurden noch einmal defekte Sensoren und Geräte ausgetauscht. Dennoch geschah es, dass 2011 der Temperatur- Feuchtesensor auf Grund falsch eingelegter Batterien den Hitzetod fand. Für ein ¾ Jahr konnte meine Wetterstation keine korrekten Daten liefern. Abhilfe schaffte erst ein von Helmut Bayerlein in seiner Freizeit erstellter Sensor. Er hatte sich der Thematik WS2000/WS2500 Sensoren schon deutlich früher angenommen und durch Entschlüsselung des Funkprotokolls war es ihm möglich eigene Sensoren zu entwickeln. 2014 gelang dann auch mir der Durchbruch. Im Frühjahr 2014 schaffte ich es, durch einen alten, ausgeschlachteten WS2xxx-Repeater, die Funksignale zu dekodieren. Der Repeater wurde seinem Sendemodul beraubt und am Daten-Sendepin (Eingang des Sendemoduls) habe ich die Interruptpins meines AVR-Mikrokontrollers angelötet. Dieser Mikrokontroller wertete nun die Zeit zwischen High/Low bzw Low/High Flanken aus und zählte in der Zwischenzeit eine Variable hoch. Dies in einer Exceltabelle dargestellt sah dann folgendermaßen aus:

 

1

37

0

Präambel

2

37

0

 

3

37

0

 

4

37

0

 

5

37

0

 

6

37

0

 

7

37

0

 

8

37

0

 

9

37

0

 

10

37

0

 

11

87

1

 

12

87

1

Sensortyp

13

37

0

°C / %

14

37

0

 

15

49

0

 

16

87

1

 

17

37

0

 

18

37

0

 

19

37

0

 

20

49

0

 

21

87

1

 

22

87

1

Zehntel°C

23

87

1

7

24

87

1

 

25

49

0

 

26

87

1

 

27

87

1

1°C

28

87

1

3

29

37

0

 

30

49

0

 

31

87

1

 

32

87

1

10°C

33

37

0

1

34

37

0

 

35

49

0

 

36

87

1

 

37

37

0

Zehntel %

38

37

0

 

39

87

1

4

40

49

0

 

41

87

1

 

42

37

0

1%

43

37

0

 

44

37

0

 

45

99

1

8

46

87

1

 

47

37

0

10%

48

37

0

 

49

37

0

 

50

99

1

8

 

 

 

 

 

13,7°C - 88%

 

 

 

 

13,7°C

 

 

 

88,40%

Diese besteht aus 7 bis 10 mal log. 0. Bei dem hier dekodierten Sensor war es 10 mal log. 0.

 

In der Zeit von einem Flankenwechsel zum nächsten wird im Mikrokontrollerprogramm eine Variable hoch gezählt. Deren Zählstand zum Zeitpunkt des Flankenwechsels ist in der zweiten Spalte angegeben.

 

Alle Zählwerte <80 sind als log. 0 zu sehen, während alle Zählwerte >80 als log. 1 anzusehen sind.

 

 

Spalte 11: Diese logische 1 ist ein Trennbit. In diesem Fall trennt es die Präambel vom ersten Byte des Datentelegramms.

 

Spalten 12-15: Dem Binärsystem folgend, stellt das erste Bit den Wert 1 dar. Da dieser logisch 1 ist und die Bits für die Werte 2, 4 und 8 je 0 sind, ist der resultierende Sensortyp 1, was den Temperatur/Feuchtigkeitssensor darstellt.

 

 

Spalte 16: Erneut Trennbit, um die einzelnen Bytes voneinander zu trennen.

 

Spalten 17-19: Da alle Bits der Sensoradresse 0 sind, hat der Sensor die Sensoradresse 0. Da die Empfangseinheit (WS2000/WS2500/Funkinterface/WS2500-Display…) die Sensoradressen 1-8 verwendet wird hier 1 dazu addiert so das aus de Sensoradresse 0, Sensoradresse 1 wird.

 

Spalte 20: 0 = Temperatur positiv (>0,0°C) / 1 = Temperatur negativ (<0,0°C)

 

Der Rest dürfte selbsterklärend sein.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Hier noch einmal der übertragene Datensatz: Sensortyp = °C/% , Sensoradresse = 1, Temperatur = 13,7°C, Feuchtigkeit = 88,4%

 

 

Was in dieser Tabelle nicht aufgeführt ist, sind die Werte für die Prüfsumme (Alle Datenbits werden aufsummiert und 5 dazu addiert) sowie die XOR Checksumme. Diese werden vom Empfänger mit ausgewertet zur Prüfung ob der Datensatz auch korrekt empfangen wurde. Die genaue Kodierung der Sensortelegramme ist hier zu finden: http://www.dc3yc.privat.t-online.de/protocol.htm.

 

Damit war es mir nun möglich meine ersten eigenen Sensoren zu bauen. Es wurden Experimente mit Temperaturabhängigen Widerständen, als auch mit digitalen Temperaturgebern wie dem DS18S20 gemacht. Letzterer erwies sich als deutlich zuverlässiger, da hier die Messerwerte bereits von dem Sensorelement selbst erfasst und digital über das OneWire Interface übertragen werden. Da lohnt sich der Aufwand die temperaturabhängigen Widerstände mittels Spannungsteiler auf korrekte Werte abzugleichen, kaum. Zumal diese oft trotz allem, bei kalten Temperaturen zu größeren Fehlmessungen neigen. Der neue +5cm Sensor wurde entsprechend mit einem DS18S20 Sensor realisiert, während ein Attiny44 hier als Prozessor verwendet wurde. Im Juli 2014 wurde ich dann auf den Raspberry Pi aufmerksam, mit welchem ich endlich meine eigene Wetterstation auf Basis der WS2xxx Reihe von ELV realisierte.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Hier sind der Raspberry Pi, sowie die kleine Empfängerschaltung zu sehen. Auf der Rückseite der Empfängerplatine

befindet sich die Empangsplatine „Aurel 4mm5 RX“ an deren Antennenanschluss und GND ein Antennenkabel angelötet ist.

An der anderen Seite des Antennenkabels befindet sich eine Dipolantenne. Beide Dipole bestehen aus einem 4mm

Messing-Vollmaterialstab und sind je 32,6cm lang. Dadurch wird der Empfang nochmals deutlich gesteigert.

 

 

Der Empfänger:

 

Hierbei handelt es um einen Atmega16, welcher über seine Interruptpins die Daten des Aurel 4mm5 RX auswertet. Int0 ist auf steigende Flanke eingestellt, Int1 auf fallende. Löst Int0 aus, so wird ein Timer gestartet, welcher eine Variable hoch zählt. Löst nun Int1 aus, so wird der Timer gestoppt und die Variable ausgewertet. Entspricht die gemessene Zeit der Bedingung für eine log. 1 (+Fehlertoleranz), so wird das erste Bit einer Datenvariable auf log. 1 gesetzt. Entspricht sie der Bedingung einer log. 0, so wird das Variablenbit auf log. 0 gesetzt. Entspricht die gemessene Zeit selbst mit Fehlertoleranz keiner von beiden Bedingungen, so wird einfach nichts gemacht.

 

 

Als Präambel (Startzeichen, das jetzt ein Datentelegramm vom Sensor kommt) werden 7-10 mal log. 0 gefolgt von einer logischen 1 gesendet. Es muss also mind. 7 mal der Zustand 0 gefolgt von log. 1 empfangen werden. Auf die Art wird ein Bit nach dem anderen der Datenvariable gesetzt. Da die Funksensoren im 4 Bit Modus senden, ist die erste Datenvariable nach 4 Bits bereits fertig. Nach einem Trennbit, welches immer log. 1 ist, folgen dann die Bits für die zweite Datenvariable. Im Programm gibt es daher auch für den log. 0 Zustand eine Zählvariable. Ist diese größer gleich 7 UND das letzte empfangene Bit ist log. 1, dann beginnt gerade ein Sensortelegramm. Alles weitere wurde oben bereits genauer beschrieben.

 

Danach folgt als erstes der Sensortyp, wovon es 6 gibt. 0= Temperatursensor (Nur WS2000), 1= Temperatur und Feuchtesensor, 2=Regensensor, 3=Windsensor, 4=Innensensor mit Temperatur, Feuchte und Luftdruck (Nur WS2000), 5=Helligkeitssensor (nur WS2500). Gefolgt von der Sensoradresse. Bei den Temperatursensoren kann diese mittels Steckbrücken eingestellt werden, während sie bei Regen, Wind, Helligkeit und dem Innensensor fest verlötet sind und auf 7 stehen. Nach diesen beiden ersten „Bytes“ (Anführungszeichen-Zeichen daher, da ja nur 4, statt wie üblich 8 Bit) kommen nun die eigentlichen Daten. Nach jedem „Byte“, also jedes 5. Bit, ist eine log. 1 als Trennzeichen.

 

Diese Daten fasst der Atmega16 zu Zahlenwerten zusammen, verarbeitet sie und gibt sie letztlich alle 5 Minuten über seine UART Schnittstelle aus, welches dann wie folgt aussieht:

 

02.08.2014;01:15;20.1;79.4;259;14.2;135;1014;0#

Datum;Zeit;Temperatur2m;Feuchte2m;Zählerstand Regensensor;Windgeschwindigkeit;Windrichtung;Luftdruck;Helligkeit#

Das Semikolon stellt hierbei das Datenrennzeichen dar und ist damit kompatibel zu dem CSV Standart, welcher bei MS Excel Anwendung findet.

 

 

Der Raspberry:

 

Es wurde das Modell B mit 512MB RAM bestellt und als er dann da war, erst einmal großes grübeln wie denn die Daten vom UART Ausgang des verwendeten Atmega16 den Weg in den Raspberry finden sollten. Denn hier war nun eine Pegelanpassung von 5V auf 3,3V notwendig. Auch wenn es so nicht im Datenblatt steht, aber der Atmega16 (keine L-Version) läuft auch mit 3,3V sehr gut und stabil, wodurch die Pegelanpassung dann entfallen kann. Programmiert wird unter Lazarus, welches auch auf dem Raspberry läuft und dort Programme kompilieren kann. Jedoch hatte ich große Probleme Schnittstellenkomponenten zu installieren, mit denen ein direkter Empfang der Wetterdaten am UART möglich gewesen wäre. Also blieb mir nichts anderes übrig, als die Wetterdaten per *.sh Script in eine Datei schreiben zu lassen und diese Datei vom Programm auf Änderungen zu überprüfen. Wenn in der Datei eine neue Zeile geschrieben wurde, so werden die Daten vom Programm übernommen und ausgewertet. Dieser Weg führte schnell zum Ziel und mittels der Lazarus eigenen Diagramm Komponenten, können nun farbenfrohe und übersichtliche Diagramme in Echtzeit generiert werden. Das Programm bekam dann noch weitere Routinen um die aktuellen Wetterdaten in eine *.htm Datei zu gießen, so dass diese dann zusammen mit den als *.jpg gespeicherten Diagrammen per crontab im 5 Minuten Intervall ins Internet geladen werden können.

 

Die Funktion „stty“ schreibt, per *.sh Script gestartet, alle über die UART Schnittstelle beim Raspberry eintreffenden Datenpakete zusammen mit Datum und Zeit in eine Textdatei. Denn Der Atmega16 gibt keine Datums und Zeitdaten aus, daher werden diese durch den Raspberry hinzugefügt. Im Laufe eines Tages ergibt sich eine reichlich gefüllte Datei.

 

Hier mal ein kleiner Ausschnitt aus einer solchen Datei:

 

02.08.2014;00:01;19.5;79.2;259;10.3;120;1014;0#

02.08.2014;00:06;19.7;78.9;259;5.8;115;1014;0#

02.08.2014;00:11;19.7;78.9;259;5.6;115;1014;0#

02.08.2014;00:16;19.7;78.9;259;8.5;120;1014;0#

02.08.2014;00:21;19.8;78.9;259;8.9;125;1014;0#

02.08.2014;00:26;20.0;78.9;259;14.2;125;1014;0#

02.08.2014;00:31;20.0;78.9;259;15.6;125;1014;0#

02.08.2014;00:36;20.1;79.0;259;11.3;125;1014;0#

02.08.2014;00:41;20.1;79.1;259;11.6;125;1014;0#

02.08.2014;00:46;20.1;79.1;259;9.6;130;1014;0#

02.08.2014;00:51;20.1;79.1;259;11.4;125;1014;0#

02.08.2014;00:56;20.1;79.0;259;8.2;125;1014;0#

02.08.2014;01:00;20.1;79.0;259;8.2;125;1014;0#

02.08.2014;01:05;20.1;79.3;259;10.1;125;1014;0#

02.08.2014;01:10;20.1;79.3;259;11.3;130;1014;0#

02.08.2014;01:15;20.1;79.4;259;14.2;135;1014;0#

02.08.2014;01:20;20.1;79.4;259;11.3;120;1014;0#

02.08.2014;01:25;20.1;79.4;259;11.2;15;1014;0#

02.08.2014;01:30;20.0;79.7;259;9.2;30;1014;0#

02.08.2014;01:35;20.0;79.7;259;9.2;30;1014;0#

02.08.2014;01:40;20.0;79.3;259;7.3;115;1014;0#

02.08.2014;01:45;19.9;79.4;259;6.9;100;1014;0#

02.08.2014;01:50;19.9;79.4;259;9.0;95;1014;0#

02.08.2014;01:55;19.9;79.4;259;6.2;105;1014;0#

02.08.2014;02:00;19.7;80.4;259;11.5;95;1014;0#

02.08.2014;02:05;19.7;81.0;259;9.7;100;1014;0#

 

Diese wird im 5 Minutentakt vom Programm neu geladen und schaut ob eine weitere Zeile hinzugekommen ist. Ist dies der Fall, so wird die letzte Zeile Zeichen für Zeichen abgearbeitet. Die Daten werden solange in ein und die selbe Variable geschrieben, bis das aktuelle Zeichen ein Semikolon ist. Ist dem so, so wird die nächste Variable angefangen. Auf diese Weise werden die Daten ausgelesen und können nun von Textzeichen in Zahlenwerte umgewandelt und in die Diagramme eingetragen werden.

 

Noch einmal großes Grübeln verursachte die Umsetzung der Taupunktberechnung. Diese Formeln kamen nun zum Einsatz:

 

SDD(T) = 6.1078 * 10^((a*T)/(b+T))

DD(r,T) = r/100 * SDD(T)

r(T,TD) = 100 * SDD(TD) / SDD(T)

TD(r,T) = b*v/(a-v) mit v(r,T) = log10(DD(r,T)/6.1078)

AF(r,TK) = 10^5 * mw/R* * DD(r,T)/TK; AF(TD,TK) = 10^5 * mw/R* * SDD(TD)/TK

 

Bezeichnungen:

r = relative Luftfeuchte

T = Temperatur in °C

TK = Temperatur in Kelvin (TK = T + 273.15)

TD = Taupunkttemperatur in °C

DD = Dampfdruck in hPa

SDD = Sättigungsdampfdruck in hPa

 

Parameter:

a = 7.5, b = 237.3 für T >= 0

a = 7.6, b = 240.7 für T < 0 über Wasser (Taupunkt)

a = 9.5, b = 265.5 für T < 0 über Eis (Frostpunkt)

 

Quelle: http://www.wetterochs.de/wetter/feuchte.html

 

Wie man sieht, sind noch 2 Einheiten zu berechnen, bevor man damit den Taupunkt berechnen kann. Zunächst gilt es SDD(t) zu berechnen, da dies in der Formel für DD(r,T) vor kommt. DD(r,T) wird wiederum für die Berechnung von v(r,T) benötigt, welches wiederum in der Formel für den Taupunkt verwendet wird. Am einfachsten ist es, diesen Parametern je eine eigene Variable zu spendieren und sie am besten auch so zu benennen wie sie in der Formel verwendet werden.

 

 

tmp=(a*T)/(b+T) --- tmp ist hier als kleiner Zwischenspeicher zu verstehen

SDD=6.1078 * 10^tmp

DD= (r/100) * SDD

V=log10(DD/6.1078)

TD=(b*v)/(a-v)

 

Ich hatte wirklich lange probieren müssen, bis ich mit dieser Routine genau auf die Werte kam, welche auch online Taupunktrechner und die eigene Wetterstation lieferten. Als es dann aber soweit war, wurde diese Routine noch flugs ins Echtzeitprogramm eingebunden und es stand nun auch der Taupunkt zur Verfügung.

 

Letztlich sieht nun das auf dem Raspberry laufende Programm folgender Maßen aus:

 

Hier unter Windows7 geladen um einen Screenshot machen zu können. Oben rechts sind die geladenen Tagesdaten in einer Textfeldkomponente zu sehen, darunter die automatisch generierte Homepage-Webseite. Diese wird in einer Textfeldkomponente erzeugt und als HTM-Seite gespeichert. Parallel dazu werden die Grafiken der 3 Diagramme als JPG Datei gespeichert. Im 3 Minuten Takt wird per Cronjob ein Uploadscript ausgeführt, welches die Webseite, sowie die 3 Diagrammgrafiken auf die Homepage hoch laden.

 

Die Echtzeitdatenerfassung allein ist ja alles gut und schön. Da es aber ein wenig sinnlos ist, wenn die Daten des aktuellen Tages nach 23:59 Uhr verloren gehen, wurde noch eine weitere Routine eingebaut, welche permanent im Sekundentakt die aktuelle Zeit prüft. Ist es 23:58:30 Uhr, dann werden die Datensätze des aktuellen Tages in eine Textdatei mit dem aktuellen Datum als Dateiname (Datum.txt) exportiert und die Datei, in welche das *.sh Script die Daten vom Empfänger ablegt, geleert. Da der Inhalt der Diagramme unter Lazarus leider nicht zu löschen geht, beendet sich das Programm nach dem Ablegen der Datum.txt selbst und wird mittels cronjob um 00:15 Uhr wieder gestartet. In der Zwischenzeit schnappt sich um 23:59 Uhr ein weiteres, selbst geschriebenes Lazarus-Programm die erstellte Datum.txt, liest diese ein und erstellt daraus die Monats-HTM-Datei, zusammen mit den in der Monatsdatei verlinkten Tagesdiagrammen. Monatsdatei und Tagesdiagramme werden dann mittels cronjob um 00:10 Uhr per FTP-Upload ins Internet gestellt, so dass man die Daten des Vortages in der Monatsdatei als Grafiklink vorfindet. Die Daten in der Monatsdatei welche nicht als Minimum oder Maximum ausgwiesen sind, stellen Tagesdurchschnittswerte dar. Da das Monatsprogramm so und so den gesamten Tagesdatensatz lädt um diesen noch einmal in die Diagramme zu zeichnen, wird die Gelegenheit genutzt um alle Werte aufzusummieren und letztlich durch die Anzahl der Werte zu teilen. Es ergeben sich daher die Tagesdurchschnittswerte dieser Werte.