2020-10-16 08:46 AM
Greetings,
On the custom board I'm working on, the HTS is powered off (electrically) when unused. The rail used to power the HTS can't remain on because it also powers other components which must be powered off to meet the consumption target.
I noticed that it takes quite some time for the HTS to be ready to answer to a first I2C request, and it's not consistent. It generally takes 300ms, but I've had devices where the 1s timeout expires. I can't find a max boot up time specified in the datasheet.
I need to know this in order to determine a maximum timeout, and maybe have a deeper look at the I2C implementation in case something is wrong here.
Thank you.
Solved! Go to Solution.
2020-10-27 06:43 AM
Hello,
I update this thread to indicate that my problem has been resolved by adding a 350ms delay between powering the sensor and the first I2C communication. This solution only comes from empirical evidences. I wish ST had provided a maximum power up time, either in the sensor datasheet or on this board.
For example, the datasheet of Sensirion's SHT31 includes the following short paragraph :
4.1 Power-Up and Communication Start
The sensor starts powering-up after reaching the powerup threshold voltage VPOR specified in Table 3. After reaching this threshold voltage the sensor needs the time tPU to enter idle state. Once the idle state is entered it is ready to receive commands from the master (microcontroller).
2020-10-19 05:00 AM
Hi @ABrua.1 ,
it's strange... in our experience you could face "timeout" on the stability of the humidity value in case of condensation on the sensor, but not on the I2C master-slave communication directly...
Is your Master I2C pattern following all the parameters of the "I²C - control interface" described in p.10 of the datasheet? in particular, which are the values of the Vdd, Vdd_IO, pull-up resistors (and eventually the parasitic C load) in your I2C circuit?
You may check also if your initialization code has a similar structure with respect to the reference C code on hts221_read_data_polling.c?
-Eleon
2020-10-20 08:32 AM
Hi @Eleon BORLINI ,
Thank you for your answer. I have checked the I2C parameters:
The sensor is powered by a set of two AA alkaline battery, so Vdd is somewhere between 2.7V and 3.2V, depending on battery charge. The clock frequency is 100kHz. SCL and SDA are pulled high by 4.7kOhms resistors.
I'm not sure what is Vdd_IO and I do not know the parasitic C load.
My initialization code is very similar to the polling example. Because I don't know how long it takes for the module to boot, I "poll" the I2C bus for the device using HAL_I2C_IsDeviceReady() function:
int I2C_WaitDevice(uint8_t DevAddr, clock_time_t StartTick, clock_time_t Timeout)
{
while( HAL_I2C_IsDeviceReady(&I2cHandle, DevAddr, 1, 10) != HAL_OK ) {
if( (clock_time() - StartTick) > Timeout ) {
return -1;
} else {
clock_wait(10 * CLOCK_SECOND / 1000);
}
}
return 0;
}
I've observed shorter boot time if I wait 300ms before polling the sensor for readiness. In this case, the sensor is usually ready within 350ms. If I start polling the sensor for readiness immediately after power up, it can take up to 600ms. Since polling seems to negatively advert boot time, it would also be interesting to know the typical boot time, which I could use to wait before starting to poll, and a maximum boot time to timeout.
Actually, I'm unsure my previous version of the driver failed at I2C initialization (it was lacking precise return code for each error case), but considering that no delay after power up seems to increase boot time, is it possible that starting to poll the device before it's properly powered-up could make it crash entirely ?
For reference, here is the complete initialization function, in case you see something fishy:
static int activate(void)
{
int result;
uint8_t whoami = 0;
clock_time_t start_tick;
const clock_time_t timeout = 1500 * CLOCK_SECOND / 1000; //1.5s
TRACE("[temperature-sensor] activating\n");
//Enable vcc_temp power rail to power up the sensor
pm_enable_vcc_temp();
//Configure DRDY interrupt pin
activate_gpio();
//Wait for I2C ready
start_tick = clock_time();
clock_wait(300 * CLOCK_SECOND / 1000);
//Initialize the I2C bus
if( I2C_Init() != HAL_OK ) {
TRACE("[temperature-sensor] failed to init i2c\n");
result = -1;
goto i2c_failed;
}
if( I2C_WaitDevice(HTS221_I2C_ADDRESS, start_tick, timeout) != 0) {
TRACE("[temperature-sensor] Device not ready\n");
result = -2;
goto i2c_failed;
}
printf("[temperature-sensor] Device ready after %lums\n",
(clock_time() - start_tick) * 1000 / CLOCK_SECOND);
if( hts221_device_id_get(&sensor_ctx, &whoami) != 0 ) {
TRACE("[temperature-sensor] Failed to read id\n");
result = -3;
goto deinit;
}
if( whoami != HTS221_ID ) {
TRACE("[temperature-sensor] Failed to identify sensor: %x\n", whoami);
result = -4;
goto deinit;
}
if( !got_calibration_values ) {
int rc = load_calibration_values(start_tick, timeout);
if( rc == 0) {
got_calibration_values = 1;
} else {
printf("[temperature-sensor] Failed to read calibration values: %d\n", rc);
result = -5;
goto deinit;
}
}
//Set resolution
if( hts221_humidity_avg_set(&sensor_ctx, HTS221_H_AVG_32) != 0 ) {
TRACE("[temperature-sensor] Failed to set humidity average\n");
result = -6;
goto deinit;
}
if( hts221_temperature_avg_set(&sensor_ctx, HTS221_T_AVG_256) != 0 ) {
TRACE("[temperature-sensor] Failed to set temperature average\n");
result = -7;
goto deinit;
}
//Enable interrupts
if( hts221_drdy_on_int_set(&sensor_ctx, 1) != 0 ) {
TRACE("[temperature-sensor] Failed to enable interrupts\n");
result = -8;
goto deinit;
}
uint16_t dump;
//Read reception registers to clear status reg
if( hts221_temperature_raw_get(&sensor_ctx, (uint8_t*)&dump) != 0 ) {
TRACE("[temperature-sensor] Failed to empty temp reg\n");
result = -9;
goto deinit;
}
if( hts221_humidity_raw_get(&sensor_ctx, (uint8_t*)&dump) != 0 ) {
TRACE("[temperature-sensor] Failed to empty hum reg\n");
result = -10;
goto deinit;
}
//Set block data update to prevent reading incoherent values
if( hts221_block_data_update_set(&sensor_ctx, PROPERTY_ENABLE) != 0 ) {
TRACE("[temperature-sensor] Failed to set BDU\n");
result = -11;
goto deinit;
}
//Set acquisition rate
if( hts221_data_rate_set(&sensor_ctx, HTS221_ODR_1Hz) != 0 ) {
TRACE("[temperature-sensor] Failed to set acquisition rate\n");
result = -12;
goto deinit;
}
//Power on device
if( hts221_power_on_set(&sensor_ctx, PROPERTY_ENABLE) != 0 ) {
TRACE("[temperature-sensor] Failed to power on sensor\n");
result = -13;
goto deinit;
}
_active = 1;
return 0;
deinit:
I2C_DeInit();
i2c_failed:
pm_disable_vcc_temp();
//If we failed to activate, consider that we did not get calibration values
got_calibration_values = 0;
_active = 0;
return result;
}
2020-10-27 06:43 AM
Hello,
I update this thread to indicate that my problem has been resolved by adding a 350ms delay between powering the sensor and the first I2C communication. This solution only comes from empirical evidences. I wish ST had provided a maximum power up time, either in the sensor datasheet or on this board.
For example, the datasheet of Sensirion's SHT31 includes the following short paragraph :
4.1 Power-Up and Communication Start
The sensor starts powering-up after reaching the powerup threshold voltage VPOR specified in Table 3. After reaching this threshold voltage the sensor needs the time tPU to enter idle state. Once the idle state is entered it is ready to receive commands from the master (microcontroller).
2020-10-27 07:25 AM
Hi @ABrua.1 ,
thank you for your reporting and your feedback on the solution, i.e. "adding a 350ms delay between powering the sensor and the first I2C communication".
This startup delay after POR is usually specified in ST MEMS sensors' datasheets in standard Vdd line conditions (i.e. with no parasitic capacitance on Vdd and VddIO, but only with decoupling capacitors. Is it your case too?), but not for the HTS221, I see...
This is a good practice and I'll report your finding to the internal humidity sensor product champion.
-Eleon
2020-10-27 09:27 AM
In my case, there is 12.3µF decoupling in total which is WAY over the top, I suppose. Scope verification shows that Vdd reaches 3V in 5µs, so I would assume this is of no significance for startup time.
2020-10-27 09:40 AM
Thank you @ABrua.1 for the useful detail