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.

Parents
  • 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? 

Reply Children
Related