Go Down

Topic: Using sleep mode effectivelly (Read 5081 times) previous topic - next topic

Odisej

Whoooops, there's a glitch, my mistake. I guess I copyed the wrong code, from one of my tests... you need to do "input" before going to sleep and put back to "output" when exiting sleep.
Code: [Select]


#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,OUTPUT); // 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,INPUT); // 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
}




april

Thanks again Odisej
I have tried your code above and with debugging on get the count OK but not the temperature . Code is reading the sensor but this bit below seems to give wrong type of write in terminal output
.
Quote
///////// 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 = 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///////////

Groove

Quote
this bit below seems to give wrong type of write

And the right type of write would be what, exactly?
Per Arduino ad Astra

Odisej

OMG, I'm so sory. I forgot a small detail... put a small delay (let's say delay(2); ) after printing the last thing on serial. That is to finish the transmission before processor sleeps.

I'll test the code when I find one of my arduino's :)

Groove

Quote
OMG, I'm so sory. I forgot a small detail


Don't knock yourself out about it - the delay was there in your first post at reply #8!   :)

Maybe worth commenting that the delay is baud-rate dependent, i.e a slower baud rate will need a longer delay, to allow the UART time to clock out the last character.
Per Arduino ad Astra

april

Very Much thanks Odisej

Happy to report temperature device is now reading properly and it seems that the arduino is switching off now between reads. I will put my testing code here again . I reduced timer to see effect more quickly
Note that Address array does not get an address in this code . It prints as 0 0 0 0 0 0 0 0 . Not sure why  I not need address on my use

Good work !

Code: [Select]
#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(4);  //set to 9 for longer sleep time

}

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,OUTPUT); // 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();
     }
        Serial.println();
     
     
        Serial.print("A=");
         for( i = 0; i < 8; i++) {
           Serial.print(addr[i], HEX);
           Serial.print(" ");}
      Serial.print("D=");
        for( i = 0; i < 12; i++) {
          Serial.print(data[i], DEC);
           Serial.print(" ");}


       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");
     delay(10);
       ///////////////1-wire end///////////

     pinMode(pinLed,INPUT); // 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
}





Odisej

You never said you need more than one sensor. Do you?
If you don't, the code is fine. The address is 0 because you do ds.skip(); which means, you skip address reading/selection.

april

No thanks I only seek to understand . Code out and working now.
also I seek to understand the use of "present " as I can find no use of it.
I see your code is drawn from examples so possibly some can be deleted without effect

Go Up