Arduino mit OneWireFirmata
Einleitung zur OneWireFirmata (ConfigurableFirmata)
mit dem Modul 10_FRM.pm kann man einen Arduino als OneWire-Busmaster für das Modul 00_OWX.pm benutzen. Auf dem Arduino muss dazu eine erweiterte Version der Firmata-Firmware geladen werden. Unterstützt werden im prinzip alle Arduino-Versionen. Auf Arduinos mit nur 16kb RAM (MEGA168P) muss man die Zahl der eingebauten Features reduzieren, auf allen Arduinos mit mehr als 16kb Ram (MEGA328P aufwärts) läuft die Firmware unverändert.
Die aktuelle Arduino-IDE bringt zwar schon eine Version der StandardFirmata mit, diese enthält aber noch keine Unterstützung für OneWire. Diese findet man im eigenen Fork. Den kompletten Branch kann man sich auch bequem als zip-Archiv herunterladen
Die ConfigurableFirmata kommuniziert mit FHEM über den USB-anschluss oder Ethernet (sowohl original EthernetShield, 'Arduino Ethernet' als auch ENC28J60 basierte Boards werden unterstützt, letztere unter Verwendung der UIPEthernet-library).
Alternativ kann man einen DS2482 als 1-Wire-Busmaster an den I2C-Bus des Arduino anschließen. Die nötige ConfigurableFirmata mit DS2482-Unterstützung findet sich hier bzw kann man sich hier als zip herunterladen.
Allgemeine Funktionsweise
Der Arduino ist in der Lage bestimmte 1-Wire-kommandoabfolgen selbstständig auszuführen. Der Firmata-client (OWX(_ASYNC)) fordert vom Arduino/Firmata entweder an: 'mache eine 1-Wire-Bussuche', dann läuft diese auf dem Arduino und schickt das Ergebniss (alle gefundenen Devices) an den Firmata-client zurück. Oder es wird angefordert: 'mache einen Bus-reset, sprich ein bestimmtest Device mit der Addresse XXX an, schicke folgende Bytes dorthin und lese anschließend YY Bytes. Der Arduino tut das und wenn er fertig ist, schickt er die YY Bytes an den Firmata-client zurück. Mehr Intelligenz steckt im OneWire-firmata feature nicht drin. Der Arduino merkt sich dabei nichts. Nach dem Abarbeiten einer 1-Wire-kommandfolge und dem Verschicken des Ergebnisses vergisst er alles, was er getan hat. Mehr Eingenintelligenz wäre bei der Speicherknappheit auch nicht stabil unterzubringen, als Alternaive müsste man die Anzahl der Devices auf dem 1-Wire Bus (stark) einschränken. Das ist aber schon deutlich mehr Eigenintelligenz als die anderen Busmasterchips (DS2480 oder DS2482) mitbringen. Denen muss man jeden Einzelschritt vorgenannter Abfolgen einzeln sagen (und dabei noch auf das korrekte Timing achten). Beim Arduino bedeutet das Starten einer Bussuche, dass OWX gerade einmal 4 Bytes in einem Rutsch abschickt und dann auf das fertige Ergebnis wartet. OWX wartet dabei synchron und blockiert FHEM, OWX_ASYNC wartet in einem Protothread wärend FHEM weiterläuft und der Arduino parallel dazu den 1-Wire-bus durchsucht.
Der FirmataScheduler wird zur Zeit von den FRM-Modulen noch nicht unterstützt. Geplant ist damit iButtons über OWID mit einer schnellen, arduinoseitig getriggerten Bussuche zu versorgen. Der Scheduler ist in der Lage Firmata-kommando-abfolgen zu speichern und zeitversetzt (auch zyklisch) abzuspielen, damit kann man sich das Senden der genannten 4 Bytes zum Starten der Bussuche sparen. Der Arduino schickt dann die Ergebnisse selbstständig im vorgegebenen Interval. Leider kann man (wg. des begrenzten Speichers) keine komplexeren Aufgaben im FirmataScheduler unterbringen, insbesonders kann man nicht einfach mal alle Device-abfragen da rein programmieren, da wäre schon nach einer Handvoll Devices der Speicher des Arduinos voll. (Eine DS18B20 Abfrage braucht z.B. ca. 30 Bytes pro Device. Das klingt nach wenig, ist aber eine ganze Menge, wenn nur wenige 100kb verfügbar sind). Ist der Speicher zu Ende stürzt der Arduino einfach ab bzw. resettet sich.
Wenn man einen DS2482 am Arduino hat, dann ändert sich nichts prinzipielles an oben gesagtem. Mit dem DS2482 hat der Arduino ggf. ein physikalisch besser an 1-Wire angepasstes Interface und muss weniger Timing selber in Software machen. Damit sollten mehr Devices bei längerem 1-Wire-bus funktionieren, als mit der reinen Softwarelösung. Alle anderen Einschränkungen und/oder Möglichkeiten sind aber praktisch identisch.
Vorbereitungen in der Arduino IDE
Zur Installation auf den Arduino wird natürlich erst mal die Arduino-IDE benötigt (http://arduino.cc/en/Guide/Libraries))
Hat man das 'libraries' Verzeichnis seiner Arduino-ide-installation gefunden (unter Ubuntu z.B. unter /usr/share/arduino/libraries/), gibt es dort normalerweise schon ein Verzeichnis 'Firmata'. Falls nicht, muss dieses angelegt werden. Die in dem Verzeichnis befindlichen Dateien 'Firmata.h', 'Firmata.cpp' und 'Boards.h' müssen durch die im arduino-configurable.zip-file enthaltenen Versionen ersetzt werden. Am besten kopiert man einfach den gesamten Inhalt des Ordners 'arduino-configurable' in das 'libraries/Firmata'-Verzeichnis (mitsamt des Unterordners 'examples').
Anschließend sollte man noch den Unterordner 'ConfigurableFirmata' aus den soeben kopierten Examples in sein Sketchbook kopieren. Wichtig: der Ordnername darf nicht umbenannt werden ansonsten erkennt die Arduino-IDE das Verzeichnis nicht als korrekten Sketch. Macht man das so, dann findet man nach einem Neustart der IDE den ConfigurableFirmata-sketch unter 'Datei'->'Sketchbook'->'sketches'->'ConfigurableFirmata'.
Kompilierung
Wenn man die in dieser neuen Firmataversion eingebauten Features reduzieren möchte (weil man nur eine MEGA168P verwenden will und z.B. gar keine Servos ansteuern möchte), muss man nur im 'ConfigurableFirmata'-sketch die entsprechenden includes auskommentieren.
Werden aufgrund der Sketchgröße einige Features auskommentiert und gibt es bei der ersten Kompilierung Fehler, so muss der Sketch erstmalig mit allen Features kompiliert werden. Erst anschließend kann auf das notwendige Maß der Umfang reduziert werden.
Um 1wire zu nutzen muss neben OneWireFirmata auch FirmataExt aktiviert werden. FirmataExt ist für SysEx-basierte Features (wie 1-Wire) unverzichtbar. Ohne FirmataExt geht nur Digital+Analog-I/O
Grundsätzlich ist empfohlen nur die wirklich benutzten Features zu aktivieren. Beispielsweise passen I2C und 1Wire nicht gleichzeitig mit UIPEthernet ins RAM eines ATMega328. Kann man zwar noch flashen, stürzt dann aber mangels ausreichend Heap sofort ab. Also erst mal sparsam anfangen und nur die Dinge, die wirklich genutzt werden gleichzeitig aktivieren. Wenn es geht, dann eine fixe IP verwenden (kein DHCP), dann kann man UDP in der uipethernet-conf.h abstellen - das spart ca. 5kb Flash und ein paar 100 Bytes RAM.
Naja - hat man es erst mal geschafft, dann muss man nur noch unter 'Tools'->'Board' den eigenen Arduino, 'Tools'->'Programmer' den verwendeten Programmieradapter sowie unter 'Tools'->'serieller Port' den korrekten Port auswählen und mit dem Upload-knopf (der Rechtspfeil im Kreis oben links) den geladenen Sketch compilieren und auf das Board hochladen.
Falls man unter Windows Probleme hat den Arduino über USB zu connecten findet sich hier weitere Information: http://arduino.cc/en/Guide/Windows#toc2
Einbindung des Arduino in FHEM
Der Arduino wird in FHEM über das Modul 10_FRM.pm angesprochen (dazu bitte die aktuelle Development-version herunterladen (http://www.dhs-computertechnik.de/downloads/fhem-cvs.tgz) aus dem SVN auschecken oder per updatefhem aktualisieren).
# definiere FRM als IO-Device - Baudrate 57600 ist default in der Standardfirmata define Arduino FRM /dev/ttyUSB0@57600 # definiere FRM als IO-Device über Ethernet ('global' bindet an alle IP-Addressen des Servers) define Arduino FRM <port> global
Siehe dazu auch die Commandref
Einbindung der 1WireDevices in FHEM
Ein im Anschluss daran definiertes 1-Wire Device kann dann einfach einen der Arduino-Pins als 1-Wire Busmaster nutzen. Das funktioniert an allen Pins, die Digital IO unterstützen. Wenn man das FRM Device schon definiert hat, findet man im laufenden FHEM unter den FRM-Attributen einen Eintrag: 'onewire-pins', dieser listet alle Pins auf, die 1-Wire unterstützen:
define <device-name> OWX <arduino-pin>
Zb. ist beim Arduino Mini Pro der D9 = Pin9 gut geeignet.
Nach dem Definieren des 1-Wire Devices fängt dieses selbsttätig an über den Arduino-Pin nach 1-Wire Devices zu suchen und im Raum 'OWX' automatisch anzulegen.
Wenn man die DS2482-Firmata benutzt, dann findet man beim FRM-Device unter 'onewire-pins' nur die I2C-Pins. Das sind z.B. bei einem Uno/Nano die Pins 18 und 19 (das entspricht den Analogpins 4 und 5). Einen der beiden muss man dann bei der Definition des OWX-Moduls angeben um die DS2482-Unterstützung zu aktivieren:
define <device-name> OWX 18