I2C after Power-down sleep (ATmega328P)

Hello,

Is there a minimum time limit for how long it takes for I2C to become usable after waking up from Power-down sleep?

I understand that after waking up, the code should call Wire.begin(), which initializes some variables and invokes twi_init(), where the actual register settings are applied.

Once Wire.begin() returns, can actual transmission be started immediately? For example, disabling the RTC chip alarm. Does anyone know of any issues that could be traced back to 'too fast' I2C usage after wake-up?

I use both 100kHz and 400kHz I2C after wake-up under certain conditions, with 4.7kΩ pull-ups. I haven’t encountered any issues so far, but I’d like to gather more information on this.

Thanks in advance.

Hi @amazed ,

There isn’t a defined minimum delay required for I2C after waking from Power-down sleep. When your device wakes up and you call Wire.begin(), it reinitializes the TWI (I2C) hardware—including setting up the registers via twi_init(). Once Wire.begin() returns, the I2C bus should be ready for immediate use (e.g., to disable an RTC chip alarm).

That said, while the microcontroller’s I2C hardware is operational right away, keep in mind that some I2C devices might have their own wake-up or stabilization delays. As long as your devices are fully powered and stable, and your pull-ups (4.7kΩ in your case) are correctly set, there shouldn’t be any issues with using I2C immediately after wake-up.

Hope this helps!

  • Simone from Italy

Not necessary
The microcontroller will be in the same state after wake-up as it was just before it went to sleep.

Is there a minimum time limit for how long it takes for I2C to become usable after waking up from Power-down sleep?

No

You're right. I forgot to add that Wire.begin() is needed, because I intentionally disable I2C before going to sleep.

Why?

Good question, I don't know to be honest.

I mainly gathered my sleep function from Gammon's page years ago and I haven't reviewed it since then. But as I see it now, he turns off I2C only in his Powering off external devices example, where the external chip is powered from a digital pin. So I assume he turns off I2C and internal pull-ups to prevent "shadow powering" the chip.

So there is no power saving in my case (external chip has separate supply and external pull-ups are used) at all?

True but I wonder if it will cause glitches on the I2C bus since the I/O pins are changing modes when you disable.

It may have something to do with what the I2C lines are pulled up to. In the case of the DS3231 for exmple, you may want to switch off it's Vcc power through a GPIO pin, so it will run on much less power on its Vbat pin. But if the I2C lines are pulled up to Vcc, then when it goes low, they become pulldown resistors. In that case you don't want any pullups in the MCU to be enabled, which would waste current. My memory is that Gammon does Wire.begin(), and then immediately does pinMode() instructions to convert both lines to INPUT. Apparently, Wire leaves them that way.

In any case, if you turn on Vcc power to the RTC when you wake up, you shouldn't need any delay after that before communications resume. At least I don't remember ever doing that.

That is not possible. Once the I2C peripherial has control of the pins you can't alter them unless you do a wire.end.

I understand, and agree that should be the case, but the pullup state may be an exception. Google's AI says:

"Yes, even after calling Wire.begin() on an Arduino, you can still change the state of pull-up resistors on digital pins used for I2C communication; however, it's important to be aware that directly manipulating pull-ups on I2C pins can potentially disrupt communication with connected devices if not done carefully."

It is not

AI is never right, Haven't you learned yet that here on the forum most knowledgeable hate AI and being challenge by AI garbage.

Well, as far as the pullups after Wire.begin() are concerned, it seems one of us needs to test it. Would you like to volunteer?

Well, nevermind. I'm snowed in, so have nothing better to do. I modified the I2C scanner sketch to change the I2C lines of a Nano to INPUT after Wire.begin(). I have a 1Meg pulldown on each line, and a 5.6K pullup to D4 on each line (switchable external pullups).

There's a 20-second delay to measure voltages, then I turn on the pullups, do the scan, then turn off the pullups.

Before and after the scan, I measure near zero volts on both lines. So apparently you can disable the pullups on the I2C lines after Wire.begin(), and it will still work - so long as you have external pullups somewhere.

// --------------------------------------
// i2c_scanner

// 1M pulldown resistors on A4 and A5
// 5.6K resistors pulled to D4 from A4 and A5

#include <Wire.h>

void setup()
{
  Wire.begin();
  pinMode(A4,INPUT);
  pinMode(A5,INPUT);
  pinMode(4,INPUT);
 
  delay(20000);

//measure voltage on A4 and A5 during delay 
  
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);  // turn on external pullup resistors

  Serial.begin(9600);
  while (!Serial);             // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}


void loop()
{
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ ) 
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4) 
    {
      Serial.print("Unknown error at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  pinMode(4,INPUT);  //turn off external pullups  
  while(1);

  // measure voltage here
  
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.