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

TWI Scanner works on nRF52 DK, doesn't work on 3rd Party Modules

I've been trying to get TWI Sensor to work on 3rd party boards for a while now and no luck. 

The code I'm using is only slightly modified, (1) it explicitly defines .scl and .sda pins in main.h

void twi_init (void)
{
    ret_code_t err_code;

    const nrf_drv_twi_config_t twi_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_config, NULL, NULL);
    APP_ERROR_CHECK(err_code);

    nrf_drv_twi_enable(&m_twi);
}

(2) it takes the scanner that happens once on startup and throws it in the loop so I can see the scanner even if I don't open the COM port when the program loads:

 while (true)
    {
        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();
        }
        if (!detected_device)
        {
            NRF_LOG_INFO("No device was found.");
            NRF_LOG_FLUSH();
        }
        nrf_delay_ms(500);
    }

This code has worked well and successfully identified two separate I2C sensors when it was flashed to the nRF52832 that is on the nRF52 DK.

However, I've tried flashing it both to the Sparkfun nRF52832 Breakout as well as the BT832, the latter of which is listed as an official 3rd Party Module on the Nordic website. Both 3rd party boards are unable to scan any I2C slaves, and the COM port just prints "No device was found." I have confirmed that pins 26 and 27 on the third party boards are creating pulses on an oscilloscope, and to me the pulses look the same as the ones created by the nRF52832 that works correctly on the DK. I have also changed the .scl and .sda pins to other ones on the board (I've tried 9/8, 15/14, ...) and have seen those pins I assigned as .scl and .sda pulsing on an oscilloscope, but again the Third Party Modules don't recognize the I2C device and report "No device was found."

Does anyone have advice on what I can try to fix this and get TWI Scanner to work on a 3rd Party Module?

The full project and code is attached below, I was working out of "nRF5_SDK_15.2.0_9412b96\examples\peripheral\twi_scanner\pca10040\blank\ses"

twi_scanner.zip

  • Hi,

    • What voltage are you running the boards/modules on?
    • Can you post screenshots of the scope communication with DK and the modules?
    • What kind of sensors are you interfacing, and how are these powered?

    Best regards,
    Jørgen

  • Hi Jørgen, sorry for the late reply, I was out of office yesterday.

    • What voltage are you running the boards/modules on? What kind of sensors are you interfacing, and how are these powered?

    When I'm powering the I2C devices (the two devices are an MPU6050, I2C address 0x68 in this case, and an LSM6DS3, I2C address 0x6B in this case), no matter what nRF module I'm testing code on, I am always powering them from VDD of the nRF52 DK. When I probed this voltage using my DMM, I read 2.80V.

    I am also powering the Sparkfun nRF52832 Breakout and the BT832 with the 2.80V VDD originating from the nRF52 DK. So all nRF and I2C modules are being powered from the same voltage generated from the nRF52 DK.

    • Can you post screenshots of the scope communication with DK and the modules?

    Sure. These are some very low-resolution screenshots that lets you see the whole signal in clusters, but I will also attach a high-resolution sampling of the first part of the first cluster of pulses (as high res as I could capture with my oscilloscope without signal aliasing).

    DK with 2 I2C devices attached:

    DK with 1 I2C device attached:

    DK zoomed in on SCL/SDA lines:

    COM Port when DK is configured and I2C is working:

    Sparkfun nRF52 Breakout Board with 2 I2C devices attached:

    Sparkfun nRF52 Breakout Board with 1 I2C device attached:

    Sparkfun nRF52 Breakout Board zoomed in on SCL/SDA lines:

    COM Port when Sparkfun is configured and I2C communication is not working:

    And the BT832 also had identical characteristics to the DK and Sparkfun board when interacting with 1 or 2 I2C devices.

    I have also attached samples from both the DK and Sparkfun board, they capture the first couple thousand points after the scope triggers on the first cluster of pulses.

    Any ideas on what I can fix to get the Sparkfun or BT832 to recognize the I2C devices? It looks like there is some interaction happening, they share similar characteristics when moving between 1 and 2 I2C devices...

    nRF52_DK_with_working_I2C.CSV

    Sparkfun_nRF52_breakout_with_broken_I2C.CSV

  • I cannot see any reasons that the modules should not be able to detect the sensors. Are the sensors powered directly from VDD on the 52-DK? Are you testing with the unmodified example from the SDK?

  • Disappointed

    All sensors are powered directly from the DK, so even when an external module is being used, the power rails all come from VDD on the DK, and not "bottlenecked" through the external board.

    I mentioned the modifications I made to the SDK example and attached my project file in a ZIP to the OP, but it's virtually unchanged (just a slight mod to make it repeatedly print I2C devices instead of only printed once). I experienced the same problems with the 100% unmodified code too, however.

    When the I2C data line is hooked up to two devices and get's pulled low twice, instead of once for one device, does that indicate that the MCU is acknowledging the I2C slave? or does the slave pull the data line low and it's possible that the MCU isn't "listening"?

    Do you have any other recommendations for debugging? Have you gotten this code to work with 3rd party modules? Do you think I should try stepping through the code by using the external debugger? Or perhaps I should try to communicate directly with the modules (check the WHO_AM_I register) to see if perhaps there's just a bug with the code but I2C itself is functional ... ?

  • Update:

    I decided step through the application in debug mode, working with the Sparkfun 3rd party nRF52832 module (see OP). The only change I've made to the code was enabling NRF_LOG_BACKEND_RTT_ENABLING in sdk_config.h so I can step through in the Debug Terminal:

    #ifndef NRF_LOG_BACKEND_RTT_ENABLED
    #define NRF_LOG_BACKEND_RTT_ENABLED 1
    #endif

    After doing that and setting a breakpoint on the "NRF_LOG_FLUSH();" right after "if (err_code == NRF_SUCCESS)", ...

    while (true)
        {
            detected_device = false;
    
            for (address = 0x67; address <= 0x69; 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();
            }
            if (!detected_device)
            {
                NRF_LOG_INFO("No device was found.");
                NRF_LOG_FLUSH();
            }
            nrf_delay_ms(500);
        }

    ... I stepped through until "address" read a value "0x68", and the I2C sensor was actually recognized in terminal! I can even remove the breakpoint and press "play" and it works 100% normally, printing "<info> app: TWI device detected at address 0x68." every half-second just like it should have in the COM port.

    However, after exiting debug mode and opening the COM port in Docklight, without changing a single thing in my setup, once again the Sparkfun 3rd party module prints "No device was found." Huh??

    So it seems as though this code works in the Debug Terminal, but not in the COM port. I am very confused. Why could this be happening?

    ...so now that I know I can (sometimes?) communicate with I2C devices, I'm going to move on and try to read registers and see if I can send it over Bluetooth. While proving communication with the device is possible is progress, I would really like to understand why this bug occurs, otherwise the same exact thing could happen when I'm trying to send data over Bluetooth.

Related