Verwendung des F-RAM-Moduls unter ioBroker

Verwendung des F-RAM-Moduls unter ioBroker

Verwendung des F-RAM-Moduls unter ioBroker

F-RAM ist ein statischer Speicher auf ferromagnetischer Basis, der seinen gespeicherten Inhalt auch ohne eine Stützspannung behält.

Daher ist er der ideale Speicher, um z.B. bei Stromausfall Daten zu sichern und wieder zurückzulesen (Status einer Alarmanlage oder Zustände von Beleuchtung etc.).

Zusätzliche Spannungsquellen wie Batterien oderKondensatoren sind daher nicht notwendig.

Dazu haben F-RAMs eine hohe Zuverlässigkeit und sind nicht anfällig für defekte Speicherzellen durch häufige Schreibvorgänge. Bei unseren verwendeten Chips gibt der Hersteller eine Lebensdauer von 10 Jahren an, wenn die gleiche Speicherzelle 3000 mal pro Sekunde beschrieben wird. Das sind mehrere Trillionen Schreibzugriffe.

 

Der F-RAM wird über den I2C-Bus angesprochen. Dazu nutzen wir die I2C-Tools, die mit "sudo apt-get install i2c-tools" installiert werden.

Danach kann mit "i2cdetect -y 1" überprüft werden, ob das Modul ansprechbar ist. Die "1" im Befehl kennzeichnet die Nummer des Busses, welche je nach verwendetem Single-Board-Computer abweichen kann (RasPi und Tinker Board = 1, Banana Pi M1 "2").

 

Das Ergebnis sollte wie folgt aussehen:

 

i2cdetect_FRAM

Das Speichermodul besitzt die Busadresse 0x50 (hexadezimal). Ist die "50" wie im Bild zu sehen, ist das Modul ansprechbar,.

 

In ioBroker wird nun in den Einstellungen des Javascript-Adapters das Modul "i2c-bus" eingetragen, welches die Kommunikation mit dem Modul abwickelt:

 

Javascript-Adapter

 

Anschliessend wird diese Einstellung mit "Speichern & Schliessen" gesichert und der Adapter neu gestartet. Dies dauert einen Moment, da der Adapter das neu hinzugefügte Modul automatisch installiert.

Nun können Sie in der Seitenleiste das Feld "Scripte" auswählen und ein neues Blockly-Script erzeugen. Dazu klicken Sie oben links auf das Symbol (1). Bitte erzeugen Sie das neue Script NICHT in den vorhandenen Ordnern "global" oder "common"!

Geben Sie nun dem Script einen Namen. Jetzt klicken Sie auf den Button zum Importieren eines Scripts (2).

 

Blockly-Script

 

In das sich darauf öffnende Feld fügen Sie den folgenden Code ein und drücken anschliessend OK:

 

Code:

 <xml xmlns="http://www.w3.org/1999/xhtml">
  <block type="procedures_defcustomnoreturn" id="APks4ftk%~Uh{Zb8H1by" x="88" y="-37">
    <mutation statements="false">
      <arg name="Adress"></arg>
      <arg name="ObjectName"></arg>
      <arg name="StateListe"></arg>
    </mutation>
    <field name="NAME">FramWriteVariable</field>
    <field name="SCRIPT">Y29uc3QgaTJjID0gcmVxdWlyZSgnaTJjLWJ1cycpOwpjb25zdCBGUkFNX0FERFIgPSAweDUwOwpjb25zdCBpMmMxID0gaTJjLm9wZW5TeW5jKDEpOwp2YXIgdGVtcDsKdmFyIHRlbXAyID0gMDsKdmFyIGRhdGEgPSBuZXcgQnVmZmVyKFsweDAwLCAweDAwLCAweDAwXSk7CnZhciBEYXRhQnVmID0gbmV3IEJ1ZmZlcihbMHgwMCwweDAwXSk7CnZhciBzZW5kQnl0ZXMgPSAwOwp2YXIgZmlyc3RTdGFydCA9IGZhbHNlOwp2YXIgaSA9IDA7CnZhciB0ZW1wUmVjZWl2ZSA9IDA7CgoKdGVtcCA9IGdldFN0YXRlKE9iamVjdE5hbWUpLnZhbDsgCgppZiAodGVtcCA9PT0gdHJ1ZSkgeyAvL1dlbm4gQk9PTCA+IFRSVUUgZGFubiAyNTUKICAgIHRlbXAyID0gMHhmZjsgfQogICAgZWxzZSBpZiAodGVtcCA9PT0gZmFsc2UpIHsgLy9XZW5uIEJPT0wgPiBGQUxTRSBkYW5uIDI1NAogICAgICAgIHRlbXAyID0gMHhmZTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIGlmICh0ZW1wIDw9IDI1MykgewogICAgICAgIHRlbXAyID0gTWF0aC5yb3VuZCh0ZW1wKTsgLy9SdW5kZW4gYXVmIEdhbnp6YWhsIQogICAgICAgIH0KICAgICAgICBlbHNlIHsgY29uc29sZS5sb2coIlphaGwgenUgZ3Jvc3MgenVtIFNwZWljaGVybiwgaWdub3JpZXJ0ISIpCiAgICB9CiAgICB9CgovL0FkcmVzc2UgaW4gTE9XLXVuZCBISUdILUJ5dGUgemVybGVnZW4gLyBQdWZmZXIgYXVmYmVyZWl0ZW4KCkFkcmVzcyAtPSAxOwogICAgIApkYXRhWzBdID0gQWRyZXNzID4+PiA4OyAKZGF0YVsxXSA9IEFkcmVzcyAlIDI1NTsKZGF0YVsyXSA9IHRlbXAyOwoKCnNlbmRCeXRlcyA9IGkyYzEuaTJjV3JpdGVTeW5jKEZSQU1fQUREUiwgMywgZGF0YSk7Ci8vY29uc29sZS5sb2coIlRyYW5zbWl0dGVkIGJ5dGVzOiAiICsgc2VuZEJ5dGVzKTsKaTJjMS5jbG9zZVN5bmMoKTsKCnJldHVybiAwOwovL2NvbnNvbGUubG9nKCJUcmlnZ2VyZWQgT2JqZWN0OiAiICsgT2JqZWN0TmFtZSArICIgV2VydDogIiArIHRlbXAyICsgIiBBZHJlc3NlOiAiICsgQWRyZXNzKQo=</field>
    <comment pinned="false" h="80" w="160">Schreibt Wert von Objekt in FRAM. Achtung! Datentyp wird automatisch ermittelt. Zahlenwerte möglich bis 253,Zahlen werden gerundet OHNE Kommastellen gespeichert!</comment>
  </block>
  <block type="procedures_defcustomreturn" id="=#k8cx?OI]SQ^1INn`6R" x="88" y="-12">
    <mutation statements="false">
      <arg name="StateListe"></arg>
      <arg name="StartUp"></arg>
    </mutation>
    <field name="NAME">FramRestore</field>
    <field name="SCRIPT">Y29uc3QgaTJjID0gcmVxdWlyZSgnaTJjLWJ1cycpOwpjb25zdCBGUkFNX0FERFIgPSAweDUwOwpjb25zdCBpMmMxID0gaTJjLm9wZW5TeW5jKDEpOwp2YXIgRGF0YUJ1ZiA9IG5ldyBCdWZmZXIoWzB4MDAsMHgwMF0pOwp2YXIgc2VuZEJ5dGVzID0gMDsKdmFyIGZpcnN0U3RhcnQgPSBmYWxzZTsKdmFyIGkgPSAwOwp2YXIgdGVtcFJlY2VpdmUgPSAwOwoKICAgZm9yIChpID0gMDsgaSA8PSAoU3RhdGVMaXN0ZS5sZW5ndGggLSAxKTsgaSsrKXsKICAgICAgIAogICAgICAgIERhdGFCdWZbMF0gPSBpID4+PiA4OyAvL1B1ZmZlciBpbiBMT1ctIHVuZCBISUdIYnl0ZSB6ZXJsZWdlbiAKICAgICAgICBEYXRhQnVmWzFdID0gaSAlIDI1NTsKICAgICAgICAKICAgICAgICBpMmMxLmkyY1dyaXRlU3luYygweDUwLCAyLCBEYXRhQnVmKTsgLy9aZWlnZXIgaW0gRlJBTSBhdWYgQWRyZXNzZSBzZXR6ZW4KICAgICAgICB0ZW1wUmVjZWl2ZSA9IGkyYzEucmVjZWl2ZUJ5dGVTeW5jKDB4NTApOwogICAgICAgIAogICAgICAgIGlmICh0ZW1wUmVjZWl2ZSA9PSAyNTQpIHsKICAgICAgICAgICAgc2V0U3RhdGUoU3RhdGVMaXN0ZVtpXSxmYWxzZSk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHRlbXBSZWNlaXZlID09IDI1NSkgewogICAgICAgICAgICBzZXRTdGF0ZShTdGF0ZUxpc3RlW2ldLHRydWUpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmICh0ZW1wUmVjZWl2ZSA8PSAyNTMpIHsKICAgICAgICAgICAgc2V0U3RhdGUoU3RhdGVMaXN0ZVtpXSx0ZW1wUmVjZWl2ZSk7ICAgCiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBjb25zb2xlLmxvZygiVmFyaWFibGUga2FubiBuaWNodCBnZXNjaHJpZWJlbiB3ZXJkZW4iKTsKICAgICAgICB9CiAgICAgICAgICAgIGNvbnNvbGUubG9nKCJPYmpla3QgTmFtZTogIiArIFN0YXRlTGlzdGVbaV0pOyAKICAgfSAKCmkyYzEuY2xvc2VTeW5jKCk7CgpyZXR1cm4gMDsK</field>
    <comment pinned="false" h="80" w="160">Liest die Werte aus dem FRAM und schreibt sie in die Objekte zurück.</comment>
  </block>
  <block type="variables_set" id="=K!e=GxST+2O65jgI?pz" x="138" y="138">
    <field name="VAR">firstStart</field>
    <value name="VALUE">
      <block type="logic_boolean" id="yhD|mD|t`#7G{WSGHPBJ">
        <field name="BOOL">FALSE</field>
      </block>
    </value>
    <next>
      <block type="comment" id="LOb`CKqQ}T#Sh9mWAU,w">
        <field name="COMMENT">Liste mit zu sichernden Objekten</field>
        <next>
          <block type="variables_set" id="Nq]I/{nCjrE#U.U)N+!q">
            <field name="VAR">ListStates</field>
            <value name="VALUE">
              <block type="lists_create_with" id="^lJCd%paO{4:rJ%||nxV">
                <mutation items="1"></mutation>
                <value name="ADD0">
                  <block type="field_oid" id="#n@-_3_0}rnahwfZaxPW">
                    <field name="oid">default</field>
                  </block>
                </value>
              </block>
            </value>
            <next>
              <block type="timeouts_settimeout" id="GX7uLLj+K?}afc:WvXf_">
                <field name="NAME">timeout</field>
                <field name="DELAY">60</field>
                <field name="UNIT">sec</field>
                <statement name="STATEMENT">
                  <block type="comment" id="5q*ICW-0PQ.qoQH6-=%h">
                    <field name="COMMENT">Aufruf der Funktionen:</field>
                    <next>
                      <block type="comment" id="L~9rd,ld,A8#U{T4*m7I">
                        <field name="COMMENT">prüft ob System neu gestartet ist und liest Werte zurück in die Objekte</field>
                        <next>
                          <block type="controls_if" id="`=7[@S/JrE711z/,/+(Y">
                            <value name="IF0">
                              <block type="logic_compare" id="{)L3T`[omTZvb5eC?;I{">
                                <field name="OP">NEQ</field>
                                <value name="A">
                                  <block type="variables_get" id="0=8[1~qls/IeoT9`H~OE">
                                    <field name="VAR">firstStart</field>
                                  </block>
                                </value>
                                <value name="B">
                                  <block type="logic_boolean" id="+=2Nmh7XDD)RappH_.zT">
                                    <field name="BOOL">TRUE</field>
                                  </block>
                                </value>
                              </block>
                            </value>
                            <statement name="DO0">
                              <block type="variables_set" id="sQLpL+AH-1OsW2f+x^UM">
                                <field name="VAR">firstStart</field>
                                <value name="VALUE">
                                  <block type="procedures_callcustomreturn" id="p_DE.G+c5T#+%f~?jr:v">
                                    <mutation name="FramRestore">
                                      <arg name="StateListe"></arg>
                                      <arg name="StartUp"></arg>
                                    </mutation>
                                    <value name="ARG0">
                                      <block type="variables_get" id="[IlM7WJDB4QCAP[EKb0T">
                                        <field name="VAR">ListStates</field>
                                      </block>
                                    </value>
                                    <value name="ARG1">
                                      <block type="variables_get" id="K,?wmg+:ISt}VC|A1RKR">
                                        <field name="VAR">firstStart</field>
                                      </block>
                                    </value>
                                  </block>
                                </value>
                                <next>
                                  <block type="variables_set" id="cCgMY=%{P,sJ}h9-`8Ey">
                                    <field name="VAR">firstStart</field>
                                    <value name="VALUE">
                                      <block type="logic_boolean" id="-D0zUPe@1/IAXe2lB6k{">
                                        <field name="BOOL">TRUE</field>
                                      </block>
                                    </value>
                                  </block>
                                </next>
                              </block>
                            </statement>
                          </block>
                        </next>
                      </block>
                    </next>
                  </block>
                </statement>
                <next>
                  <block type="comment" id="cec.eAW/tJ)1,g*UA8O#">
                    <field name="COMMENT">Schreibt bei jeder Änderung den jeweiligen Wert in den FRAM</field>
                    <next>
                      <block type="on_ext" id="Cg1qI~h8r_#WP~v+3X{I">
                        <mutation items="1"></mutation>
                        <field name="CONDITION">ne</field>
                        <field name="ACK_CONDITION"></field>
                        <value name="OID0">
                          <shadow type="field_oid" id="ffe7IE*N0U}hQYJKcmX/">
                            <field name="oid">default</field>
                          </shadow>
                          <block type="variables_get" id="gxhJ`jNJc5178lZ9jp4G">
                            <field name="VAR">ListStates</field>
                          </block>
                        </value>
                        <statement name="STATEMENT">
                          <block type="controls_if" id="-eU:*rVa*e)QN8[~@=eE">
                            <value name="IF0">
                              <block type="logic_compare" id="vSK+[Cm}2JiS/Y*fc(o;">
                                <field name="OP">EQ</field>
                                <value name="A">
                                  <block type="variables_get" id="ZFQLAq9tsh/llbr*OGFM">
                                    <field name="VAR">firstStart</field>
                                  </block>
                                </value>
                                <value name="B">
                                  <block type="logic_boolean" id="`j[gF;lcXV[1CCm*vcNf">
                                    <field name="BOOL">TRUE</field>
                                  </block>
                                </value>
                              </block>
                            </value>
                            <statement name="DO0">
                              <block type="procedures_callcustomnoreturn" id=",OFt^a:mWT.;k)IH(yX_">
                                <mutation name="FramWriteVariable">
                                  <arg name="Adress"></arg>
                                  <arg name="ObjectName"></arg>
                                  <arg name="StateListe"></arg>
                                </mutation>
                                <value name="ARG0">
                                  <block type="lists_indexOf" id="?G!=oKmoo(7zd~r~m*hz">
                                    <field name="END">FIRST</field>
                                    <value name="VALUE">
                                      <block type="variables_get" id="`Di,Vaa2,RW#?glOfSEJ">
                                        <field name="VAR">ListStates</field>
                                      </block>
                                    </value>
                                    <value name="FIND">
                                      <block type="on_source" id="^s/~!40A[6v*ULrbfLBO">
                                        <field name="ATTR">id</field>
                                      </block>
                                    </value>
                                  </block>
                                </value>
                                <value name="ARG1">
                                  <block type="lists_getIndex" id=",3u,G{-*Le1wd99J25^V">
                                    <mutation statement="false" at="true"></mutation>
                                    <field name="MODE">GET</field>
                                    <field name="WHERE">FROM_START</field>
                                    <value name="VALUE">
                                      <block type="variables_get" id="A@~I,rDsXxM}VUx6r5`d">
                                        <field name="VAR">ListStates</field>
                                      </block>
                                    </value>
                                    <value name="AT">
                                      <block type="lists_indexOf" id="k5w|G|*wUClk.T%!,nyS">
                                        <field name="END">FIRST</field>
                                        <value name="VALUE">
                                          <block type="variables_get" id="UqNf4X^UNte0|QQ]Gzb4">
                                            <field name="VAR">ListStates</field>
                                          </block>
                                        </value>
                                        <value name="FIND">
                                          <block type="on_source" id="K--I8Ag=(`=JdyH6(zX*">
                                            <field name="ATTR">id</field>
                                          </block>
                                        </value>
                                      </block>
                                    </value>
                                  </block>
                                </value>
                                <value name="ARG2">
                                  <block type="variables_get" id="NN[Ig1EL.)F8yTulNn-C">
                                    <field name="VAR">ListStates</field>
                                  </block>
                                </value>
                              </block>
                            </statement>
                            <next>
                              <block type="debug" id="!7F3rr+BxvUg.3%IzR;}">
                                <field name="Severity">debug</field>
                                <value name="TEXT">
                                  <shadow type="text" id="%~e?sSCq)pUs9{Q/84n-">
                                    <field name="TEXT">test</field>
                                  </shadow>
                                  <block type="on_source" id="Fj/}a}W(N~2C8CdsTc7M">
                                    <field name="ATTR">id</field>
                                  </block>
                                </value>
                              </block>
                            </next>
                          </block>
                        </statement>
                      </block>
                    </next>
                  </block>
                </next>
              </block>
            </next>
          </block>
        </next>
      </block>
    </next>
  </block>
</xml>


   Jetzt  sollte das Script wie folgt erscheinen:

Objekt_hinzufuegen

 

Unter dem ersten gelben Kommentar können Sie nun ein Objekt anhängen,welches gesichert werden soll. Mit Klick auf das Zahnrad im Block "erzeuge Liste mit" können weitere "Anschlüsse" hinzugefügt werden.

Das Script wrd bei jeder Änderung den Wert des jeweiligen angeschlossenen Objektes in den FRAM speichern und nach einem Neustart des Scriptes (z.B. einem Stromausfall etc.) wieder zurücklesen.

Damit bleiben wichtige Einstellungen und Zustände auch bei Stromausfall oder einem Absturz des Rechners erhalten und werden automatisch wiederhergestellt. Das Script erkennt dabei selbstständig den Datentyp des Wertes. Zahlenwerte sind so bis zu einem Wert von 253 möglich, Kommastellen werden automatisch auf ganze Zahlen gerundet. Auch Logikwerte (true/false) werden gespeichert.

Mit unserem FRAM-Modul können Sie so bis zu 8192 Werte sichern.