2024-02-09 06:27 AM
Hi,
I'm developing a power meter bicycle using the LSM6DSOTR with NRF52832 microcontroler. In my project I defined that 3 minutes without moviment, the system is turned off and wake up when the LSM6DSOTR detect the movement. Below, the code to init my sensor.
void Wake_up_init(void){
write_register(LSM6DS0_WAKE_UP_DUR, 0x00); // Set Activity/Inactivity threshold
write_register(LSM6DS0_WAKE_UP_THS, 0x02); // Select sleep-change notification - Select Slope Filter
write_register(LSM6DS0_TAP_CFG0, 0x51); // Turn on the gyroscope - ODR_G = 104 Hz, FS_G = ±2000 dps
write_register(LSM6DS0_TAP_CFG2, 0x80); // Set duration for Inactivity detection - Select Activity/Inactivity threshold resolution and duration
write_register(LSM6DS0_CTRL1_XL, 0x70); // Turn on the accelerometer - ODR_XL = 104 Hz, FS_XL = ±2 g
write_register(LSM6DS0_CTRL2_G, 0x4C); // Turn on the gyroscope - ODR_G = 104 Hz, FS_G = ±2000 dps
nrf_delay_ms(4);
write_register(LSM6DS0_CTRL1_XL, 0x10); // Turn on the accelerometer - ODR_XL = 104 Hz, FS_XL = ±2 g
write_register(LSM6DS0_MD1_CFG, 0x20); // Activity/Inactivity interrupt driven to INT1 pin
}
This function works fine in the previous version of my board, but now in new version board always reset. I connected the osciloscope on INT1 pin to verify and the LSM6DSOTR generate ramdom pulses without detect any movement and then resets the microcontroller.
I suspect that the problem can be the soldering temperature, because, I soldering with 400ºC and the JEDEC J-STD-020 show the critical temperature under 270ºC.
This situation can damage the device to cause it?
I need solve it and can you help me?
Regards
Laerte
2024-02-09 06:36 AM
Use this button to properly post source code:
2024-02-09 07:10 AM
Hi @LClad.1 ,
Your soldering procedure is not the one suggested so, yes, it could be damaged.
However it could be that it is not well soldered, for example the Vdd or GND, you could check with readings whether the registers modified via fw remain with those values even after the event.
2024-02-15 05:14 AM
The VCC, GND and I2C pins are well soldered, because in my code there is a i2c init function below... (Thanks @Andrew Neil for the tip)
void twi_init (void)
{
ret_code_t err_code;
nrf_gpio_pin_clear(SCL_PIN);
nrf_gpio_cfg_output(SCL_PIN);
// Enable I2C interface on slave 0
nrf_gpio_cfg_output(CS_PIN);
nrf_gpio_pin_set(CS_PIN);
nrf_gpio_cfg_output(SAD_PIN);
nrf_gpio_pin_set(SAD_PIN);
nrf_delay_ms(2);
const nrf_drv_twi_config_t twi_config = {
.scl = SCL_PIN,
.sda = SDA_PIN,
.frequency = NRF_DRV_TWI_FREQ_100K,
.interrupt_priority = APP_IRQ_PRIORITY_HIGH,
.clear_bus_init = false
};
err_code = nrf_drv_twi_init(&twi, &twi_config, NULL, NULL);
if (err_code != NRF_SUCCESS)
{
NRF_LOG_ERROR("Failed to initialize TWI interface (%i)", err_code);
APP_ERROR_CHECK(err_code);
//return false;
}
nrf_drv_twi_enable(&twi);
}
When malfuction occurs, the app_error_check function end the code. But in my case, I have a imu_begin function in the sequece of code that init the mems function.
bool imu_begin(imup_t *p_imu){
ret_code_t err_code;
uint8_t who_am_i_buffer = 0;
err_code = rw_register(twi, LSM6DS0_ADDRESS, LSM6DS0_WHO_AM_I_REG,&who_am_i_buffer, 1,false); // WHO AM I .. Return 0x6C
APP_ERROR_CHECK(err_code);
if(err_code == NRF_SUCCESS){
watch_dog = true;
}
else watch_dog = false;
NRF_LOG_INFO("IMU ID: %i", who_am_i_buffer);
nrf_delay_ms(15);
//Custom_init();
//Tilt_detect_init();
//Free_fall_init();
//Wake_up_init();
Wake_up_init_2();
//Orientation_6D_init();
//Single_tap_init();
//Double_tap_init();
//Activity_recognition_init();
//Custom_Activity_recognition_init();
nrf_delay_ms(15);
for (int j = 0; j < 3; j++)
{
p_imu->accel_g[j] = 0;
}
for (int j = 0; j < 3; j++)
{
p_imu->gyro_dps[j] = 0;
}
p_imu->temp_c = 20;
return err_code;
}
Below, my wake_up_init_2 function that I use to wake_up board when it sleep
void Wake_up_init_2(void){
//wake-up interrupt 2 (Using Slope filter)
write_register(LSM6DS0_WAKE_UP_DUR, 0x00); // Set Activity/Inactivity threshold
write_register(LSM6DS0_WAKE_UP_THS, 0x02); // Select sleep-change notification - Select Slope Filter
write_register(LSM6DS0_TAP_CFG0, 0x51); // Turn on the gyroscope - ODR_G = 104 Hz, FS_G = ±2000 dps
write_register(LSM6DS0_TAP_CFG2, 0x80); // Set duration for Inactivity detection - Select Activity/Inactivity threshold resolution and duration
write_register(LSM6DS0_CTRL1_XL, 0x70); // Turn on the accelerometer - ODR_XL = 104 Hz, FS_XL = ±2 g
write_register(LSM6DS0_CTRL2_G, 0x4C); // Turn on the gyroscope - ODR_G = 104 Hz, FS_G = ±2000 dps
nrf_delay_ms(4);
write_register(LSM6DS0_CTRL1_XL, 0x10); // Turn on the accelerometer - ODR_XL = 104 Hz, FS_XL = ±2 g
write_register(LSM6DS0_MD1_CFG, 0x20); // Activity/Inactivity interrupt driven to INT1 pin
}
And the processor read each interrupt sent by the int1 pin when detect the movement and reset this counter. But if does not occur any movement in 3 minutes, the system is turned off.
As mentioned before, my code works fine in some new boards. And anothers the the mems reset direct when the timeout movement occurs. The mems waking up the system after the timeout.
Regards
Laerte
2024-02-15 06:27 AM
@LClad.1 wrote:Thanks @Andrew Neil for the tip)
You're welcome.
Perhaps you could contribute to this thread:
https://community.st.com/t5/feedback-forum/formatting-code-should-be-easier/td-p/631565
to help ST understand how the forum could better support this...