Important increase of supply current when inserting a delay in temperature sensor readout by TWI

Hello,

I have a strange problem and don't know how to solve it.

We use a nRF52840 (with SDK15.3), at this a TMP117 is connected by TWI. As the temperature is measured only every 2 seconds the power of the TMP117 is switched on and off at the begin and at the end of the function.

The configuration of the TMP117 shall start the conversion and make 8 measures, each takes 15,5 ms. So after 124 ms the job is done and the nRF52840 could read the result. The strange thing is: When powering, configuring and starting the measurement at the TMP117 I use a nrf_delay of 140 ms and want to read the measured value. Now I have a strange behaviour: With this delay I read out a perfect temperature, only while the delay the supply current increases by at least 500 µA. With a longer delay this increase is even more. When eliminating this delay of course the TMP117 has not already valid values, so I read 0 - but no current increase. What can I do to read out good sensor values without current increase?

Unfortunately I can't deliver a oscillogram; due to space limitations at the PCB and the footprints of the TMP117 and the used module containing the nRF52840 I have no access to SCL or SDA...

Thanks for any good idea...

matthK

The function is realized like this:

#ifdef TMP117_SENSOR

Enable_Vcc_Temp(); // switch on Vcc for TMP117

#endif

#ifdef I2C_BUS_ACTIVE

Enable_TWI_Pull_Up(); // Configure SCL and SDA P0->DIR as input, Conf = 0x60C for SDA and SCL

twi_init_and_enable();

NRF_LOG_INFO("TWI init done");

TMP117_set_mode();

nrf_delay_ms(140);

if (bProblemAtTWIBus == false)

{

read_temp_sensor_data();

}

// while(!NRF_TWIM1->EVENTS_RXDREADY){}; // necessary for Power down

NRF_TWIM1->TASKS_STOP = 1;

#endif

twi_disable();

twi_uninit();

Disable_TWI_Pull_Up();

#ifdef TMP117_SENSOR

Disable_Vcc_Temp();

#endif

*(volatile uint32_t *)0x40004FFC = 0; // workaround from Nordic for erratum 89

*(volatile uint32_t *)0x40004FFC; // workaround from Nordic for erratum 89

*(volatile uint32_t *)0x40004FFC = 1; // workaround from Nordic for erratum 89

  • Hi,

    nrf_delay_ms() will keep the CPU active (busy-looping) during the requested delay time. The CPU current consumption is quite high (CPU running), and using this method is a waste of power.

    You should rather use the application timer library to start a timer that times out in 140ms when you have enabled the sensor, and do the readout/disabling of the sensor in the timer callback, see nRF5 SDK Application Timer Tutorial. You can then put the CPU to sleep (__WFE()) in the main loop during the operation.

    Best regards,
    Jørgen

  • Hello Jorgen,

    indeed - this was the problem, now the current consumption is much lower - thanks for the input!

    I was looking also at the table (CPU running) and have 2 questions:

    1. For Bluetooth communication the frequency has to be very stable - does this mean that only HFX0 should be used when Bluetooth is active? In my application I use HFINT only in sleep mode, in active mode HFX0 is used.

    2. When using m_xfer_done for TWI: Does a while (m_xfer_done == false) {} has the same CPU load and waste of energy as the nrf_delay_ms()?

    Thanks in advance.

    Best regards,

    matthk

  • Hi,

    matthk said:
    1. For Bluetooth communication the frequency has to be very stable - does this mean that only HFX0 should be used when Bluetooth is active? In my application I use HFINT only in sleep mode, in active mode HFX0 is used.

    Yes, HFXO is required for correct Bluetooth communication. The SoftDevice will automatically start the HFXO when this is needed by the stack, this is not something the application need to care about. HFXO can also be started in application if better accuracy than HFINT can provide is needed, for instance if TIMER and UART(E) peripherals are used.

    matthk said:
    2. When using m_xfer_done for TWI: Does a while (m_xfer_done == false) {} has the same CPU load and waste of energy as the nrf_delay_ms()?

    Correct, the while loop will keep the CPU active and constantly checking the state of the variable. You can add a __WFE() call inside the while loop to put the CPU into sleep mode. The CPU will then wake up whenever a HW event is generated (for instance by the TWI(M) peripheral when the transfer is done.

    Best regards,
    Jørgen

Related