Anfänger versucht sich an Pi mit I2C und Port Expander

Begonnen von BorisKsoll, 16 März 2019, 19:48:59

Vorheriges Thema - Nächstes Thema

BorisKsoll

Moin!

Ich habe hier:

(0) https://forum.fhem.de/index.php/topic,23164.0.html

gefunden was ich suche und erprobe mich jetzt bei der Umsetzung ;-)

(1) Die Installation von FHEM auf Pi verlief problemlos nach https://wiki.fhem.de/wiki/Raspberry_Pi

(2) Meinen Port Expander habe ich mit drei MCP23017 bestückt. Die Interruptleitung habe ich mit den GPIO7 des Pi verbunden (Frage *1)

(3) Danach ging ich nach commandref vor: https://commandref.fhem.de/#I2C_MCP23017

(3a) Zunächst https://commandref.fhem.de/#RPII2C
dabei habe ich die Optionen raspi-config, install i2c-tools und  or into /etc/rc.local gewählt. Letztere mangels einer /etc/init.d/fhem. Die Definition war problemlos. (Port 1)

define I2C_Unterstuetzung RPII2C 1
attr I2C_Unterstuetzung room System


(3b) Die Adressen meiner PortExpander ermittelte ich mit i2cdetect -y 1:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: 20 -- 22 -- 24 -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- -- 

(3c) In FHEM richtete ich sie wie folgt ein:

define PortExpanderA_INPUT I2C_MCP23017 0x20
attr PortExpanderA_INPUT IODev I2C_Unterstuetzung
attr PortExpanderA_INPUT room System

define PortExpanderB I2C_MCP23017 0x22
attr PortExpanderB IODev I2C_Unterstuetzung
attr PortExpanderB room System

define PortExpanderC_Output I2C_MCP23017 0x24
attr PortExpanderC_Output IODev I2C_Unterstuetzung
attr PortExpanderC_Output room System


(4) Kurze Pause zum Freuen, weil bisher alles gut geklappt hat

(5) Zum Testen habe ich dann GND mit einen GPIO des MCP23017 mit der Adresse 0x20 verbunden. Da die Voreinstellung "Input" ist gehe ich davon aus, dass jetzt ein Reading auf "On" stehen müsste. (*2)

Dem ist leider nicht so.

Deshalb meine Fragen:

(*1): Unter (0) hatte ich gelesen, dass der MCP23017 einen Interrupt nicht über I2C auslösen kann und deswegen mit einen GPIO des PI verbunden werden muss, dass dies aber nur für Inputs notwendig ist.

(a) Habe ich das richtig verstanden?
(b) Ist egal welcher GPIO?
(c) Ich muss doch bestimmt irgendwo in irgendein attr eintragen, welchen GPIO ich genommen habe? Wo?

(*2) Funktion

(a) Im deviceOverview meiner PortExpander sehe ich "State: OK". Bedeutet das jetzt, dass der Baustein als Hardware entdeckt und auf Funktion geprüft wurde oder nur dass er softwareseitig eingerichtet wurde? (Ich habe einen vierten unter einer nicht vorhandenen Adresse definiert und habe als state "transmission error" bekommen, ich gehe also davon aus, dass FHEM den "State: OK" nur anzeigt, wenn wirklich eine Kommunikation mit dem Baustein erfolgte.)

(b) Was muss ich machen, um einen Input abfragen zu können?

Ich habe unter (0) nicht alles verstanden, das übersteigt mein derzeitiges Wissen - ich bitte um Welpenschutz ;-)

Danke & viele Grüße
Boris



BorisKsoll

(2b) Es fehlte: attr PortExpanderA_INPUT Pullup A0,A1,A2,A3,A4,A5,A6,A7,B0,B1,B2,B3,B4,B5,B6,B7

BorisKsoll

(1) So sollte es funktionieren:

define INT_ExAB RPI_GPIO 7
attr INT_ExAB active_low yes
attr INT_ExAB direction input
attr INT_ExAB room System


Allerdings bin ich jetzt zum testen zu müde.


klausw

Hi Boris,

wie weit bist du jetzt gekommen?
Wenn OK dasteht ist das schon einmal gut.

Die Attribute

  • Interrupt
  • InterruptOut
fehlen bei den Input MCPs noch.

Das Attribut

  • interrupt
fehlt beim GPIO noch

Bitte beachten das GPIO Nummer und Pinnummer auf dem Pfostenstecker nicht identisch sind.

Auf INT_ExAB müsstest du noch mit einem notify reagieren das die MCPs aktualisiert.
Oder z.B.:
attr Interrupt INT_ExAB test {fhem ("get PortExpanderA_INPUT"); return "done";}

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

BorisKsoll

Hallo Klaus,

ich bin begeistert. Zwar ist noch nicht alles fertig - aber die Grundfunktionen sind da.

define PEx0x20 I2C_MCP23017 0x20
attr PEx0x20 IODev I2C_Unterstuetzung
attr PEx0x20 Interrupt A0,A1,A2,A3,A4,A5,A6,A7,B0,B1,B2,B3,B4,B5,B6,B7
attr PEx0x20 InterruptOut separate_active-low
attr PEx0x20 Pullup A0,A1,A2,A3,A4,A5,A6,A7,B0,B1,B2,B3,B4,B5,B6,B7
attr PEx0x20 comment A2 Saallicht;; A5 Bad;; A7 Klingel;; A7 Treppe
attr PEx0x20 group PortExpanderkarte1
attr PEx0x20 invert_input A0,A1,A2,A3,A4,A5,A6,A7,B0,B1,B2,B3,B4,B5,B6,B7
attr PEx0x20 poll_interval 1
attr PEx0x20 room System
define PEx0x22 I2C_MCP23017 0x22
setuuid PEx0x22 5c8d1e94-f33f-97ef-ff85-0af112812c4ee036
attr PEx0x22 IODev I2C_Unterstuetzung
attr PEx0x22 OutputPorts A0,A1,A2,A3,A4,A5,A6,A7,B0,B1,B2,B3,B4,B5


define INT1B RPI_GPIO 26
setuuid INT1B 5c9504a6-f33f-97ef-8358-d97ba7d54870bb5b
attr INT1B active_low yes
attr INT1B direction input
attr INT1B group PortExpanderkarte1
attr INT1B interrupt both
attr INT1B room System
attr INT1B userReadings test {fhem ("get PEx0x20")}
define INT1A RPI_GPIO 19
setuuid INT1A 5c950680-f33f-97ef-b92f-4c4803309a2c4bdb
attr INT1A active_low yes
attr INT1A direction input
attr INT1A group PortExpanderkarte1
attr INT1A interrupt both
attr INT1A room System
attr INT1A userReadings test {fhem ("get icMCP23017")}


Die Ports habe ich jeweils mit einen readingsproxy "gekoppelt" - egal ob Inout oder Output.

Beispiel Output:

define Badlicht readingsProxy PEx0x22:PortA2
attr Badlicht alexaName Badlicht
attr Badlicht devStateIcon off:switch_off on:switch_on:off
attr Badlicht setFn {($CMD eq "on")?"PortA2 off":"PortA2 on"}
attr Badlicht setList on off
attr Badlicht valueFn {($VALUE eq "on")?"off":"on"}


Und der Input (Lichtschalter) dazu:

define sw_bad readingsProxy PEx0x20:PortA5


Die "Logik" dazwischen:

define DI_Badlicht DOIF ([sw_bad] eq "on") (set Badlicht on) DOELSE (set Badlicht off)
attr DI_Badlicht wait 0.5:0.5


Die klassischen Verbraucher kann ich jetzt mit Relais schalten und Schalter und Taster auslesen. Als nächstes kommen Sensoren und die Heizung dazu - aber das ist dann nicht mehr MCP23017.

Interessant wird die Anbindung der anderen Etagen: Ziehe ich alle Stromkabel zu meinen Serverraum oder verteile ich Relaiskarten auf jede Etage, was deutlich einfacher wäre. Verbinde ich die Relaiskarten dann über Schaltleitungen mit den MCP23017 das am Raspberry in der anderen Etage hängt oder nehme ich Firmata über LAN oder lässt sich vielleicht der I2C-Bus am langen Kabel betreiben...

Timo_FHEM

Hi Boris,

ich habe 2 Port Expander verbaut und Fensterkontakte angeschlossen. Funktioniert ganz gut. Ein Problem war, dass sporadisch alle Eingänge auf "offen" standen und nur durch einen reboot wieder richtig funktioniert haben.
Dann habe ich einen Kondensator zum puffern der Versorgungsspannung eingebaut und seitdem (vor ca. 4 Wochen) keinen Ausfall mehr gehabt. Ich vermute, dass die Spannung kurz eingebrochen war und der MCP23017 danach nicht mehr hoch kam.

Gruß Timo

Gesendet von meinem A0001 mit Tapatalk


BorisKsoll

Danke,

das werde ich bei der nächsten Arbeit an der Hardware mit umsetzen.

klausw

Zitat von: BorisKsoll am 25 März 2019, 23:34:09

ich bin begeistert. Zwar ist noch nicht alles fertig - aber die Grundfunktionen sind da.
...
define INT1B RPI_GPIO 26
setuuid INT1B 5c9504a6-f33f-97ef-8358-d97ba7d54870bb5b
attr INT1B active_low yes
attr INT1B direction input
attr INT1B group PortExpanderkarte1
attr INT1B interrupt both
attr INT1B room System
attr INT1B userReadings test {fhem ("get PEx0x20")}



Respekt, sieht gut aus.
Das Attribut interrupt würde ich noch auf eine Flanke setzen.
Die INTOUTs vom MCP23017 werden aktiv sobald ein Input Pin den Status ändert und schalten inaktiv sobald die Input Register gelesen werden (also das "get PEx0x20" in deinem Fall). Steht das Attribut interrupt auf both wird nach dem Register lesen der Interrupt des GPIO erneut ausgelöst und ein weiterer Lesevorgang angestoßen. Das könnte zu negativen Seiteneffekten führen, insbesondere bei mehreren MCPs.
In deinem Fall (attr PEx0x20 InterruptOut separate_active-low, attr INT1B active_low yes) müsste das dann "rising" sein.


Zitat von: BorisKsoll am 25 März 2019, 23:34:09
Interessant wird die Anbindung der anderen Etagen: Ziehe ich alle Stromkabel zu meinen Serverraum oder verteile ich Relaiskarten auf jede Etage, was deutlich einfacher wäre. Verbinde ich die Relaiskarten dann über Schaltleitungen mit den MCP23017 das am Raspberry in der anderen Etage hängt oder nehme ich Firmata über LAN oder lässt sich vielleicht der I2C-Bus am langen Kabel betreiben...

I2C ist eher ein lokaler Bus.
Mit einem geschirmten Kabel kommst du sicher ein paar Meter.
Du solltest nur bedenken, das I2C in Bezug auf Störgestigkeit, Fehlererkennung nicht darauf ausgelegt ist.
Alternativ könntest du mit I2C über den CAN Hardware Layer gehen siehe Seite 4
Firmata müsste auch gehen, oder Ein Pi Zero pro Etage.
Mit der Anzahl der Controller steigt halt auch der Stromverbrauch. In Bezug darauf ist die Variante mit einem zentralen Knotenpunkt wo alle Kabel ankommen die beste.

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

BorisKsoll

Danke,

die Interrupts sind geändert auf "rising".

Ich habe etwas mit Firmata experimentiert. Ich könnte mir einen Arduino Mega für jede Etage vorstellen - da kann ich die Relaiskarten gleich an die vielen GPIOs hängen und habe auch gleich ein paar Analog-In.

Ich restauriere übrigens in Eigenarbeit eine 143 Jahre "Ruine" mit 24 Zimmern - kein Zeitdruck und somit viel Gelegenheit zum experimentieren. Mein FHEM mit LCARS Floorplan schafft einen herrlichen Kontrast zu den Gründerzeit "Template" des Hauses das ich so weit wie möglich wieder herstelle.

Nach aussen öffnende Fenster mit echten Sprossen und ohne innenliegendes Gestänge, dafür aber eingelassenen mit Reed-Kontakten sind eine interessante Herausforderung. ;-)

BorisKsoll

#9
Ein kleines Problem bleibt:


define INT1B RPI_GPIO 26
attr INT1B active_low yes
attr INT1B direction input
attr INT1B group PortExpanderkarte1
attr INT1B interrupt both
attr INT1B room System
attr INT1B userReadings test {fhem ("get PEx0x20")}


ist der Interrupt für

setuuid PEx0x20 5c8d1da8-f33f-97ef-1676-8acb1db2048313ed
attr PEx0x20 IODev I2C_Unterstuetzung
attr PEx0x20 Interrupt A0,A1,A2,A3,A4,A5,A6,A7,B0,B1,B2,B3,B4,B5,B6,B7
attr PEx0x20 InterruptOut separate_active-low
attr PEx0x20 Pullup A0,A1,A2,A3,A4,A5,A6,A7,B0,B1,B2,B3,B4,B5,B6,B7
attr PEx0x20 comment A0 PiPi-PIR;; A2 Saallicht;; A5 Bad;; A6 Klingel;; A7 Treppe
attr PEx0x20 group PortExpanderkarte1
attr PEx0x20 invert_input A1,A2,A3,A4,A5,A6,A7,B0,B1,B2,B3,B4,B5,B6,B7
attr PEx0x20 poll_interval 10
attr PEx0x20 room System


Im Logfile finde ich folgendes:

2019.04.04 21:42:09 1: PERL WARNING: INT1B userReadings test evaluated to undef at fhem.pl line 4630, <GEN166630> line 2533.
2019.04.04 21:42:09 3: eval: {fhem ("get PEx0x20")}
2019.04.04 21:42:09 1: stacktrace:
2019.04.04 21:42:09 1:     main::__ANON__                      called by fhem.pl (4630)
2019.04.04 21:42:09 1:     main::readingsEndUpdate             called by ./FHEM/51_RPI_GPIO.pm (545)
2019.04.04 21:42:09 1:     main::RPI_GPIO_Except               called by fhem.pl (3689)
2019.04.04 21:42:09 1:     main::CallFn                        called by fhem.pl (795)


Die Zeile

attr INT1B userReadings test {fhem ("get PEx0x20")}

soll doch ein Reading namens "Test" erzeugen durch das "get" einen Update der Readings des Portexpander erzeugen?

In der Kommandozeile ergibt

get PEx0x20

keinen Fehler in der Logdatei.

Frank_Huber

Versuch es doch mal mit ReadingsVal bzw InternalsVal.
Denke da eignet sich im Userreading besser.

Gesendet von meinem Doogee S60 mit Tapatalk


Timo_FHEM

Hi, bei mir funktioniert es so:

attr Interrupt_20 userReadings test {fhem ("get icMCP23017_20");; "egal" }


Hatte das Problem vorher auch.

VG Timo


Gesendet von meinem A0001 mit Tapatalk


BorisKsoll

#12
Danke. Ich werde testen und berichten.

Wenn ich "get PEx0x20" in die Kommandozeile eingebe erhalte ich ein "OK-Fenster" zum betätigen.

Bewirkt ";; egal", diese Bestätigung?

BorisKsoll

Zitat von: Timo_FHEM am 05 April 2019, 08:51:15
Hi, bei mir funktioniert es so:

attr Interrupt_20 userReadings test {fhem ("get icMCP23017_20");; "egal" }


Hatte das Problem vorher auch.

VG Timo


Gesendet von meinem A0001 mit Tapatalk

das funktioniert - danke.