The TWI problems continue ...

Hello all,

for the last few weeks I am trying to workout the i2c protocol with the sensor and the nrf52dk , so far none of the solution that I have considered work. More can be seen here: https://devzone.nordicsemi.com/f/nordic-q-a/84978/twi-reading-and-writing-basics/363652#363652

I am thinking can the speed of the processor be too fast for the sensor prototype, like the wires to the board may be too long, for example, for example, the same prototype works on the Arduino's Atmel omega just ok... 

Therefore, to test this out my question is, how to reduce the speed of the i2c to less than 100kHz and how to reduce the speed of the processor? Indeed, if you have other suggestions please do not hesitate.

Thank you in advance, looking forward to your suggestions, ideas, how to tackle this further.

Best.

Parents
  • Hello Edvin and thank you for your reply,

    indeed, the voltage drops that we were thinking about are not relevant, measured it on the current wiring setup, so far so good.

    Tested the address with the TWI Scanner example and got : 

    <info> app: TWI scanner started.
    <info> app: TWI device detected at address 0x60.

    Apparently, the sensor is found ok, btw please remind me where is the address on the TWI specifically defined? I want to check that in my application...

    I have easily copied the code from the TWI scanner into my application and interesting things pop out, not sure, if this is ok?

    TWI scanner started.<info> app: TWI scanner started.
    error code :    nothing?TWI device detected at address 0x1.<info> app: TWI device detected at address 0x1.
    TWI device detected at address 0x2.<info> app: TWI device detected at address 0x2.
    TWI device detected at address 0x3.<info> app: TWI device detected at address 0x3.
    TWI device detected at address 0x4.<info> app: TWI device detected at address 0x4.
    TWI device detected at address 0x5.<info> app: TWI device detected at address 0x5.
    TWI device detected at address 0x6.<info> app: TWI device detected at address 0x6.
    <info> app: TWI device detected at address 0x7.
    TWI device detected at address 0x8.TWI device detected at address 0x9.<info> app: TWI device detected at address 0x1C.
    TWI device detected at address 0x1d.<info> app: TWI device detected at address 0x1D.
    TWI device detected at address 0x1e.<info> app: TWI device detected at address 0x1E.
    TWI device detected at address 0x1f.<info> app: TWI device detected at address 0x1F.
    TWI device detected at address 0x20.<info> app: TWI device detected at address 0x20.
    TWI device detected at address 0x21.TWI device detected at address 0x22.TWI device detected at address 0x33.<info> app: TWI device detected at address 0x33.
    TWI device detected at address 0x34.<info> app: TWI device detected at address 0x34.
    TWI device detected at address 0x35.<info> app: TWI device detected at address 0x35.
    TWI device detected at address 0x36.<info> app: TWI device detected at address 0x36.
    TWI device detected at address 0x37.<info> app: TWI device detected at address 0x37.
    TWI device detected at address 0x38.TWI device detected at address 0x40.<info> app: TWI device detected at address 0x40.
    TWI device detected at address 0x41.<info> app: TWI device detected at address 0x41.
    TWI device detected at address 0x42.<info> app: TWI device detected at address 0x42.
    TWI device detected at address 0x43.TWI device detected at address 0x44.TWI device detected at address 0x50.<info> app: TWI device detected at address 0x50.
    TWI device detected at address 0x51.<info> app: TWI device detected at address 0x51.
    TWI device detected at address 0x52.<info> app: TWI device detected at address 0x52.
    TWI device detected at address 0x53.<info> app: TWI device detected at address 0x53.
    TWI device detected at address 0x54.<info> app: TWI device detected at address 0x6B.
    TWI device detected at address 0x6c.<info> app: TWI device detected at address 0x6C.
    TWI device detected at address 0x6d.<info> app: TWI device detected at address 0x6D.
    TWI device detected at address 0x6e.<info> app: TWI device detected at address 0x6E.
    TWI device detected at address 0x6f.<info> app: TWI device detected at address 0x6F.
    TWI device detected at address 0x70.<info> app: TWI device detected at address 0x70.
    <info> app: TWI device detected at address 0x76.
    TWI device detected at address 0x77.<info> app: TWI device detected at address 0x77.
    TWI device detected at address 0x78.<info> app: TWI device detected at address 0x78.
    TWI device detected at address 0x79.<info> app: TWI device detected at address 0x79.

    Best.

  • This is not the unmodified twi_scanner sample, right? It looks like it is finding a device on every address, which I assume is not actually the case. What does your application look like?

  • Not, this is the "modified scanner example", actually the code from the scanner example is used within my application to see the slave address... the output is give above ... 

    The ide of the application is to read the data from the sensor, namely it should enable the sensor triggering and fetch this data back to the uC via i2c, and that is it. In short, the main() setup, is the twi init() and sensor config, while during the while() loop the values from the sensor are read in constant manner and that is it, Can share the bits of code if it will help. At the moment, I am only after working i2c/twi ... and as you can see that salve_address is not explict, when accessing the sensor... where would you look for the slave address ? For example, according to the data sheet and twi scanner example, the address of the sensor is 0x60, this should be explicitly used within the rx and tx functions?

    Best.

  • does thw TWI part of your application look like this when it prints "TWI device detected at address 0xXX."?

    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();
    
        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();
        }
    
        while (true)
        {
            /* Empty loop. */
        }
    }

    Does nrf_drv_twi_rx() return NRF_SUCCESS on all addresses, address = 1; address <= TWI_ADDRESSES; address++ ?

Reply
  • does thw TWI part of your application look like this when it prints "TWI device detected at address 0xXX."?

    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();
    
        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();
        }
    
        while (true)
        {
            /* Empty loop. */
        }
    }

    Does nrf_drv_twi_rx() return NRF_SUCCESS on all addresses, address = 1; address <= TWI_ADDRESSES; address++ ?

Children
  • Hello, I guess it does, otherwise the address would not even be printed? See the code below.

    int main(void) {
    
      // search for sensor address
      if (true) {
    
        counter = 0;
        printf("Scanning for the sensor address \r\n");
        nrf_delay_ms(1000);
    
        ret_code_t err_code;
        uint8_t address;
        uint8_t sample_data;
        bool detected_device = false;
    
        printf("TWI scanner started.\r\n");
        nrf_delay_ms(1000);
      
        printf("initializing the twi !\r\n ");
    
        twi_init();
    
        nrf_delay_ms(500);
    
        for (address = 1; address <= TWI_ADDRESSES; address++) {
    
          err_code = nrf_drv_twi_rx(&m_twi, address, &sample_data, sizeof(sample_data));
         
            //nrf_delay_ms(100);
            //printf("nrf_sucess ", NRF_SUCCESS);
            //nrf_delay_ms(100);
    
          if (err_code == NRF_SUCCESS) {
            
            detected_device = true;
            printf("TWI device detected at address 0x%x. \r\n", address);
          }
               
        }
    
        if (!detected_device) {
          printf("No device was found. \r\n");
    
        }
    
        nrf_delay_ms(2000);
      }
    
      
    
      while (true) {
     
        printf("nothing in while loop \r\n");
       
        //nothing here
    
      }
    }

    Here is the output:

    initializing the twi !
    TWI device detected at address 0x1. 
    TWI device detected at address 0x10. 
    TWI device detected at address 0x1f. 
    TWI device detected at address 0x2d. 
    TWI device detected at address 0x3b. 
    TWI device detected at address 0x49. 
    TWI device detected at address 0x58. 
    TWI device detected at address 0x66. 
    TWI device detected at address 0x74. 
    nothing in while loop 

    Best.

    PS I have found the slave address that is used within the sensor library, api, code ...

  • Can I see your TWI init? Does your twi have an event handler? If it does, then the nrf_drv_twi_rx will return NRF_SUCCESS, and then later it should trigger the callback. If so, you will need to check the event handler, and not the return value of nrf_drv_twi_rx() to see whether anyone responded to that address.

    BR,

    Edvin

  • void twi_init(void) {
      ret_code_t err_code;
    
      const nrf_drv_twi_config_t twi_config = {
          .scl = 26, // Add you SCL Pin Here
          .sda = 27, // Add you SDA Pin Here
          .frequency = NRF_DRV_TWI_FREQ_100K,
          .interrupt_priority = APP_IRQ_PRIORITY_HIGHEST,
          .clear_bus_init = false};
    
      err_code = nrf_drv_twi_init(&m_twi, &twi_config, twi_handler, NULL);
    
      printf("error code :    ", err_code);
      nrf_delay_ms(550);
    
      printf("nothing ? \r\n");
      nrf_delay_ms(550);
    
      APP_ERROR_CHECK(err_code);
    
      nrf_delay_ms(550);
    
      nrf_drv_twi_enable(&m_twi);
    }

    There we go!
    BEST.

  • Edvin said:
    Does your twi have an event handler? If it does, then the nrf_drv_twi_rx will return NRF_SUCCESS, and then later it should trigger the callback.

    So because your TWI has an event handler (twi_handler), it means that all (most) calls to nrf_drv_twi_rx() will return NRF_SUCCESS, which means that the TWI successfully queued the operation. Do you get any callbacks in your twi_handler? What sort of events do you get?

    I guess you should look for the NRF_DRV_TWI_EVT_DONE, and check the address for those events. Something like:

    static void twi_handler(nrf_drv_twi_evt_t const * p_event,void * p_context)
    {
        switch(p_event->type)
        {
            case NRF_DRV_TWI_EVT_DONE:
                NRF_LOG_INFO("transfer success on addr 0x%02x", p_event->xfer_desc.address);
                break;
            case NRF_DRV_TWI_EVT_ADDRESS_NACK:
                NRF_LOG_INFO("Address nack on addr 0x%02x", p_event->xfer_desc.address);
                break;
            case NRF_DRV_TWI_EVT_DATA_NACK:
                NRF_LOG_INFO("Data nack on addr 0x%02x", p_event->xfer_desc.address);
                break;
            default
                break;
    }

  • "My" event 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) {
        }
        m_xfer_done = true;
        break;
      default:
        break;
      }
    }

    "Your" event handler, btw different printing used:

    static void twi_handler(nrf_drv_twi_evt_t const *p_event, void *p_context) {
      switch (p_event->type) {
      case NRF_DRV_TWI_EVT_DONE:
        printf("transfer success on addr 0x%02x \n", p_event->xfer_desc.address);
        //NRF_LOG_INFO("transfer success on addr 0x%02x", p_event->xfer_desc.address);
        break;
      case NRF_DRV_TWI_EVT_ADDRESS_NACK:
      printf("transfer success on addr 0x%02x \n", p_event->xfer_desc.address);
        //NRF_LOG_INFO("Address nack on addr 0x%02x", p_event->xfer_desc.address);
        break;
      case NRF_DRV_TWI_EVT_DATA_NACK:
      printf("Data nack on addr 0x%02x \n", p_event->xfer_desc.address);
        //NRF_LOG_INFO("Data nack on addr 0x%02x", p_event->xfer_desc.address);
        break;
      default:
        break;
      }
    }

    it finds the sensor slave address, "transfer success on addr 0x60 "

    I guess this was the aim of this code?

Related