cancel
Showing results for 
Search instead for 
Did you mean: 

LSM6DSOTR generating random interrupt and reset microcontroler (Soldering problem... or not)

LClad.1
Associate II

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

4 REPLIES 4

Use this button to properly post source code:

AndrewNeil_0-1707489364000.png

 

 

Federica Bossi
ST Employee

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.

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.

Hi @Federica Bossi 

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

 


@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...