Homematic Wired - Homebrew
Home > Elektronik > Homematic > HBW-WDS-C7  
 

Wetterstation - 868 MHz Empfänger

Da ich mit meinem aktuell Helligkeitssensor (LDR) für die Beschattungssteuerung nicht zufrieden war, wollte ich mir eine schöne Wetterstation zulegen... und in das bestehende Homematic Wired / FHEM einbinden. LAN / W-LAN, etc. wollte ich nicht, und ein SIGNALDuino per USB im Keller ist mit der Entfernung zum Dach ebenfalls ungünstig. Daher eine neue Kreation... Herausgekommen ist das Gerät HBW-WDS-C7.

Diese Modul stellt die Messwerte einer Bresser 7 in 1 (Artikelnummer Sensor: 7803200) oder 5 in 1 Wetterstation als Homematic Wired Gerät zur Verfügung.
Die Code-Basis ist ein SIGNALDuino mit cc1101 868 MHz Modul, dazu ein I2C EEPROM mit 2k Byte.
Es kann parallel am RS-485 Bus und USB betrieben werden. Die Funktion des SIGNALDuino (advanced) ist nicht eingeschränkt.
Entwickelt auf/für einen Raspberry Pi Pico. Kompiliert mit dem "earlephilhower" Arduino Board.

Messwerte / "readings":

 

top Elektronik

Zuerst wollte ich eine Lochrasterplatine nehmen... aber wenn man schon fast alle Teile im Layout Editor hat - dann auch "richtig":

Taster, LED und EEPROM im Sockel auf der Oberseite - DC-DC Wandler und RS-485 Treiber auf der Rückseite. Das RF c1101 Modul hat einen Anschluss von RM 2 auf 2,54 mm erhalten. Neben 1*8 Pins ist auch ein 2*4 Pin Anschluss für ein RF Modul vorhanden.
 
Mit Raspberry Pi Pico huckepack.
 
Verpackt in einem einfachen Gehäuse (Verteilerdose). Ja, die Antenne ragt in einen Deckel einer Zahnpastatube... inkl. frischem Geruch nach Minze.  
     

Statt 133 MHz lasse ich den Pi Pico mit 50 MHz laufen, das spart ca. 24% Energie. Insgesamt ist Leistungsaufnahme rel. hoch, besonders das c1101 Modul benötigt mehr als erwartet... ca. 100 mW (~30 mA bei 3,3V). Was ich für reinen Empfang nicht erwartet hatte. Laut Datenblatt liegt RX bei 15 mA @3V.
Ohne RF Modul (also Pi Pico + RS485 Treiber + EEPROM - alles im Leerlauf) ca. 180 mW. Ähnlich der Schaltungen mit ATmega 328 bei 16 MHz.
Die gesamte Schaltung (inkl. DC-DC Wandler Verluste, etc.) bei 50 MHz nimmt 11,7 mA an knapp 24 V auf - also ca. 280 mW. Bei 133 MHz sind es ca. 370 mW.

 

top Code

Da der Raspberry Pi Pico zwei Prozessorkerne hat, bietet es sich an SIGNALDuino auf core0 und Homematic HBW auf core1 laufen zu lassen. Dazu Hardware SPI, I2C und 2 UART Schnittstellen für die Kommunikation.
Der SIGNALDuino Code ist vom eigenen Sketch (*.ino) in eine SIGNALDuino.ino.hpp gewandert und in die Standardstruktur eines HBW Gerät / Sketch eingebunden.

#include "HBWSIGNALDuino_adv/SIGNALDuino.ino.hpp"

Die relativ geringen Änderungen am SIGNALDuino Code bedeuten aber auch das die Konfiguration (wie z.B. Pin-Belegung) auf verschiedene Dateien verteilt ist. Da aber die Standard Pins für SPI0, I2C0 und UART1 benutzt werden ist es kein Drama.

Ein wenig mehr Probleme bereitete mir der struct hbw_config, bzw. Anfangs dachte ich es gibt ein Problem mit dem externen EEPROM, da der Pi Pico bei der HBW config Initialisierung immer einfror. Nachdem ich aber verschiedene EEPROM Libs durchprobiert hatte und mich mit Debug Ausgaben an den Code-bereich herangetastet hatte (readConfig() / getCentralAddress()) der die Abstürze verursachte schien es eher pointer bezogen zu sein… letztendlich liegt das Problem wohl bei der Architektur des Pi Pico Prozessors (Cortex M0+).

Bei einem Atmega 328, ein 8-Bit Mikrocontroller startet die Variable central_address bei +1 Byte. (nach logging_time, mit der Größe von 1 Byte)

struct hbw_config {
  uint8_t logging_time;     // hbw_config address +0
  uint32_t central_address;  // address +1

Verwendet man diesen struct mit dem Pi Pico werden aber nach dem Byte logging_time weitere 3 Bytes padding eingefügt. Start ist dann bei +4 Byte.
Beim Versuch mit dem bestehenden Code auf eine 4 Byte (32 bit) Variable im struct an Position/Adresse +1 zuzugreifen, würde man auf die 3 padding Byte und auf die ersten 8 bit der Variable "central_address" zugreifen, was der Prozessor aber verhindert... vernünftigerweise.
Lösung ist ein neuer struct und angepasste Methoden von readConfig() und getCentralAddress() welche die bisherigen ersetzen (override). Natürlich müssen die neuen Adressen auch bei Erstellung der Device XML beachtet werden.

Angepasster struct, mit einem Vielfachen von 4 byte:

struct hbw_config {
  uint8_t logging_time; // 0x01 - eeprom addr
  uint8_t padding[2]; // 0x02 - 03
  uint8_t direct_link_deactivate:1; // 0x04:0
  uint8_t fillup :7; // 0x04:1-7
  uint8_t central_address[4]; // 0x05 - 0x08
  hbw_config_...
} hbwconfig;

Die vererbten Methoden von readConfig() und getCentralAddress() werden in einer neuen Klasse (HBWRpiPicoDevice) mit folgenden überschrieben:

protected:
  void readConfig() override { // read config from EEPROM
    // read EEPROM
    EepromPtr->read(0x01, config, configSize);
    // turn around central address
    uint8_t addr[4];
    for(uint8_t i = 0; i < 4; i++) {
      addr[i] = hbwconfig.central_address[i];
   }
   for(uint8_t i = 0; i < 4; i++) {
      hbwconfig.central_address[i] = addr[3-i];
    }
    // set defaults if values not provided from EEPROM or other device specific stuff
    pendingActions.afterReadConfig = true; // tell main loop to run afterReadConfig() for device and channels
  }

  // get central address
  uint32_t getCentralAddress() override {
    return *((uint32_t*)hbwconfig.central_address);
  }

 

top Schaltpläne/Layout

Aktuelle Version zum download.

Schaltplan.  

Quellcode auf GitHub.

Der für den Raspberry Pi Pico erweiterte SIGNALDuino dev-r335_cc1101