Using the LIS2DH12 driver of the SDK v15.0.0 to configure the LIS2DH12 sensor

FormerMember
FormerMember

Hi everyone,

I'm trying to get the LIS2DH12 driver (SDK v15.0.0) to configure a LIS2DH12 sensor connected to my nRF52 Dev Kit.

I've wired the chip up as follows (using the I2C interface)

nRF52 -> chip
P0.26 -> SDA
P0.27 -> SCL

GND -> GND

VDD -> VDD, VDD_IO, CS, SDO

I've managed to read out the WHO_AM_I register using the driver and poll some samples. The samples do change when I drop my hand on the table on which the sensor is placed.

Now I'm trying to configure the FIFO and an interrupt (for now FIFO watermark) using this function:

#define TWI_INSTANCE_ID             0

#define MAX_PENDING_TRANSACTIONS    33

#define LIS2DH12_MIN_QUEUE_SIZE     32

NRF_TWI_MNGR_DEF(m_nrf_twi_mngr, MAX_PENDING_TRANSACTIONS, TWI_INSTANCE_ID);

NRF_TWI_SENSOR_DEF(m_nrf_twi_sensor, &m_nrf_twi_mngr, LIS2DH12_MIN_QUEUE_SIZE);

LIS2DH12_INSTANCE_DEF(m_lis2dh12, &m_nrf_twi_sensor, LIS2DH12_BASE_ADDRESS_HIGH);

...

/**
 * initialize and configure LIS2DH12 sensor
 */
void acc_init()
{
	ret_code_t err_code;

	nrf_drv_twi_config_t const config = {
		.scl                = 27,
		.sda                = 26,
		.frequency          = NRF_DRV_TWI_FREQ_100K,
		.interrupt_priority = APP_IRQ_PRIORITY_LOWEST,
		.clear_bus_init     = false
	};

	err_code = nrf_twi_mngr_init(&m_nrf_twi_mngr, &config);
	APP_ERROR_CHECK(err_code);

	err_code = nrf_twi_sensor_init(&m_nrf_twi_sensor);
	APP_ERROR_CHECK(err_code);

	// FIFO configuration
	LIS2DH12_FIFO_CFG(m_lis2dh12, true, LIS2DH12_FIFO, false, 16);

	// data acquisition configuration
	LIS2DH12_DATA_CFG(m_lis2dh12, LIS2DH12_ODR_1HZ, false, true, true, true, LIS2DH12_SCALE_2G, false);

	// interrupt configuration
	LIS2DH12_INT1_PIN_CFG(m_lis2dh12, false, true, false, false, false, true, false, false);

	err_code = lis2dh12_init(&m_lis2dh12);
	APP_ERROR_CHECK(err_code);

	err_code = lis2dh12_who_am_i_read(&m_lis2dh12, print_register, &m_data);
	APP_ERROR_CHECK(err_code);

	//LIS2DH12_INT1_CFG(m_lis2dh12, 100, 1, false, true, false, false, false, false, false, false, false);
	//err_code = lis2dh12_cfg_commit(&m_lis2dh12);
	//APP_ERROR_CHECK(err_code);
}



However I didn't manage to detect any interrupt (even with a oscilloscope) so far and the FIFO seems to be stuck at 32 available values while polling does not change the corresponding register value.

I am at a loss here - from what I've read in the LIS2DH12 data sheet and driver code, the driver seems to do the interfacing with the chip right. I'm suspecting a wrong order in my configuration function or wrong configuration parameters.

Any pointers on what I am doing wrong?

  • FormerMember
    0 FormerMember

    Hi everyone,

    I managed to figure it out on my own!

    Configuration:

    NRF_TWI_MNGR_DEF(m_nrf_twi_mngr, MAX_PENDING_TRANSACTIONS, TWI_INSTANCE_ID);
    
    NRF_TWI_SENSOR_DEF(m_nrf_twi_sensor, &m_nrf_twi_mngr, LIS2DH12_MIN_QUEUE_SIZE);
    
    LIS2DH12_INSTANCE_DEF(m_lis2dh12, &m_nrf_twi_sensor, LIS2DH12_BASE_ADDRESS_HIGH);
    
    void acc_init()
    {
    	ret_code_t err_code;
    
    	nrf_drv_twi_config_t const config = {
    		.scl                = 27,
    		.sda                = 26,
    		.frequency          = NRF_DRV_TWI_FREQ_100K,
    		.interrupt_priority = APP_IRQ_PRIORITY_LOWEST,
    		.clear_bus_init     = false
    	};
    
    	err_code = nrf_twi_mngr_init(&m_nrf_twi_mngr, &config);
    	APP_ERROR_CHECK(err_code);
    
    	err_code = nrf_twi_sensor_init(&m_nrf_twi_sensor);
    	APP_ERROR_CHECK(err_code);
    
    	err_code = lis2dh12_init(&m_lis2dh12);
    	APP_ERROR_CHECK(err_code);
    
    	// data acquisition configuration: 10HZ sample rate, low power mode, x axis, y axis, z axis, values in range -2g <-> +2g, disable high resolution mode (in this case step size is 256)
    	LIS2DH12_DATA_CFG(m_lis2dh12, LIS2DH12_ODR_10HZ, true, true, true, true, LIS2DH12_SCALE_2G, 0);
    	err_code = lis2dh12_cfg_commit(&m_lis2dh12);
    	APP_ERROR_CHECK(err_code);
    
    	// FIFO configuration: enable FIFO, streaming mode, int1 pin used, 32 values watermark
    	LIS2DH12_FIFO_CFG(m_lis2dh12, 1, LIS2DH12_STREAM, 0, LIS2DH12_MIN_QUEUE_SIZE);
    	err_code = lis2dh12_cfg_commit(&m_lis2dh12);
    	APP_ERROR_CHECK(err_code);
    
    	// interrupt configurataion: disable everything except the FIFO watermark interrupt
    	LIS2DH12_INT1_PIN_CFG(m_lis2dh12, 0, 0, 0, 0, 1, 0, 1, 0);
    	err_code = lis2dh12_cfg_commit(&m_lis2dh12);
    	APP_ERROR_CHECK(err_code);
    }


    Interrupt (using P004 and a LED to indicate that an interrupt has happend):

    void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
    	nrf_drv_gpiote_out_toggle(PIN_OUT);
    	data_available = 1;
    }
    
    static void gpio_init(void)
    {
    	ret_code_t err_code;
    
    	err_code = nrf_drv_gpiote_init();
    	APP_ERROR_CHECK(err_code);
    
    	nrf_drv_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_SIMPLE(false);
    
    	err_code = nrf_drv_gpiote_out_init(PIN_OUT, &out_config);
    	APP_ERROR_CHECK(err_code);
    
    	nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);
    
    	err_code = nrf_drv_gpiote_in_init(PIN_IN, &in_config, in_pin_handler);
    	APP_ERROR_CHECK(err_code);
    
    	nrf_drv_gpiote_in_event_enable(PIN_IN, true);
    }
    


    And finally: retrieving and printing the values:

    void acc_print_data()
    {
    	ret_code_t err_code;
    
    	err_code = lis2dh12_data_read(&m_lis2dh12, 0x00, m_sample, LIS2DH12_MIN_QUEUE_SIZE);
    	APP_ERROR_CHECK(err_code);
    
    	for (uint8_t i = 0; i < LIS2DH12_MIN_QUEUE_SIZE; i++)
    		NRF_LOG_INFO("%d %d %d", m_sample[i].x, m_sample[i].y, m_sample[i].z);
    
    }
    
    [...]
    
    	while (true) {
    		// avoid accessing the registers to fast, value arbitrarily chosen
    		nrf_delay_ms(200);
    		// debug: check FIFO_SRC register to see the FSS value rise
    		err_code = lis2dh12_fifo_src_read(&m_lis2dh12, 0x00, &m_data);
    		APP_ERROR_CHECK(err_code);
    		NRF_LOG_INFO("WTM: %d OVN: %d EMPTY: %d FSS: %2d ", (m_data & 0b10000000), (m_data & 0b01000000), (m_data & 0b00100000), (m_data & 0b0001111));
    
    		// do not try to access FIFO values if watermark was not reached yet
    		if (!data_available)
    			continue;
    
    		// collect and print the data
    		acc_print_data();
    		// "reset" interrupt
    		data_available = 0;
    		nrf_drv_gpiote_out_toggle(PIN_OUT);
    
    		NRF_LOG_FLUSH();
    	}


    I've encountered following "issues":
    * fatal system error on the nRF52 side if the watermark was not reached but data is read
    * accessing the sensor's registers to fast

    I don't know whether or not I'm still doing something wrong which then leads to the issues ...

  • And finally: retrieving and printing the values:

    Your code snippet helped me a lot in establish communication with LIS2DH.
    When I print the axis values,it looks a bit weird to me.

    I see no change in the values rather than self updating values (please look at the 4th line after "Update Accl Timer")from register read.

    You can have a look at my post here

    Below is my debug log:

    <info> app: 0 0 0
    <info> app: 17392 3 3
    <info> app: 6 471 0
    <info> app: 255 0 0
    <info> app: Update Accl Timer
    <info> app: 0 0 0
    <info> app: 0 0 0
    <info> app: 17392 3 3
    <info> app: 6 508 0
    <info> app: 255 0 0
    <info> app: Update Accl Timer
    <info> app: 0 0 0
    <info> app: 0 0 0
    <info> app: 17392 3 3
    <info> app: 6 545 0
    <info> app: 255 0 0
    <info> app: Update Accl Timer
    <info> app: 0 0 0
    <info> app: 0 0 0
    <info> app: 17392 3 3
    <info> app: 6 582 0
    <info> app: 255 0 0
    <info> app: Update Accl Timer
    <info> app: 0 0 0
    <info> app: 0 0 0
    <info> app: 17392 3 3
    <info> app: 6 619 0
    <info> app: 255 0 0
    <info> app: Update Accl Timer
    <info> app: 0 0 0
    <info> app: 0 0 0
    <info> app: 17392 3 3
    <info> app: 6 656 0
    <info> app: 255 0 0
    <info> app: Update Accl Timer
    <info> app: 0 0 0
    <info> app: 0 0 0
    <info> app: 17392 3 3
    <info> app: 6 693 0
    <info> app: 255 0 0
    <info> app: Update Accl Timer
    <info> app: 0 0 0
    <info> app: 0 0 0
    <info> app: 17392 3 3
    <info> app: 6 735 0
    <info> app: 255 0 0
    <info> app: Update Accl Timer
    <info> app: 0 0 0
    <info> app: 0 0 0
    <info> app: 17392 3 3
    <info> app: 6 772 0
    <info> app: 255 0 0

    I was wondering if you can point me out in the correct direction.
    Any suggestion would do me a great favor.

  • FormerMember
    0 FormerMember in reply to tamojit

    Hi tamojit,

    sorry for the late reply. I also have to give a major disclaimer as I haven't worked with the nRF52832 or LIS2DH12 in a long time.

    From what I understood from your code you try to read 5 samples every second at a sample rate of 10Hz. My best guess is that you need to enable and configure the FIFO otherwise you're probably reading garbage values / you are not able to read multiple samples (except reading a single sample every ~100ms (-> 10Hz sampling frequency)). See also the datasheet page 22 (www.st.com/.../lis2dh12.pdf).

    I'd also recommend using the FIFO watermark (WTM) interrupt instead of the timer (datasheet page 41).

Related