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

ntruchsess

Hallo Klaus,

das FRM_I2C-modul kann ja nichts außer Registerinhalte über I2C auslesen. Die eigentliche Kommunikation geht da über die Perl-firmata-library und der I2C-bus selber hängt dann am Arduino. Zwischen der Perl-firmata und dem FRM_I2C-modul sitzt noch das eigentliche FRM-modul das die Verbindung zur Perl-firmata verwaltet. Der einzige Anwendungsfall für I2C den ich selber nutzen konnte war ein über I2C angebundenes LCD-display (siehe Modul FRM_LCD).

Nützlich wäre es natürlich für unterschiedliche Arten von I2C-bus-anbindung ein einheitliches Interface in FHEM zu haben, das von Modulen wie z.b. mein Modul für I2C-basierte LCDs als IODev benutzt wird und den Hardwarenahen Zugriff einheitlich kapselt (Analog zu OWX das ja auch zwischen den 1-Wire-devicespezifischen Modulen und den verschiedenen Busmastern vermittelt). Wie das Interface konkret für I2C ausssehen könnte, darüber hbe ich mir bisher allerdings noch nicht so recht Gedanken gemacht - wenn Du da was sinnvolles erarbeitest, dann würde ich mein FRM_I2C-modul gerne daran anpassen. FRM-like wäre es Referenzen auf die Funktionen in der Initialize-methode über einen symbolischen Namen im device-hash abzulegen (so wie das z.B. mit ReadFn etc gemacht wird). Perl-like wäre es die Hardwarespezifischen Module in eigenen Packages unterzubringen und die Methoden tatsächlich gleich zu benennen (und den Hardwarespezifischen Treiber als Objekt zu instanziieren). Guck die mal an, wie das im asynchronen OWX gelöst ist. Siehe dazu:
00_OWX.pm
11_OWX_SER.pm
11_OWX_FRM.pm
11_OWX_CCC.pm
11_OWX_Executor.pm
Hier implementiert 00_OWX die Methoden, die die einzelnen Device-module (OWTHERM, OWSWITCH...) aufrufen und delegiert die Aufrufe an die in den Busmasterspezifischen Module weiter.

Gruß,

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

klausw

Hallo Norbert,

Die OWX ist derzeit zu komplex für meine Programmierkenntnisse. Ich habe z.B. nicht verstanden, wie 21_OWTHERM die Werte zurückgeliefert bekommt. Aber das nur am Rande. Vielleicht geht auch ein anderer Ansatz:
Derzeit habe ich 2 I2C Hardwarelösungen zum testen.

  • Raspbery Pi
  • ein über Ethernet angebundener PIC-Controller, auf dessen I2C über RAWTCP durchgegriffen werden kann
Und ein logisches Modul für den PCF8574 Portextender.

In denen ist die WriteFn implementiert, auf die ich über logische Module mit IOWrite() zugreife.
In umgekehrter Richtung kann ich mit  Dispatch() an das logische Modul die Anworten senden, welche dort in der  ParseFn verarbeitet werden.
Die Grundlagen dafür habe ich aus der 00_CUL.pm und der 10_FS20.pm übernommen.
Den Vorteil in dieser Lösung sehe ich, das zwar für jede I2C Hardware ein Modul geschrieben werden müsste, aber die logischen Module dafür nicht angefasst werden müssen. Ausserdem lässt sich leicht auch unterschiedliche Schnittstellengegebenheiten eingehen:
Beim Raspberry z.B. kann ich die I2Cread Kommandos direkt beantworten, während ich es bei der Lösung über Netzwerk über einen Sendepuffer und die ReadFn mache.
Hat diese Variante einen Nachteil? Du hast es ja doch ein bisschen anders gelöst.
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

ntruchsess

was sind denn die Aufrufparameter der WriteFn? I2C-addresse, Übertragungsrichtung, optionale Daten und Übertragungsgeschwindigkeit?
while (!asleep()) {sheep++};

klausw

An die WriteFn wird mit beispielsweise IOWrite übergeben:

IOWrite($hash, "i2cwrite", ( defined( $hash->{ID} )? $hash->{ID} : "00" ) . " " . $hash->{I2C_ADDR} . " " . sprintf("%.2X ",$msg));

IOWrite($hash, "<i2cwrite|i2cread>", <id> ) . " " . <I2C Adresse> [. " " . <Daten für I2C wenn i2csend>]);

Die ID hatte ich eingefügt, falls man z.B. einen Portextender in einzelene Devices aufteilen möchte...sonst würde die Zuordnung über Dispatch() in die andere Ringtung nicht laufen. Sie kann aber "00" bleiben wenn nur ein Device pro I2C Adresse genutzt wird.

Empfangene Daten kommen über die ParseFn:
sub I2C_PCF8574_Parse($$) {
my ($hash, $msg) = @_;
my($sid, $addr, @msg) = split(/ /,$msg);
...

da ist wieder ID, I2CAdresse, und die Daten

Übertragungsgeschwindigkeit würde ich, wenn nötig, im physikalischen Modul für die Schnittstelle fest einstellen. Habe ich derzeit nicht vorgesehen. Ist für das LCD ein Sendeintervall notwendig?

Als ich mit dem PIC-Controller angefangen habe musste ich mir keine Gedanken machen, ob ich Byte oder Word Werte lesen möchte. Das lief
automatisch. BeiM Raspberry ist das anders. Das ist für das LCD sicher nicht so interessant, da nur Byteweise gesendet wird.

Wie gesagt, alles ein erster Wurf. Für Vorschläge bin ich offen.
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

ntruchsess

#19

                                          Hier ist wohl eine Klammer zu viel?
                                          V
IOWrite($hash, "<i2cwrite|i2cread>", <id> ) . " " . <I2C Adresse> [. " " . <Daten für I2C wenn i2csend>]);


Im Prinzip würde ich sagen, dass das prinzipiell passt, wobei ich die parameter nicht als einen einzigen String, sondern als einzelne Parameter übergeben würde. Der Aufruf der WriteFn erlaubt das. Eventuell in einen Hash der Art { direction => i2cwrite, id => <..>, i2caddress => <...>, data => <...> } gepackt - wenn man optionale Parameter hat, können die im Hash einfach weggelassen werden, bei positionalen Parametern muss man sie explizit als undef mit angeben (und in einem zu parsenden String müsste man einen Platzhalter für ungesetzte Parameter vereinbaren).

Dispatch und ParseFn würde ich nicht benutzen, das ist einfach zu sehr auf den Anwendungsfall zugeschnitten, dass quasi ungefragt empfangene Messages von Dispatch verteilt werden sollen und dieses erst herausfinden muss, an welches Device die jeweilige Message gesendet werden soll. Bei der I2C-Kommunikation ist die I2C-addresse ja schon bekannt (und nicht Bestandteil der gelesenen Daten. Das sollte man benutzen, in dem man über die Clientdevices iteriert und schaut, bei welchem die I2C-addresse passt. Man kann ja trotzdem die in der Initialize-methode angegebene ParseFn aufrufen oder (da die Aufrufsemantic ja nicht dieselbe ist) z.B. eine 'I2CReceiveFn' oder so definieren.

So was wie Sendeintervalle würde nicht im physikalischen Modul abwickeln.
while (!asleep()) {sheep++};

klausw

Die Übergabe durch Parameter ist natürlich viel übersichtlicher. Das werde ich abändern.

Mit Dispatch und ParseFn war ich auch nicht so glücklich, ich habe die I2C Adresse halt immer mit zurückgesendet, um das passende Modul zu finden.
Wie kann ich denn im physikal. Modulteil nach dem passenden Client suchen? Würde das mit devspec2array gehen?
Es könnten ja die verschiedensten Module sein.
Und wie bekomme ich die Botschaft dann an das passende Client  'I2CReceiveFn' gesendet?

Zitat von: ntruchsess am 04 Februar 2014, 17:09:39
So was wie Sendeintervalle würde nicht im physikalischen Modul abwickeln.
Ok, was ich nicht verstehe ist, wozu die Sendeintervalle benötigt werden.
Ich schicke im Moment alles so schnell wie möglich raus (also direkt nach einer Antwort vom I2C Bus)
Grundsätzlich kann man Intervalle in die Sendeschleife im phys. Modul mit einbauen.
Wenn ein Sendeintervall über IOWrite mit übergeben wird, speichere ich den mit im Sendebuffer ab und setze wenn eine Zeit definiert ist einfach einen Timer, der entsprechend wartet.
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

ntruchsess

Wie findet das physikalische Modul den zur I2C-response passenden Client?

Man legt die I2C-Addresse wärend define im Client-hash ab. Anschließend assoziiert man den Client-hash per AssignIODev mit seinem physikalischen Modul. Hierbei wird der der Client-hash im '.clientArray' des physikalischen Moduls abgelegt. Wenn man die I2C-response an den Client zurückschicken will, iteriert man (so wie in der Dispatch-funktion) über alle Clients aus '.clientArray' des physikalischen Devices bis man den Client-hash findet, der die passende I2C-addresse enthält.

die 'I2CReceiveFn' ruft man mit der CallFn-methode (aus fhem.pl) auf. Aufrufschema findest Du gleich mehrfach in fhem.pl.

der I2CReceiveFn sollte auch einen Parameter 'success' mitgeben, damit das Modul erfährt, ob ein Schreibvorgang erfolgreich war.

ein Sende- oder Leseinterval ist natürlich nur für I2C-module sinnvoll, aus denen man einen veränderlichen Wert auslesen kann - z.B. einen A/D-wandler oder eine Echtzeituhr. Weil das naturgemäß spezifisch für das jeweilige I2C-Device ist, muss das im Client-modul definiert sein.

FRM_I2C ist übrigens ein generisches I2C-Client-modul, das eigentlich nur dazu taugt in einem regelmäßigen Intervall ein I2C-Device auszulesen. Das physikalische Modul dazu ist FRM selbst. FRM_LCD setzt direkt auf FRM auf und hat sonst keine Verbindung mit FRM_I2C.

... Wir sollten für das I2C-thema einen eigenen Thread aufmachen, das führt von Arduino/Firmata jetzt ganz schön weit weg ;-)

Gruß,

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

klausw

da hast du recht

hier ist der Neue:
http://forum.fhem.de/index.php/topic,19797.0.html

da wartet schon die NAchricht ;)
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

Dr. Boris Neubert

Hallo Norbert,

nachdem mein Raspberry Pi samt 1-Wire-Bus-Installation beim Blitzschlag in Elektronikschrott verwandelt wurde, suche ich nun eine neue Lösung für das Interfacing von FHEM mit meinem S0-fähigen Stromzähler.

Die alte Lösung nutzte den DS2423-Dual-Counter. Der ist aber abgekündigt und nur noch teuer erhältlich.

Ich habe hier noch einen Arduino-Nano-Klon aus China rumliegen. Der könnte dann auch gleich noch ein paar andere Schaltaufgaben übernehmen, z.B. die Lüfter im Rack schalten. Entweder baue ich mir eine eigene Spezialfirmware dafür oder ich nutze Firmata mit Deinen Modulen. Zu letzteren habe ich eine Frage:

Ich möchte die Zählimpulse puffern, so dass ich nicht nach jedem Neustart von FHEM den Zählerstand händisch neu kalibrieren muss. Das geht prinzipiell, wenn ich den eingebauten Counter im ATmega328p nutze. Gehe ich recht in der Annahme, dass Firmata das Auslesen des Counters NICHT unterstützt? Meine Google-Suche dazu war ergebnislos.

Viele Grüße
Boris



Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

ntruchsess

Hallo Boris,

die Counter des Atmega328 nutzt die Firmata bisher noch nicht. Wäre aber an sich nicht schwer das einzubauen.

Ist eher eine Frage des drumherum (Brownout-detection, Persistierung im eeprom, Konfiguration der Firmata aus eeprom bei Reset (ohne Verbindung zu FHEM, sauberes Wiederaufsetzen beim re-connect ohne 'Reset und Neukonfiguration') was fehlt, damit das tatsächlich signifikant besser wäre als FHEM-seitiges Zählen dessen, was der verbundene Arduino 'live' meldet. Die Firmata ist halt primär auf 'Verbunden mit einem PC' hin ausgerichtet. Wobei eigentlich alle anderen Firmata-features von gewissen Offline-fähigkeiten bzw. konfigurierbarem Safe-fallback profitieren würden. Vieliecht hättest Du ja Lust dich da an der Entwicklung (mit code oder auch nur Konzeptionell - sprich Protokoll-design) zu beteiligen?

Gruß,

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

Dr. Boris Neubert

Danke, Norbert, für die Antwort.

Um ein Gefühl dafür zu bekommen, was eigentlich gemacht werden müsste, habe ich einmal eine Custom-Firmware für den Arduino-Nano-Klon geschrieben, welche bis zu 6 Counter (schalten bei fallender Flanke) und 3 Switches bedienen kann, und welche ich über eine kleine Kommandosprache steuere. Wegen einiger durch die Arduino-Library bedingten Einschränkungen habe ich die Counter nicht über die internen Counter/Timer gelöst sondern über Pin Change Interrupts.

In Kombination mit der Entprellung der Zähleingänge habe ich da nun doch einen ganzen Tag lang dran gesessen. Eine Integration in Firmata würde noch eine Schicht Komplexität darüber legen, ohne mir extra Nutzen zu bringen. Bei Interesse stelle ich den Kode aber gerne als Anschauungsobjekt zur Verfügung. Ich habe ihn so geschrieben, dass die Kommandos leicht über ECMD/ECMDDevice zu geben sind.

Morgen nehme ich das Teil mal als kombiniertes Interface für den S0-Zähler und die Lüftersteuerung im Rack in Betrieb.

Viele Grüße
Boris
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!