-
Notifications
You must be signed in to change notification settings - Fork 88
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
Power management library (pmu.h) doesn't work after the first analogRead is made #155
Comments
I read almost the same issue in connection with the Arduino_Vcc library. Yveaux/Arduino_Vcc#7 |
I see. But not only that, the board doesn't even go to sleep at all. I assume it gets woken back up. Maybe the analog comparator wakes it up? |
I think clocks of the internal modules must be shut down before sleep mode by setting PRR and PRR1 registers. |
I played a bit and the lib is definitely not made for the 328p. The PMU library uses the sleep command instead of the RRR register. It also switches the clock to the secondary 32khz one. (the sleep command should also turn off almost all peripherals) I tried turning everything off via RRR registers, stopping all timers and the main clock and switching to the internal 32khz one, it also saves a similar amount of power, but the In any case, I find no explanation for having to disable the ADC via Unfortunately I don't have a unit w/o LDO so I think 90% of the remaining consumption is that and the power LED. I'll have to find an excuse to butcher a mini-style just to see how low this chip can go in deep sleep. It even has a full off mode with an pin change interrupt or some "LPRC" timer (low power oscillator, up to 1s) which seems to turn off even the RAM (unit will reset after sleep). I really wonder how much that consumes!
|
|
I found an example, how to use sleep modes on page 7 in this doc: https://github.com/dbuezas/lgt8fx/blob/master/docs/Porting_from_LGT8FX8D_to_LGT8FX8P_v1.0.0.pdf |
Uhh. It appeared to me after several days of studying the sleep modes this sentence:
The third sentence of the Power management section. And what could be the "and so on" thing? |
Maybe the other peripherals? (serial, spi, timers, ...) |
Serial, spi, timers are not analog modules so they are not "and so on", if the quoted sentence above can be taken seriously. Anyway, after I finish studying the sleep modes I plan to fix this package's power management examples. |
Right I see. Then the differential amplifier could be the missing one |
I found 2 more analog modules. These 2 modules can be shut down by writing ADCSRD register to 0x0. So there are 8 analog devices with their own shutdown control bits. ADC, DAC0, AC0, AC1, LVD, DAP, IVREF and the internal voltage division circuit. |
I have read this issue many times, but I just now understood, what was your idea about the issue.
Low-Power library for Arduino is a useful, simple and widely used library with better power settings in sleep.
This library could be copied into this repository and could be expanded with LGT8F328x's capabilities. With this library the PMU library will be obsolete. Edit: Document how to use LowPower library: https://www.engineersgarage.com/reducing-arduino-power-consumption-sleep-modes/ |
I am pushing hard to get that 1uA. I decimated LDO, power LED, and another LED onboard (I used some version of mini pro board with LGT8F328p without USB-TTL chip such as CH341 etc.) @dbuezas . @LaZsolt I tried PMU lib and also found that is only for 328D and maybe I should use some of 328E's code which is embraced by #if defined(LGT8FX8E). It looks to me that these code section
carefully set up the peripherals that may have substantial power consumption. Now I am getting ~41uA for DPS2 mode, just by setting DDRx to 0 and PORTx to 0xff to enable pull-up to avoid floating input. ==========UPDATE=============== |
Did you try turning the low voltage detector (LVD) off? AFAIK it is like the atmega's BOD but has more features. VDTCR |= 1<<WCE; // this should allow changing other bits during the next 6 cycles. Not sure if it is needed for VDTEN
VDTCR &= ~(1<<VDTEN); |
Maybe also VDREN: |
It is interesting why save power |
Turning off the LVD:
Update: |
Comment edited #155 (comment) |
does it make a difference on the consumption? |
Should I turn them all off to get 1uA DPS2 sleep? |
@LaZsolt @dbuezas |
No, you shouldn't. In DPS2 mode the LGT8F328P turning off all internal devices. Watch my experiment: #202 (comment) |
OMG @LaZsolt you are right. I used your code and got 0.67uA (670nA)! The best sleep current I ever got on any MCUs including ATtiny, ATmega, STM32, GD32, CH32, ESP8266, ESP32 and ESP32-C3. New record. (Well that is not exactly a fair comparison since I didn't disable WDT on ATtiny and ATmega, the sleep current is ~4uA. If WDT is disabled, the sleep current is sub 1uA level) And if you go even further to lower the supply voltage to 1.8V, sleep current goes to 0.22uA (220nA). I am not sure if my meter is perfectly calibrated, but I measured current of 10M at 1.8V and it gives 0.19uA so I guess the accuracy is acceptable. |
That's astounding! do you wake up via reset or did you manage to get wake on pin at those currents? |
Wake up via reset pin or wake on PortD pins doesn't change the power consumption. Only if you turn on many PortD pins for pin change wake up from DPS2, the MCU is more susceptible to interference (in my test I use my hand to touch PortD pins randomly) and may drain 10s or 100s of uA additional current via the weak (20k-40k according to datasheet) pull-up resisters. I am trying to use LPRC to enable periodic wake up (by setting DPS2R= 0b00001111) but without success so far. The MCU can only sleep for 50ms and then wake up instead of the claimed 1s on datasheet. |
maybe you need to increase the prescaler on some clock to reach the full second |
=====On LPRC clock and time to wake up===== I used my joulescope to measure the wake-sleep cycle by setting DPS2R differently: DPS2R = 0b1100; // sleep for 2.37s Aha, I guess I found a datasheet error here. According to datasheet, the lowest 2 bits of DPS2R are TOS1 and TOS0., With TOS[1:0] = 00 being the shortest sleep time and 11 the longest. Actually it is just the opposite. Someone may have written a wrong datasheet, or the MCU designer wrote the wrong verilog code. ====On accuracy and power consumption of DPS2 mode with LPRC periodical wakeup==== Another bad news is the current of LPRC is not really low power. It costs 5.78 uA to operate it. So we have (if I am doing things correctly, please point out if I did something wrong. @LaZsolt ) When Vcc=3.3V
If you are really paranoidal about power saving, you can use Vcc = 1.8V at which lgt8f328p enjoys the privilege run at 32Mhz at active mode while ATmega328p demands at least 2.7V to operate only at 8Mhz. =====The code=====
|
So lower VCC means longer timing. I suppose the timing of this RC timer is also temperature dependent. |
@sullivanzheng
The value of 16.5 µA does not seem too much compared to DPS2 5.78 µA without SRAM and register retention. |
I don't think 16uA is the end game. That number was measured when I didn't know how to properly get sub 1uA power consumption by DPS2 sleep. (I wrote a bunch of random code to fiddle with all kinds of registers including ADSCRA=0 ADSCRD=0 etc.) may incur extra power consumption. Will see if I can get that number down a bit. In addition, 16uA additional sleep current may be offset by shorter active time of lgt due to faster clock and single cycle instruction. Here is my calculation: I got several project using ATmega328p with 1% duty cycle and sleep current of 5uA and active current of 4.7mA. Overall average current is 52uA. If I switch to LGT, active time may be reduced by 70% (32Mhz vs 8Mhz), therefore duty cycle is now 0.3%, active current is 11mA. sleep current 16uA, total average is 49uA. So it seems that the key is if I can fully leverage the faster core speed and slash the active time effectively.... STM32F103 (blue pill) and other faster MCU seems to treat the power saving using similar logic (faster core speed, shorter active time, to trade off higher sleep current ~ 15uA for full SRAM retention and WDT). |
4.7 µA for ATmega328p ? Not good.
and
|
Heads up: it seems there are atmega328p clones which are out of spec in regards to power consumption: I assume we all source these carelessly (ebay, ali,...), so no wonder. |
Although last time I got 40uA on an aliexpress pro mini and I also had other chips powered (sleeping too). He reports >100uA on his likely-fake atmega328p |
On the datasheet for ATmega328p, chapter 28.4 speed grades, it says the safe operation area is from 2.7V to 5.5V? So I guess 1.8V @ 1Mhz is not officially recommended Vcc? They actually sell ATmega48/88/168V which officially support 1.8V. BTW 1Mhz clock is quite slow. It will make active time substantially longer. Of course people worked with 8051 MCU will think that is not slow clock speed since AVR instructions are mostly 1T or 2T. |
Out of curiosity, has anybody measured the consumption of the lgt while deep sleeping on different F_CPU clock speeds? I assume it should be the same since it isn't even running, but if isn't, there may be the possibility of dialling up the prescaler right before sleep. Again, I doubt this is a thing, but who knows |
Are we looking at the same part? I checked ATmega328p official product page but I got very different datasheet. In my datasheet, 1.8V is no more officially specified. Not only that, 20Mhz @ 5V is also removed as "external clock drive". |
Check these new power management library files: lgt8fx_lowpower
I have edited this comment: This files are not ready to use. There will be a lot of work to do with it. I uploaded it for demonstration purposes only. |
You can check what is powered on-chip before sleep with this program. |
I found minor error. |
Solved. After the analogRead(); The ADIF bit of ADCSRA is set. ADIF = ADC Interrupt Flag Interesting. It raises further questions, why hasn't this caused problems for others? |
Can this issue report be closed? |
I think this issue is very well discussed. I have used DPS2 mode and LPRC as my "default deep-sleep and reset" routine for quite a few sensor and IoT projects. Very handy. |
Forgot to close |
This works fine:
This doesn't work. It doesn't go to sleep:
After some debugging, I pinned point the line that causes this behaviour. It is
cores/lgt8f/wiring_analog.c:97
sbi(ADCSRA, ADSC);
which just starts one measurement.
Curiously, setting
ADCSRA = 0;
before sleeping doesn't do anything, but wrapping the sleep fn like this:(i.e disabling the ADC temporarily) makes it work again.
I see that in the lib there is a
#if defined(__LGT8FX8E__)
before clearing and restoring the ports, dir registers and the ADCSRA, but replicating that behaviour doesn't work in the 328p.My assumption is that the PMU library in this core is not actually made for the lgt328p, but the 328d instead.
There's probably a lot more current that can be saved by making a new version for the 328p.
Thoughts?
The text was updated successfully, but these errors were encountered: