Pages: [1] 2   Go Down
Author Topic: Inturrupts and millis() function problem  (Read 1125 times)
0 Members and 1 Guest are viewing this topic.
Western Australia
Offline Offline
Newbie
*
Karma: 1
Posts: 48
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ardunio Due'
I am using the millis() function to keep track of timed events, but as my hardware needs to go into "sleep" mode I need the millis() function to keep counting.
I have attached a sample program that has 3 different "ISR" samples taken from several Arduino blogs etc.
I can not get any to work with out stopping the millis timer....
I have tried all sleep modes, and yes I understand that some will cause the timers to stop, but pwrSave, ADC and Idle should be ok?
Please advice

* Interrupt_01.ino (2.35 KB - downloaded 6 times.)
Logged

Western Australia
Offline Offline
Newbie
*
Karma: 1
Posts: 48
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

 Hi
Actual this is a
Arduino Duemilanove w/ Atmega328, no a Arduino Due
Might have been mistaken as on the first line I put:
Ardunio Due'
(could not be bothered to put the rest of the Italian in, so used a " ' " on the end.....)
Please can you move it back???
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Topic moved to "Arduino Due" section because it started with "Ardunio Due'".

Moved back, sigh.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can post small sketches into the forum directly. Here it is:

Code:
#include <Sleep_n0m1.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <avr/power.h>

/*
I am trying to keep the "millis()" timer going while I put the CPU to sleep.
I understand that full sleep mode will stop the "timers"
but I can not get ANY of the sample interrupt functions to work without stopping millis() from counting
Samples are taken from several Arduino sites, so I assume "I" have a problem.......!
*/

Sleep sleep;    // Set up SLEEP   

void setup(void)
{
  Serial.begin(9600);
 
}

void loop(void)

    delay(1000);
 
//Sleep # 1
    Serial.print("Start of sleep # 1 milli count is  ");
    Serial.println(millis(), DEC);
    Serial.flush();
    sleep.pwrSaveMode(); //set sleep mode. pwrDownMode, or idleMode, adcMode
    sleep.sleepInterrupt(0,FALLING); //sleep intill....INT starts falling LOW, eg a new TAG is touched 
    // WAKE up from change in interrupt, INT0 going LOW/FALLING
       
    Serial.print("Wake up from sleep # 1 milli count is  ");
    Serial.println(millis(), DEC);
    delay(1000);
   
//Sleep # 2

    Serial.print("Start of sleep # 2 milli count is  ");
    Serial.println(millis(), DEC);
    Serial.flush();
    sleep_enable();
    attachInterrupt(0, wakeUp, LOW);
    // 0, 1, or many lines of code here
    set_sleep_mode(SLEEP_MODE_PWR_SAVE);
    cli();
    //sleep_bod_disable();
    sei();
    sleep_cpu();
    //wake up here
    sleep_disable();
   
    Serial.print("Wake up from sleep # 2 milli count is  ");
    Serial.println(millis(), DEC);
    delay(1000);

//Sleep # 3

    Serial.print("Start of sleep # 3 milli count is  ");
    Serial.println(millis(), DEC);
    Serial.flush();
    set_sleep_mode(SLEEP_MODE_PWR_SAVE);   // sleep mode is set here
    sleep_enable();          // enables the sleep bit in the mcucr register // so sleep is possible. just a safety pin
    attachInterrupt(0, wakeUp, LOW);
    sleep_mode();            // here the device is actually put to sleep!!
    // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP
    sleep_disable();         // first thing after waking from sleep: // disable sleep...   
   
    Serial.print("Wake up sleep # 3 milli count is  ");
    Serial.println(millis(), DEC);
    delay(1000);
    Serial.println("Start again....");
   
}   
 void wakeUp()
{
sleep_disable();
        detachInterrupt(0);
        //pin2_interrupt_flag = 1;
delay(10);
        }
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

http://www.gammon.com.au/interrupts


One thing I note there is that the millis() timer causes an interrupt, and thus your sketch will wake up about 1 mS later. You'll have to stop timer 0 if you don't want that.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Actually it was in:

http://www.gammon.com.au/power


A lot of stuff there about power saving.

What hardware do you have connected? Is pin 2 kept high by a pull-up or something?
Logged

Western Australia
Offline Offline
Newbie
*
Karma: 1
Posts: 48
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Western Australia
Offline Offline
Newbie
*
Karma: 1
Posts: 48
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Western Australia
Offline Offline
Newbie
*
Karma: 1
Posts: 48
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

UK
Offline Offline
Shannon Member
****
Karma: 184
Posts: 11197
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Western Australia
Offline Offline
Newbie
*
Karma: 1
Posts: 48
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 443
Posts: 23834
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Western Australia
Offline Offline
Newbie
*
Karma: 1
Posts: 48
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Pages: [1] 2   Go Up
Jump to: