Easy I2C Shutdown
on

The I2C bus is highly vulnerable due to its design — both SCL and SDA “float” at high potential and are pulled low by the individual components. As soon as a sensor gets stuck and keeps one of the lines permanently low, bus communication is terminated for all participants.
Not So Easy: Bus Off
At the author’s company, a humidity sensor system was implemented based on an STM32 and a Texas Instruments HDC2010. After a few thousand interactions, a strange problem occurred: the I2C bus no longer responded to commands because the sensor held one of the lines low. Turning the power supply of the entire system off and on solved the problem.
Where there is a functioning I2C bus, pull-up resistors are not far away. This means that a transistor that isolates the bus participant from VCC is not necessarily the right solution, because a ghost power supply via the pull-ups could be enough to continue supplying the misbehaving logic parts of a rebellious sensor.
Steal the Ground!
One solution is to carry out the shutdown by removing the ground potential instead. To do this, it is sufficient to insert a MOSFET into the ground connection of the sensors, as shown in Figure 1. Since the sensors used here have minimal power consumption, the voltage drop is negligible.

When a problem occurs, the host microcontroller can switch off the MOSFET and thus disable the sensor. The reward for this effort is that the sensor can be switched off without affecting the main supply of the MCU.
On the code side, a few minor adjustments are required. First, the reading routine must detect a sensor or bus that has fallen asleep — in the case of the HDC2010, this was done by returning an implausible temperature value. The next step is to briefly cut off the power supply:
{
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);
After all problem areas have been eliminated, a complete reconfiguration of the sensor is, of course, required:
uint8_t configContents;
configContents = hdc2010_readReg(CONFIG);
configContents = (configContents | 0x80);
hdc2010_writeReg(CONFIG, configContents);
HAL_Delay(50);
}
Practical Experience
Since the circuit adjustments discussed here, our sensor system has been working without problems. The prototypes achieved runtimes of several months before they stopped working due to battery exhaustion. Because of the low cost of the transistor, this is a circuit that you should definitely plan for.
Editor's Note: This article (250221-01) appears in the Elektor Circuit Special 2025.
Discussion (2 comments)