Arduino / Firmata (FRM)

Begonnen von ntruchsess, 24 Januar 2013, 12:07:28

Vorheriges Thema - Nächstes Thema

ntruchsess

Hi,

das ist mein allererstes Posting hier im Forum (in der Mailinglist war ich auch nicht aktiv), ich benutze FHEM allerdings schon ein paar Jahre mit cul und FHT und Hilfe dazu habe ich eigentlich nie benötigt (ich gehöre zu den Leuten, die erst mal im Sourcecode nachschauen, bevor sie Fragen stellen...)
Nunden, daher fange ich hier auch gleich mal damit an, was ich zu FHEM in den letzen Wochen dazugebastelt habe:

Die Arduino-plattform (http://www.arduino.cc) ist ja recht beliebt für die Umsetzung kleinerer Mess- und Regelaufgaben. Unter anderem beinhaltet die Plattform das Firmata-protokoll (siehe http://www.firmata.org) um auf einfache Weise vom PC aus auf die Pins eines Arduinos zugreifen zu können. Einfach einen Arduino über USB am Rechner anschließen, Standardfirmata mit der Arduino-IDE (findet sich dort unter 'Beispiele) auf den Arduino flashen, die gewünschte Hardware an den Arduino-pins anschließen und loslegen...
Ich habe ein paar FHEM-module geschrieben, die das an FHEM anbinden. Die Module benutzen die 'perl-firmata' von ursprünglich geschrieben von Aki Mimoto (https://github.com/amimoto/perl-firmata), ich habe in den letzten Wochen substanziell zum Projekt beigetragen. (Mein Branch der Perl-firmata auf Github https://github.com/ntruchsess/perl-firmata ist sozusagen der 'Unstable' Branch)...

Die FHEM-module findet Ihr jetzt im FHEM-svn, auf Github wird das nicht mehr weitergepflegt.

10_FRM.pm
20_FRM_IN.pm
20_FRM_OUT.pm
20_FRM_AD.pm
20_FRM_PWM.pm
20_FRM_SERVO.pm
20_FRM_I2C.pm

10_FRM ist sozusagen die Basis (das IODev) für die anderen Module.
Die Module '20_FRM_*' bilden jeweils einen als Digitaler Eingang (IN), digitaler Ausgang (OUT), analoger Eingang (AD) oder analoger Ausgang (PWM) konfigurierten Pins des Arduino ab. Das Modul FRM_SERVO etspricht im wesentlichem dem Modul FRM_PWM, rechnet aber Gradangaben selbsttätig in die zugehörigen Pulsweiten um. Es lassen sich jeweils so viele Ein/Ausgabe Devices pro Arduino konfigurieren, wie dieser physikalisch besitzt. (Natürlich muss man darauf achten, dass nicht alle Arduino-pins alle Ein-/ausgabemöglichkeiten besitzen). Konfiguriert man einen Pin für einen nicht unterstützen Modus so gibt es mit der aktuellen Firmata-version (2.3) direkt einen Fehler - ältere Versionen schlucken so eine Fehlkonfiguration einfach so, der betreffende Pin funktioniert dann einfach nicht.

Hier mal ein kurzer Ausschnitt aus der fhem.cfg:
---------------------------------------
# definiere FRM als IO-Device - Baudrate 57600 ist default in der Standardfirmata

define FIRMATA FRM /dev/ttyUSB0@57600
attr FIRMATA loglevel 6
attr FIRMATA sampling-interval 1000 # Wert ist in ms und 14Bit breit, also nur bis 16384 setzbar (Beschränkung des Firmata-protokolls) - gilt für alle Pins

define Firmata_OUT FRM_OUT 11 # definiert Arduino Pin 11 als digitalen Ausgang

define Firmata_IN FRM_IN 12 # definiert Arduino Pin 12 als digitalen Eingang

define Firmata_ANALOG FRM_AD 17 # definiert Arduino Pin 17 als analogen Eingang
---------------------------------------

das zeigt ziemlich genau den aktuell unterstützen Stand. Man muss noch alles manuell eintragen, autocreate wird noch nicht unterstützt. Derzeit legen Eingabe-module den jeweils gelesenen Wert im 'state'-reading ab.

Die Module für I2C und OneWire sind auch fertig (s.u.). Mit denen kann man ICs die I2C bzw. OneWire unterstützen am Arduino anschließen und dann über FHEM auslesen, zyklisch loggen oder beschreiben kann. Ein Modul um Modellbauservos zu steuern ist auch geplant.

Über Vorschläge, was da funktionell noch sinnvoll unterzubringen wäre (z.B. weitere readings?), würde ich mich freuen.

Gruß,

Norbert
while (!asleep()) {sheep++};

rudolfkoenig

> Die FHEM-module findet Ihr aktuell noch auf Github (falls ich mal Schreibberechtigung auf das FHEM-svn bekommen sollte, würde ich es dorthin umziehen):

Dazu benoetige ich ein sourceforge account (kein OpenID), und die Zusage, dass die Module
- grundsaetzlich funktionieren
- im Modul selbst fuer commandref.html dokumentiert sind
- Du in der naechsten Zeit bereit bist diese Module hier im forum zu supporten.

ntruchsess

na dann schaue ich mir mal an, wie das mit der internen Dokumentation funktioniert, kann ja nicht so schwer sein.
while (!asleep()) {sheep++};

ntruchsess

The modul for I2C-devices attached to Arduino is working :-)

https://github.com/ntruchsess/fhem-mirror/blob/firmata/FHEM/20_FRM_I2C.pm

to enable one has to define the attribute 'i2c-config' to FRM in fhem.cfg:

define Firmata FRM /dev/ttyUSB0@57600
attr Firmata i2c-config 0

for each I2C Device attached to the Arduino define a FRM_I2C entry:
define Firmata_I2C FRM_I2C <i2c-address> <register-to-read> <bytes-to-read>

e.g. to read data from a DS1307 (a realtime-clock) you define:
define Firmata_I2C FRM_I2C 104 0 7

104 is the 7-bit address of DS1307, Firmata reads out 7 bytes starting at register-address 0 and sends them to FRM_I2C in intervals of sampling-interval defined for the FRM-device (default 1000ms).

the byte values are stored as a space-separated string in reading 'values'.
while (!asleep()) {sheep++};

ntruchsess

so, pod-dokumentation in den Modulen ist drin. Mein Account auf Sourceforge ist 'ntruchsess' (so wie hier).

die Module funktionieren hier bei mir, ich rüste damit gerade meine eigene FHEM-installation um erweiterte Mess- und Steuerungsmöglichkeiten auf.

Im Forum supporten ist im Prinzip kein Problem, jedenfalls dann, wenn die sich das ganze erst mal in einem Supporthread bündelt damit ich benachrichtigt werden, wenn sich jemand meldet.

Gruß,

Norbert
while (!asleep()) {sheep++};

rudolfkoenig

Hab Dich hinzugefuegt. Wg. support wuerde ich empfehlen erst mal "Sonstige Systeme" zu abonnieren. Wenn es viel wird, koennen wir mit sicherheit eine Neue Gruppe anlegen.

ntruchsess

danke, ich habe die Module grade ins SVN committed. Wie sollen wir mit den perl-firmata libraries umgehen - als externe Dependency belassen (und in der commandref.html dokumentieren, wo man das herunterladen und wie man es installieren kann) oder eine Kopie in fhem aufnehmen?

Gruß,

Norbert
while (!asleep()) {sheep++};

rudolfkoenig

Darfst Du entscheiden. Wenn aufnehmen, dann bitte in einem der beiden FHEM Unterverzeichnisse, nicht direkt in FHEM.

ntruchsess

ich habe in FRM Unterstürzung für das OWX-modul eingebaut, man kann damit jetzt einen Arduino als aktiven OneWire BusMaster mit OWX (und allen unterstützten Devices) nutzen. Im Test mit 2 DS18B20 Temperatursensoren funktioniert es hier ganz ordentlich.

Dazu muss man nur ein FRM-device konfigurieren und in der Definition des OWX den Arduino-pin angeben, den man als OneWire-Anschluss benutzen möchte:

define FIRMATA FRM /dev/ttyUSB0@57600
define Firmata_OWX OWX 10

macht den Arduino-pin 10 als OneWire Bus nutzbar. Angeschlossene Sensoren werden vom OWX beim selbstständig gefunden und definiert :-)

Gruß,

Norbert

P.S: ich hab die perl-firmata ins FHEM/lib Verzeichnis abgelegt. Damit sollte das out-of-the-box bei jedem laufen.

P.P.S: wo kriege ich einen Login für das wiki her? Ich würde dort gerne ein HowTo ablegen, damit das Thema auch unter die Leute komme ;-)

while (!asleep()) {sheep++};

ntruchsess

ich hab ein neues Modul 20_FRM_SERVO.pm geschrieben.
Damit kann man (analoge) Modelbauservos an Arduino-pins ansteuern. Mit Set kann man einfach Gradangaben setzen, der Arduino gibt dann am konfigurierten Pin ein Pulsweitenmoduliertes Signal aus, das den Servo in die gewünschte Stellung drehen läßt.
Die meisten Servomotoren erwarten Pulsweiten von ca. 500-2500 ms. (Die Defaults im Modul sind entsprechend gesetzt). Hat man ein Servo, das andere Pulsweiten erwartet, kann man das über die Attribute 'min-pulse' und 'max-puls' einstellen.

Viel Spaß damit,

Norbert
while (!asleep()) {sheep++};

ntruchsess

FRM_IN hat jetzt einen counter, jedesmal, wenn der gemonitorte Pin seinen Status ändert, wird der Counter hochgezählt. Man kann über das Attribut 'count-mode' einstellen, ob das bei einer ansteigenden Flanke ('rising'), einer fallenden Flanke ('falling') oder in beiden Fällen ('both') geschehen soll.
Wenn der Counter höher als der im attribut 'count-threshold' eingestellte Wert zählt, wird das reading 'alarm' auf 'on' gesetzt. Anschließend beginnt der Counter wieder bei 0. Der Alarm muss mit 'set <name> alarm off' wieder gelöscht werden.

FRM_AD kann jetzt Schwellwerte überwachen. Diese setzt man mit den Attributen 'upper-threshold' und 'lower-threshold'. Beim Über- ('upper-threshold') beziehungweise Unter-schreiten ('lower-threshold') wird jeweils das zugehörige reading 'alarm-upper-threshold' bzw. 'alarm-lower-threshold' auf 'on' gesetzt. Diese Alarme müssen nicht zurückgesetzt werden - sobald der gelesene Wert den jeweiligen Grenzwert wieder unter- bzw. überschreitet, wird der zugehörige Alarm selbsttätig auf 0 gesetzt.

Beide Module benutzen das im 'FRM'-device gesetzte 'sampling-interval' zur Überwachung. (Das gibt's in Firmata nur einmal pro Arduino). Erfolgen die Statusänderungen an den Pins schneller als das Sampling-interval es monitored, dann können Alarme bzw. Zählvorgänge übersprungen werden, da der Arduino die Pins mit dem Sampling-interval pollt. Das minimale Sampling-interval liegt mit der Standardfirmata bei 19ms, das sollte für Hausautomationsbelange reichen ;-).

Auch wenn auf dem selben Arduino Abfragen an I2C oder OneWire Devices erfolgen, können Messungen verspätet stattfinden und dabei ggf. zu zählende Ereignisse übergangen werden. Die maximale Verzögerung bei OneWire-Abfragen liegt bei ca. 300ms. (Auch das sollte für Hausautomation dicke langen...)

Gruß,

Norbert
while (!asleep()) {sheep++};

ntruchsess

while (!asleep()) {sheep++};

ntruchsess

mal ein Update:
FRM unterstützt jetzt auch Arduino/Firmata über Ethernet:
Link
while (!asleep()) {sheep++};

ntruchsess

es gibt ein neues Modul für FRM:

20_FRM_LCD.pm

damit kann man über I2C an einem Arduino mit Firmata angeschlossene LCD Displays ansteuern und sich so eine nette kleine Statusanzeige an seinen FHEM-server basteln.

Unterstützt werden bisher Displays die über einen PCF8574T an I2C angebunden sind (das sind die, die auf eBay günstig unter den Suchbegriffen 'LCD' und 'I2C' angeboten werden, ich habe es mit diesem hier getestet. Die zahlreichen eBay-angebote mit 20x4 Zeichen scheinen den gleichen Umsetzer für den I2C-bus zu benutzen (irgendwie kommen offenbar fast alle diese chinesischen I2C-LCDs mit der gleichen Library für den Arduino daher...)

Die Library habe ich nach perl portiert, man braucht also keine spezielle Firmata (außer dass I2C-support mit drin sein muss, aber das kann die StandardFirmata schon lange).

eingebunden wirds mit:

define <name> FRM_LCD <typ> <size-x> <size-y> <i2c-addresse>
z.B. also 'define Display FRM_LCD i2c 16 2 63' für o.g. LCD

die Ausgabe wird durch setzen des 'text' readings geupdated. Backlight, automatischer Zeilenumbruch und so was wird über Attribute an-/und abgeschaltet.

Viel Spaß damit :-)

Gruß,
Norbert

while (!asleep()) {sheep++};

klausw

Zitat von: ntruchsess am 08 März 2013, 19:14:50
es gibt ein neues Modul für FRM:

20_FRM_LCD.pm

Hallo Norbert,

ich schreibe gerade ein Modul, um den I2C vom Raspberry Pi anzusprechen (two level approach)
lässt sich Dein I2C Modul erweitern, das es auch andere Schnittstellenmodule ausser FRM nutzen kann?
Bei den FRM Modulen steige ich nicht ganz durch. Ich nutze IOWrite() für die Kommunikation zum Schnittstellenmodul.

Grüße
Klaus
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280