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

Not able to read the register values from external sensor using the nrf_drv_twi_tx and nrf_drv_twi_rx functions in the twisensor example.

Hi,

I have been trying to read the register values, from BNO_080, using the functions nrf_drv_twi_tx to write and nrf_drv_twi_rx to read. But for some reason, i have been getting a constant value as the output, when i try to see them on the serial monitor. I have attached my code below. I have put a flag after every function, but for some reason, it does not go into the flag , the one after the read_sensor_data() in the int main().

Any information why?

 

#define SHTP_REPORT_COMMAND_RESPONSE 0xF1
#define SHTP_REPORT_COMMAND_REQUEST 0xF2
#define SHTP_REPORT_FRS_READ_RESPONSE 0xF3
#define SHTP_REPORT_FRS_READ_REQUEST 0xF4
#define SHTP_REPORT_PRODUCT_ID_RESPONSE 0xF8
#define SHTP_REPORT_PRODUCT_ID_REQUEST 0xF9
#define SHTP_REPORT_BASE_TIMESTAMP 0xFB
#define SHTP_REPORT_SET_FEATURE_COMMAND 0xFD

/* TWI instance ID. */
#define TWI_INSTANCE_ID     0
#define TRANSACTION_QUEUE_SIZE 5

#define BNO_080  0x4B         							//the BNO_080 address, which gets toggled when we call the tx or rx functions to either 1 or a 0//
#define SENSOR_REPORTID_GAME_ROTATION_VECTOR 0x08       //this is the register data, which we are trying to send out//
#define SENSOR_REPORTID_ACCELEROMETER 0x01
#define SENSOR_REPORTID_GYROSCOPE 0x02
#define SENSOR_REPORTID_MAGNETIC_FIELD 0x03
#define SENSOR_REPORTID_LINEAR_ACCELERATION 0x04
#define SENSOR_REPORTID_ROTATION_VECTOR 0x05
#define SENSOR_REPORTID_GRAVITY 0x06
#define SENSOR_REPORTID_GEOMAGNETIC_ROTATION_VECTOR 0x09
#define SENSOR_REPORTID_TAP_DETECTOR 0x10
#define SENSOR_REPORTID_STEP_COUNTER 0x11
#define SENSOR_REPORTID_STABILITY_CLASSIFIER 0x13
#define SENSOR_REPORTID_PERSONAL_ACTIVITY_CLASSIFIER 0x1E

/* Indicates if operation on TWI has ended. */
static volatile bool m_xfer_done = false;

/* TWI instance. */
static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
uint8_t address = SENSOR_REPORTID_STEP_COUNTER;

void BNO_080_set_mode(void)
{
    ret_code_t err_code;
    uint8_t reg[2] = {SHTP_REPORT_PRODUCT_ID_REQUEST, 0b00000000};
    err_code = nrf_drv_twi_tx(&m_twi, BNO_080, reg, sizeof(reg), false);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);

    reg[0] = SHTP_REPORT_PRODUCT_ID_RESPONSE;
    m_xfer_done = false;
    err_code = nrf_drv_twi_tx(&m_twi, BNO_080, reg, 1, false);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);
}


__STATIC_INLINE void data_handler(uint8_t address)
{
    NRF_LOG_INFO("Data: %d.\r\n", address);
    NRF_LOG_FLUSH();
}

/**
 * @brief TWI events handler.
 */
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)
            {
                data_handler(address);
            }
            m_xfer_done = true;
            break;
        default:
            break;
    }
}

/**
 * @brief UART initialization.
 */
void twi_init (void)
{
    ret_code_t err_code;

    const nrf_drv_twi_config_t twi_bno080_config = {
            .scl                = 27,
            .sda                = 26,
            .frequency          = NRF_DRV_TWI_FREQ_400K,
            .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
            .clear_bus_init     = false
    };

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

/**
 * @brief Function for reading data.
 */
static void read_sensor_data(void)
{
    m_xfer_done = false;
    ret_code_t err_code = nrf_drv_twi_rx(&m_twi, BNO_080, &address, sizeof(address));
    APP_ERROR_CHECK(err_code);
//    ret_code_t err_code;
//    err_code = nrf_drv_twi_tx(&m_twi, BNO_080, &address, 1, true);
//    if (NRF_SUCCESS == err_code)
//        err_code = nrf_drv_twi_rx(&m_twi, BNO_080, dataValue, 12, false);
//    APP_ERROR_CHECK(err_code);
}

int main(void)
{
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    NRF_LOG_INFO("FLAG 1:\r\n");
    NRF_LOG_FLUSH();
    twi_init();
    NRF_LOG_INFO("Flag 2:\r\n");
    NRF_LOG_FLUSH();
    BNO_080_set_mode();
    NRF_LOG_INFO("Flag 3: \r\n");
    NRF_LOG_FLUSH();

    while (true)
    {
        nrf_delay_ms(500);

        do
        {
            __WFE();
        }
        while (m_xfer_done == false);

        read_sensor_data();

        NRF_LOG_INFO("Flag4:\r\n")
        NRF_LOG_FLUSH();
    }
}

Parents
  • What do you mean by this: "But for some reason, i have been getting temperature values as the output"?

    The BNO_080 seems to be a IMU sensor, it should not give you temperature values?

  • I do not know what protocol or commands your sensor expects, this you will have to read from the datasheet of the device. However, it looks like your read_sensor_data function only calls nrf_drv_twi_rx, and not nrf_drv_twi_tx. Normally I2C/TWI devices expect some register to be written, to know what will be output, and then you can read the output. I see you have some commented commands as well, but you do not seem to have any sync between the calls to make sure the previous transfer is completed. The TWI driver will work in non-blocking mode if you pass a callback handler to the init function. You then need to wait for a transfer to finish using 'while (m_xfer_done == false);' before starting next transfer.

  • You are printing the address of the data variable on line 70, not the actual data. Change the line from:

    NRF_LOG_INFO("Data: %x.\r\n", &buffer);

    to:

    NRF_LOG_INFO("Data: %x.\r\n", buffer);

    You also seems to have a global variable called buffer. You should change one of the variable names to avoid confusion with regards to which variable is referenced. 

  • #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 SHTP_REPORT_COMMAND_RESPONSE 0xF1
    #define SHTP_REPORT_COMMAND_REQUEST 0xF2
    #define SHTP_REPORT_FRS_READ_RESPONSE 0xF3
    #define SHTP_REPORT_FRS_READ_REQUEST 0xF4
    #define SHTP_REPORT_PRODUCT_ID_RESPONSE 0xF8
    #define SHTP_REPORT_PRODUCT_ID_REQUEST 0xF9
    #define SHTP_REPORT_BASE_TIMESTAMP 0xFB
    #define SHTP_REPORT_SET_FEATURE_COMMAND 0xFD
    
    /* TWI instance ID. */
    #define TWI_INSTANCE_ID     0
    #define TRANSACTION_QUEUE_SIZE 5
    
    #define BNO_080  0x4B         							                //the BNO_080 address, which gets toggled when we call the tx or rx functions to either 1 or a 0//
    #define SENSOR_REPORTID_GAME_ROTATION_VECTOR 0x08                       //this is the register data, which we are trying to send out//
    #define SENSOR_REPORTID_ACCELEROMETER 0x01
    #define SENSOR_REPORTID_GYROSCOPE 0x02
    #define SENSOR_REPORTID_MAGNETIC_FIELD 0x03
    #define SENSOR_REPORTID_LINEAR_ACCELERATION 0x04
    #define SENSOR_REPORTID_ROTATION_VECTOR 0x05
    #define SENSOR_REPORTID_GRAVITY 0x06
    #define SENSOR_REPORTID_GEOMAGNETIC_ROTATION_VECTOR 0x09
    #define SENSOR_REPORTID_TAP_DETECTOR 0x10
    #define SENSOR_REPORTID_STEP_COUNTER 0x11
    #define SENSOR_REPORTID_STABILITY_CLASSIFIER 0x13
    #define SENSOR_REPORTID_PERSONAL_ACTIVITY_CLASSIFIER 0x1E
    
    /* TWI instance. */
    static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
    
    /* Indicates if operation on TWI has ended. */
    static volatile bool m_xfer_done = false;
    
    uint8_t buffer1[12];
    uint8_t buffer2[12];
    uint8_t buffer3[12];
    
    uint16_t i;
    uint16_t j;
    uint16_t k;
    uint16_t real;
    
    void BNO_080_set_mode(void)
    {
        ret_code_t err_code;
    //    m_xfer_done = false;
    //    uint8_t reg1[2] = {SHTP_REPORT_COMMAND_REQUEST, 0x00};
    //    err_code = nrf_drv_twi_tx(&m_twi, BNO_080, reg1, sizeof(reg1), false);
    //    APP_ERROR_CHECK(err_code);
    //    err_code = nrf_drv_twi_rx(&m_twi, BNO_080, buffer1, sizeof(buffer1));
    //    APP_ERROR_CHECK(err_code);
    //    while (m_xfer_done == false);
    //
    //
    //    uint8_t reg2[2] = {SHTP_REPORT_COMMAND_RESPONSE, 0x00};
    //    err_code = nrf_drv_twi_tx(&m_twi, BNO_080, reg2, sizeof(reg2), false);
    //    APP_ERROR_CHECK(err_code);
    //    while (m_xfer_done == false);
    //    err_code = nrf_drv_twi_rx(&m_twi, BNO_080, buffer2, sizeof(buffer2));
    //    APP_ERROR_CHECK(err_code);
    
        uint8_t reg3[2] = {SENSOR_REPORTID_ROTATION_VECTOR, 0x00};
        err_code = nrf_drv_twi_tx(&m_twi, BNO_080, reg3, sizeof(reg3), false);
        APP_ERROR_CHECK(err_code);
        while (m_xfer_done == false);
    
        err_code = nrf_drv_twi_rx(&m_twi, BNO_080, buffer3, sizeof(buffer3));
        APP_ERROR_CHECK(err_code);
    
    }
    
    /**
     * @brief TWI events handler.
     */
    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)
                {
    //                NRF_LOG_INFO("Data: %x.\n", &buffer);    // do not uncomment this, will give an error, because of buffer and variables clashing
    //                NRF_LOG_FLUSH();
    
                }
                m_xfer_done = true;
                break;
            default:
                break;
        }
    }
    
    /**
     * @brief UART initialization.
     */
    void twi_init (void)
    {
        ret_code_t err_code;
    
        const nrf_drv_twi_config_t twi_bno080_config = {
                .scl                = 27,
                .sda                = 26,
                .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_bno080_config, twi_handler, NULL);
        APP_ERROR_CHECK(err_code);
        nrf_drv_twi_enable(&m_twi);
    }
    
    /**
     * @brief Function for reading data.
     */
    static void read_sensor_data(void)
    {
        ret_code_t err_code;
        m_xfer_done = false;
    //    uint8_t reg1[2] = {SHTP_REPORT_COMMAND_REQUEST, 0x00};
    //    err_code = nrf_drv_twi_tx(&m_twi, BNO_080, reg1, sizeof(reg1), false);
    //    APP_ERROR_CHECK(err_code);
    //    err_code = nrf_drv_twi_rx(&m_twi, BNO_080, buffer1, sizeof(buffer1));
    //    APP_ERROR_CHECK(err_code);
    //    while (m_xfer_done == false);
    //
    //
    //    uint8_t reg2[2] = {SHTP_REPORT_COMMAND_RESPONSE, 0x00};
    //    err_code = nrf_drv_twi_tx(&m_twi, BNO_080, reg2, sizeof(reg2), false);
    //    APP_ERROR_CHECK(err_code);
    //    while (m_xfer_done == false);
    //    err_code = nrf_drv_twi_rx(&m_twi, BNO_080, buffer2, sizeof(buffer2));
    //    APP_ERROR_CHECK(err_code);
    
        uint8_t reg3[2] = {SENSOR_REPORTID_ROTATION_VECTOR, 0x00};
        err_code = nrf_drv_twi_tx(&m_twi, BNO_080, reg3, sizeof(reg3), false);
        APP_ERROR_CHECK(err_code);
        while (m_xfer_done == false);
    
        err_code = nrf_drv_twi_rx(&m_twi, BNO_080, buffer3, sizeof(buffer3));
        APP_ERROR_CHECK(err_code);
    
    
    }
    
    int main(void)
    {
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
    
        twi_init();
        BNO_080_set_mode();
    
        while (true)
        {
            nrf_delay_ms(100);
    
            do
            {
                __WFE();
            }
            while (m_xfer_done == false);
    
            i = ((buffer3[4] << 8) | (buffer3[5] & 0xff));
            j = ((buffer3[6] << 8) | (buffer3[7] & 0xff));
            k = ((buffer3[8] << 8) | (buffer3[9] & 0xff));
            real = ((buffer3[10] << 8) | (buffer3[11] & 0xff));
    
    
    //        y_msb = buffer[6];
    //        y_lsb = buffer[10];
    
            read_sensor_data();
    
            NRF_LOG_INFO("Data: %X %X %X %X \n", i, j, k, real);
    //        NRF_LOG_INFO("Data: %X \n", buffer3);
    //        NRF_LOG_INFO("First: %X Second: %X \n",i, j);
    
            NRF_LOG_FLUSH();
        }
    }

    I have replaced the variable name, and also, i am not printing the address of the variable. But i am getting this output now, only two interchanging values. 

    In BNO_080, the report ID is the pre-processor defined stuff, which corresponds to the GAME_ROTATION_VECTOR. Now when i want to read the report ID, which i get as a response, its a 12 byte array. So, i am trying to store the data in the variables named i,j,k,real for the quaternion data. But my problem is that, they are repeated and it does not change when i change the orientation of the sensor. 

    Here's the output:

    <info> app: Data: 102 202 202 202

    <info> app: Data: 202 C00 0 0

    <info> app: Data: 102 202 202 202

    <info> app: Data: 202 C00 0 0

    <info> app: Data: 102 202 202 202

    <info> app: Data: 202 C00 0 0

    <info> app: Data: 102 202 202 202

    <info> app: Data: 202 C00 0 0

    <info> app: Data: 102 202 202 202

  • According to the datasheet, BNO080 does not expect a stop condition between the write of the register address and the read operation. You need to set the no_stop parameter of nrf_drv_twi_tx to true.

  • I have tried changing the no_stop condition from false to true. Also, i tried removing the stop condition in between the write and read commands. But now, i don't get any data on the serial monitor.

  • Sorry, seems like I missread the datasheet and that you perform write and read operations separatelu. Are you sure you have configured the device to output new values? I would recommend that you compare your code towards other working libraries for the sensor on other platforms, or read the datasheet thoroughly to make sure you have configured it correctly.

Reply Children
No Data
Related