Homematic Wired - Homebrew Devices

Begonnen von Thorsten Pferdekaemper, 27 April 2014, 00:13:17

Vorheriges Thema - Nächstes Thema

Thorsten Pferdekaemper

Hallo,
ich habe mal angefangen, mir über "Homematic Wired Homebrew" Gedanken zu machen. Die Idee ist, ähnlich wie es das schon für Funk-Homematic gibt, auch eigene Geräte für's Kabel zu machen. Das Schöne ist, dass das viel einfacher zu sein scheint. (Zumindest zu den ersten Erfolgserlebnissen.)
Ich weiß, dass Dirk da auch dran ist. Ich habe die meisten Informationen auch von ihm. Speziell das hier ist sehr nützlich:
http://forum.fhem.de/index.php?action=dlattach;topic=10027.0;attach=2441

Mein momentanes Experimentier-Setup besteht im Wesentlichen aus einem Arduino Uno, einem MAX487, einem HMW-LC-Sw2-DR mit passendem Netzteil und ein paar Kabeln. (Siehe Bild.) Zumindest kann ich damit schon die Messages sehen (und dank Dirks Doku auch verstehen), die vom Sensor/Aktor geschickt werden.

Damit ich die normale serielle Schnittstelle für Debug-Ausgaben benutzen kann, verwende ich für die RS485 die Pins 2 bis 5 und die SoftwareSerial Library. (Theoretisch ginge es sogar mit nur drei Pins.) Mit folgendem Sketch kann sieht man die Nachrichten im seriellen Monitor.
// Testprogramm RS485

#define PinDI 2
#define PinDE 3
#define PinRE 4
#define PinRO 5
#define PinLED 13

// RS485 uses SoftSerial
#include <SoftwareSerial.h>

SoftwareSerial rs485(PinRO, PinDI); // RX, TX

void setup() {
   
  // Pin 2: Driver Input
  pinMode(PinDI, OUTPUT);
  digitalWrite(PinDI, LOW);
  // Pin 3: DE
  pinMode(PinDE, OUTPUT);
  digitalWrite(PinDE, LOW);
  // Pin 4: !RE
  pinMode(PinRE, OUTPUT);
  digitalWrite(PinRE, LOW);
  // Pin 5: Receiver Output
  pinMode(PinRE, INPUT); 
  // Vorerst nur empfangen und ueber normale serielle
  // Schnittstelle weitergeben
  pinMode(PinLED, OUTPUT);
 
  // SoftSerial konfig
  rs485.begin(19200);
 
  Serial.begin(57600);
  Serial.println("Ready...");
}


void loop() {
 
  signalLED();
  if (rs485.available()) {
    byte c = rs485.read();
    if( c == 0xFD ) Serial.println();
    char buf[10];
    sprintf(buf, "%02X-", c);
    Serial.write(buf);
  };
  if( rs485.overflow()) Serial.println("Overflow"); 
}


void signalLED(){
  static unsigned long lasttime = 0;
  static byte state = 0;
  unsigned long time = millis();

  if(time-lasttime >= 1000){
    digitalWrite(PinLED, state);
    state = 1 - state;
    lasttime = time; 
  }   

};


Es gab nur ein kleines Problemchen mit der SoftwareSerial Library. Standardmäßig verwendet die keine Parity-Bits. Zumindest zum Empfangen bekommt man das mit folgenden kleinen Änderungen an SoftwareSerial.cpp hin:
/* static */
inline void SoftwareSerial::tunedDelay(uint16_t delay) {
  uint8_t tmp=0;

  asm volatile("sbiw    %0, 0x01 \n\t"
    "ldi %1, 0xFF \n\t"
    "cpi %A0, 0xFF \n\t"
    "cpc %B0, %1 \n\t"
    "brne .-10 \n\t"
    : "+w" (delay), "+a" (tmp)       // <<<<< hier heissts im Original : "+r" (delay...
    : "0" (delay)
    );
}

und
void SoftwareSerial::recv()
{

#if GCC_VERSION < 40302

[...]

      else // else clause added to ensure function timing is ~balanced
        d &= noti;
    }

    // PFE skip parity bit
    tunedDelay(_rx_delay_stopbit);     // <<<<< das ist neu

    // skip the stop bit
    tunedDelay(_rx_delay_stopbit);
    DebugPulse(_DEBUG_PIN2, 1);

[...]


Natürlich wird das Parity-Bit nicht ausgewertet und beim Senden kommt es noch nicht mit, aber für's Empfangen reicht's.

Ich weiß, dass das noch nichts wirklich großartiges ist, aber ein Anfang ist gemacht.

Gruß,
    Thorsten



FUIP

Dirk

Hallo Thorsten,

Cool. Da hat es dir wohl in den Fingern geribbelt? :)
Hast den Code neu entwickelt oder konntest du den Code von mir nach C++/Arduino portieren?
Kannst mir das ja mal zukommen lassen. Dann können wir da gemeinsam weiter machen.

Gruß
Dirk

Thorsten Pferdekaemper

Zitat von: Dirk am 27 April 2014, 10:52:11Cool. Da hat es dir wohl in den Fingern geribbelt? :)
Heftigst...
ZitatHast den Code neu entwickelt oder konntest du den Code von mir nach C++/Arduino portieren?
Naja, so viel gab's da nicht zu entwickeln. Im Prinzip gebe ich ja nur nach Serial weiter, was von SoftwareSerial reinkommt. Den Rest (Baudrate, Parity, "0xFD") habe ich von Deiner Protokolldoku übernommen.
Die notwendigen Änderungen an SoftwareSerial habe ich mir dann zusammengesucht, nachdem es zuerst nicht funktionieren wollte.
Ich denke aber, dass ich Deinen Code noch auf Arduinisch übersetzen kann. Das dürfte nur ein bisschen dauern.
Zitat
Kannst mir das ja mal zukommen lassen. Dann können wir da gemeinsam weiter machen.
Coding siehe meinen ersten Post im Thread. Von wegen gemeinsam weiter: Ja, das war so gedacht.

Gruß,
    Thorsten
FUIP

reneFHEM

Hallo Thorsten,hallo Dirk,

ich bin auch mit der Entwicklung eines Homebrew-Modul für HMW beschäftigt. Ich habe mir als Basis allerdings das openHC-Projekt ausgesucht, da dort schon ein Atmega88 verwendet wird. Aktuell bin ich aber noch dabei die HW und SW-Plattform anzupassen. Aus Zeitgründen geht das allerdings etwas langsamer voran.

Mein Testaufbau sieht ähnlich aus: Netzteil, 2x HMW-SW-LC2-DR, Digitus DA-70157.

Könnten wir uns hier nicht zusammen tun?

Gruß Rene

Thorsten Pferdekaemper

Zitat von: reneFHEM am 04 Mai 2014, 21:17:10Ich habe mir als Basis allerdings das openHC-Projekt ausgesucht,
Das kannte ich bisher noch nicht. Sieht interessant aus, zumindest gibt es da schonmal die Designs, die UP-Dosen etc. passen. Von der Hardware her vertraue ich allerdings lieber Dirk als mir selbst.
Zitatda dort schon ein Atmega88 verwendet wird.
Ich bin mir nicht sicher, ob 8kB Flash Speicher ausreichen. Das HMW-Protokoll kann ja schon einiges und 8kB (incl. Bootloader...) ist nicht gerade viel.
ZitatAktuell bin ich aber noch dabei die HW und SW-Plattform anzupassen. Aus Zeitgründen geht das allerdings etwas langsamer voran.
Geht mir nicht anders. Wahrscheilich geht's bei mir erst fruehestens am 12.Mai weiter. ...aber ein bisschen "Projektmanagement" geht vorher.
ZitatKönnten wir uns hier nicht zusammen tun?
Klar, das faende ich gut. Dirk wollte ein git-Repository dafuer anlegen.
@Dirk: Hast Du das schon gemacht?
Ansonsten waere es vielleicht gut, wenn wir ausmachen, wer sich um was kuemmert. Wie schon gesagt wollte ich damit anfangen, das HMW-Protokoll nach "Arduinisch" zu uebersetzen. Ich wollte das mit einem normalen Arduino Uno machen, es duerfte aber einfach sein, das auf andere Atmega-Plattformen zu uebertragen. Was die Hardware angeht, kann ich einfache Sachen zusammenstecken und -loeten, aber was ich mache wird normalereise zu gross, um es tatsaechlich einsetzen zu koennen. Das ueberlasse ich dann lieber anderen.

Gruss,
    Thorsten

FUIP

reneFHEM

Hallo Thorsten,

welche HW gebraucht wird, dafür habe ich auch noch kein Gefühl.

Zitatich einfache Sachen zusammenstecken und -loeten, aber was ich mache wird normalereise zu gross, um es tatsaechlich einsetzen zu koennen
Zusammenstecken und Löten kann ich auch, aber richtige Platinen (womöglich noch mit SMD) habe ich schon länger nicht mehr gebaut. Das wird sicher nicht auf Anhieb funktionieren :-)

Deshalb werde ich mir mal ein Arduino Uno besorgen. Wenn es damit läuft, kann man immer noch sehen, welcher Atmega tatsächlich gebraucht wird.

ZitatAnsonsten waere es vielleicht gut, wenn wir ausmachen, wer sich um was kuemmert.
Sehe ich auch so. Hier müssten wir uns separat abstimmen, wenn es das Repository gibt.

Gruß Rene

Thorsten Pferdekaemper

Zitat von: reneFHEM am 05 Mai 2014, 20:58:48Zusammenstecken und Löten kann ich auch, aber richtige Platinen (womöglich noch mit SMD) habe ich schon länger nicht mehr gebaut. Das wird sicher nicht auf Anhieb funktionieren :-)
Da wuerde ich auf Dirk vertrauen. Das sieht bei ihm professionell aus.
ZitatDeshalb werde ich mir mal ein Arduino Uno besorgen. Wenn es damit läuft, kann man immer noch sehen, welcher Atmega tatsächlich gebraucht wird.
Vergiss den RS485-Bustreiber nicht.
FUIP

reneFHEM

ZitatVergiss den RS485-Bustreiber nicht.
Den habe ich schon da :-)

Dirk

Zitat von: Thorsten Pferdekaemper am 05 Mai 2014, 12:13:57
Das HMW-Protokoll kann ja schon einiges und 8kB (incl. Bootloader...) ist nicht gerade viel.Geht mir nicht anders.
Zumindest die fertigen Module haben alle einen Atmega32 on Board. Wenn man die Module auch selber miteinander interagieren lassen möchte, Sprichwort Peering, dann braucht es auch noch Flash-Speicher. 1K wie beim Atmega32x sind schon ok. Weniger würde ich da nicht einplanen.

Zitat
@Dirk: Hast Du das schon gemacht?
Nein, noch nicht. Zeitlich sieht es bei mir im Moment auch nicht soo gut aus.
Ich werde das Repo aber diese Woche wenigstens mal anlegen.

Zitat
Wie schon gesagt wollte ich damit anfangen, das HMW-Protokoll nach "Arduinisch" zu uebersetzen.
In dem "alten" Code von mir ist das Protokoll ja schon fertig. Das muss du "nur" noch von Bascom in C++ portieren. :)

Zitat von: reneFHEM am 05 Mai 2014, 20:58:48
welche HW gebraucht wird, dafür habe ich auch noch kein Gefühl.
Ein kleiner Arduino, z.B ein Pro Micro sollte als Hardware vollkommen ausreichen.
Dann noch z.B. ein Max485 an den UART und schon kann es losgehen.
Für Debug-Ausgaben dann reicht dann ein Soft-UART.

Gruß
Dirk

Thorsten Pferdekaemper

Zitat von: Dirk am 05 Mai 2014, 23:58:35Wenn man die Module auch selber miteinander interagieren lassen möchte, Sprichwort Peering, dann braucht es auch noch Flash-Speicher. 1K wie beim Atmega32x sind schon ok.
Du meinst EEPROM, oder?
ZitatIn dem "alten" Code von mir ist das Protokoll ja schon fertig. Das muss du "nur" noch von Bascom in C++ portieren. :)
Schon klar, aber auch das braucht seine Zeit. Vor Allem wuerde ich das gerne ordentlich machen, also nicht einfach uebersetzen.
ZitatDann noch z.B. ein Max485 an den UART und schon kann es losgehen.
Für Debug-Ausgaben dann reicht dann ein Soft-UART.
Vorerst wuerde ich es erstmal dabei belassen, dass ich den RS485 per Soft-UART ansteuere. Dann kann ich den Arduino weiterhin ganz normal ueber USB am PC lassen. Spaeter wuerde ich dann das Coding flexibel gestalten. Zumindest soweit der Plan.

FUIP

Dirk

Zitat von: Thorsten Pferdekaemper am 06 Mai 2014, 11:10:41
Du meinst EEPROM, oder?
Selbstverständlich, keiner Verschreiber :)

Vorerst wuerde ich es erstmal dabei belassen, dass ich den RS485 per Soft-UART ansteuere. Dann kann ich den Arduino weiterhin ganz normal ueber USB am PC lassen.
Zum Debugen ist das ok.
Am Ende sollte die Firmware auch über den Bus einspielbar sein.

Thorsten Pferdekaemper

Zitat von: Dirk am 06 Mai 2014, 12:55:31Am Ende sollte die Firmware auch über den Bus einspielbar sein.
Klar, aber eins nach dem Anderen.
FUIP

reneFHEM

Der Arduino Uno ist bei mir Einsatzbereit. Ich kann also auch mit machen. Ich würde ja erstmal deb HMW-LC-SW2-DR nachbauen, da wir ja alle so ein Modul als Referenz besitzen.

Da könnte ich mich ja erstmal um das Userinterface kümmern. Also die Modis die über die beiden Tasten einstellbar sind. Oder brauchst Du Hilfe bei der Portierung des Stacks?


Thorsten Pferdekaemper

Zitat von: reneFHEM am 10 Mai 2014, 21:26:39
Der Arduino Uno ist bei mir Einsatzbereit. Ich kann also auch mit machen. Ich würde ja erstmal deb HMW-LC-SW2-DR nachbauen, da wir ja alle so ein Modul als Referenz besitzen.
Ich bin momentan (soweit es die Zeit zwischendurch erlaubt) dabei, eine Art IO-Modul zu bauen. Sozusagen ein HMW-IO-8-FM. Das liegt einfach daran, dass Dirks bisherige Sourcen schon etwas ähnliches machen.

ZitatDa könnte ich mich ja erstmal um das Userinterface kümmern. Also die Modis die über die beiden Tasten einstellbar sind.
Daran hatte ich bisher gar nicht gedacht. Mir würde es eigentlich ausreichen, wenn man das Teil über den Bus "programmieren" kann. ...aber mach' mal.

ZitatOder brauchst Du Hilfe bei der Portierung des Stacks?
Ich denke, dass ich das hinbekomme. Ich werde halt noch ein paar Tage brauchen. Je nach Wetter kann es sein, dass ich nächstes Wochenende was lauffähiges habe.

Bisher habe ich die folgenden Fragen/ offene Punkte:  (Es sind noch ein paar mehr...)

  • Es gibt immer noch kein git-Repository. (@Dirk: ?)
  • Das ganze sollte auch einen eigenen Bootloader bekommen. Es gibt dazu auch schon (Bascom)-Sourcen, aber mir ist noch nicht klar, wie ich das tatsächlich auf "Arduinisch" bekomme. Die Idee dazu ist, dass man eine neue Firmware tatsächlich auch über den RS485-Bus flashen kann.
  • Ich habe etwas den Überblick verloren, wie weit die Anbindung von Homematic Wired an FHEM gediehen ist. Insbesondere ist mir nicht klar, woher FHEM später wissen soll, wo im EEPROM welche Konfig-Option liegt.

Gruß,
    Thorsten
FUIP

MarkusO

Hallo zusammen,
ich beschäftige mich auch seit einigen Tagen mit dem Thema "Homebrew HMW-device mit Arduino" und war deshalb total begeistert, als ich diesen Thread gefunden habe.

Ich verwende einen Arduino Uno, den ich direkt per USB mit FHEM verbinde (erstmal zum Testen, RS485 kommt später). Das Device im FHEM ist dementsprechend /dev/ttyACM0.
Was bisher funktioniert: mit "define client HM485 000000AB" und "get client info" wird der Client angelegt und Infos zu HW-Typ, Version und Seriennummer abgefragt. Der Arduino-Client liefert diese Infos zurück (gibt sich als HMW_IO_12_Sw7_DR aus), so dass im FHEM 12 keys und 7 switches angelegt werden. Soweit so gut. Jetzt zu den Problemen.

Schalten der Ausgänge:
Beim Schalten der Ausgänge (z.B. client_14 auf ON) schickt FHEM zunächst 3x eine Botschaft raus, deren Bedeutung mir nicht ganz klar ist. Bei der anschließenden Botschaft wird der Befehl "x" verwendet, laut Protokoll-Doku hätte ich hier "s" erwartet. Ist das eine "normale" Kommunikation oder läuft hier irgend etwas schief, weil der Client noch nicht vollständig gepairt ist?

2014.05.11 13:06:09 3: HM485_LAN: TX: (93) I[0](0,F,B)(18) 00000001 -> 000000AB [2] FF(?)
2014.05.11 13:06:09 3: HM485_LAN: ACK: (93)
2014.05.11 13:06:09 3: HM485_LAN: Response: (93)
2014.05.11 13:06:09 3: HM485_LAN: TX: (94) I[1](0,F,B)(1A) 00000001 -> 000000AB [2] FF(?)
2014.05.11 13:06:09 3: HM485_LAN: ACK: (94)
2014.05.11 13:06:09 3: HM485_LAN: Response: (94)
2014.05.11 13:06:09 3: HM485_LAN: TX: (95) I[2](0,F,B)(1C) 00000001 -> 000000AB [2] FF(?)
2014.05.11 13:06:09 3: HM485_LAN: ACK: (95)
2014.05.11 13:06:09 3: HM485_LAN: Response: (95)
2014.05.11 13:06:09 3: HM485_LAN: TX: (96) I[3](0,F,B)(1E) 00000001 -> 000000AB [5] 78(x) 0DC8
2014.05.11 13:06:09 3: HM485_LAN: ACK: (96)
2014.05.11 13:06:09 3: HM485_LAN: Response: (96) 780DC8


Lesen der Eingänge:
Wird am Arduino eine angeschlossene Taste gedrückt, verschickt der Client die folgende Botschaft:
2014.05.11 13:16:34-681 3: HM485d: Rx:  I[2](0,Y,F,B)(9C) 000000AB -> FFFFFFFF [6] 4B(K) 01000A {8DFA}


In der FHEM-Zentrale passiert allerdings nichts (die Zeile steht auch nicht im allgemeinen Logfile, sondern nur in dem Logfile für das HM485-Gateway). Auch hier wieder die Frage, ob sich der Client "normal" verhält und es an den Einstellungen im FHEM liegt, oder ob die Botschaften von Original-HMW-Clients anders aussehen.


Zusammengefasst habe ich folgende Fragen:
1. Hat jemand Interesse an dem Arduino-Code? Dann würde ich das ganze nochmal etwas aufräumen, den Code mehr kommentieren und posten. Ist allerdings nichts was wirklich ausgereift ist, sondern nur schnell zusammen geschrieben, um die Kommunikation testen zu können.
2. Hat vielleicht jemand die Rohdaten von einer Kommunikation zwischen FHEM und Aktor bzw. FHEM und Sensor?
3. Sind die Quellen für das HMW-Gateway, die im Wiki angegeben sind (https://github.com/kc-GitHub/FHEM-HM485), noch aktuell, oder gibt es mittlerweile irgendwo Arbeitsstände mit weiteren Funktionen?
4. Irgendwo im Netz habe ich die Protokolldoku von Dirk gefunden. Besten Dank dafür - großartige Hilfe! Ist die Version 14 vom 04.04.2012 die aktuellste die es gibt? Besonders interessieren mich etwas mehr Details zum Discovery-Mode, aber dazu stelle ich später vielleicht noch ein paar Fragen. Eins nach dem Anderen.


Besten Dank & schöne Grüße
Markus

PS: Sorry, dass meine Fragen so protokolllastig sind - hab gesehen, dass es dazu auch einen eigenen Thread gibt. Aber wegen dem Arduino/Homebrew-Thema passt es hier vielleicht auch rein.