Author Topic: ATmega 328P-AU power saving  (Read 2186 times)

markus1234

  • Newbie
  • *
  • Posts: 12
  • Country: at
ATmega 328P-AU power saving
« on: March 27, 2017, 02:53:07 AM »
Hi,

I'm currently trying to learn a little bit more about powersaving techniques with the 328P. Therefore I mad an ampty PCB with just the ATmega 328P and a PinHeader to breakout all the needed connections (for ISP programming). I'm powering it from a 3.3 V source

So I tried various things from http://gammon.com.au/power and with the LowPower arduino library.
But the best result I can achieve was around 40 uA - nothing connected just in power down state (with every pin set to output und low)

Acording to http://gammon.com.au/power I should get results as low as ~6 uA.

Does anyone know how to achieve this?

Thanks in advance

My fuses are currently set to:


WhiteHare

  • Hero Member
  • *****
  • Posts: 1298
  • Country: us
Re: ATmega 328P-AU power saving
« Reply #1 on: March 27, 2017, 05:21:10 AM »
1.  How are you measuring the current?  It matters.
2.  Try Gammon's "Sketch J".  That's his most potent cocktail of power saving techniques.
3.  Your fuse settings look correct.

markus1234

  • Newbie
  • *
  • Posts: 12
  • Country: at
Re: ATmega 328P-AU power saving
« Reply #2 on: March 27, 2017, 03:08:36 PM »
Thanks for your answer. You pointed me in the right direction: I measured current in series between my pcb and the programmer (which is fine), but the serial lines were still attached. If i measure it with detached serial lines, it now uses only 0.1 uA with the J sketch.

With an RFM69 attached, I'm still at 27 uA. Is there any software switch to reduce its power? (beside sleep() )
Would it be possible to power the RFM69 module from an IO Pin (and set it to low before sleeping?)

Thanks in advance

WhiteHare

  • Hero Member
  • *****
  • Posts: 1298
  • Country: us
Re: ATmega 328P-AU power saving
« Reply #3 on: March 27, 2017, 03:53:53 PM »

Would it be possible to power the RFM69 module from an IO Pin (and set it to low before sleeping?)

Interesting question!  Not sure.   IIRC, the max current that's spec'd for an Arduino pin is 20ma, so the 16ma of Rx is pretty close to that.  If using the RFM69HW module, you could easily go over 20ma on Tx if you aren't careful.

Maybe someone else can add more color to the answer.

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6018
  • Country: us
    • LowPowerLab
Re: ATmega 328P-AU power saving
« Reply #4 on: March 27, 2017, 03:56:43 PM »
I would not even try or recommend that. It's conceptually not a good idea. If your project has power from a source it means you can power the radio from that same source. If you need to cut power use a mosfet, which you can turn on/off via GPIO.

markus1234

  • Newbie
  • *
  • Posts: 12
  • Country: at
Re: ATmega 328P-AU power saving
« Reply #5 on: March 27, 2017, 04:53:38 PM »
So at best it should look like this?



VDD => RFM69

Should I connect D4 to ground?
« Last Edit: March 27, 2017, 04:57:40 PM by markus1234 »

WhiteHare

  • Hero Member
  • *****
  • Posts: 1298
  • Country: us
Re: ATmega 328P-AU power saving
« Reply #6 on: March 27, 2017, 05:31:45 PM »
Should I connect D4 to ground?

Well if you did that, wouldn't the MOSFET be, effectively, permanently ON?

What you probably want instead is:
Code: [Select]
digitalWrite(4,LOW);

and then:
Code: [Select]
digitalWrite(4,HIGH);
when you want to power-off the radio.

Something to consider:  depending on your choice of parts, it may turn out that the leakage current from your MOSFET may exceed the ~100na of simply sleeping the radio instead. 

perky

  • Hero Member
  • *****
  • Posts: 873
  • Country: gb
Re: ATmega 328P-AU power saving
« Reply #7 on: March 27, 2017, 06:20:05 PM »
Interesting question!  Not sure.   IIRC, the max current that's spec'd for an Arduino pin is 20ma, so the 16ma of Rx is pretty close to that.  If using the RFM69HW module, you could easily go over 20ma on Tx if you aren't careful.

An I/O driver can be modelled as Vcc with a series resistor when driving high (i.e. the resistance of the top FET in the I/O port), and a resistor down to ground when driving low (i.e. the resistance of the bottom FET).  I/O currents are specified at logic levels. So for example the max 20mA I/O spec will mean the driver will drive above the logic 1 threshold plus a noise margin at 20mA. Often this is 2.4V with 3.3V Vcc, that means the output impedance of the top FET when drivng high is a maximum of (3.3 - 2.4)/0.02, or 55R. Similarly driving low will drive below say 0.6V when sinking 20mA, so that's a resistance of 30R. Note that the maximum current at logic levels isn't usually specified, although short circuit current is. Note it is also usual to have a stronger driver in the low state than the high state, specifically because a logic level 0 is closer to ground than a logic 1 is to Vcc.

In other words, you won't get 20mA drive current with zero voltage drop from the driver, so you can't generally use a pin for supplying that kind of current. What you should do instead is use a buffer like a FET to reduce the output impedance so that it can supply the current without much voltage drop.

Mark.

Edit: This is also the reason why it is better to drive LEDs that require more than a few mA with active low rather than active high signals. Since the output impedance is lower when driving low it allows you to control the current better with an external resistor.
« Last Edit: March 27, 2017, 06:35:15 PM by perky »

ChemE

  • Sr. Member
  • ****
  • Posts: 402
  • Country: us
Re: ATmega 328P-AU power saving
« Reply #8 on: March 27, 2017, 08:58:13 PM »
With an RFM69 attached, I'm still at 27 uA. Is there any software switch to reduce its power? (beside sleep() )

Something is odd then because with the radio sleeping and the 328p in power down mode with the WDT running, you should be around 4uA.  Without the WDT, i.e. sleeping forever, you should be at 250nA.  I have had radio.sleep() commands ignored before depending on what else is going on in the code.  I would look here first.

Perhaps issue a radio.sleep() command and then radio.readAllRegs() and post the serial output here for us to analyze.
« Last Edit: March 27, 2017, 09:01:51 PM by ChemE »

markus1234

  • Newbie
  • *
  • Posts: 12
  • Country: at
Re: ATmega 328P-AU power saving
« Reply #9 on: March 28, 2017, 01:09:19 AM »
Hi,

thanks for all your  anwsers.

This is the output for readAllRegs() - with REGISTER_DETAIL = 1:

Code: [Select]
Address - HEX - BIN
1 - 0 - 0
Controls the automatic Sequencer ( see section 4.2 )
SequencerOff : 0 -> Operating mode as selected with Mode bits in RegOpMode is automatically reached with the Sequencer

Enables Listen mode, should be enabled whilst in Standby mode:
ListenOn : 0 -> Off ( see section 4.3)

Aborts Listen mode when set together with ListenOn=0 See section 4.3.4 for details (Always reads 0.)

Transceiver's operating modes:
Mode : 000 -> Sleep mode (SLEEP)

2 - 0 - 0
Data Processing mode:
DataMode : 00 -> Packet mode

Modulation scheme:
Modulation Type : 00 -> FSK

Data shaping: in FSK:
ModulationShaping : 00 -> no shaping

3 - 2 - 10
4 - 40 - 1000000
Bit Rate (Chip Rate when Manchester encoding is enabled)
BitRate : 55555

5 - 3 - 11
6 - 33 - 110011
Frequency deviation
Fdev : 49959

7 - 6C - 1101100
8 - 40 - 1000000
9 - 0 - 0
RF Carrier frequency
FRF : 432750592

A - 41 - 1000001
RC calibration control & status
RcCalDone : 1 -> RC calibration is over

B - 0 - 0
Improved AFC routine for signals with modulation index lower than 2.  Refer to section 3.4.16 for details
AfcLowBetaOn : 0 -> Standard AFC routine

C - 2 - 10
Reserved

D - 92 - 10010010
Resolution of Listen mode Idle time (calibrated RC osc):
ListenResolIdle : 10 -> 4.1 ms

Resolution of Listen mode Rx time (calibrated RC osc):
ListenResolRx : 01 -> 64 us

Criteria for packet acceptance in Listen mode:
ListenCriteria : 0 -> signal strength is above RssiThreshold

Action taken after acceptance of a packet in Listen mode:
ListenEnd : 01 -> chip stays in Rx mode until PayloadReady or Timeout interrupt occurs.  It then goes to the mode defined by Mode. Listen mode stops and must be disabled (see section 4.3)

E - F5 - 11110101
F - 20 - 100000
10 - 24 - 100100
11 - 9F - 10011111
12 - 9 - 1001
13 - 1A - 11010
14 - 40 - 1000000
15 - B0 - 10110000
16 - 7B - 1111011
17 - 9B - 10011011
18 - 0 - 0
19 - 42 - 1000010
1A - 8A - 10001010
1B - 40 - 1000000
1C - 80 - 10000000
1D - 6 - 110
1E - 0 - 0
1F - 0 - 0
20 - 0 - 0
21 - 0 - 0
22 - 0 - 0
23 - 0 - 0
24 - 0 - 0
25 - 40 - 1000000
26 - 7 - 111
27 - 80 - 10000000
28 - 0 - 0
29 - DC - 11011100
2A - 0 - 0
2B - 0 - 0
2C - 0 - 0
2D - 3 - 11
2E - 88 - 10001000
2F - 2D - 101101
30 - 1 - 1
31 - 0 - 0
32 - 0 - 0
33 - 0 - 0
34 - 0 - 0
35 - 0 - 0
36 - 0 - 0
37 - 90 - 10010000
38 - 42 - 1000010
39 - 0 - 0
3A - 0 - 0
3B - 0 - 0
3C - 8F - 10001111
3D - 13 - 10011
3E - 48 - 1001000
3F - 6F - 1101111
40 - 6D - 1101101
41 - 65 - 1100101
42 - 48 - 1001000
43 - 75 - 1110101
44 - 62 - 1100010
45 - 44 - 1000100
46 - 65 - 1100101
47 - 66 - 1100110
48 - 61 - 1100001
49 - 75 - 1110101
4A - 6C - 1101100
4B - 74 - 1110

This is produced by (using the unmodified GIT Version of the  LowPowerLab/RFM69 lib):
Code: [Select]
#include <LowPower.h>
#include <RFM69.h>

RFM69 radio;

void setup() {
  Serial.begin(9600);
 
  radio.initialize(RF69_433MHZ,7,1);
  radio.sleep();

  radio.readAllRegs();
}

void loop() {
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);   
}

As of hardware this is just a atmega328 connected to a RFM69CW (the RFM12B compatibility version) and a pinheader - nothing else.

Now, with this sketch it uses ~27 uA
« Last Edit: March 28, 2017, 02:28:32 AM by markus1234 »