Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
tutorials_sleep [2018/08/24 06:57] theo |
tutorials_sleep [2018/08/24 07:01] (current) theo |
||
---|---|---|---|
Line 4: | Line 4: | ||
We want to collect data from sensors and then periodically send packets of data. When we do not want to do this at a high frequency, we have some dead times. This leads to high energy consumption, which can have a significant impact on the battery life of sparrow when it is powered by a battery. | We want to collect data from sensors and then periodically send packets of data. When we do not want to do this at a high frequency, we have some dead times. This leads to high energy consumption, which can have a significant impact on the battery life of sparrow when it is powered by a battery. | ||
- | Bellow you can see the code for sleep library. | + | You can download SleepLibrary code from [[https://github.com/TheodorUngureanu/SparrowV/tree/master/SleepLibrary|here]]. |
+ | |||
+ | Bellow you can see and example on how to use sleep library. | ||
<code C> | <code C> | ||
- | #include <avr/sleep.h> | + | /* This is an example for SparrowVSleep library. |
- | #include <avr/wdt.h> | + | You need to call SparrowV_SleepInit function. |
- | #include <avr/interrupt.h> | + | The funciton has 2 params. |
- | #include <Arduino.h> | + | 1st param: integer (> 1 second, greater than 1 second) (represent time in seconds, how long the board will sleep) |
- | #include <util/delay.h> | + | 2nd param: bool (true - with data retention, false - with no data retention) |
- | #include "SparrowVsleep.h" | + | In case of no data retention the board can sleep max 8 secons and it will |
- | + | reboot after time end. | |
- | // #define DEBUG // uncomment for debunging | + | */ |
- | // (also comment /* (1 << PRUSART0) */ from PRR0 ) | + | |
- | + | ||
- | int global_seconds; | + | |
- | bool global_data_retention; | + | |
- | + | ||
- | ISR(WDT_vect) | + | |
- | { | + | |
- | #ifdef DEBUG | + | |
- | Serial.println("Watchdog Interrupt "); | + | |
- | Serial.flush(); | + | |
- | + | ||
- | Serial.print("global_seconds: "); | + | |
- | Serial.println(global_seconds); | + | |
- | Serial.flush(); | + | |
- | #endif | + | |
- | + | ||
- | if (global_seconds == 0) | + | |
- | { | + | |
- | Serial.println(); | + | |
- | Serial.println("Ready sleep"); | + | |
- | // reenable the transciever | + | |
- | PRR1 &= ~(1 << PRTRX24); | + | |
- | + | ||
- | // reenable ADC | + | |
- | ADCSRA = (1 << ADEN); | + | |
- | + | ||
- | //restore PRR | + | |
- | PRR0 = 0; | + | |
- | PRR1 = 0; | + | |
- | + | ||
- | wdt_disable(); | + | |
- | } | + | |
- | else | + | |
- | { | + | |
- | #ifdef DEBUG | + | |
- | Serial.println(); | + | |
- | Serial.println("going to sleep again"); | + | |
- | #endif | + | |
- | + | ||
- | // going to sleep again | + | |
- | choose(global_seconds); | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | void choose(int seconds) | + | |
- | { | + | |
- | #ifdef DEBUG | + | |
- | Serial.println("entering choose function"); | + | |
- | Serial.flush(); | + | |
- | #endif | + | |
- | + | ||
- | if(seconds % 8 == 0) | + | |
- | { | + | |
- | #ifdef DEBUG | + | |
- | Serial.println("choose 8"); | + | |
- | Serial.flush(); | + | |
- | #endif | + | |
- | setup_WDT(8); | + | |
- | } | + | |
- | else if (seconds % 4 == 0) | + | |
- | { | + | |
- | #ifdef DEBUG | + | |
- | Serial.println("choose 4"); | + | |
- | Serial.flush(); | + | |
- | #endif | + | |
- | setup_WDT(4); | + | |
- | } | + | |
- | else if (seconds % 2 == 0) | + | |
- | { | + | |
- | #ifdef DEBUG | + | |
- | Serial.println("choose 2"); | + | |
- | Serial.flush(); | + | |
- | #endif | + | |
- | setup_WDT(2); | + | |
- | } | + | |
- | else if (seconds % 1 == 0) | + | |
- | { | + | |
- | #ifdef DEBUG | + | |
- | Serial.println("choose 1"); | + | |
- | Serial.flush(); | + | |
- | #endif | + | |
- | setup_WDT(1); | + | |
- | } | + | |
- | else | + | |
- | { | + | |
- | //TODO for less than 1 second | + | |
- | return; | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | void setup_WDT(int situation) | + | |
- | { | + | |
- | #ifdef DEBUG | + | |
- | Serial.println("setup WDT"); | + | |
- | Serial.flush(); | + | |
- | #endif | + | |
- | + | ||
- | cli(); | + | |
- | + | ||
- | wdt_reset(); // reset the WDT timer | + | |
- | MCUSR &= ~(1 << WDRF); // Clear the reset flag. (because the data sheet said to) | + | |
- | + | ||
- | // Setup Watchdog for interrupt and not reset, and a approximately x seconds timeout | + | |
- | switch (situation) | + | |
- | { | + | |
- | // wake up after 8 seconds | + | |
- | case 8: // Enter in configuration mode | + | |
- | WDTCSR = (1 << WDCE) | (1 << WDE); | + | |
- | WDTCSR = (1 << WDIE) | (1 << WDP3) | (1 << WDP0); | + | |
- | global_seconds -= 8; | + | |
- | #ifdef DEBUG | + | |
- | Serial.println("WDT 8"); | + | |
- | Serial.flush(); | + | |
- | #endif | + | |
- | break; | + | |
- | + | ||
- | // wake up after 4 seconds | + | |
- | case 4: // Enter in configuration mode | + | |
- | WDTCSR = (1 << WDCE) | (1 << WDE); | + | |
- | WDTCSR = (1 << WDIE) | (1 << WDP3); | + | |
- | global_seconds -= 4; | + | |
- | #ifdef DEBUG | + | |
- | Serial.println("WDT 4"); | + | |
- | Serial.flush(); | + | |
- | #endif | + | |
- | break; | + | |
- | + | ||
- | // wake up after 2 seconds | + | |
- | case 2: // Enter in configuration mode | + | |
- | WDTCSR = (1 << WDCE) | (1 << WDE); | + | |
- | WDTCSR = (1 << WDIE) | (1 << WDP2) | (1 << WDP1) | (1 << WDP0); | + | |
- | global_seconds -= 2; | + | |
- | #ifdef DEBUG | + | |
- | Serial.println("WDT 2"); | + | |
- | Serial.flush(); | + | |
- | #endif | + | |
- | break; | + | |
- | + | ||
- | // wake up after 1 second | + | |
- | case 1: // Enter in configuration mode | + | |
- | WDTCSR = (1 << WDCE) | (1 << WDE); | + | |
- | WDTCSR = (1 << WDIE) | (1 << WDP2) | (1 << WDP1); | + | |
- | global_seconds -= 1; | + | |
- | #ifdef DEBUG | + | |
- | Serial.println("WDT 1"); | + | |
- | Serial.flush(); | + | |
- | #endif | + | |
- | break; | + | |
- | + | ||
- | //TODO for less than 1 second | + | |
- | } | + | |
- | sei(); | + | |
- | + | ||
- | // sleep setup and going to sleep | + | |
- | SparrowV_SleepSet(global_data_retention); | + | |
- | } | + | |
- | + | ||
- | void SparrowV_SleepSet(bool data_retention) | + | |
- | { | + | |
- | #ifdef DEBUG | + | |
- | Serial.println("sleep setup"); | + | |
- | Serial.flush(); | + | |
- | #endif | + | |
- | + | ||
- | // prepare Deep-sleep Mode | + | |
- | + | ||
- | // transcieverul off | + | |
- | PRR1 |= (1 << PRTRX24); | + | |
- | + | ||
- | // Shut down ADC before invoking the PRR bit for it | + | |
- | ADCSRA = 0; | + | |
- | + | ||
- | // Power reduction registers | + | |
- | PRR0 |= (1 << PRTWI) | (1 << PRTIM2) | (1 << PRTIM0) | (1 << PRPGA) | + | |
- | | (1 << PRTIM1) | (1 << PRSPI) | (1 << PRADC) | (1 << PRUSART0); | + | |
- | + | ||
- | PRR1 |= (1 << PRTIM5) | (1 << PRTIM4) | (1 << PRTIM3) | (1 << PRUSART1) | + | |
- | | (1 << PRUSART1); | + | |
- | + | ||
- | // Data renention (if no data retention max 8s sleep and then restart) | + | |
- | if (data_retention == false) { | + | |
- | PRR2 |= (1 << PRRAM3) | (1 << PRRAM2) | (1 << PRRAM1) | (1 << PRRAM0); | + | |
- | } | + | |
- | // Sleep Mode Control Register (sleep enable & power down) | + | #include <SparrowVsleep.h> |
- | SMCR = (1 << SE) | (0 << SM0) | (1 << SM1) | (0 << SM2); | + | |
- | // comand for sleep | + | void setup() { |
- | sleep_cpu(); | + | Serial.begin(9600); |
} | } | ||
- | void SparrowV_SleepInit(int seconds, bool data_retention) | + | void loop() { |
- | { | + | // put your main code here, to run repeatedly: |
- | // update global variables | + | Serial. println("****************************"); |
- | global_seconds = seconds; | + | Serial.println("Start"); |
- | global_data_retention = data_retention; | + | Serial.flush(); |
- | #ifdef DEBUG | + | //sleep for 25 seconds with data retention |
- | Serial.println("global_seconds: "); | + | SparrowV_SleepInit(25, true); |
- | Serial.println(global_seconds); | + | |
- | Serial.flush(); | + | |
- | #endif | + | |
- | choose(seconds); | + | Serial.println("Stop"); |
+ | Serial. println("****************************"); | ||
+ | Serial. println(); | ||
+ | Serial.flush(); | ||
+ | delay(5000); | ||
} | } | ||
</code> | </code> |