Energiesparen Tutorial Umwelt

Z-Wave Wetterstation DIY Teil 1 - Z-UNO Hard- & Software

Geschrieben von mdietinger

Da es keine wirklich brauchbaren Wetterstationen im Z-Wave Bereich gibt, griff er zum Lötkolben sowie einem Z-UNO und baute eben selbst eine Wetterstation. Hier ist seine Bauanleitung. Ein Gastbeitrag von Markus Dietinger.

Z-Wave Wetterstation DIY

Ich war relativ lange auf der Suche für eine Wetterstation welche ich mit meiner Fibaro HC2 integrieren konnte.
Die am Markt erhältlichen Stationen konnten mich alle miteinander nicht überzeugen.

Sei es die Netatmo Station, welche ich selbst betrieben habe oder auch Z-Weather.

Netatmo ist relativ einfach zu installieren und betreiben sollte auch ausreichend genau sein, aber die Sensor Lösung lässt keine rechte Freude aufkommen.

Der Temperatur und Feuchtesensor ist in einem Aluminiumghäuse mit unzureichender Lüftung.

Dadurch gibt es eine starke Eigenerwärmung und ziemliche Trägheit des Systemes.
Weiters konnte ich Luftfeuchtunterschiede >10% zwischen den Sensoren am gleichen Standort feststellen.

Der Windsensor mit Ultraschall hatte immer wieder Windspitzen > 100km/h ohne merklichen Wind.
Der grösste Nachteil war das die Messwerte immer 15 Minuten verzögert waren. (Batteriebetrieben/Kompromiss)

Zum Z-Weather habe ich einige Berichte gelesen dass es Probleme mit der Solarstromversorgung gibt und das aus Stromspargründen die Übertragung äußerst selten ist.

[amazon_link asins='B0098MGWA8,B016OHME1A,B010ECHWOA' template='CopyOf-ProductGrid' store='siio.de-21' marketplace='DE' link_id='5ba72194-3bd6-11e8-bf1c-99a42f5fff68']

Der Plan:

Ich hatte schon einige Zeit einen Z-Uno herumliegen, welchen ich für mein Projekt verwenden wollte. https://z-uno.z-wave.me/
Meine Komponenten sind eher im Hochpreissegment angesiedelt, aber haben auch eine hohe Genauig- und Zuverlässigkeit.

Weiter wollte ich hochwertige Komponenten verwenden:

Im Internet konnte ich einige Beispiele finden in welchem HYT939, BH1750 und die Daviskomponenten an einen Arduino angeschlossen wurden.

Eine gute Seite ist zum Beispiel cactus.io.
Gut sind auch die Diversen Beispiele auf Z-Uno -> hier.
Eine relativ kostengünstige Lösung für Innensensoren mittels Z-Uno findet sich hier.

Die Umsetzung:

[alert variation="alert-warning"]Warnung!
Bitte nur Nachbauen wenn ihr ein Grundverständnis in Elektronik habt und mit der Arduino Programierumgebung umgehen könnt. Grundlegende Programmierfähigkeiten sind auch notwendig. Ich habe die Lösung nach Bestem Wissen und Gewissen dokumentiert und kann nur begrenzt Support geben.[/alert]

Zuerst habe ich die ganze Lösung auf einem Breadboard aufgebaut und getestet, diesen Schritt habe ich nicht als Foto dokumentiert.

Danach wurde die Schaltung auf einer Lochrasterplatine aufgebaut.
Die Transistoren im Bild sind schlussendlich ohne Funktion geblieben. (Bitte ignorieren)

Der Z-UNO wird von einem 5V Netztteil ständig mit Spannung betrieben.

Dadurch konnte ich die Updateintervalle bei einer Minute programieren und brauchte keine besonderen Vorkehrungen bezüglich Stromverbrauch und Akkubetrieb machen.

[carousel arrows="display" buttons="display" interval="4"]
[panel title="Wetterstation Z-Wave"][/panel]
[panel title="Wetterstation Z-Wave"][/panel]
[/carousel]

 

Mittels Blockklemmen und RJ11 Buchsen konnte die Schaltung ohne zuviel an Lötarbeiten fertiggestellt werden.
Die RJ11 Buchsen erlauben einen relativ einfachen Sensortausch ohne jedes Mal die Schaltung angreifen zu müssen.

Wind und Regensensor kommen mit RJ11 Stecker und brauchen nur noch angesteckt werden. HY939 und BH1750 müsst ihr noch an ein RJ11 Kabel anschliesen.

[carousel arrows="display" buttons="display" interval="4"]
[panel title="Wetterstation Z-Wave"][/panel]
[panel title="Wetterstation Z-Wave"][/panel]
[/carousel]

Die Schaltung:

Der I2C Bus muss mit Pullup Widerständen auf 3,3V Hochgezogen werden.

An die Pulseingänge für Regen und Windsensor müssen noch Glättkondensatoren geschalten werden um ein Prellen der Kontakte zu verhindern.

Der Regensensor:

Das Kabel am vorgesehenen RJ11 Port anstecken.
Pro Wippenschlag werden 0,2mm Regen gemessen.
Bei leichtem Regen können einige Minuten vergehen bis der Sensor den Regen weitermeldet(0,2mm).

Der Windsensor:

Den Windsensor am Besten an einem Mast installieren welche das höchste Bauwerk überragt.
Die Windfahne muss auch nach Norden ausgerichtet werden. Ich überrage mein Dach um 2 Meter. (Div. Wetterseiten schlagen eine Masthöhe von 10 Meter vor).
Das Kabel wie gehabt an den entsprechenden RJ11 Buchse anhängen.

[carousel arrows="display" buttons="display" interval="4"]
[panel title="Wetterstation Z-Wave"][/panel]
[panel title="Wetterstation Z-Wave"]

[/panel]
[/carousel]

 

Der Temperatur und Lichtsensor:

Ich habe den HYT939 in eine Dostmann Strahlungsschutz eingebaut und zusätzlich noch einen Ventilator eingebaut.

Dadurch sollte der Sensor in direkter Sonne sich nicht selbst aufheizen.

Erste Tests zeigen dass direkte Sonne die Temperatur trotzdem um 1-2° steigen lässt. Da werde ich in Zukunft noch am Design arbeiten müssen.

Den Lichtsensor habe ich unter einer Glaskugel untergebracht. (Weihnachtsartikel)

Für den Lichtsensor ist auch noch etwas an Programmänderung in Zukunft geplant, da max. 400W angezeigt werden können.

 

[carousel arrows="display" buttons="display" interval="4"]
[panel title="Wetterstation Z-Wave"][/panel]
[panel title="Wetterstation Z-Wave"][/panel]

[panel title="Wetterstation Z-Wave"]

[/panel]
[/carousel]

 

Erfahrungen:

Die Wetterstation läuft nun schon 3 Monate ohne größere Probleme.

Genauigkeit von Wind und Regensensor sollten sehr hoch sein da Davis Qualitätskomponenten verwendet wurde.

Temperatur und Feuchtigkeit sind auf Grund des verwendeten HYT939 äußerst genau und sprechen auf jede noch so kleine Änderung sofort an.

Wie schon ausgeführt werde ich in Zukunft das Gehäuse Design überarbeiten um auch in direkter Sonne genaue Werte zu bekommen. (Trotzdem um Lichtjahre besser als Netatmo).

Kittlist:

[table id=5 /]

 

Z-UNO CODE:

//PIN18-rain (3V3-2K2-PIN18-100nF-GND)
//PIN4 ADC1
//PIN9-SCL         (2K2 pullup to 3V3)
//PIN10-SDA     (2K2 pullup to 3V3)
//GND-Ground
//3V3-3Volts</pre>
//WIND:
//*
//2-3V3(Yellow)
//3-PIN4-Winddirection(Green)
//4-GND(Red)
//5-PIN17-Windspeed(Black)
//*

//RAIN:
//*
//*
//3-PIN18-Rainsensor
//4-GND
//*
//*

//I2C Temperature &amp; Light:
//*
//2-3V3
//3-PIN9-SCL
//4-GND
//5-PIN10-SDA
//*

#include &lt;Wire.h&gt;
#include &lt;math.h&gt;
#include "EEPROM.h"
#define EEPROM_ADDR 0x800 // EEPROM address
#define EEPROM_UPDATE_INTERVAL 120000 // Delayed EEPROM writing to minimize writting attempts
#define HYT_ADDR 0x28 // I2C address of the HYT 939
#define BH1750_ADDR 0x23 // I2C address of the BH1750
#define BH1750_MODE 0x20 // Mode of the BH1750
#define wind2_factor 0.50292 //m/s per pulse in 2 seconds
#define rain_factor 0.2 //mm per pulse
ZUNO_SETUP_ISR_INT0(int0_handler); // Davis Windsensor
ZUNO_SETUP_ISR_INT1(int1_handler); // Davis Regensensor
ZUNO_SETUP_ISR_GPTIMER(gpt_handler); // 2" Timer (2" &amp; 1 Minute measurements)

struct meter_data {
dword rain_total;
byte crc8;
};
meter_data my_meter_data;
struct sensor_data {
int temperature = 0;
unsigned int humidity = 0;
unsigned int wind_speed = 0;
unsigned int wind_gust = 0;
unsigned int wind_direction = 0;
unsigned int rain_rate = 0;
dword light = 0;
};
sensor_data my_sensor;
long last_write_EEPROM_millis = 0;
unsigned int wind_pulses = 0;
unsigned int wind_pulses60 = 0;
unsigned int wind_boe60 = 0;
unsigned int rain_pulses = 0;
unsigned int rain_pulses300 = 0;
byte data_updated = FALSE;
byte GPT_2sec = 0;
byte count_2sec = 0;
byte minute_Count = 0;
byte hour_Count = 0;
byte RR[12];

ZUNO_SETUP_CHANNELS(// set up channels
ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_TEMPERATURE,
SENSOR_MULTILEVEL_SCALE_CELSIUS,
SENSOR_MULTILEVEL_SIZE_TWO_BYTES,
SENSOR_MULTILEVEL_PRECISION_TWO_DECIMALS,
getterTemperature),
ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_RELATIVE_HUMIDITY,
SENSOR_MULTILEVEL_SCALE_PERCENTAGE_VALUE,
SENSOR_MULTILEVEL_SIZE_TWO_BYTES,
SENSOR_MULTILEVEL_PRECISION_TWO_DECIMALS,
getterHumidity) ,
ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_VELOCITY,
SENSOR_MULTILEVEL_SCALE_METERS_PER_SECOND,
SENSOR_MULTILEVEL_SIZE_TWO_BYTES,
SENSOR_MULTILEVEL_PRECISION_TWO_DECIMALS,
getterVelocity),
ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_VELOCITY,
SENSOR_MULTILEVEL_SCALE_METERS_PER_SECOND,
SENSOR_MULTILEVEL_SIZE_TWO_BYTES,
SENSOR_MULTILEVEL_PRECISION_TWO_DECIMALS,
getterVelocityBoe),
ZUNO_SENSOR_MULTILEVEL_ANGLE_POSITION (getterDirection),
ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_RAIN_RATE,
SENSOR_MULTILEVEL_SCALE_MILLIMETERS_PER_HOUR,
SENSOR_MULTILEVEL_SIZE_TWO_BYTES,
SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL,
getterRainRate),
ZUNO_METER(ZUNO_METER_TYPE_WATER,
METER_RESET_ENABLE,
ZUNO_METER_WATER_SCALE_PULSECOUNT,
METER_SIZE_FOUR_BYTES,
METER_PRECISION_ONE_DECIMAL,
getterRain,
resetterRain),
ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_LUMINANCE,
SENSOR_MULTILEVEL_SCALE_LUX,
SENSOR_MULTILEVEL_SIZE_FOUR_BYTES,
SENSOR_MULTILEVEL_PRECISION_ZERO_DECIMALS,
GetterLightLux),
ZUNO_SENSOR_MULTILEVEL_ANGLE_POSITION (getterCount)
);

void setup() {
zunoExtIntMode(ZUNO_EXT_INT0, RISING);
zunoExtIntMode(ZUNO_EXT_INT1, RISING);
zunoGPTInit(ZUNO_GPT_SCALE1024|ZUNO_GPT_CYCLIC);
zunoGPTSet(62500); // 2 Sekunden Timer
zunoGPTEnable(1);
EEPROM.get(EEPROM_ADDR, &amp;my_meter_data, sizeof(meter_data));
if (my_crc8((byte*)&amp;my_meter_data, sizeof(meter_data) - 1) != my_meter_data.crc8) {
my_meter_data.rain_total = 0;
update_meter_data();
}

}

void int0_handler() // PIN17-wind sensor interupt
{
wind_pulses++;
}

void int1_handler() // PIN18-rain sensor interupt
{
rain_pulses++;
}

void gpt_handler() // 2" Timer
{
GPT_2sec++;
}

void loop() {
if (count_2sec != GPT_2sec) {
count_2sec = GPT_2sec;
if (wind_pulses &gt; wind_boe60) {
my_sensor.wind_direction = map(analogRead(A1), 0, 1024, 0, 100); //PIN4- wind direction 0-100 in 3.6° steps 100=N
wind_boe60 = wind_pulses ;
}
wind_pulses60 = (wind_pulses60 + wind_pulses);
wind_pulses = 0;
if (rain_pulses &gt; 0) {
my_meter_data.rain_total = my_meter_data.rain_total + 1; //Debounce 2 would be 180-360mm/h
rain_pulses300 = rain_pulses300 +1;
rain_pulses = 0;
data_updated = true;
}
if (count_2sec &gt; 29) {
minute_Count++;
if (minute_Count &gt; 4) {
minute_Count = 0;
hour_Count++;
if (hour_Count &gt; 11) { hour_Count = 0; }
RR[hour_Count] = rain_pulses300;
rain_pulses300 = 0;
for (byte i = 0; i &lt; 12; i++) {
rain_pulses300 = rain_pulses300 +RR[i] ;
}
my_sensor.rain_rate = rain_pulses300 ;
rain_pulses300 = 0;
}
my_sensor.wind_speed = wind_pulses60 * wind2_factor / 30 * 100; //Measurement in m/s
my_sensor.wind_gust = wind_boe60 * wind2_factor * 100; //Measurement in m/s
wind_boe60 = 0;
wind_pulses60 = 0;
GPT_2sec = 0;
readSensor();
}
}
if (data_updated &amp;&amp; (millis() - last_write_EEPROM_millis) &gt; EEPROM_UPDATE_INTERVAL) { // To save EEPROM from a lot of r/w operation write it once in EEPROM_UPDATE_INTERVAL if data was updated
update_meter_data();
data_updated = false;
last_write_EEPROM_millis = millis();
}
delay(100);
}

void readSensor () {
dword lightLux;
Wire.begin();
Wire.beginTransmission(BH1750_ADDR);
Wire.write(BH1750_MODE);
Wire.endTransmission();
delay(500);
Wire.requestFrom(BH1750_ADDR, 2);
if(Wire.available() == 2) {
((byte *)&amp;lightLux)[3] = 0;
((byte *)&amp;lightLux)[2] = 0;
((byte *)&amp;lightLux)[1] = Wire.read();
((byte *)&amp;lightLux)[0] = Wire.read();
my_sensor.light = lightLux / 1.2;
}
delay(500);
int iData[4];
Wire.beginTransmission(HYT_ADDR);
Wire.write(0x80);
Wire.endTransmission();
delay(500);
Wire.requestFrom(HYT_ADDR, 4);
if(Wire.available() == 4) {
iData[1] = Wire.read();
iData[2] = Wire.read();
iData[3] = Wire.read();
iData[4] = Wire.read();
int rawHumidity = iData[1] &lt;&lt; 8 | iData[2];
rawHumidity = (rawHumidity &amp;= 0x3FFF);
my_sensor.humidity = 100.0 / pow(2,14) * rawHumidity*100;
iData[4] = (iData[4] &gt;&gt; 2);
int rawTemperature = iData[3] &lt;&lt; 6 | iData[4];
my_sensor.temperature = (165.0 / pow(2,14) * rawTemperature - 40)*100;
}
zunoSendReport(1);
zunoSendReport(2);
zunoSendReport(3);
zunoSendReport(4);
zunoSendReport(5);
zunoSendReport(6);
zunoSendReport(7);
zunoSendReport(8);
zunoSendReport(9);
}

byte my_crc8(byte * data, byte count) {
byte result = 0xDF;
while(count--) {
result ^= *data;
data++;
}
return result;
}

void update_meter_data() {
my_meter_data.crc8 = my_crc8((byte*)&amp;my_meter_data, sizeof(meter_data) - 1);
EEPROM.put(EEPROM_ADDR, &amp;my_meter_data, sizeof(meter_data));
}

word getterTemperature() {
return my_sensor.temperature;
}

word getterHumidity() {
return my_sensor.humidity;
}

word getterVelocity() {
return my_sensor.wind_speed;
}

word getterVelocityBoe() {
return my_sensor.wind_gust;
}

word getterDirection() {
return my_sensor.wind_direction;
}

word getterRainRate() {
return my_sensor.rain_rate * rain_factor * 10;
}

word getterCount() {
return minute_Count;
}

void resetterRain(byte v) {
my_meter_data.rain_total = 0;
update_meter_data();
}

dword getterRain(void) {
return my_meter_data.rain_total * rain_factor * 10;
}

dword GetterLightLux() {
return my_sensor.light;

Vorschau 2.Teil:

  • Virtuelles Device
  • Nextion Display zur Anzeige
  • Integration mit Wunderground
  • Integration mit EmonCMS

 

 

 

 

 

 

 

 

 

Diesen Blogpost hat geschrieben ...

mdietinger

6 Kommentare

  • Sehr cooles Projekt!
    Bin schon auf Teil 2 gespannt, wie du das ganze dann im HC2 verarbeitest und als VD ausgibst. Das Wetterdisplay sieht auch interessant aus :-)

    Bastelobjekte wie deines machen das SmartHome gleich viel interessanter

  • Echt interessante Idee :)

    Ich hab auch schon überlegt, ob ich mir den Z-Uno mal holen soll für ein Projekt.
    Da ich mir eh noch eine Wetterstation bauen wollte, kommt mir dein Tutorial bzw. Bericht gerade recht :D

    Liebe Grüße,
    Sascha

    • Sascha,

      falls du Unterstützung brauchst, melde dich einfach.
      Falls du auch einen Lichtsensor verbauen willst: ich habe mittlerweile den BH1750 durch einen GY49 ersetzt.
      Dieser Sensor bietet einen größeren Lichtbereich ohne zusätzliche Kniffe ab.

      Liebe Grüße,

      Markus

  • Hallo sehr tolles Projekt. Möchte gerade den Windsensor auch bei mir einbinden aber das ganze an einem d1 mini von Wemos. Leider funktioniert die Liste der benutzten Bauteile auf der Seite nicht mehr. Welche Pullup Widerstände und welche Glättkondensatoren werden genutzt. Entspricht die Farbgebung im Schaltplan der wirklichen Farbkennung der Widerstände?

    Gruß Stev

Schreibe einen Kommentar zu mdietinger X

WordPress Cookie Hinweis von Real Cookie Banner