Atmega328p saving energy

Go To Last Post
2 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have an atmega328p running on a supercapacitor, so I need to lower the energy as much as possible, I run it on 8MHz to do thinks as fast as possible and go to power save (1uA).
I have two issues I don't know how to solve:
1.

do {
        TIMER2_OVERFLOW_FLAG = false;
           while (ASSR & flags(TCN2UB, OCR2AUB, OCR2BUB, TCR2AUB, TCR2BUB));
        do {
            sleep_enable();
            sei();
            sleep_cpu();
            sleep_disable();
            cli();
        } while (!TIMER2_OVERFLOW_FLAG);
        TCCR2A = TCCR2A; // dummy write to wait one tick
        count--;
    } while(count);

Timer2 is running in async mode, so there is one Timer2 tick per 244,140625 CPU ticks; most of the time between sleeps is waisted on while (ASSR & flags(TCN2UB, OCR2AUB, OCR2BUB, TCR2AUB, TCR2BUB));
Due to my measures, active mode with 8MHz consumes ~2,60mA, 0,5MHz consumes ~270uA
I think that setting CLKPR to /16 before the loop and going back to /1 ater the loop would save some energy. Am I right? Maybe someone have any better idea?

2. Every 30 minutes I need to read the temperature from the DS18B20 with 1-wire protocol. To handle read and write slots I have to sleep for some microseconds. So for example I need to sleep for 60us during write slot. It's not enough time to use async Timer2 with power save mode, so I'm thinking about using prescaler to save some energy.
Idle mode with 8MHz consumes 510uA, while active mode with /32 prescaler consumes only 130uA.

CLKPR = _BV(CLKPCE);
CLKPR = _BV(CLKPS2) | _BV(CLKPS0); // /32
CLKPR = _BV(CLKPCE);
CLKPR = 0; // /1

I measured how much time it takes to exec those 4 commands, by setting pin high before, and low after. On the oscilloscope it was always 19,80us.
So doing it 3 times should take about 60us.
The problem is with the datasheet:
"Hence, itis not possible to determine the state of the prescaler - even if it were readable, and the exacttime it takes to switch from one clock division to the other cannot be exactly predicted. From thetime the CLKPS values are written, it takes between T1 + T2 and T1 + 2 * T2 before the newclock frequency is active. In this interval, 2 active clock edges are produced. Here, T1 is the pre-vious clock period, and T2 is the period corresponding to the new prescaler setting"
So going from /1 to /32 should take between
0.000000125 + 0.000004 = 4.125us
and
0.000000125 + 2*0.000004 = 8.128us
and going back from /32 to /1 should take between
0.000004‬ + 0.000000125 = 4.125us
and
0.000004‬ + 2*0.000000125 = 4.25us
The problem is that no matter how many NOPs i put before it's always exactly 19,80us
Should I use that method or due to the datasheet it's a stupid idea?
Any other idea to sleep exactly 60us saving energy?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

60us that is with 8MHz just 500 instruction cycles. you have instruction cycles needed to set everything up for sleep and you will have instruction cycles for leaving sleep.

Have you done math on the actual power saving you will be doing? sleeping 60us on 100us or on 1 second......

Do you need the 8MHz speed or is it possible to drop down to even lower speeds, perhaps you get more current gain from that.

Now in the datasheet there is also a mentioning of power down registers. You could check to see if using that to just really power down the peripheral blocks you do not use and safe even more.