TWI Scanner no device was found

Hi, I'm using nRF52 DK (nRF52832) to detect my sensor. The sensor I2C address is 0x21 (verified by Arduino UNO).

My nRF52 DK (master) could detect the slave sensor before. But after I changed code somewhere (I forgot), the nRF52 DK cannot detect the slave sensor anymore. Any idea, pls? Thank you! 

/**
 * Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 *
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 *
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
/** @file
 * @defgroup tw_scanner 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 <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
    };

    /**
     * @brief Function for initializing the TWI driver instance.
     *
     * @param[in] p_instance      Pointer to the driver instance structure.
     * @param[in] p_config        Initial configuration.
     * @param[in] event_handler   Event handler provided by the user. If NULL, blocking mode is enabled.
     * @param[in] p_context       Context passed to event handler.
     *
     * @retval NRF_SUCCESS             If initialization was successful.
     * @retval NRF_ERROR_INVALID_STATE If the driver is in invalid state.
     * @retval NRF_ERROR_BUSY          If some other peripheral with the same
     *                                 instance ID is already in use. This is
     *                                 possible only if PERIPHERAL_RESOURCE_SHARING_ENABLED
     *                                 is set to a value other than zero.
     */
    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[9];
    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 = 0; address < TWI_ADDRESSES; address++)
    {
     /**
       * @brief Function for reading data from a TWI slave.
       *
       * The transmission will be stopped when an error occurs. If a transfer is ongoing,
       * the function returns the error code @ref NRF_ERROR_BUSY.
       *
       * @param[in] p_instance Pointer to the driver instance structure.
       * @param[in] address    Address of a specific slave device (only 7 LSB).
       * @param[in] p_data     Pointer to a receive buffer.
       * @param[in] length     Number of bytes to be received.
       *
       * @retval NRF_SUCCESS                    If the procedure was successful.
       * @retval NRF_ERROR_BUSY                 If the driver is not ready for a new transfer.
       * @retval NRF_ERROR_INTERNAL             If an error was detected by hardware.
       * @retval NRF_ERROR_DRV_TWI_ERR_OVERRUN  If the unread data was replaced by new data
       * @retval NRF_ERROR_DRV_TWI_ERR_ANACK    If NACK received after sending the address in polling mode.
       * @retval NRF_ERROR_DRV_TWI_ERR_DNACK    If NACK received after sending a data byte in polling mode.
       */
        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 decimal %d = hex 0x%x.",address ,address);
            NRF_LOG_FLUSH();
        }
        NRF_LOG_FLUSH();
    }

    if (!detected_device)
    {
        NRF_LOG_INFO("No device was found.");
        NRF_LOG_FLUSH();
    }

    while (true)
    {
        /* Empty loop. */
        
    }
}

/** @} */

  • Note: my sensor returns 9 bytes of data (2 bytes of pressure, 1 byte of Check, 2 bytes of temperature, 1 byte of Check, 2 bytes of scaling factor, 1 byte of Check)

  • Hi Steven,

    I have some suggestions that may helpful for your debugging:

    1. Did you check with Arduino again to make sure the device is still alive?

    2. Can you try with the original twi_scanner example?

    3. Do you have a logic analyzer to see what happens on the TWI bus? Please double check the wires' connectability.

    Best regards,

    Charlie

  • Problem Solved! 

    The code doesn't work due to the slave device and time delay issue. The sensor I'm using requires:

    1) reset-->send continuous mode command-->read data (I didn't add reset command before)

    2) meanwhile, for each read/write command, we must add a time delay (e.g. 5 ms) after the command

    Thanks to everyone who helped me before! Cheers

  • Could you please Share the code? I am having the same problem.

  • Sorry, Baha. 

    Since it's the company product, I cannot share the code. My suggestion is to read the datasheet + check the hardware connection. 

    Hints 

    1. Some sensors need to wait for a few us or ms after sending the command. e.g. delay 27 us after sending command

    2. Also, some sensors need to be initialized at the beginning. 

    3. You may ask your supplier for software / debugging issue. 

    4. Use the print function (e.g. NRF_LOG_INFO() ) to debug, see where the error is. 

Related