Inturrupts and millis() function problem

Pin 2 is connected via a 4.7k to Vcc
Re stopping timer, will this stop millis()?
I put in all 3 ISR to test, but would like just to have millis() running while the CPU is in a lower power mode, and then wake up when INT0 goes low.

Thanks

jamesvote:
I ...would like just to have millis() running while the CPU is in a lower power mode, and then wake up when INT0 goes low.

No doubt. But it doesn't.

Timer 0 is what drives millis(). Without timer 0, millis() won't increment.

One approach is to attach a RTC chip (around $9 on a board) and have that keep track of the time. My post (http://www.gammon.com.au/power) shows how you might "power up" such a chip when required, and get the time from it.

Hi Nick

Would have liked to keep my chip count down, but if no other way, then add hardware....
Thanks the help, best regards
James

Depends how accurate you want it to be. If you are sleeping for 8 seconds with the watchdog timer, you know 8 seconds are up, right? However there would probably be a bit of creep, but you might be able to factor that in by trial and error.

Basically you could take the millis result (from when it is awake) and add in 8000 for every time it slept for 8 seconds, plus some factor you might determine, which is the time taken to wake up and get millis up and running.

Ok, so I sleep for a fixed period of time (save the millis) wake up add fixed amount to millis and if no INT(0) go back to sleep...?
As I was hoping to use millis for an RTC, I don't think it would be very accurate over a day.....
Also if INT(0) is triggered by the operator I would have to add the watchdog timer to millis to get a true figure...
Getting a bit complex just to get timed events recorded.

Thanks, but it looks like more hardware....

James

There are various power saving libraries that will take care of the different power saving modes for you. At least some of these will also take care of correcting the millis() value afterwards.

Hi Peter

I have had a look over some of these but can not see any that look after the millis() while sleeping?
If you have a chance please supply a "hint" on were to look, or if possible, sample code

Thanks

You have a duemilanove?
What is the power source?
The FTDI does not sleep, the regulator does not sleep, the power LED does not sleep, the op-amp/comparator does not sleep.
Your sketch does not put all the unused inputs as either high or low (high with internal pullup is best).
Given all that, you may be disappointed with your power savings when sleeping vs just being on & waiting.

Hi Crossroads

Arduino Duemilanove w/ Atmega328
My problem is NOT that I can put the CPO to sleep it is that I want to keep millis() running.....
See sample's on ISR, these are just test programs to see if millis() will still work while either IDLE, ADC or in SAVE mode
But what I have been shown via Nick is that the Timer 0 stops on ANY sleep function (Arduino compiler problem !!?)

James

So if you're not going to sleep why would millis stop?

Do the other timers stop in the various sleep modes also?

Hi
Bit of confusion.
It is going to sleep but millis() stops.....
I would like to find a way to put the CPU to sleep (save power) but I need millis() to keep running, so when I trigger INT(0) low, I use it to record timed events and run off and do other stuff, then go back to sleep again.
From reading the Atmel328 I was under the impression that power SAVE mode would still keep the timers running.
But it seems that the "Arduino" has other ideas.....

I will admit that I haven't ever played with the various sleep modes, but I was under the impression that when one is in any of the sleep modes that code will not be executing with the millis() function requires. So I don't see how your desire to sleep but also run code at the same time is possible?

Lefty

Hi Lefty

Yes it is looking like millis stops on all sleep modes.
I might see if I can go down to machine code and get the timer 0 count rather use millis()

James

I thought the goal was that after a sleep the result from millis() reflected the time that had elapsed during the sleep, rather than freezing. Presumably because it makes the calculations of subsequent timed events easier since the sleep can be ignored for all practical purposes.

I thought the Rocket Scream power management library did this but I seem to have misremembered since it isn't mentioned in the description. I would have thought it was easy enough to increment the millis() count by however long the sleep has lasted when doing a timed sleep, and I'd be disappointed if nobody writing power management libraries had added that capability. I suppose there's nothing stopping you from just incrementing timer0_millis for yourself, if you wanted.

Hi Peter

No, the idea is that I use millis to give a me a "time" from start of program to an interrupt on INT(0) (low)
Then go back to sleep untill the next event.
But the problem is that millis stops in sleep mode, well by the look of things in any sleep mode.....
I have given samples of ISR programs to see if millis would stay running, but alas no.

So the basic question is
Is there a way to use the Arduino compiler to put it into "a sleep" mode but keep Timer 0 running, and an idea of the code would be nice

regards
James

millis is a function.

A function doesn't "stay running".

So you possibly mean "to see if timer 0 stays running".

If timer 0 stayed running, and it generated an interrupt, after 1.024 mS then the processor would wake up.

You can't have the processor stay asleep, and millis() increment. Simple as that.

Further testing appears to indicate that Timer 0 does not run even in IDLE mode, so my page about power may be wrong about that.

According to the datasheet, Timer 2 stays running if using an external clock source, so you may be able to keep timer 2 as a time keeper. However being an 8 bit timer, you would have to wake up pretty quickly when it overflowed or you wouldn't know how many times it overflowed.

Timer 0 stops on ANY sleep function (Arduino compiler problem !!?)

It's absolutely nothing to do with the compiler. It is what the chip is capable of.

jamesvote:
No, the idea is that I use millis to give a me a "time" from start of program to an interrupt on INT(0) (low)

That's the same thing I am saying: you want the value you get back from millis() after the sleep to reflect the duration of the sleep so that you can use it to determine the real-world elapsed time. Normally, when the Arduino sleeps the value of millis() stops incrementing so that millis() shows how long the Arduino has been running, rather than the elapsed time since it started.

If you want to achieve that then one way to do it is to add the sleep duration to timer0_millis each time you perform a sleep. For example you could write a utility function to do that. If you want the value of millis() to be accurate within the interrupt handler that cause the Arduino to wake then it might be best to do the increment immediately before the sleep rather than after.

Thanks for the advice.
I looked around again and found this interesting Application Note from Atmel about RTC and very low power mode

Regards
James