This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

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

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?

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

  • 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