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

TWI Scanner I2C address is 1 bit wrong

I'm using <TWI Scanner> example on nRF52 DK to find my sensor's address.

According to the sensor datasheet, the sensor's address is 0x21. However, <TWI Scanner> finds the address at 0x20. 

Any idea, please? 

  • Hi,

    Some I2C slaves lets you select one of a few addresses by hooking some pin(s) to VDD or ground, so that could be the case. Which sensor are you using?

  • I'm using SDP31 pressure sensor. Its datasheet is here. 

    According to page 4, section 3.3, my ADDR connects to GND. So its I2C address should be 0x21. But <TWI scanner> demo shows that the address is 0x20. 

    Thanks, Einar! 

  • Then I am out of ideas. The whole TWI Scanner example is essentially just this for loop:

        for (address = 1; address <= TWI_ADDRESSES; address++)
        {
            err_code = nrf_drv_twi_rx(&m_twi, address, &sample_data, sizeof(sample_data));
            if (err_code == NRF_SUCCESS)
            {
                detected_device = true;
                NRF_LOG_INFO("TWI device detected at address 0x%x.", address);
            }
            NRF_LOG_FLUSH();
        }

    As you can see, it prints the address (loop iteration #) of any device it is able to read from. It should not fail... If this is still a problem, perhaps you can use a logic analyzer to see how this looks on the TWI bus?

  • Here are the signals I got from SCL (red) and SDA(blue) for <TWI scanner demo>.

    meanwhile, here is my code <TWI scanner>

    #include <stdbool.h>
    #include <stdint.h>
    #include "nrf_delay.h"
    #include <stdio.h>
    #include "boards.h"
    #include "app_util_platform.h"
    #include "app_error.h"
    #include "nrf_drv_twi.h"
    
    
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    /* TWI instance ID. */
    #if TWI0_ENABLED
    #define TWI_INSTANCE_ID     0
    #elif TWI1_ENABLED
    #define TWI_INSTANCE_ID     1
    #endif
    
     /* Number of possible TWI addresses. */
     #define TWI_ADDRESSES      127
    
    /* TWI instance. */
    static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
    
    
    /**
     * @brief TWI initialization.
     */
    void twi_init (void)
    {
        ret_code_t err_code;
    
        const nrf_drv_twi_config_t twi_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_config, NULL, NULL);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_twi_enable(&m_twi);
        NRF_LOG_INFO("TWI enabled");
    }
    
    
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
        ret_code_t err_code;
        uint8_t address;
        uint8_t sample_data;
        bool detected_device = false;
    
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        NRF_LOG_INFO("TWI scanner started.");
        NRF_LOG_FLUSH();
        twi_init();
    
        /* Configure board. */
        bsp_board_init(BSP_INIT_LEDS);
    
        for (address = 1; address <= TWI_ADDRESSES; address++)
        {
            err_code = nrf_drv_twi_rx(&m_twi, address, &sample_data, sizeof(sample_data));
            // NRF_LOG_INFO("%d",(uint32_t)err_code);
            
            if (err_code == NRF_SUCCESS)
            {
                detected_device = true;
                NRF_LOG_INFO("TWI device detected at address 0x%x.", address);
            }
            NRF_LOG_FLUSH();
        }
    
        if (!detected_device)
        {
            NRF_LOG_INFO("No device was found.");
            NRF_LOG_FLUSH();
        }
    
        while (true)
        {
            /* Empty loop. */
        }
    }
    

  • Hi,

    Looking at the 9th clock pulse it looks like the SDA stays high, so there is no ACK here. Also, the data bits does not match address 0x20 (look like 0x03). Are you sure this is from the correct loop iteration? Can you modify your code to try to talk to only a single address at a time, so that you know that you are checking the correct one?

Related