15

I'm trying to reduce power as much as possible in an Arduino board I have created. How should the unused input pins be configured? There are a few answers (here, here) already for this, but I'm after something specific to the ATMega328P.

  1. Set pin to input, drive pin high to engage internal pull-up
  2. Set pin to input, drive pin low
  3. Set pin to input, external pull up
  4. Set pin to input, external pull down
  5. Set pin to output low
  6. Set pin to output high
  7. Set pin to output low, external pull down
geometrikal
  • 4,921
  • 2
  • 23
  • 41

3 Answers3

12

After digging through the datasheet, I found this:

14.2.6 Unconnected Pins

If some pins are unused, it is recommended to ensure that these pins have a defined level. Even though most of the digital inputs are disabled in the deep sleep modes as described above, floating inputs should be avoided to reduce current consumption in all other modes where the digital inputs are enabled (Reset, Active mode and Idle mode).

The simplest method to ensure a defined level of an unused pin, is to enable the internal pull-up. In this case, the pull-up will be disabled during reset. If low power consumption during reset is important, it is recommended to use an external pull-up or pull-down. Connecting unused pins directly to VCC or GND is not recommended, since this may cause excessive currents if the pin is accidentally configured as an output.

update in relation to comment/question:

According to table 14-1, the pull-up resistor is only active when the the following conditions are satisfied:

  1. The pin is set as input (DDxn bit is logic low)
  2. PORTxn is set logic high
  3. PUD is logic low

The only way you'll get significant current flowing through the pull-up resistor is if the pin experiences a low level with the pull-up enabled. This means either Atmel messed up badly (unlikely) or you have the pin configured as input with the pull-up enabled and the pin is somehow connected to ground.

Section 14.2.5 discusses digital input enable and sleep modes. To summarize, the digital input is clamped to ground at the input of the Schmitt Trigger to prevent a floating level while in sleep mode, unless the pin is configured as an external interrupt. I can't tell if digital output is disabled in sleep mode. It doesn't look like it is disabled according to figure 14-2, though I wouldn't be too surprised if it was. The best bet is to use either an internal or external pull-up resistor.

Andrew Morton
  • 2,389
  • 1
  • 17
  • 26
helloworld922
  • 16,600
  • 10
  • 54
  • 87
  • thanks, do you think this is better than setting to an output, in terms of power used? Does any current flow through the internal pull-up? The device will be in power down sleep mode for the majority of time. – geometrikal Oct 12 '12 at 04:46
  • updated answer. I don't think you'll have too much problems with it being an output, but best bet is to take Atmel's advice. – helloworld922 Oct 12 '12 at 05:12
11
  1. Set pin to input, drive pin high to engage internal pull-up: I think this should read: "make input high by engaging internal pull-up". (I would use the word "drive" only if you do so actively, by means of a FET to Vcc or ground.) It's clear that you want a defined level, and the pull-up takes care of that. Make sure enabling the pull-up is one of the first things you do after reset. That goes for I/O initialization in general. The only current will be the leakage current of the NFET of the push-pull pair, and the gate leakage of the input FET. Less than 1 µA: OK.
  2. Set pin to input, drive pin low: Not a good idea. If the software goes bananas and would switch the pin to output high you're shorting the pin, damaging the PFET of the complementary pair.
  3. Set pin to input, external pull up: Is the same as 1), only more expensive. But has the advantage that the pull-up will always be there; you may forget to enable the internal pull-up (which is disabled by default). If the I/O would accidentally switch to output low you'll have a small current drain.
  4. Set pin to input, external pull down: Again the cost of a resistor (yes, I know they're cheap, but cheap + unnecessary = expensive.) The same current as in 3) if the pin would go to active high.
  5. Set pin to output low: Has a higher leakage current than when configured as input, but still below 1 µA, so nothing to worry about. I would still enable the internal pull-up. It won't be active with the I/O as output, but if it would accidentally be switched to input the pin wouldn't remain floating.
  6. Set pin to output high: Same as 5)
  7. Set pin to output low, external pull down: The pull-down resistor is an unnecessary cost: it would make an output low, which is already low. But compared to 5) has the advantage that you're sure the pin won't float if unintended switched to input.

I would go for 1): input with internal pull-up; no external parts required. In an FMEA 5) may fare better, but that depends on how high you estimate the risk that you forget to enable the internal pull-up. A software design peer review should give you insurance.

stevenvh
  • 145,145
  • 21
  • 455
  • 667
  • Nick Gammon's [measurements](http://gammon.com.au/power) (Section Sketch D) seem to conflict with your 5), i.e. 'Has a higher leakage current than when configured as input' - since that article reports 1.25 µA (for input+pull-up) vs. 0.35 µA (for output+low) - when configuring 6 unconnected pins, that is. See also the answers to a [similar question](https://arduino.stackexchange.com/q/88319/13174) on Android SE where this is also discussed. – maxschlepzig Jan 10 '22 at 21:48
1

The pins dont usually make a huge difference themselves. You will see each pin has a specific function too - disable the function of the pin

volatile uint8_t timer2sum; // see interrupt handler

void Initialize()
{
    // configure pin for output
    DDR_LED |= LED;

    // set Power Reduction Register
    PRR = (1<<PRTWI)     // turn off TWI
        | (1<<PRTIM0)    // turn off Timer/Counter0
        | (1<<PRTIM1)    // turn off Timer/Counter1 (leave Timer/Counter2 on)
        | (1<<PRSPI)     // turn off SPI
        | (1<<PRUSART0)  // turn off USART (will turn on again when reset)
        | (1<<PRADC);    // turn off ADC

    // select POWER SAVE mode for sleeping, which allows Timer/Counter2 to wake us up
    set_sleep_mode(SLEEP_MODE_PWR_SAVE);

    // configure Timer/Counter2 to wake us up as infrequently as possible
    TCCR2B |= (1<<CS22) | (1<<CS21) | (1<<CS20); // clock at 14400 Hz
    TIMSK2 |= (1<<TOIE2);                        // interrupt on overflow, 56.25 Hz
    timer2sum = 0;                               // see interrupt handler
    sei();                                       // enable interrupts
}

taken from http://www.nerdkits.com/library/lowpowerexample/ who also use the same chips.

Trygve Laugstøl
  • 1,410
  • 2
  • 19
  • 28
exussum
  • 109
  • 3