Der I2C-Bus ist ob seines Aufbaus – sowohl SCL als auch SDA „schweben” auf High-Potential und werden von den einzelnen Komponenten auf low gezogen – in höchstem Maße anfällig. Sobald ein Sensor stecken bleibt und eine der Leitungen dauerhaft auf low hält, ist die Buskommunikation für alle Teilnehmer beendet.

Gar nicht so einfach: Bus aus

Im Unternehmen des Autors wurde ein Feuchtigkeitssensorsystem auf Basis eines STM32 und eines HDC2010 von TI realisiert. Nach einigen tausend Interaktionen trat ein seltsames Problem auf: der I2C-Bus reagierte nicht mehr auf Befehle, weil der Sensor eine der Leitungen auf low hielt. Ein Ein- und Ausschalten der Stromversorgung des Gesamtsystems löste das Problem.

Wo ein funktionierender I2C-Bus ist, sind Pull-Up-Widerstände nicht fern. Daraus folgt, dass ein Transistor, der den Busteilnehmer von VCC trennt, nicht unbedingt zielführend ist. Eine Geistspeisung über die Pull-Ups könnte ausreichen, um die bockenden Logikteile eines rebellierenden Sensors weiterzuversorgen.

Abonnieren
Tag-Benachrichtigung zu I2C jetzt abonnieren!

Masse weg!

Ein Weg zur Lösung ist, die Abschaltung stattdessen durch Entzug des Massepotentials vorzunehmen. Hierzu reicht es aus, wie in Bild 1 gezeigt, einen MOSFET in die Masseverbindung der Sensoren einzuschleifen. Da die hier verwendeten Sensoren einen minimalen Stromverbrauch aufweisen, ist der Spannungsabfall vernachlässigbar.

Easy I2C Shutdown
Bild 1. Diese Schaltung sorgt für Ruhe.

Wenn nun ein Problem auftritt, kann der Host-Mikrocontroller den MOSFET abschalten und den Sensor so lahmlegen. Lohn der Mühen ist, dass eine Abschaltung des Sensors erfolgt, ohne dass dazu die Hauptversorgung der MCU tangiert wird.

Auf Codeseite sind einige kleine Anpassungen erforderlich. Erstens muss die Leseroutine einen eingeschlafenen Sensor beziehungsweise Bus erkennen – im Fall des HDC2010 erfolgte dies durch das Zurückliefern eines unplausiblen Temperaturwerts. Nächste Amtshandlung ist dann das kurzfristige Kappen der Stromversorgung:

{

  HAL_GPIO_WritePin(I2C_POWERCTRL_GPIO_Port,

      I2C_POWERCTRL_Pin, GPIO_PIN_RESET);

  HAL_Delay(250);

  HAL_GPIO_WritePin(I2C_POWERCTRL_GPIO_Port,

      I2C_POWERCTRL_Pin, GPIO_PIN_SET);

  HAL_Delay(20);

 

Nach dem Verenden aller Problemstellen ist logischerweise eine komplette Neu-Konfiguration des Sensors erforderlich:

 

  uint8_t configContents;

  configContents = hdc2010_readReg(CONFIG);

 

  configContents = (configContents | 0x80);

  hdc2010_writeReg(CONFIG, configContents);

  HAL_Delay(50);

}

Praxis

Seit der hier besprochenen Schaltungsanpassung funktioniert unser Sensorsystem unproblematisch: Die Prototypen erreichten Laufzeiten im Bereich mehrerer Monate, bevor sie ob Erschöpfung der Batterie den Geist aufgaben. Wegen der geringen Kosten für den Transistor handelt es sich hier um eine Schaltung, die man auf jeden Fall einplanen sollte.


Anmerkung der Redaktion: Dieser Artikel (250221-02) erscheint in der Elektor Circuit Special 2025.


Fragen oder Kommentare?

 

Wenn Sie technische Fragen oder Anmerkungen zu diesem Artikel haben, nehmen Sie bitte Kontakt auf mit dem Autor tamhan@tamoggemon.com oder der Elektor-Redaktion unter redaktion@elektor.de.

 

Abonnieren
Tag-Benachrichtigung zu Circuits & Circuit Design jetzt abonnieren!