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

Reading Data from Sensor by TWIM

Hi,

I would like to read data from sensor and send it over BLE to nRF connect. Unfortunaly, something went wrong while reading the data by TWIM.

I´m using SDK16.

I would like to read 12 Bytes from a Sensor and store this in a Puffer. After this, I send the Puffer ober BLE to nRF connect. So the procedure should be:

- determine Sensor

- determine start register

- read 12 Bytes, starting at start register

- send 12 Bytes ober Bluetooth Low Energy

I think someting goes wrong by collecting the data over TWIM. For doing this, I use the following functions to determine the correct Sensor:

void ICM20948_set_mode(void)
{


      
ret_code_t err_code;

    /* Sensor on */
    uint8_t reg3[2] = {0x06, 0x01};
    nrfx_twim_xfer_desc_t normal_mode_config = NRFX_TWIM_XFER_DESC_TX(ICM20948_ADDR, reg3, sizeof(reg3));
    err_code = nrfx_twim_xfer(&m_twim, &normal_mode_config, NULL);
    while (m_xfer_done == false);

    /* Register choose */
    uint8_t reg4[1] = {0x2D}; // Since this register there are 12 Bytes we would have to read
    m_xfer_done = false;
    nrfx_twim_xfer_desc_t temp_reg_write = NRFX_TWIM_XFER_DESC_TX(ICM20948_ADDR, reg4, sizeof(reg4));
    err_code = nrfx_twim_xfer(&m_twim, &normal_mode_config, NULL);    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);


}

After determine the correct sensor and correct register, I would like to read 12 Bytes from the register and send it by bluetooth.:

static void read_sensor_data()
{


    m_xfer_done = false;
    nrfx_twim_xfer_desc_t lm75b_reading = NRFX_TWIM_XFER_DESC_RX(ICM20948_ADDR, &m_sample[0], sizeof(m_sample));
 

    /* Read 12 bytes from the specified address - skip 3 bits dedicated for fractional part of temperature. */
    ret_code_t err_code = nrfx_twim_xfer(&m_twim, &lm75b_reading, NULL);
    APP_ERROR_CHECK(err_code);


// Send data over Bluetooth 
                     
//nrf_delay_ms(100); 
uint32_t err_code2; 
uint16_t length = (uint16_t)12;

err_code2 = ble_nus_data_send(&m_nus, m_sample, &length, m_conn_handle);
if ((err_code2 != NRF_ERROR_INVALID_STATE) &&
(err_code2 != NRF_ERROR_RESOURCES) &&
(err_code2 != NRF_ERROR_NOT_FOUND))
{
APP_ERROR_CHECK(err_code2);
}

}

Unfortunaly, there are not the correct sensor values on nRF connect app. For analyzing, I attached the hole project for you too.

It would be great, if someone could have a look to my functions I use.

Thanks in advance.

Simon

ble_app_uart_with_twim v0.1.zip

Parents Reply Children
  • Okay, I´m now able for debugging. I can take a watch to my relevant variables.

    Could you please help me with a TWIM read function? I have initialized the TWIM and Sensor successfully. In my read function, I just read one byte by TWIM. The value I would like to read is a known constance, stored in register "0". Sometimes, the watch shows the correct value in the watch window. So it seems that a part of my code is working. But not always. The value is changing all the time (I update the variable two times a second). Because in this register is just stored a constance, I have to read always the same value. Could you please have a look to a few lines code of my read function?

    static void read_sensor_data()
    {
    
    static uint8_t m_sample;
    
            /* Sensor Register 0 write to Sensor */
            uint8_t reg5 = {0x00};
            nrfx_twim_xfer_desc_t test = NRFX_TWIM_XFER_DESC_TX(ICM20948_ADDR, &reg5, sizeof(reg5));
    
    
            /* Read 1 byte from the specified address. */
            m_xfer_done = false;
            nrfx_twim_xfer_desc_t lm75b_reading = NRFX_TWIM_XFER_DESC_RX(ICM20948_ADDR, &m_sample, sizeof(m_sample));
    
            ret_code_t err_code = nrfx_twim_xfer(&m_twim, &lm75b_reading, NULL);
            APP_ERROR_CHECK(err_code);
    
    }

    Like I said, sometimes the correct value of register "0" is stored in my buffer "m_sample".

    Is there something I´m doing wrong? Is the way I try to read a value by TWIM correct (send register to I2C address - read from I2C adrdess)?

    Thanks in advance

    Simon

  • What does the sensor's datasheet say you need to do to read a register?

  • I am working with ICM20948 sensor:

    https://invensense.tdk.com/wp-content/uploads/2016/06/DS-000189-ICM-20948-v1.3.pdf

    1. Sensor has to powered up

    2. correct user bank/map has to be selected

    3. correct register has to be selected.

    How I am doing sep 3 I sent in my last post. Steps 1 and 2 I´m doing like the following:

    void ICM20948_set_mode(void)
    {
    
    ret_code_t err_code;
    
        /* Sensor on , Step 1*/
        uint8_t reg3[2] = {0x06, 0x01};
        nrfx_twim_xfer_desc_t normal_mode_config = NRFX_TWIM_XFER_DESC_TX(ICM20948_ADDR, reg3, sizeof(reg3));
        err_code = nrfx_twim_xfer(&m_twim, &normal_mode_config, NULL);
        while (m_xfer_done == false);
    
            /* USER BANK selection, Step 2 */
        uint8_t reg4[2] = {0x7F, 0x00};
        nrfx_twim_xfer_desc_t reg_usr_bank      = NRFX_TWIM_XFER_DESC_TX(ICM20948_ADDR, reg4, sizeof(reg4));
        err_code = nrfx_twim_xfer(&m_twim, &reg_usr_bank, NULL);  
        while (m_xfer_done == false);
    }

    Thanks in advance for your help.

    Simon

  • I suggest you scope you serial communication with a logic analyzer and compare that with the read/write descriptions in chapter 6.3 of the invensense datasheet. 

  • Hi haakonsh,

    could you please help me a bit more, in special with my code? I already used TWI sensor example of SDK and get it working. So there are no hardware or wrong voltage level faults. The change toTWIM is not working, so I think there are errors in my code. Unfortunaly, there are no examples for TWIM in SDK 16 or is there anywhere some stuff, showing the TWIM communication?

    Regards

    Simon

Related