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

nRF52832 and LIS3DH accelerometer

Hi, 

I am trying to read LIS3DH accelerometer with my nRF52832. I am using a custom board. Is there any tutorial or example that can help me? After some changes in the code, I tried "twi_sensor" example. 

#include <stdio.h>
#include "boards.h"
#include "app_util_platform.h"
#include "app_error.h"
#include "nrf_drv_twi.h"
#include "nrf_delay.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

#define LSM6_ADD      (0XD6U >> 1)

#define G_EARTH 9.80665
#define GAUSS_TO_TESLAS 100

#define TWI_INSTANCE_ID     0

static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
static volatile bool m_xfer_done = false;


typedef union 
{
    int16_t data[3];
    int8_t buff[6];
} data_int_convert_t;

typedef struct
{
    float x;
    float y;
    float z;
    float gain;
} axis_data_t;

axis_data_t axis_data_lsm6_a;
axis_data_t axis_data_lsm6_g;


void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{
    switch (p_event->type)
    {
        case NRF_DRV_TWI_EVT_DONE:
            if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX)
            {
                
            }
            m_xfer_done = true;
            break;
        default:
            break;
    }
}

void twi_init (void)
{
    ret_code_t err_code;
    const nrf_drv_twi_config_t twi_vnet_config = {
       .scl                = 14,
       .sda                = 15,
       .frequency          = NRF_DRV_TWI_FREQ_100K,
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
       .clear_bus_init     = false
    };

    err_code = nrf_drv_twi_init(&m_twi, &twi_vnet_config, twi_handler, NULL);
    APP_ERROR_CHECK(err_code);
    nrf_drv_twi_enable(&m_twi);	
}

void twi_reg_write(uint8_t addr, uint8_t *reg, uint16_t length)
{
    m_xfer_done = false;
    uint32_t err_code;

    err_code = nrf_drv_twi_tx(&m_twi, addr, reg, 2, false);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false){

    }
 
}

void twi_reg_read_t(uint8_t const addr, uint8_t reg, uint8_t *value, uint16_t length, uint32_t delay)
{
    uint32_t err_code;
    uint8_t buff[2];
    m_xfer_done = false;
    err_code = nrf_drv_twi_tx(&m_twi, addr, &reg, sizeof(reg), false);
    APP_ERROR_CHECK(err_code);

    m_xfer_done = false;
    nrf_delay_us(delay);
    err_code = nrf_drv_twi_rx(&m_twi, addr, value, length);
    APP_ERROR_CHECK(err_code); 
}

void LSM6_CFG(void)
{

    uint8_t reg[2] = {0x10, 0x80};
    m_xfer_done = false;
    uint32_t err_code;
    twi_reg_write(LSM6_ADD, reg, 2);
                 printf("LSM6 CFG");

    reg[0] = 0x11; reg[1] = 0x80;
    twi_reg_write(LSM6_ADD, reg, 2);
    reg[0] = 0x12; reg[1] = 0x04;
    twi_reg_write(LSM6_ADD, reg, 2);

    /* Writing to LM75B_REG_CONF "0" set temperature sensor in NORMAL mode. */
    //uint8_t reg[2] = {LM75B_REG_CONF, NORMAL_MODE};
    //err_code = nrf_drv_twi_tx(&m_twi, LM75B_ADDR, reg, sizeof(reg), false);
    //APP_ERROR_CHECK(err_code);
    //while (m_xfer_done == false);

    /* Writing to pointer byte. */
    //reg[0] = LM75B_REG_TEMP;
    //m_xfer_done = false;
    //err_code = nrf_drv_twi_tx(&m_twi, LM75B_ADDR, reg, 1, false);
    //APP_ERROR_CHECK(err_code);
    //while (m_xfer_done == false);
}

static void LSM6_Read(void)
{
    uint8_t i = 0;
    data_int_convert_t data_cnv_lsm6_a;
    data_int_convert_t data_cnv_lsm6_g;
    uint8_t reg[2] = {0x28, 0x22};
    twi_reg_read_t(LSM6_ADD, reg[0], data_cnv_lsm6_a.buff, 6, 1300);
    nrf_delay_us(1000);
    //twi_reg_read_t(LSM6_ADD, reg[1], data_cnv_lsm6_g.buff, 6, 1300);
    
    axis_data_lsm6_a.gain = 0.061 / 1000.0;
    axis_data_lsm6_a.x = (float)data_cnv_lsm6_a.data[0] * axis_data_lsm6_a.gain * G_EARTH;
    axis_data_lsm6_a.y = (float)data_cnv_lsm6_a.data[1] * axis_data_lsm6_a.gain * G_EARTH;
    axis_data_lsm6_a.z = (float)data_cnv_lsm6_a.data[2] * axis_data_lsm6_a.gain * G_EARTH;
    axis_data_lsm6_g.gain = 8.75 / 1000.0;
    axis_data_lsm6_g.x = (float)data_cnv_lsm6_g.data[0] * axis_data_lsm6_g.gain;
    axis_data_lsm6_g.y = (float)data_cnv_lsm6_g.data[1] * axis_data_lsm6_g.gain;
    axis_data_lsm6_g.z = (float)data_cnv_lsm6_g.data[2] * axis_data_lsm6_g.gain;
     NRF_LOG_INFO("\r\nTWI leitura do sensor feita.");

}

int main(void)
{
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();
    NRF_LOG_INFO("\r\nTWI sensor example started.");
    NRF_LOG_FLUSH();
    twi_init();
    LSM6_CFG();
     printf("leitura do sensor feita");
    while (true)
    {

        NRF_LOG_FLUSH();
        LSM6_Read();
        nrf_delay_ms(1000);
    }
}

But, in line 79, "m_xfer_done" is always false and I can't get any measure. 

Thanks in advance,

Gabriel 

Parents
  • "The Slave ADdress (SAD) associated to the LIS3DH is 001100xb. The SDO/SA0 pad can be used to modify the less significant bit of the device address. If the SA0 pad is connected to the voltage supply, LSb is ‘1’ (address 0011001b) else if SA0 pad is connected to ground, the LSb value is ‘0’ (address 0011000b). This solution permits to connect and address two different accelerometers to the same I2C lines"

    This means that the slave address used in the example is incorrect for the LIS3DH, so it will not respond:

    #define LSM6_ADD      (0XD6U >> 1)

    Search this forum for LIS3DH and LIS2DH where there are multiple discussions on the usage of this part; there are also Adafruit examples on the web to go through.

Reply
  • "The Slave ADdress (SAD) associated to the LIS3DH is 001100xb. The SDO/SA0 pad can be used to modify the less significant bit of the device address. If the SA0 pad is connected to the voltage supply, LSb is ‘1’ (address 0011001b) else if SA0 pad is connected to ground, the LSb value is ‘0’ (address 0011000b). This solution permits to connect and address two different accelerometers to the same I2C lines"

    This means that the slave address used in the example is incorrect for the LIS3DH, so it will not respond:

    #define LSM6_ADD      (0XD6U >> 1)

    Search this forum for LIS3DH and LIS2DH where there are multiple discussions on the usage of this part; there are also Adafruit examples on the web to go through.

Children
Related