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

twi can't read data from sensor

   Hi,

   example :  nRF5_SDK_15.0.0_a53641a\examples\peripheral\twi_sensor


    I am using the HTU21D sensor.
    I was download the twi_scanner example to scan the HTU21D sensor's slave address. the others sensors can be sanned.But the HTU21D can't be scanned.
    I  used the slave address 0x80 > > 1 (the address is 0x80 from HTU21D datasheet), the amazing things was happened. i can used (write and read) the user register. But i  can't use (read) the   Temperature and  Humidity register.

    1.   I want to know how to add the delay function after sent/written the read address.


    2.  I will  be happy to get your advice.

  • We need a scope from a digital analyzer in order to know what's going on. 

    The holding/delay seems to be controlled by the slave, not the master.

  • Hi,

    I use oscilloscope, at first there is level conversion, then there is no.

    I used analog I2c could  add the delay function after sent/written the read address by the master.

    Below is the main.c file 

    /** @file
     * @defgroup tw_sensor_example main.c
     * @{
     * @ingroup nrf_twi_example
     * @brief TWI Sensor Example main file.
     *
     * This file contains the source code for a sample application using TWI.
     *
     */
    
    #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"
    
    /* TWI instance ID. */
    #define TWI_INSTANCE_ID     0
    
    /* Common addresses definition for temperature sensor. */
    
    #define        HTU21D_SlaveAddress   (0x80U>>1)          //¶¨ÒåHTU21DÔÚI2C×ÜÏßÉϵĴӵØÖ·
    
    /* Mode for LM75B. */
    #define NORMAL_MODE 0U
    
    /* 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);
    
    /* Buffer for samples read from temperature sensor. */
    static uint8_t m_sample;
    
    /**
     * @brief Function for handling data from temperature sensor.
     *
     * @param[in] temp          Temperature in Celsius degrees read from sensor.
     */
    __STATIC_INLINE void data_handler(uint8_t temp)
    {
        NRF_LOG_INFO("Value: 0x%x .", temp);
    }
    
    /**
     * @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(m_sample);
                }
                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_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);
    }
    
    void HTU21D_sensor_init()
    {
    		//reset sensor
    		ret_code_t err_code;
    		m_xfer_done=false;
        uint8_t reg[1] = {0xfe};
        err_code = nrf_drv_twi_tx(&m_twi, HTU21D_SlaveAddress, reg, sizeof(reg), false);
        APP_ERROR_CHECK(err_code);
        while (m_xfer_done == false);
    }
    
    void read_data_reg(uint8_t regAddr)
    {
    		ret_code_t err_code;
    		uint8_t reg[1] = {regAddr};
        m_xfer_done = false;
        err_code = nrf_drv_twi_tx(&m_twi, HTU21D_SlaveAddress, reg, 1, false);
        APP_ERROR_CHECK(err_code);
        while (m_xfer_done == false);
    		
    		m_xfer_done = false;
        /* Read 1 byte from the specified address - skip 3 bits dedicated for fractional part of temperature. */
        err_code = nrf_drv_twi_rx(&m_twi, HTU21D_SlaveAddress, &m_sample, sizeof(m_sample));
        APP_ERROR_CHECK(err_code);
    		
    }
    
    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();
    		HTU21D_sensor_init();
    		read_data_reg(0xE7);  //read user register
    		
        while (true)
        {
            nrf_delay_ms(500);
    				
    				read_data_reg(0xE3);  //read Temperature  register LSB
    				read_data_reg(0xE3+1);  //read Temperature  register MSB
    			
    				NRF_LOG_FLUSH();
        }
    }
    
    /** @} */
    

    Below is the log file

    <info> app: Value: 0x2 .
    <error> app: ERROR 17 [NRF_ERROR_BUSY] at ..\..\..\main.c:110
    PC at: 0x000021A5
    <error> app: End of error report
    

    I sincerely look forward to your reply. thanks

  • NRF_ERROR_BUSY means that the TWI peripheral is still in a transaction and that you need to retry at a later point. 

     

    lisi said:
    I use oscilloscope, at first there is level conversion, then there is no.

     I do not know what that means, can you share a scope of the TWI lines? 

  • I used an oscilloscope to grab the waveform of the SCL line, and there was no waveform change after the application reported an NRF_ERROR_BUSY error. I debug found that the applocation is stop at while (m_xfer_done == false);

    that you need to retry at a later point. 

    Sorry, I didn't understand what that meant

  • Can you share a scope of the SDA and SCL lines? 

    lisi said:
    that you need to retry at a later point. 

     It means that the driver is busy with the last transaction and that you need to wait until the last transaction has completed until you can issue another one. 


Related