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

Reading data from LSM6DS3 Sensor via I2C using nRF52 DK

Hi 

I'm a total beginner here and I have the gyroscope sensor LSM6DS3 and I have the nRF52 DK

I want to read the sensor's data via I2C (i.e. using SDA and SCL pins) using the nRF52 DK

I have downloaded the SEGGER Embedded studio and I have tried to run some of the ready examples to understand how the code works, but unfortunately, I didn't understand the code of any example expect this project "blinky_pca_10040" 

I can build and run any of the examples to the DK successfully without problems, but my problem is that I don't understand the codes!

I feel like understanding the code of any project is so difficult and I need to connect my sensor to the DK and I don't even know what to do or where to start!

I would really appreciate your help in this issue and I totally appreciate your patience with my ignorance of this matter.

Parents
  • Hi,

    Have a look here what component do.

    crash coarse.

    const nrf_drv_twi_config_t twi_lm75b_config
    setup for the twi

    err_code = nrf_drv_twi_init(&m_twi, &twi_lm75b_config, twi_handler, NULL);
    start twi
    params: twi instance, config, event handler, context (void pointer).

    err_code = nrf_drv_twi_rx(&m_twi, LM75B_ADDR, &m_sample, sizeof(m_sample));
    read data,
    params: twi instance, address, rx buffer, size of rx buffer in bytes.

    err_code = nrf_drv_twi_tx(&m_twi, LM75B_ADDR, reg, sizeof(reg), false);
    send data:
    params: twi instance, address, tx buffer, size of tx buffer in bytes, send no stop.


    void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
    events:
    NRF_DRV_TWI_EVT_DONE: RX/TX done.
    p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RXNRF_DRV_TWI_XFER_RX: receive is done


  • To be honest, I didn't understand anything from the reply. 

    I spent a lot of time trying to understand what you mean, but unfortunately I couldn't.

    As I mentioned in the main post, I'm a total beginner. So, I need something like a simple guide or simple steps to follow. 

    I can even read any document even if it is a long one but only if it can help and can give me the fundamentals of using the I2C on the nRF52 DK

    I really appreciate if you can make things clearer for me.

    Thank you Slight smile

Reply
  • To be honest, I didn't understand anything from the reply. 

    I spent a lot of time trying to understand what you mean, but unfortunately I couldn't.

    As I mentioned in the main post, I'm a total beginner. So, I need something like a simple guide or simple steps to follow. 

    I can even read any document even if it is a long one but only if it can help and can give me the fundamentals of using the I2C on the nRF52 DK

    I really appreciate if you can make things clearer for me.

    Thank you Slight smile

Children
  • I'm a total beginner

    Apologies this is very difficult to gauge this. Hopefully this is more understandable.

    TWI = I2C.

    In the examples SDK\examples\peripheral\twi_sensor

    1.

    /* TWI instance ID. */
    #define TWI_INSTANCE_ID     0
    
    /* TWI instance. */
    static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);


    These refer to the hardware TWI instant you are using. The nRF52s has more than one hardware TWI interface.

    2.

    /**
     * @brief Function for setting active mode on MMA7660 accelerometer.
     */
    void LM75B_set_mode(void)
    {
        ret_code_t err_code;
    
        /* 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);
    }


    uint8_t reg[2] is the data buffer to be sent via TWI. In this case the register and data.

    3.
    err_code = nrf_drv_twi_tx(&m_twi, LM75B_ADDR, reg, sizeof(reg), false);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);


    3.1
    err_code = nrf_drv_twi_tx(&m_twi, LM75B_ADDR, reg, sizeof(reg), false);

    send data:
    params: twi instance, address, tx buffer, size of tx buffer in bytes, send no stop.

    3.2
    This sends data via the TWI.
    m_twi: the hardware TWI instant being used ref 1.
    LM75B_ADDR: the address of the TWI device.
    reg: is the data to be sent ref 2.
    sizeof(reg): the length of data to be sent in bytes. sizeof(reg) = 2
    false: send a stop (send_no_stop). true don't send a TWI stop.

    Returns a error code and check it.
    Then wait for the TWI to finish ref 6.

    4.

    void twi_init (void)
    {
        ret_code_t err_code;
    
        const nrf_drv_twi_config_t twi_lm75b_config = {
           .scl                = ARDUINO_SCL_PIN,
           .sda                = ARDUINO_SDA_PIN,
           .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_lm75b_config, twi_handler, NULL);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_twi_enable(&m_twi);
    }


    4.1
    const nrf_drv_twi_config_t twi_lm75b_config
    setup for the twi

    .scl pin used for SCL on the nrf.
    .sda pin used for SDA on the nrf.
    .frequency speed of the TWI interface
    .interrupt_priority how important is the interrupt of TWI.
    .clear_bus_init can't remember.

    4.2
    err_code = nrf_drv_twi_init(&m_twi, &twi_lm75b_config, twi_handler, NULL);
    start twi
    params: twi instance, config, event handler, context (void pointer).

    m_twi: the hardware TWI instant being used ref 1.
    twi_lm75b_config: config for the TWI ref 4.1.
    twi_handler: function to handle events from the TWI ref 6.
    NULL: not in the scope to explain this just leave it as NULL.

    Returns a error code and check it.

    4.3
    nrf_drv_twi_enable(&m_twi);
    enable/start the TWI interface
    m_twi: the hardware TWI instant being used ref 1.

    5.
    static void read_sensor_data()
    {
        m_xfer_done = false;
    
        /* Read 1 byte from the specified address - skip 3 bits dedicated for fractional part of temperature. */
        ret_code_t err_code = nrf_drv_twi_rx(&m_twi, LM75B_ADDR, &m_sample, sizeof(m_sample));
        APP_ERROR_CHECK(err_code);
    }


    err_code = nrf_drv_twi_rx(&m_twi, LM75B_ADDR, &m_sample, sizeof(m_sample));
    read data,
    params: twi instance, address, rx buffer, size of rx buffer in bytes.

    m_twi the hardware TWI instant being used ref 1.
    LM75B_ADDR the address of the TWI device.
    m_sample holdes the data that is read from the TWI device.
    sizeof(m_sample) the number of bytes to read.

    NOTE: this is typically used after a nrf_drv_twi_tx(); with no stop set to true. Please refer to the TWI spec on how to read a device.

    6.
    /**
     * @brief TWI events handler.
     */
     //function to handle events
    void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
    {
        switch (p_event->type) // what event happend
        {
            case NRF_DRV_TWI_EVT_DONE: // TWI is done doing stuff
                if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX) //was the last tranfer a read 
                {
                    data_handler(m_sample);// handle the read data
                }
                m_xfer_done = true; //tells the app the the TWI is done doing stuff
                break;
            default:
                break;
        }
    }


    Please read the comments in the code.


Related