Vorstellung: HBW-Sen-SC16: universal Input Device

Begonnen von katze, 16 Februar 2017, 20:39:42

Vorheriges Thema - Nächstes Thema

katze

Hallo
ich habe aus Thorstens SC8 ein SC16 mit vielen Einstellmöglichkeiten gemacht:
Basis ist ein Arduino Nano - in der SC16 Version sind alle Pins belegt, darum ist debug nicht mehr möglich ;D

Es werden bis zu 4 Events gesendet:

       
  • press_short
  • press_double
  • press_long
  • release_long
Für jeden Kanal sind folgende Settings möglich:

       
  • input_locked (bei yes wird dieser Kanal nicht eingelesen)
  • inverted (bei yes wird 5V als nicht gedrückt erkannt / 0V ist gedrückt)
  • pullup (bei yes wird der Interne Pullup verwendet)
  • multiclick_time (0 bis 500ms, zur entprellung für doubleclick)
  • long_click_time (bis 2.5s, zur entprellung für long clicks)
  • double_click_aktion (was soll bei erkanntem doubleclick gesendet werden [doubleclick, n-times short, 1 time short, nothing])
  • long_click_action (was soll bei erkanntem long click gesendet werden [long+hold+release, short+hold+release, short, short+short on release, short+release, nothing])
Durch diese Einstellungsmöglichkeiten lassen sich sowohl Türkontakte, Taster als auch Schalter einlesen. (Oder andere Geräte)
Peering ist noch nicht möglich (und von mir vorerst nicht vorgesehen)

Arduino Auslastung:
Flash: 51%
RAM: 59%
EEProm: 71% (mit Link Tabelle für 100 peerings)
Programmdurchlaufzeit 0.33ms bis 0.45ms im Idle

Änderungen:

       
  • Kanalanzahl auf 16 erhöht
  • Einstellmöglichkeiten hinzugefügt
  • device ID auf 0x7F geändert
  • FW Version aufgeteilt (HByte ist jetzt Application und LByte Protokoll: aus 0x0306 wurde 0x0136)
  • InterframeSpace im Protokoll hinzugefügt (wegen meinem Raspberry UART-485 Transciever)
  • pm File angepasst
  • FactoryReset Button auf Analogkanal A7 (kann nur als Analog eingang verwendet werden und verbraucht keinen IO Pin)
Sourcecode: https://github.com/katze2k/HBW
Als nächstes kommt dann ein 16 Kanal Ausgang - Viel mehr als Digitale Ein und Ausgänge braucht man ja nicht  ::)
Beide Geräte sollen dann eine gemeinsam nutzbare Platine für ein Hutschinengehäuse bekommen...

Thorsten Pferdekaemper

Hi,
so ein riesiger Unterschied zum HBW-Sen-Key-12 ist da ja nicht, oder?
Zum InterframeSpace: Kannst Du das ein bisschen näher erläutern?
...und zum .pm-File: Hoffentlich hast Du auch ein XML gemacht. Es wird demnächst große Änderungen im FHEM-Teil zu HM485 geben, so dass diese selbst gebastelten pm-Dateien nicht mehr funktionieren werden.
Gruß,
   Thorsten
FUIP

katze

Hallo
ich habe gestern leider gemerkt, dass du ne aktuelle Lib im Github hast :(
Mein Device basiert auf der 2 Jahre alten aus https://github.com/kc-GitHub/HM485-Lib
Deine aktuelle hat schon ein Interframespace(#define DIFS_), wobei ich für 7ms anstelle 210 + 100 bin (laut Protokollbeschreibung)
Die Aktuellste lib ist doch https://github.com/ThorstenPferdekaemper/HBWired/ oder?
Wenn das die aktuellste ist, werde ich mein device auf diesen stand migrieren (und mir nochmals den Key-12 anschauen).

ein xml habe ich nicht erstellt, wird aber mit hilfe deines tutorials nachgeholt.

Und bei Gelegenheit ziehe ich links von der wiki zu dem Tutorial und Github (dann gibt es eine zentrale Informationsstelle, was die Arbeit für einige erleichtern wird.)

Gruß

Thorsten Pferdekaemper

Zitat von: katze am 17 Februar 2017, 09:58:42
Deine aktuelle hat schon ein Interframespace(#define DIFS_), wobei ich für 7ms anstelle 210 + 100 bin (laut Protokollbeschreibung)
Das müsste ich mir selbst nochmal genau anschauen. Ich glaube, dass die 210+100 nur nach einer erkannten Kollission gelten. Sonst sind es weniger.

Zitat
Die Aktuellste lib ist doch https://github.com/ThorstenPferdekaemper/HBWired/ oder?
Ja, und alles andere wird momentan nicht mehr gepflegt. Ich muss vielleicht mal einen Kommentar bei Dirks git reinschreiben.

ZitatWenn das die aktuellste ist, werde ich mein device auf diesen stand migrieren
Das solltest Du auf jeden Fall machen. Dadurch wird das ganze auch kompakter.

Zitatein xml habe ich nicht erstellt, wird aber mit hilfe deines tutorials nachgeholt.
Hintergrund ist der: Die pm-Dateien haben starke Schwächen. Z.B. geht die Reihenfolge der config-Parameter verloren. Ich werde wahrscheinlich eine automatische Umwandlung der XML in .pm einbauen, oder aber direkt aus den XML lesen (was aber zu langsam werden könnte).

Zitat
Und bei Gelegenheit ziehe ich links von der wiki zu dem Tutorial und Github (dann gibt es eine zentrale Informationsstelle, was die Arbeit für einige erleichtern wird.)
Ja, das ware gut.

Gruß,
   Thorsten
FUIP

katze

#4
Hab wegen der Interframespace nachgeschaut:
1) wenn sendFrame(onlyIfIdle=true) aufgerufen wird:
wird nur gesendet, falls seit 210ms bis 310ms Busruhe war. wenn keine Busruhe war wird 1 zurückgegeben (nicht blockierend).
Aufgerufen wird dies nur bei broadcastAnnounce(), sendInfoMessage() und sendKeyEvent() - in diesen Fällen ist das device dafür zuständig das senden erneut zu versuchen (wie bei handleBroadcastAnnounce() ).
2) wenn sendFrame() aufgerufen wird:
wird sofort gesendet. Aufgerufen wird so nur bei sendAck() und processEvent().
3) Bei Kollisionen:
Falls ein Ack erwartet wird und nicht kommt, wird immer 200ms gewartet und dann neu gesendet bis zu 3 mal (blockierend). Falls onlyIfIdle=true wird nach dem ersten Versuch abgebrochen, falls ein Frame innerhalb 150ms empfangen wurde, aber kein Ack (also andere Geräte miteinander sprechen)

da es DIFS heist gehe ich davon aus, dass es nur zur Priorisierung eingefügt wurde (erst wenn alle notwendigen/schnellen Antworten gesendet wurden, kann eine DIFS Nachricht gesendet werden)

dann bau ich mir noch ein SIFS mit rein.

aufgetauchte Fragen:
1) werden beim Sen-Key-12 tastenevents "verschluckt", falls mehrere tasten innerhalb von 300 ms gedrückt werden, denn da wird nur einmal versucht zu senden ???
2) im processEvent() wird als antwort auf (A)nnounce kein gültiger txframe erzeugt (data[0] = i; aber keine länge der Daten) - Andererseits dürft ein Announce niemals an dieser Stelle ankommen da es immer ein Broadcast ist.

Thorsten Pferdekaemper

Zitat von: katze am 17 Februar 2017, 19:42:56
Hab wegen der Interframespace nachgeschaut:
1) wenn sendFrame(onlyIfIdle=true) aufgerufen wird:
wird nur gesendet, falls seit 210ms bis 310ms Busruhe war. wenn keine Busruhe war wird 1 zurückgegeben (nicht blockierend).
Aufgerufen wird dies nur bei broadcastAnnounce(), sendInfoMessage() und sendKeyEvent() - in diesen Fällen ist das device dafür zuständig das senden erneut zu versuchen (wie bei handleBroadcastAnnounce() ).
Das habe ich so implementiert, wie ich es aus Dirks Beschreibung des Protokolls rausgelesen habe. Ich habe aber nicht ausprobiert, wie das die Standard-Homematic-Geräte machen. Wenn das mal jemand messen könnte...
Andererseits ist dabei wahrscheinlich die Idee, dass nach 210ms nicht einmal ein erwartetes ACK mehr kommen kann. Vielleicht sollte da jedes Device mithören und nur dann wirklich 210ms warten, wenn noch ein ACK oder so zu erwarten wäre.

Zitat
2) wenn sendFrame() aufgerufen wird:
wird sofort gesendet. Aufgerufen wird so nur bei sendAck() und processEvent().
Ja, da es da ja Blödsinn wäre, zu warten. Der Sender erwartet ja eine Antwort und wartet darauf keine 210ms.

Zitat
3) Bei Kollisionen:
Falls ein Ack erwartet wird und nicht kommt, wird immer 200ms gewartet und dann neu gesendet bis zu 3 mal (blockierend).
Ja, das ist so laut der Protokollbeschreibung, siehe oben. Das mit dem Blockierend gefällt mir auch nicht so richtig, aber was wäre die Alternative? Wie viel Aktivität (Tastendrücke o.ä.) soll man puffern, wenn man gerade sowieso Sendeprobleme hat?
...und was ist mit empfangenen Kommandos? Wenn man in der Zeit, in der man auf ein ACK wartet, von der Zentrale ein Kommando bekommt oder von einem anderen Device einen Tastendruck, dann ist eh was faul.

Zitat
Falls onlyIfIdle=true wird nach dem ersten Versuch abgebrochen, falls ein Frame innerhalb 150ms empfangen wurde, aber kein Ack (also andere Geräte miteinander sprechen)
Waren das 150ms? Ich dachte 200ms.
Ja, das habe ich so eingebaut. Was soll man auch machen, wenn man seine eigenen Messages nicht durchbekommt und dann jemand anderes dazwischenquatscht?

Zitat
da es DIFS heist gehe ich davon aus, dass es nur zur Priorisierung eingefügt wurde (erst wenn alle notwendigen/schnellen Antworten gesendet wurden, kann eine DIFS Nachricht gesendet werden)
Ich habe jetzt mal nachgesehen, was DIFS und SIFS nochmal ist. Meiner Meinung nach ist DIFS implementiert. Das sind die 210 bis 310ms vor dem ungefragten Senden. Bis auf die Diskussion, wie lange DIFS sein sollte, ist das meiner Meinung nach ok so wie es ist.

Zitatdann bau ich mir noch ein SIFS mit rein.
Brauchen wir das wirklich? Wozu muss man das ACK oder die Antwort auf ein "get" verzögern? Gab es da Probleme mit der Umschaltung auf "Empfang"?

Zitat
aufgetauchte Fragen:
1) werden beim Sen-Key-12 tastenevents "verschluckt", falls mehrere tasten innerhalb von 300 ms gedrückt werden, denn da wird nur einmal versucht zu senden ???
Hmmm, das muss ich mir selbst mal anschauen. Die Frage auch hier: Was wäre die Alternative?

Zitat2) im processEvent() wird als antwort auf (A)nnounce kein gültiger txframe erzeugt (data[0] = i; aber keine länge der Daten) - Andererseits dürft ein Announce niemals an dieser Stelle ankommen da es immer ein Broadcast ist.
Muss ich mir auch mal anschauen.

Insgesamt muss ich da nochmal genauer nachschauen. Momentan bin ich aber eher dabei, die FHEM-Seite aufzupolieren. Das kann also noch ein bisschen dauern. Wir können aber gerne hier über mögliche Änderungen und Lösungen diskutieren.

Gruß,
   Thorsten
FUIP