sleep_mode() and I/O Pins

Does anyone know what happens to the I/O pins when your put the ATMega328 to sleep? I need to pull a pin high, go to sleep and leave it HIGH while it is asleep.
Do the different sleep modes have different effects on the pins? Sorry it it seems like a silly questions. I'm still at the initial stages of development and haven't been able to test this on hardware yet.

Does anyone know what happens to the I/O pins when your put the ATMega328 to sleep? I need to pull a pin high, go to sleep and leave it HIGH while it is asleep.

It will stay high in all sleep modes.

Do the different sleep modes have different effects on the pins?

Yes. Some I/O functions require a timer to be running. All but idle1 mode turn off various timers. Without the associated timer running, the I/O function stops.

1I think that's what it's called.

That's what I wanted to hear. Thanks :slight_smile:

I'll tell you what I am doing. I am using an arduino board to do a bunch of monitoring of digital inputs, talking over USB and displaying info on a 16x2 LCD. This does not leave enough pins free for all my outputs. So I am using a second ATmega328 to control about 10 outputs and will communicate with the first arduino via the I2C bus.

However I need the controllers to go to sleep so I want to use interrupt 0 (Pin 2) to tell the second atmega328 when to sleep. When the arduino sends pin 2 LOW, the second atmega328 will wake up and listens to I2C for instructions on controlling the outputs. It will also monitor pin 2 and if it goes HIGH, it will go to sleep until pin 2 goes low and wakes it up again.

So the arduino sends pin 2 HIGH, this triggers the second ATmega328 to go to sleep. Then the arduino will then go to sleep itself. As you can see, pin 2 will need to remain HIGH so the second atmega328 stays asleep.

Why do the processors need to sleep? To save power?

They don't need to sleep but if you have it powered from batteries and want some long duration you put your processor in one of the various sleep modes.

Sleeping is usually needed to save power. However in such cases the voltage regulator must be dropped. The 7805 consumes way to much power for battery applications.

Udo

@Senso & @Udo Klein:
I suspect you misunderstand the point of my question. Please allow me clarify...

@Mayhem:
Why do you want to put the two processors to sleep? Are you trying to save power? Or are you trying to honor a sleep request from the host computer?

I ask because...

So the arduino sends pin 2 HIGH, this triggers the second ATmega328 to go to sleep

Holding the pin high, even while sleeping, will require power. If Mayhem instead uses a low signal to indicate go-to-sleep, his application will use less power.

If I send the pin LOW to go into a powerdown sleep, As far as I understand, I can't tell the ATMega328 to wake on the pin going HIGH. Only when it goes LOW.

@Coding Badly: why does it consume power to hold a pin high? I thought it would consume power if it sources current or if it switches. If there is no load, then it should not consumer power. Or am I mistaken?

Udo

Btw: last weekend I was told by a micro controller professional that the current consumption caused by pins can be quite counterintuitive. There is at least one microcontroller that will consumer least power while sleeping if all pins are set to output high. This is despite the fact that the pins in questions could be tristated.

@Coding Badly: why does it consume power to hold a pin high? I thought it would consume power if it sources current or if it switches. If there is no load, then it should not consumer power. Or am I mistaken?

The other processor acts as a sink. There is current flowing from the output of #1 to the input of #2. It's a small amount but it isn't zero.

Btw: last weekend I was told by a micro controller professional that the current consumption caused by pins can be quite counterintuitive. There is at least one microcontroller that will consumer least power while sleeping if all pins are set to output high. This is despite the fact that the pins in questions could be tristated.

The AVR works this way.

If the pin is configured as an INPUT and is not connected to anything, it will float which consumes a (relatively) significant amount of power; presumably due to switching states. If the pin is an INPUT with the internal PULLUP enabled and is not connected, it consumes no power. If the pin is an OUTPUT with no connection (and set either high or low), the pin consumes no power.

Some details here...
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1243213127/all

I guess knowing that bit of trivia makes me a "micro controller professional". :stuck_out_tongue:

If I send the pin LOW to go into a powerdown sleep, As far as I understand, I can't tell the ATMega328 to wake on the pin going HIGH. Only when it goes LOW.

Using a pin-change interrupt should solve the problem.

The best plan is to first get the application working. You can play with HIGH = SLEEP versus LOW = SLEEP after everything else is functional.

Using a pin-change interrupt should solve the problem.

The best plan is to first get the application working. You can play with HIGH = SLEEP versus LOW = SLEEP after everything else is functional.

The documentation I have says that only LOW can trigger a powerdown sleep

   /* Now it is time to enable an interrupt. In the function call 
   * attachInterrupt(A, B, C)
   * A   can be either 0 or 1 for interrupts on pin 2 or 3.   
   * 
   * B   Name of a function you want to execute while in interrupt A.
   *
   * C   Trigger mode of the interrupt pin. can be:
   *             LOW        a low level trigger
   *             CHANGE     a change in level trigger
   *             RISING     a rising edge of a level trigger
   *             FALLING    a falling edge of a level trigger
   *
   * In all but the IDLE sleep modes only LOW can be used.
   */

   /*
   * The 5 different modes are:
   *     SLEEP_MODE_IDLE         -the least power savings 
   *     SLEEP_MODE_ADC
   *     SLEEP_MODE_PWR_SAVE
   *     SLEEP_MODE_STANDBY
   *     SLEEP_MODE_PWR_DOWN     -the most power savings
   */

So if I use SLEEP_MODE_PWR_DOWN, I can not use a RISE trigger.

Ah. In that case, you'll have to use LOW = WAKE if you use external interrupts.

You may be able to reduce or eliminate the sleeping power consumption by enabling the pullup resistor on the input (slave) side. When the master sinks (turns the output low) to wake the slave, current would flow. When the master sources to sleep the slave, both sides would be at the same potential so no current would flow. I think I have that correct.

You can still use pin-change interrupts to get what you need. Unfortunately, there's no support for pin-change interrupts in the Arduino libraries. They have to be enabled by directly manipulating registers.

You may be able to reduce or eliminate the sleeping power consumption by enabling the pullup resistor on the input (slave) side. When the master sinks (turns the output low) to wake the slave, current would flow. When the master sources to sleep the slave, both sides would be at the same potential so no current would flow. I think I have that correct.

Makes perfect sence. And while both are awake, disable the pullup resistor on the slave and I should have the same result. No flow. Thanks for the tip.