Integration des Port-Expanders PCA9555

So, habe den PCA9555 jetzt endlich laufen. Also noch nicht in den ESPuino-Code integriert, aber schon mal ein bisschen in die Richtung (als eigener Code) getrimmt. Wollte hier mal die Eckdaten runterschreiben, wie ich mir das so vorstelle. Vielleicht hat ja jmd. dazu was anzumerken.

Software

  • Der PCA hat zwei Ports mit je 8 Kanälen. D.h. wir haben gewissermaßen die Kanäle 0.0 bis 0.7 und 1.0 bis 1.7 zur Verfügung.
  • Über einen Hardware-Timer (100 Hz) wird der Port-Expander zyklisch ausgelesen. Aktuell arbeitet ESPuino mit 1000 Hz. Das scheint aber nicht notwendig zu sein; werde ich dann wohl generell reduzieren.
  • Man kann steuern, wieviele Ports ausgelesen werden (1 oder 2). D.h. wer mit 8 Kanälen auskommt, der sollte diese bestenfalls alle im Bereich 0.0 bis 0.7 liegen haben. D.h. ausgelesen werden entweder 8 Kanäle oder 16. Ein Port wird immer durch ein Byte repräsentiert. Insofern lese ich entweder 1 Byte aus oder 2 Bytes.
  • 0.0 bis 0.7 und 1.0 bis 1.7 ist zum Arbeiten etwas sperrig, daher linearisiere ich die von 0 bis 15 und addiere ein Offset von 100 drauf. D.h. in den Settings kann man dann, wie man das jetzt schon von den GPIOs kennt, halt die Nummern hinschreiben. Die Nummern sind dann entsprechend 100 bis 115. Finde ich irgendwie eingängig so; ich denke das lässt sich dann gut unterscheiden von GPIOs.
  • An einigen Stellen wird aktuell im ESPuino digitalRead() verwendet. Ich will jetzt als Wrapper-Funktion sowas wie digitalReadFromAll() bereitstellen. Diese erkennt anhand der abzufragenden Nummer automatisch, ob es sich um GPIO oder Port-Expander handelt. Ruft intern dann die passende Behandlung auf und arbeitet nach außen wie digitalRead(). So muss man sich nicht an n Stellen im Code drum kümmern, ob das jetzt Port-Expander ist oder nicht.
  • GPIOs für i2c (SDA und SCL) sind konfigurierbar
  • Der PCA besitzt auch einen Interrupt-Pin. Diesen würde ich auch anschließen, so dass man den ESP32 aufwecken kann. Das geht dann (unveränderbar) mit allen Sachen, die am Port-Expander angeschlossen sind.

Hardware

  • Adresse für Port-Expander ist konfigurierbar. Der PCA9555 besitzt drei Eingänge (A0 bis A2), über die man seine Adresse steuern kann. Legt man alle Eingänge auf GND, dann lautet die Adresse 0x20 (siehe Datenblatt).
  • Ansonsten braucht es nur noch PullUp-Widerstände mit je 4,7 k für SDA, SCL und Interrupt.
  • An VSS kommt GND und an VDD 3.3V.
  • Fertig gelötet auf Breadboards habe ich das nicht gesehen. Da muss man selbst Hand anlegen (wofür man SMD-Löten können muss). Zum Testen kann man z.B. sowas auf sowas löten. So habe ich das zum Test auch gemacht. Die Bauform ist TSSOP24. Es gibt die auch größer in SOP24 oder sogar (glaube ich) als DIP.

Was ist noch unklar?

  • Ich werde mal schauen, ob man das Auslesen in einen Task verschieben muss, weil es ggf. zu langsam für loop() ist.
  • Ziel ist es, dass man für Buttons GPIOs und Port-Expander mischen kann. Ob das komplett umsetzbar ist, auch im Hinblick von Multi-Button-Aktionen, muss man sehen.
1 „Gefällt mir“

Danke, das klingt alles sehr durchdacht und gut so.
Ich freue mich schon.

Laut Datenblatt braucht man am Interrupt-Pin auch einen PullUp-Widerstand.

Warum muss man überhaupt zyklisch auslesen? Kann man nicht stattdessen nur auf Interrupts reagieren, den Wert der geänderten Kanäle speichern und dann im loop nur noch die gespeicherten Werte auslesen?
Vermutlich ist das aber komplizierterer Code und ich weiß nicht, ob sich der Aufwand lohnt.

Stimmt, da hast du natürlich Recht.

Das kann man auch machen. Für mich liegt der Vorteil einfach darin, dass ich immer konstante Laufzeitverhältnisse habe. Beim Taster ist es ja so, dass der nicht einfach „an“ ist wenn man den drückt. Sondern der prellt ja. Wie sehr der prellt hängt vom Benutzer und vom Taster ab. Wenn da viele Interrupts gefeuert werden kann man in Probleme laufen, die man nur sehr schwer nachstellen kann. Polle ich, dann spielt das keine Rolle. Weil das mache ich immer gleich - ob gedrückt oder nicht.

1 „Gefällt mir“