Go Down

Topic: Sleep mode demo code (Read 6801 times) previous topic - next topic

jabella78

#15
Apr 23, 2014, 12:01 am Last Edit: Apr 23, 2014, 12:05 am by jabella78 Reason: 1
Hi everyone,
I was wondering if adding an astable 555 timer instead of a button to wake up from sleep mode my attiny 85 will draw more power than a simple delay cycle.

Jack Christensen


Hi everyone,
I was wondering if adding an astable 555 timer instead of a button to wake up from sleep mode my attiny 85 will draw more power than a simple delay cycle.


A 555 will draw power continuously, so no that would not be the lowest power solution.
Not sure exactly what you mean by "a simple delay cycle".
Give us a little more detail on what you're trying to accomplish and maybe we can be of a little more help.

jabella78

I have an attiny 85 checking every 10 seconds the temperature of the room and decides to power on the AC via 38khz LED.
This is the code:

Code: [Select]

#include <IRTinyTX.h>

float temp;
int tempPin = 3;
int on_off = 1;

unsigned int rawCodes[] = {8850,  4500, 600,  1650, 600,  1650, 600,  550, 600,  600, 550,  550, 600,  550, 600,  550, 600,  1700, 550,  550, 600,  1650, 600,  1650, 650,  550, 600,  550, 600,  550, 600,  550, 600,  550, 600,  550, 600,  550, 600,  1650, 600,  550, 650,  500, 600,  550, 600,  550, 600,  600, 600,  500, 650,  1650, 600,  500, 650,  550, 600,  550, 600,  550, 600,  1650, 600,  550, 600,  550, 600,  600, 550,  550, 600,  600, 600,  550, 600, 500, 600,  550, 600,  600, 600,  550, 600,  550, 600,  550, 600,  550, 600,  550, 600,  550, 600,  550, 600,  550, 600};             

IRsend irsend;

void setup()
{
   for (byte i=0; i<5; i++) {
     pinMode(i, INPUT);
     digitalWrite(i, HIGH);
   } 
   digitalWrite(tempPin, LOW);
   pinMode(1, OUTPUT);
   digitalWrite(1, LOW);
}

void loop()
{
  temp = analogRead(tempPin);
  temp = temp * 0.48828125;
   
  if (temp > 26.00 && on_off == 0) {
      irsend.sendRaw(rawCodes, 99, 38);
       on_off = 1;
      }
  else if (temp < 24.00 && on_off == 1) {
        irsend.sendRaw(rawCodes, 99, 38);
        on_off = 0;
      }
  delay(10000);
}


Instead of delay(10000) I was wondering if implementing your code with a 555 as  trigger, the power consumption would be less.

Jack Christensen


Instead of delay(10000) I was wondering if implementing your code with a 555 as  trigger, the power consumption would be less.


Beats me, really, without checking a 555 data sheet. I'm not current on the CMOS versions, I imagine they draw less current than the older bipolar types.

But why not use the watchdog timer to wake the MCU? No additional hardware needed, and I'd bet that the ATtiny85 sleeping with just the WDT running will draw less current than any 555 (should be on the order of 4-6µA).

Checking every 10 seconds seems maybe a bit excessive but done properly it shouldn't make all that much difference to the energy budget. I might also keep a running average over about a minute or something like that. Might make for smoother operation but I see there is already some hysteresis built in so that is good.

jabella78

#19
Apr 23, 2014, 09:21 pm Last Edit: Apr 23, 2014, 09:28 pm by jabella78 Reason: 1
Just see how to set watchdog timer!
Should this work?

Code: [Select]

#include <IRTinyTX.h>
#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

float temp;
volatile boolean f_wdt = 1;
int tempPin = 3;
int on_off = 0;
unsigned int rawCodes[] = {8850,  4500, 600,  1650, 600,  1650, 600,  550, 600,  600, 550,  550, 600,  550, 600,  550, 600,  1700, 550,  550, 600,  1650, 600,  1650, 650,  550, 600,  550, 600,  550, 600,  550, 600,  550, 600,  550, 600,  550, 600,  1650, 600,  550, 650,  500, 600,  550, 600,  550, 600,  600, 600,  500, 650,  1650, 600,  500, 650,  550, 600,  550, 600,  550, 600,  1650, 600,  550, 600,  550, 600,  600, 550,  550, 600,  600, 600,  550, 600, 500, 600,  550, 600,  600, 600,  550, 600,  550, 600,  550, 600,  550, 600,  550, 600,  550, 600,  550, 600,  550, 600};             

IRsend irsend;

void setup()
{
   for (byte i=0; i<5; i++) {
     pinMode(i, INPUT);
     digitalWrite(i, HIGH);
   } 
   digitalWrite(tempPin, LOW);
   pinMode(1, OUTPUT);
   digitalWrite(1, LOW);
   setup_watchdog(9);
}

void loop()
{
   if (f_wdt==1) {  // wait for timed out watchdog / flag is set when a watchdog timeout occurs
    f_wdt=0;       // reset flag
 
  temp = analogRead(tempPin);
  temp = temp * 0.48828125;
   
  if (temp > 26.00 && on_off == 0) {
      irsend.sendRaw(rawCodes, 99, 38);
       on_off = 1;
      }
  else if (temp < 24.00 && on_off == 1) {
        irsend.sendRaw(rawCodes, 99, 38);
        on_off = 0;
      }
  system_sleep();
  }
}

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;

  MCUSR &= ~(1<<WDRF);
  // start timed sequence
  WDTCR |= (1<<WDCE) | (1<<WDE);
  // set new watchdog timeout value
  WDTCR = bb;
  WDTCR |= _BV(WDIE);
}
 
// Watchdog Interrupt Service / is executed when watchdog timed out
ISR(WDT_vect) {
  f_wdt=1;  // set global flag
}


Thank you for suggestion, appreciated!

gvgv

#20
Aug 14, 2015, 08:36 am Last Edit: Aug 14, 2015, 08:37 am by gvgv
Hello
I tried to put up this example with Attiny85, but it does not seem to work. When I ground PB2, the led flashes once (5 times). If I repeat the procedure disconnecting and connecting PB2 to ground, the led does not flash any longer. It looks like the interrupt works only for the first pin change. I have not changed fuses - I am not yet comfortable with that. Could it be the reason the example does not work or am I expecting something that should not work?

Also, I've seen a number of posts advising that to save power one should use lower voltage (3.3V) and lower micropocessor speed (1MHz). Example here. Jack's example suggests running at 8 MHz and on 5V. So where is the truth?

kowalski

Could it be the reason the example does not work or am I expecting something that should not work?
Yes

I've seen a number of posts advising that to save power one should use lower voltage (3.3V) and lower micropocessor speed (1MHz). Example here. Jack's example suggests running at 8 MHz and on 5V. So where is the truth?
Yes

gvgv

With regard to the first "Yes" - it is yes, that I am expecting something different than Jack's example was supposed to do?

kowalski

With regard to the first "Yes" - it is yes, that I am expecting something different than Jack's example was supposed to do?
Yes, the fuse setting is important for the behavior.

Go Up