Pages: [1] 2   Go Down
Author Topic: Using sleep mode effectivelly  (Read 4033 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Full Member
***
Karma: 4
Posts: 218
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

 An old thread was not answered at the time and was  in a funny place so I bring back here.

 Is anyone able to bring chip out of sleep mode without external trigger.

Is chip able to count 30 minutes while in sleep mode then wake up . Any other way to count externally to 30 min then trigger wake up.

Any new thought here?


I see this comment at  http://www.sensor-networks.org/index.php?page=0820520514
but do not understand?
Quote
In Arduino we are going to use power save mode to save power and as interrupt source we are going to use the overflow interrupt in timer 2.

Timer 2 is a 8 bit counter (counts until 255)  and is able to trigger an overflow interrupt if we also use a 10 bits preescaler we divide the frecuency by 1024 and we get an interrupt source that is triggered 61 times per seconds (16000000 / 1024 / 255 = 61).


This is what I need .How can I program to do this and bring back after 30 minutes

Quote
From Data sheet ATMega328
9.5 Power-down Mode
               When the SM2..0 bits are written to 010, the SLEEP instruction makes the MCU enter Power-
               down mode. In this mode, the external Oscillator is stopped, while the external interrupts, the 2-
               wire Serial Interface address watch, and the Watchdog continue operating (if enabled). Only an
               External Reset, a Watchdog System Reset, a Watchdog Interrupt, a Brown-out Reset, a 2-wire
               Serial Interface address match, an external level interrupt on INT0 or INT1, or a pin change
               interrupt can wake up the MCU. This sleep mode basically halts all generated clocks, allowing
               operation of asynchronous modules only.
               Note that if a level triggered interrupt is used for wake-up from Power-down mode, the changed
               level must be held for some time to wake up the MCU. Refer to ”External Interrupts” on page 70
               for details.
               When waking up from Power-down mode, there is a delay from the wake-up condition occurs
               until the wake-up becomes effective. This allows the clock to restart and become stable after
               having been stopped. The wake-up period is defined by the same CKSEL Fuses that define the
               Reset Time-out period, as described in ”Clock Sources” on page 27.

I can turn off Watchdog and ADC and others and bring back on when awake.  I look for  the code to turn everything off except one timer to count the 30 minutes then bring it back and turn them all on again.
I have external occillator crystal operating on the arduino board anyway
      
  
« Last Edit: January 11, 2010, 05:02:49 pm by april.steel » Logged

UK
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2884
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

There is no single "sleep mode".

In the first quote, they're using "power-save" mode, which leaves the timer oscillator enabled.
In the second quote, they're talking about "power-down" mode, which allows only external stimulii (INT0, INT1, TWI address match, WDT and BDO).

See section "9.1 Sleep Modes" in the device datasheet for a better explanation of the various sleep modes.
« Last Edit: January 12, 2010, 07:39:05 am by GrooveFlotilla » Logged

Per Arduino ad Astra

0
Offline Offline
Full Member
***
Karma: 4
Posts: 218
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Is anyone able to bring chip out of sleep mode without external trigger.

Is chip able to count 30 minutes while in sleep mode then wake up . Any other way to count externally to 30 min then trigger wake up.

Any new thought here?
Logged

Sofia, Bulgaria
Offline Offline
Full Member
***
Karma: 0
Posts: 237
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi! To answer your questions:
1. Yes. Anyone who reads the mentioned article will have the knowledge to wake up the Arduino without external trigger. Here is another good article:
http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/

2. If you want to not have a timer wake up the chip multiple times, increase a counter and when the counter has counted to a specific value, i.e. the 30 min, but to count only once you have to run the chip very slow - in the KHz area. That means to attach a "slow" resonator to the atmega chip. You are asking about the chip, not the Arduino itself, which is "locked" to 16 MHz.
And secondly - yes, you can build an external trigger circuit with an 555 timer in monostable mode, that you can generate a PCInt or an external interrupt. Here are some good descriptions of 555 circuits: http://www.kpsec.freeuk.com/555timer.htm
Logged

UK
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2884
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Is chip able to count 30 minutes while in sleep mode then wake up
Please note: there is no single "sleep mode" - there are several.
It is pointless to keep referring to "sleep mode" unless you specify which one you mean.

However, you could wake up the processor from power-down mode in little bursts every time the watchdog times out.
Count the watchdog timeouts until 30 minutes has elapsed.
This is what the nightingale example does.
To get a single 30 minute timeout in power-down mode, you'd probably have to supply a very slow external clock, which may well cost you more in micro-amps than you save.
[edit]Scratch that: the watchdog has its own oscillator, duh. {smacks forehead}[/edit]
« Last Edit: January 13, 2010, 04:44:36 am by GrooveFlotilla » Logged

Per Arduino ad Astra

0
Offline Offline
Full Member
***
Karma: 4
Posts: 218
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks . The last two posts offer more potential. I will use any sleep mode that gets the job done and attaching an external timer seems  will use more than chip in turned on mode.  
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 197
Posts: 12736
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Some important notes about the watchdog oscillator...

  • It is not accurate.  Expect it to be wrong by as much as 10%.
  • It is dependant on temperature.  Warm the processor and the oscillator runs at a different rate.
  • It is dependant on processor load.  Turn a few digital outputs high and the oscillator runs at a different rate.
  • It "jitters".  Even when everything is kept constant, the oscillator runs at slightly different rates.
« Last Edit: January 13, 2010, 10:21:56 pm by bcook » Logged

0
Offline Offline
Full Member
***
Karma: 4
Posts: 218
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes thank you . I do not care if it delays 30 minutes or 34 minutes as long as it turns off between these read times.

Trouble is it seems to interfere with Dallas temperature sensors atm and the chip will turn off for 30 mins but I cannot get a Dallas reading for some reason?
Logged

Slovenia, Europe
Offline Offline
Full Member
***
Karma: 0
Posts: 103
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

If you read that article, you probably see, that by default, you can set processor to sleep for max 8sec. My solution is to multiply this 8s to get the wanted down-time. See the code, this example will blink the led 10 times every 80 seconds (approx.):
Code:
#include <avr/sleep.h>
#include <avr/wdt.h>

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

int nint;
int pinLed=13;

volatile boolean f_wdt=1;

void setup(){

  Serial.begin(9600);
  pinMode(pinLed,OUTPUT);
  Serial.println("Setup watchdog");

  // CPU Sleep Modes
  // SM2 SM1 SM0 Sleep Mode
  // 0    0  0 Idle
  // 0    0  1 ADC Noise Reduction
  // 0    1  0 Power-down
  // 0    1  1 Power-save
  // 1    0  0 Reserved
  // 1    0  1 Reserved
  // 1    1  0 Standby(1)

  cbi( SMCR,SE );      // sleep enable, power down mode
  cbi( SMCR,SM0 );     // power down mode
  sbi( SMCR,SM1 );     // power down mode
  cbi( SMCR,SM2 );     // power down mode

  setup_watchdog(9);

}

byte del;
int cnt;
int counter = 10; // timer for counting watchdog cicles
long time = 0;

//****************************************************************
//****************************************************************
//****************************************************************
void loop(){

  if (f_wdt==1) {  // wait for timed out watchdog / flag is set when a watchdog timeout occurs
    f_wdt=0;       // reset flag

    ///// debuging purpose only /////
    time = millis();
    Serial.print(counter);
    Serial.print(" ");
    Serial.println(time);
    delay(2); //needed for serial.print operation to finish
    /////////////////////////////////////

    if(counter==10)  // if ==10 -> this will be true every 10x8 = 80seconds; set to 225 to get 225x8=1800s = 30min
    {

      //////////////// put code inside this IF ////////
      
      pinMode(pinLed,INPUT); // set all used port to intput to save power

      for(int i=0; i<10; i++)
      {
        digitalWrite(pinLed, HIGH);
        delay(90);
        digitalWrite(pinLed, LOW);
        delay(90);  
      }

      pinMode(pinLed,OUTPUT); // set all ports into state before sleep
      
      ////////////////////////////////////////////////////
      
      counter = 0;
    }
    else counter++;

    system_sleep();

  }

}


//****************************************************************
// set system into the sleep state
// system wakes up when wtchdog is timed out
void system_sleep() {

  cbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter OFF

  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
  sleep_enable();

  sleep_mode();                        // System sleeps here

    sleep_disable();                     // System continues execution here when watchdog timed out
  sbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter ON

}

//****************************************************************
// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {

  byte bb;
  int ww;
  if (ii > 9 ) ii=9;
  bb=ii & 7;
  if (ii > 7) bb|= (1<<5);
  bb|= (1<<WDCE);
  ww=bb;
  Serial.println(ww);


  MCUSR &= ~(1<<WDRF);
  // start timed sequence
  WDTCSR |= (1<<WDCE) | (1<<WDE);
  // set new watchdog timeout value
  WDTCSR = bb;
  WDTCSR |= _BV(WDIE);

}
//****************************************************************
// Watchdog Interrupt Service / is executed when  watchdog timed out
ISR(WDT_vect) {
  f_wdt=1;  // set global flag
}


What dallas sensor are you using? 1-Wire? If so, do you have a delay before Read command?

Regards,
Peter
« Last Edit: February 01, 2010, 10:04:10 am by Odisej » Logged

0
Offline Offline
Full Member
***
Karma: 4
Posts: 218
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you Odisej

No I dont have delay before read ,I will try
Thanks for above code I will work  it some while and come back
Logged

0
Offline Offline
Full Member
***
Karma: 4
Posts: 218
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Is so I do have a delay before the read. I saw this some time ago related to analog inputs only as they are multiplexed to the ADC.

I am using a digital pin 7 to read the 1 wire signal for the dallas device.
Watchdog example works fine The dallas example tester in the library works too if I just put that on arduino. Still working on your program to work

So both examples work apart on own. Problem comes when combining both into one program. Watchdog is interfering somehow.
On a tested and working  sensor I get one reading only eg 28.50C and it stays the same reading even when I heat sensor.
« Last Edit: February 05, 2010, 08:18:31 am by april.steel » Logged

0
Offline Offline
Faraday Member
**
Karma: 23
Posts: 3469
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I just would like to point out that the Arduino is NOT hardwired to 16 MHz. You can overwrite the prescaler with
Code:
#include <avr/power.h>

...

clock_prescale_set(value);

value = n --> prescale by 2^n maximum value for n is found in the datasheet. I think 8 is the maximum --> 16 MHz / 256 gives 62.6 kHz.

It is possible to combine this with sleep modes. I found in my project that if I put the processor to idle then it will consume less power if I prescale as well. In my project I could not use a deeper sleep mode, but idle plus prescaling gave significant power reduction as well.

Cheers, Udo
Logged

Check out my experiments http://blog.blinkenlight.net

Slovenia, Europe
Offline Offline
Full Member
***
Karma: 0
Posts: 103
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, I don't have a sensor with me, but try this code:
Code:

#include <avr/sleep.h>
#include <avr/wdt.h>
#include <OneWire.h>

OneWire ds(7);

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

int nint;
int pinLed=13;

volatile boolean f_wdt=1;

//////// 1- wire variables /////////
int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;

byte i;
byte present = 0;
byte data[12];
byte addr[8];
////////////////

void setup(){

  Serial.begin(9600);
  pinMode(pinLed,OUTPUT);
  Serial.println("Setup watchdog");

  // CPU Sleep Modes
  // SM2 SM1 SM0 Sleep Mode
  // 0    0  0 Idle
  // 0    0  1 ADC Noise Reduction
  // 0    1  0 Power-down
  // 0    1  1 Power-save
  // 1    0  0 Reserved
  // 1    0  1 Reserved
  // 1    1  0 Standby(1)

  cbi( SMCR,SE );      // sleep enable, power down mode
  cbi( SMCR,SM0 );     // power down mode
  sbi( SMCR,SM1 );     // power down mode
  cbi( SMCR,SM2 );     // power down mode

  setup_watchdog(9);

}

byte del;
int cnt;
int counter = 10; // timer for counting watchdog cicles
long time = 0;

//****************************************************************
//****************************************************************
//****************************************************************
void loop(){

  if (f_wdt==1) {  // wait for timed out watchdog / flag is set when a watchdog timeout occurs
    f_wdt=0;       // reset flag

    /* ///// debuging purpose only /////
     time = millis();
     Serial.print(counter);
     Serial.print(" ");
     Serial.println(time);
     delay(2); //needed for serial.print operation to finish
     */    ////////////////////////////////////

    if(counter==10)  // if ==10 -> this will be true every 10x8 = 80seconds; set to 225 to get 225x8=1800s = 30min
    {

      //////////////// put code inside this IF ////////

      pinMode(pinLed,INPUT); // set all used port to intput to save power

      for(int i=0; i<10; i++)
      {
        digitalWrite(pinLed, HIGH);
        delay(90);
        digitalWrite(pinLed, LOW);
        delay(90);  
      }

      ///////// 1-wire //////////
      ds.reset();
      ds.skip();
      ds.write(0x44,1);         // start conversion, with parasite power on at the end

      delay(1000);     // maybe 750ms is enough, maybe not
      // we might do a ds.depower() here, but the reset will take care of it.

      present = ds.reset();
      ds.skip();    
      ds.write(0xBE);         // Read Scratchpad


      for ( i = 0; i < 9; i++) {           // we need 9 bytes
        data[i] = ds.read();
      }


      LowByte = data[0];
      HighByte = data[1];
      TReading = (HighByte << 8) + LowByte;
      SignBit = TReading & 0x8000;  // test most sig bit
      if (SignBit) // negative
      {
        TReading = (TReading ^ 0xffff) + 1; // 2's comp
      }
      Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25


      Whole = Tc_100 / 100;  // separate off the whole and fractional portions
      Fract = Tc_100 % 100;


      if (SignBit) // If its negative
      {
        Serial.print("-");
      }
      Serial.print(Whole);
      Serial.print(".");
      if (Fract < 10)
      {
        Serial.print("0");
      }
      Serial.print(Fract);

      Serial.print("\n");
      ///////////////1-wire end///////////

      pinMode(pinLed,OUTPUT); // set all ports into state before sleep

      ////////////////////////////////////////////////////

      counter = 0;
    }
    else counter++;

    system_sleep();

  }

}


//****************************************************************
// set system into the sleep state
// system wakes up when wtchdog is timed out
void system_sleep() {

  cbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter OFF

  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
  sleep_enable();

  sleep_mode();                        // System sleeps here

    sleep_disable();                     // System continues execution here when watchdog timed out
  sbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter ON

}

//****************************************************************
// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {

  byte bb;
  int ww;
  if (ii > 9 ) ii=9;
  bb=ii & 7;
  if (ii > 7) bb|= (1<<5);
  bb|= (1<<WDCE);
  ww=bb;
  Serial.println(ww);


  MCUSR &= ~(1<<WDRF);
  // start timed sequence
  WDTCSR |= (1<<WDCE) | (1<<WDE);
  // set new watchdog timeout value
  WDTCSR = bb;
  WDTCSR |= _BV(WDIE);

}
//****************************************************************
// Watchdog Interrupt Service / is executed when  watchdog timed out
ISR(WDT_vect) {
  f_wdt=1;  // set global flag
}



Logged

UK
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2884
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
     pinMode(pinLed,INPUT); // set all used port to intput to save power

      for(int i=0; i<10; i++)
      {
        digitalWrite(pinLed, HIGH);
        delay(90);
        digitalWrite(pinLed, LOW);
        delay(90);
      }


If you've just set the pin to INPUT, how does the LED light by simply enabling and disabling the internal pull-ups?
Logged

Per Arduino ad Astra

0
Offline Offline
Faraday Member
**
Karma: 23
Posts: 3469
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It will light very dim and consume very little power... I did this once by mistake smiley
Logged

Check out my experiments http://blog.blinkenlight.net

Pages: [1] 2   Go Up
Jump to: