I2C eenvoudig uitschakelen
op

De I2C-bus is zeer kwetsbaar, inherent aan het ontwerp – zowel SCL als SDA ‘zweven’ op een hoge potentiaal en worden laag getrokken door de afzonderlijke componenten. Zodra een sensor vastloopt en een van de lijnen permanent laag houdt, wordt buscommunicatie voor alle deelnemers onmogelijk.
Bus uitschakelen: niet zo eenvoudig
In het bedrijf van de auteur was een systeem met vochtigheidssensoren geïmplementeerd op basis van een STM32 en een HDC2010 van Texas Instruments. Na een paar duizend interacties trad er een vreemd probleem op: de I2C-bus reageerde niet meer op commando’s omdat de sensor een van de lijnen laag hield. Het uit- en inschakelen van de voeding van het hele systeem bood een oplossing voor het probleem.
Waar een actieve I2C-bus is, zijn pull-up weerstanden niet ver weg. Dit betekent dat een transistor die de busdeelnemer isoleert van VCC niet per se de juiste oplossing is, omdat een fantoomvoeding via de pull-ups voldoende kan zijn om de zich misdragende logische onderdelen van een opstandige sensor te blijven voeden.
Speel massadiefje!
Een oplossing is om uit te schakelen door in plaats daarvan de aardpotentiaal weg te nemen. Hiertoe volstaat het om een MOSFET in de massaverbinding van de sensoren op te nemen, zoals geschetst in figuur 1. Aangezien de hier gebruikte sensoren een minimaal stroomverbruik hebben, is de spanningsval verwaarloosbaar.

Als er een probleem optreedt, kan de host-microcontroller de MOSFET uitschakelen en zo de sensor afschakelen. De beloning voor deze inspanning is dat de sensor kan worden uitgeschakeld zonder de hoofdvoeding van de MCU te beïnvloeden.
In de code zijn een paar kleine aanpassingen nodig. Eerst moet de uitleesroutine een in slaap gevallen sensor of bus detecteren – in het geval van de HDC2010 gebeurde dit door een onwaarschijnlijke temperatuurwaarde te retourneren. De volgende stap is het kort uitschakelen van de voeding:
{
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);
Nadat alle problemen zijn geëlimineerd, is natuurlijk een volledige herconfiguratie van de sensor vereist:
uint8_t configContents;
configContents = hdc2010_readReg(CONFIG);
configContents = (configContents | 0x80);
hdc2010_writeReg(CONFIG, configContents);
HAL_Delay(50);
}
In de praktijk
Na de hier besproken aanpassingen aan het circuit werkt ons sensorsysteem zonder problemen. De prototypes haalden runtimes van enkele maanden voordat ze stopten met werken omdat de batterijen leeg raakten. Omdat de transistor nauwlijks iets kost, is dit een schakeling die u zeker moet overwegen.
Opmerking van de redactie: Dit artikel (250221-03) is verschenen in Elektor Circuit Special 2025.
Vragen of opmerkingen?
Hebt u technische vragen of opmerkingen naar aanleiding van dit artikel? Stuur een e-mail naar de auteur via tamhan@tamoggemon.com of naar de redactie van Elektor via redactie@elektor.com.
Discussie (0 opmerking(en))