Lichtsteuerung Teil 3: Bus / Firmware

Ein Thema hätten wir noch: Es gibt Hardware und ein tolles Webinterface, aber wie kommen die Signale dann vom Webinterface zum Schieberegister? Und was macht man, wenn man feststellt, dass man neben Lampen auch noch RGB-Streifen, 7-Segment-Anzeigen und Weiteres ansteuern möchte?

Ohne besondere Vorkehrungen passen nämlich nicht sehr viele Geräte an einen RasPi: Es gibt 10-12 nutzbare GPIO Pins, d.h. bei 2 Pins (Clock + Data) pro Endgerät ist Platz für 5-6 Geräte. Wenn man das Taktsignal gemeinsam benutzt, werden daraus sogar 9-11.
Das mag ausreichen, hat aber immer noch das Problem, dass es nicht skaliert und man für jedes neue AVR-Board ein zusätzliches Kabel vom RasPi bis zum Board ziehen muss.

Also: Warum nicht ein Datenbus?

Wir haben sowieso schon SDA und SCL und ein an I2C angelehntes Protokoll, es ist also kein Problem, auch noch Adressierung draufzuwerfen. Anstelle von einzelnen Befehlsbytes und einem “ohai ich bin fertig”-Signal gehen dann einzelne Befehlsbytes, 2 Adressbytes und das Fertigsignal über die Leitung. Üblicherweise fängt man mit der Adresse an und schickt erst dann Daten; da die am Bus angeschlossenen Geräte aber vollkommen ungeplant entwickelt werden und deshalb noch nicht mal im Voraus bekannt ist, wieviele Byte so ein Gerät maximal empfangen möchte, kommt unsere Adresse zum Schluss.

Protokoll

Aktuell haben wir drei Gerätesorten und dementsprechend drei Programme, um Bits und Bytes an AVRs zu schicken.

  • bitwrite / avrshift: Liest einzelne Bits ein und schickt je 8 Bit als Byte an einen AVR. Wird von den Schieberegistern verwendet (ein Bit je Relais)
  • bytewrite / blinkencontrol: Liest einzelne Bytes als Zahl und schickt sie an einen AVR. Wird z.B. für RGB-Steuerung benutzt (1-Byte-Mode, dann 1 Byte pro Farbkanal)
  • charwrite: Liest einzelne Zeichen, wandelt sie in Codes für 7-Segment-Displays um und schickt diese auf die Leitung. Damit kann ein im Raum aufgehängtes 7-Segment-Display extrem leicht per netcat / date ‘+%H.%M’ | si2c-charwrite / … angesteuert werden

Das “Ohai ich bin fertig”-Signal ist übrigens kein Befehlsbyte, sondern eine spezielle Kombination von SDA (“serial data”) und SCL (“serial clock”). Ein einzelnes Bit wird übertragen, indem zuerst SDA auf das Bit gesetzt und anschließend SCL von 0 (low) auf 1 (high) gewechselt wird. Beim AVR triggert das einen Interrupt und er liest ein Bit vom Bus ein, anschließend muss der Busmaster (d.h. der RasPi) zuerst SDA und anschließend SCL auf low setzen. Das Ende der Übertragung wird signalisiert, indem nach dem letzten Bit SCL high bleibt, SDA auf high gesetzt wird, und erst dann wieder SCL auf low. Darauf hat der AVR auch einen Interrupt, so dass er genau weiß, dass der Befehl durch ist und er ohne irgendwelche Timinggeschichten seine Daten auswerten und (falls die Adresse passt) übernehmen kann.

Hardware

Die reine Softwareseite wäre damit erledigt: 65535 Geräte pro Bus auszureizen wird nicht schnell gehen. Bleibt also noch die Hardware.

Zunächst eine gute Nachricht: Da sowieso SDA und SCL schon an jedem Board per Optokoppler getrennt sind, muss man sich keine Sorgen um getrennte Stromkreise machen und zusammen mit dem Datenbus auch nicht zwangsläufig noch Spannung übertragen. D.h. man kommt im einfachsten Fall mit drei Adern (SDA, SCL, GND) aus und kann beliebig dünne Kabel verwenden, denn wo keine Betriebsspannung übertragen wird, gibt es auch keinen nennenswerten Spannungsabfall zu verhindern.

Aktuell kann man die Hardwareseite des Bus grob als Daisy-Chaining bezeichnen: Vom RasPi führt genau ein Kabel weg, daran hängt z.B. eine RGB-Leiste, und diese RGB-Leiste hat ein Eingangskabel und ein Ausgangskabel für den Bus (die intern einfach miteinander verbunden sind). Daran kann dann das Kabel zum nächsten Gerät angeschlossen werden, und so weiter. Das ist simpel, führt aber spätestens zu Problemen, wenn man spontan mitten zwischen zwei Geräten noch ein drittes anschließen will.

Vampirstecker a la 10BASE5 Ethernet kommen auch nicht in Frage, da wir drei und nicht zwei Leitungen haben. Aber (mit Dank an Das Labor in Bochum, die das wohl so tun): Es gibt Vampirklemmen mit beliebig vielen Polen für Flachbandkabel, die sich auch sehr stressfrei nachträglich aufbringen lassen. Eine solche Klemme kostet 8ct, und 30m 8pol-Flachbandkabel für 6 Euro sind auch ein sehr akzeptabler Preis. Zumal man daraus sogar 60m machen kann, denn für unsere Zwecke reichen 4 Leitungen (SDA, SCL, GND und dann noch 12V für Verbraucher mit ganz geringem Stromverbrauch) völlig aus.

Diese Idee werden wir demnächst ausprobieren und dann hoffentlich einen leicht erweiterbaren und extrem simplen Datenbus haben. Er unterstützt zwar nur Kommunikation in eine Richtung und ist nicht schnell, aber für komplexere Sachen lässt sich ja ein CAN-Bus parallel dazu verlegen.