Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better power saving docs #695

Closed
eloquentarduino opened this issue Apr 26, 2022 · 9 comments
Closed

Better power saving docs #695

eloquentarduino opened this issue Apr 26, 2022 · 9 comments
Assignees
Labels
duplicate This issue or pull request already exists Information Required Information required from reporting user to begin/continue development work

Comments

@eloquentarduino
Copy link

eloquentarduino commented Apr 26, 2022

I was having troubles with deep sleep mode. Documentation says:

## Unused pins and sleep modes

IMPORTANT In order to minimize power consumption, you must eliminate or disable all floating pins... To minimize power consumption, one or more of the following must apply to every pin:

 - It is set as an OUTPUT
 - It is set INPUT_PULLUP or the internal pullups are otherwise enabled
 - It is connected to another device which is holding it HIGH or LOW
 - The input buffer is disabled in the PORTx.PINnCTRL register

I found that, at least for me, the only way to achieve low current (with my circuitery connected) is as below (copy-pasted from Atmal docs):

// call before sleep_cpu()
for (uint8_t pin = 0; pin < 8; pin++) {
    (&PORTA.PIN0CTRL)[pin] = PORT_ISC_INPUT_DISABLE_gc;
    (&PORTB.PIN0CTRL)[pin] = PORT_ISC_INPUT_DISABLE_gc;
    (&PORTC.PIN0CTRL)[pin] = PORT_ISC_INPUT_DISABLE_gc;
}

Setting as OUTPUT or INPUT_PULLUP doesn't work reliably.

@SpenceKonde
Copy link
Owner

SpenceKonde commented Apr 26, 2022 via email

@SpenceKonde
Copy link
Owner

However, the fact that only disabling the input buffer works for you is extremely strange.

Please share the circuit connected to the chip. Can't really go any further without that.

@SpenceKonde SpenceKonde added the Information Required Information required from reporting user to begin/continue development work label Apr 29, 2022
@SpenceKonde
Copy link
Owner

Assigned to original issue creator as we need more information to have any hope here.

@eloquentarduino
Copy link
Author

If I'm not wrong (will check on monday), I see this behavior even with anything connected. Need to double-check, though.

@SpenceKonde
Copy link
Owner

SpenceKonde commented Apr 30, 2022

I would be most surprised if this happened with nothing connected to the pins as long as all I/O pins were either:

  • pulled up internally
  • pulled up or down externally with a resistor
  • set as outputs driving no load

That all assumes the board wasn't filthy from hand soldering with flux paste. At least when I hand solder these parts, the immediate result attracts lint, dust and tumbleweeds of cat fur from miles around. (tip: clean the flux off sooner rather than later - the longer you leave it there, the harder ut is to get off - it seems to dry out, and particulate from the environment (for me, mostly cat hair) forms a composite with the flux that is that much more resistant to removal.
(tip2: if the cat thought that flux covered board would be a comfy place to snooze and it's now covered in fur, and you have already soldered the pin header on you may think that you'll never get the fur off it. Don't worry: use a butane torch. The key is that the flame should be pointed in the general direction of the board for less than a second in total. Fur burns off instantly. Then clean the board normally with a toothbrush and 99% IPA so it doesn't pick up more fur. maybe do that in a different room, so you don't have a butane torch right next to the bottle of highly flammable alcohol. In any event, you're going to want to open the window - both to vent the fumes and to get rid of the smell of burnt hair from the previous step.)
(tip3: After all SMT work, clean the board BEFORE you add the pin header. Rosin core solder is unique in that while it may leave crap behind, that crap isn't sticky, so you usuaklly don't have to clean after soldering pin header.... However for this specific test, you absolutely 100% do need to clean the board very thoroughly to rule out flux residue as a factor. Flux is an insulator, but air is a much better one)
tip4: 99% IPA is what you want. not 91% Dirt cheap on amazon! That 70% drugstore IPA is for... cleaning scrapes and cuts or whatever it is they advertise it for. Because it's above the azeotropic composition, 99% IPA will remove traces of moisture and not leave the board damp. Whereas 91% may just move water around and 70% will leave a bunch of water behind.

Oh right, covid, that's what IPA is used for these days, compulsively disinfecting your hands as if that will prevent you from catching an airborne disease (tip5: it wont. Neither does a mask when worn below your chin. The only truly effective countermeasure is a full face respirator, Like professionals use for spray paint This will muffle your voice; I know someone who only went out dressed like that until his second vaccine shot. He rigged up a mic in the mask and a speaker on his belt to talk to the cashiers. Dude also managed to score an oxygen concentrator just in case. That was before we knew essentially all transmission was airborne - all one needs is to make sure there's no air intake that any passersby can breath near, and never leave your home or let anyone in, and you can survive on mail-order. Eventually you'll go nuts like that - a slight problem. But if you turn on the TV (not recommended) you'll see that everyone else has gone stark raving mad too.) I've been told that for disinfecting things, ~70% works better than 91%. - though I haven't seen any peer reviewed papers on the matter. It's not completely implausible that the stronger stuff doesn't effectively contact some lucky pathogen particles as well as 70%. Just not covid - covid needs to reach our mouth or eyes or nose to infect us. (tip6 - if you're a nailbiter, you only need to disinfect your nails, not the whole hand)

@mechatroniks-git
Copy link
Contributor

Good tips on board and nail cleaning Spence.

Measure the actual voltage on the pins, what do you see? Report back.

I've seen the sleep current increase if the voltage wasn't near 0V or VCC (whatever your rail is, 3.3V or 5V, etc.).

If you set it as an output and drive it high, you might have some leakage in your circuit. If you set as input_pullup, same concern, different resistance to VCC.

@SpenceKonde
Copy link
Owner

Yes skeep current skyrockets when right in the midle of Vcc and ground because the input buffer twiddles back and forth

@SpenceKonde
Copy link
Owner

I am closing as duplicate f #158

@SpenceKonde SpenceKonde added the duplicate This issue or pull request already exists label May 1, 2022
@eloquentarduino
Copy link
Author

I soldered a fresh Attiny1616 to a simple breakout board, no flux, just the VCC, GND and UPDI pins to be sure I have the cleanest setup possible.
Here is the code I'm using for sleep:

#include <avr/sleep.h>
#include <avr/power.h>


ISR(RTC_PIT_vect) {
    RTC.PITINTFLAGS = RTC_PI_bm;
}


namespace Sleep {
  void begin() {
    while (RTC.STATUS > 0) ;
    RTC.CLKSEL = RTC_CLKSEL_INT32K_gc;
    RTC.PITINTCTRL = RTC_PI_bm;
    RTC.PITCTRLA = RTC_PERIOD_CYC32768_gc | RTC_PITEN_bm;
  
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sleep_enable();
  }

  void enable() {
    // case 1: disable input buffers
    for (uint8_t pin=0; pin < 8; pin++) {
     (&PORTA.PIN0CTRL)[pin] = PORT_ISC_INPUT_DISABLE_gc; //Disable on PAx pin
     (&PORTB.PIN0CTRL)[pin] = PORT_ISC_INPUT_DISABLE_gc; //Disable on PBx pin
     (&PORTC.PIN0CTRL)[pin] = PORT_ISC_INPUT_DISABLE_gc; //Disable on PCx pin
    }

    // case 2: set pins as either OUTPUT or INPUT_PULLUP
    for (int i = 0; i < 16; i++)
        pinMode(i, OUTPUT);

    VPORTB.DIR &= ~PIN2_bm;

    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    power_all_disable();
    sleep_enable();
    
    for (int i = 0; i < 10; i++)
      sleep_cpu();
  }

  void disable() {
    for (int i = 0; i < 16; i++)
      pinMode(i, INPUT);
      
    VPORTB.DIR |= PIN2_bm;

    sleep_disable();
    power_all_enable();
  }
}

I tested both case 1 and case 2 separately.
My measuring instrument is pretty cheap: an INA219 with 100 uA resolution.
My results:

  • case 1: current always ranges from 0 to 100 uA
  • case 2: current mostly ranges from 0 to 100 uA, but it also reaches 200 uA for a few milliseconds

I hoped I had a better instrumentation.
My conclusion: disabling input buffers is the most reliable way to lower the power consumption.
Does it have any drawback?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists Information Required Information required from reporting user to begin/continue development work
Projects
None yet
Development

No branches or pull requests

3 participants