{"id":220,"date":"2020-11-07T12:24:55","date_gmt":"2020-11-07T11:24:55","guid":{"rendered":"http:\/\/blog.0link.net\/?p=220"},"modified":"2020-11-07T16:50:24","modified_gmt":"2020-11-07T15:50:24","slug":"raspberry-python-und-i2c","status":"publish","type":"post","link":"https:\/\/blog.0link.net\/index.php\/2020\/11\/07\/raspberry-python-und-i2c\/","title":{"rendered":"4. Raspberry, Python und I2C"},"content":{"rendered":"\n<p>Mit Python habe ich bereits verschiedene Erfahrungen sammeln k\u00f6nnen, so dass ich nun &#8222;nur noch&#8220; verstehen musste, wie I2C \u00fcberhaupt funktioniert und wie man das in Python umsetzt. Als Bibliothek kommt smbus und f\u00fcr ein HD44780-LCD-Display noch eine kleine Treiber-Bibliothek aus einem Tutorial zum Einsatz. &nbsp;<\/p>\n\n\n\n<h2>Levelshifter zwischen Pi und Arduino<\/h2>\n\n\n\n<p>Bevor wir nun gedankenlos den I2C-Bus des Raspberry und des Arduino verbinden und uns wundern, dass der Pi zwei GPIO-Ports weniger hat, m\u00fcssen wir einen Pegelwandler f\u00fcr 3,3 und 5 Volt einsetzen, denn der Pi mag keine Spannungen \u00fcber 3,3V am GPIO und der Arduino arbeitet regul\u00e4r mit 5V. Der Pegelwandler wird einfach in die Busleitungen SCL und SDA eingef\u00fcgt und mit Masse und Vin aus beiden Richtungen versorgt. Wenn das erledigt ist, kann man mit dem Kommandozeilentool i2cdetec schauen, ob die Slaves am Bus gefunden werden. Ist dies der Fall, geht es an die Programmierung.<\/p>\n\n\n\n<h2>I2C im Python ansprechen<\/h2>\n\n\n\n<p>Als erstes ein paar Experimente mit dem Display. Auf dem HD44780 ist, dank des kleinen Treibers, schnell ein erster Text angezeigt. Der Code f\u00fcr die Ansteuerung ist fast selbsterkl\u00e4rend und man hat mit dem darunterliegenden I2C-Bus eigentlich noch keinen richtigen Kontakt. Wenn man es genau betrachtet ist der Treiber auch eher ein Wrapper, der die Strings f\u00fcr das Display in die passenden Bytes und Adressierungen umsetzt und die Kommunikation mit dem I2C-Bus \u00fcber smbus organisiert.<\/p>\n\n\n\n<h2>Pi spricht mit dem Arduino<\/h2>\n\n\n\n<p><strong>Aufgabe 1: <\/strong>Vom Pi einen Befehl senden, der auf dem Arduino eine LED ein oder aus schaltet. <\/p>\n\n\n\n<p>Das gelingt Mithilfe einiger Anleitungen aus dem Netz und der Wire-Bibliothek auf dem Arduino recht schnell. Den Arduino als I2C-Slave initialisieren, ihm eine Adresse geben und dann auf die ankommenden Bytes reagieren &#8230; 0x00 LED aus, 0x01 LED an &#8230; aber Moment &#8230; das muss doch auch eleganter gehen, indem ich nicht nur ein Byte als Adresse sondern je Adresse auch noch weitere Bytes als Parameter \u00fcbertrage und auswerte. <\/p>\n\n\n\n<p>Nach etwas Knoten im Kopf und umdenken (bisher habe ich in Projekten immer \u00fcber Sockets, APIs und MQTT mit Strings kommuniziert) habe ich dann herausgefunden wie die smbus-Funktionen und die C++Befehle daf\u00fcr aussehen und die Daten aufbereitet und ausgewertet werden m\u00fcssen. Nach ein paar frustranen Versuchen ist der Knoten geplatzt und es funktioniert.<\/p>\n\n\n\n<p><strong>Aufgabe 2:<\/strong> Vom Pi einen Eingang am Arduino abfragen.<\/p>\n\n\n\n<p>In  meinem Leichtsinn dachte ich, dass ich einfach auf einen Befehl antworten kann, aber bei I2C wird die \u00dcbertragung ausschlie\u00dflich vom Master gesteuert.<\/p>\n\n\n\n<p>Wenn man nochmal genau nachlie\u00dft und dann auch verstanden hat, dass der Master entweder nur Daten sendet oder einen Request mit eigenen Daten an den Slave sendet und dieser dann direkt antwortet, kommt man auf den richtigen Weg. Also im Arduino den Code umgebaut und siehe da, ich kann nun auch den aktuellen Schaltzustand meiner LED und eines Einganges abfragen.<\/p>\n\n\n\n<p><strong>Aufgabe 3:<\/strong> eine sinnvolle Adressierung auf dem Arduino f\u00fcr IN\/OUT<\/p>\n\n\n\n<p>Ich mache es kurz &#8230; ich habe einfach die wesentlichen Adressen f\u00fcr die io-Ports aus dem Datenblatt des MCP23017 \u00fcbernommen. F\u00fcr das Verst\u00e4ndnis des Datenblattes und der Abl\u00e4ufe auf dem I2C-Bus hat mir ein unten verlinktes Tutorial zum MCP sehr geholfen. <\/p>\n\n\n\n<p>Zu meiner Schande musste ich mich nach jahrelanger Erfahrung mit selbst beigebrachten Hobby-Programmierkenntnissen nun endlich mal mit bin\u00e4rer Logik besch\u00e4ftigen &#8230; also wie setze ich 8 Bits zu einem Byte zusammen und wie pr\u00fcfe ich effektiv und einfach auf der anderen Seite welche Bits 1 bzw. 0 sind. Grunds\u00e4tzlich war der Zusammenhang klar, aber wie es in Python und C++ praktisch funktioniert war dann eine Abendstudie und ein bisschen Try und Error. <\/p>\n\n\n\n<p>Dabei hat mich die Funktion pow() im C++ fast zur Verzweifelung getrieben, bis ich verstanden habe, dass sie als float-Funktion eben ein &#8222;krummes&#8220; Ergebnis liefert, was dann beim Vergleich mit einem Integer zu falschen Ergebnissen f\u00fchrt. Nach weiter Forschung habe ich dann mit bit() die f\u00fcr diesen Zweck richtig Funktion gefunden.<\/p>\n\n\n\n<p>Nun konnte ich also meinen Arduino als dummen I2C-Portexpander missbrauchen und ihn f\u00fcr Ein- und Ausg\u00e4nge an meiner Brandmeldeanlage nutzen. <\/p>\n\n\n\n<p><em>&#8222;Warum haste nicht gleich nen MCP23017 genommen?&#8220;<\/em> &#8230; das ist schnell erkl\u00e4rt: ich wollte ja verstehen, wie I2C funktioniert und wie solche Bausteine kommunizieren. Das geht nat\u00fcrlich leichter, wenn man auf beiden Seiten des Busses mitlesen kann. Mission erf\u00fcllt \ud83d\ude09<\/p>\n\n\n\n<p>Jetzt m\u00fcssen irgendwie die Taster und LEDs am Arduino mit dem MQTT verbunden werden &#8230;<\/p>\n\n\n\n<h2>Hier die erw\u00e4hnten Quellen aus dem Text<\/h2>\n\n\n\n<p>Tutorial: HD44780 per I2C ansteuern | <a href=\"https:\/\/tutorials-raspberrypi.de\/hd44780-lcd-display-per-i2c-mit-dem-raspberry-pi-ansteuern\/\" target=\"_blank\" rel=\"noreferrer noopener\">Webseite<\/a> | <a rel=\"noreferrer noopener\" href=\"http:\/\/tutorials-raspberrypi.de\/wp-content\/uploads\/scripts\/hd44780_i2c.zip\" target=\"_blank\">Python-Bibiothek<\/a><\/p>\n\n\n\n<p>Tutorial: Raspberry Pi GPIOs mittels I2C Port Expander erweitern | <a rel=\"noreferrer noopener\" href=\"https:\/\/tutorials-raspberrypi.de\/raspberry-pi-gpios-erweitern-mittels-i2c-port-expander\/\" target=\"_blank\">Webseite<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Mit Python habe ich bereits verschiedene Erfahrungen sammeln k\u00f6nnen, so dass ich nun &#8222;nur noch&#8220; verstehen musste, wie I2C \u00fcberhaupt funktioniert und wie man das in Python umsetzt. Als Bibliothek kommt smbus und f\u00fcr ein HD44780-LCD-Display noch eine kleine Treiber-Bibliothek aus einem Tutorial zum Einsatz. &nbsp; Levelshifter zwischen Pi und Arduino Bevor wir nun gedankenlos &hellip; <a href=\"https:\/\/blog.0link.net\/index.php\/2020\/11\/07\/raspberry-python-und-i2c\/\" class=\"more-link\"><span class=\"screen-reader-text\">4. Raspberry, Python und I2C<\/span> weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[6,7,3],"tags":[],"_links":{"self":[{"href":"https:\/\/blog.0link.net\/index.php\/wp-json\/wp\/v2\/posts\/220"}],"collection":[{"href":"https:\/\/blog.0link.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.0link.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.0link.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.0link.net\/index.php\/wp-json\/wp\/v2\/comments?post=220"}],"version-history":[{"count":4,"href":"https:\/\/blog.0link.net\/index.php\/wp-json\/wp\/v2\/posts\/220\/revisions"}],"predecessor-version":[{"id":261,"href":"https:\/\/blog.0link.net\/index.php\/wp-json\/wp\/v2\/posts\/220\/revisions\/261"}],"wp:attachment":[{"href":"https:\/\/blog.0link.net\/index.php\/wp-json\/wp\/v2\/media?parent=220"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.0link.net\/index.php\/wp-json\/wp\/v2\/categories?post=220"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.0link.net\/index.php\/wp-json\/wp\/v2\/tags?post=220"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}