Giter Site home page Giter Site logo

prosenb / deepsleepscheduler Goto Github PK

View Code? Open in Web Editor NEW
81.0 81.0 6.0 95 KB

DeepSleepScheduler is a lightweight, cooperative task scheduler library with configurable sleep and task supervision.

License: Apache License 2.0

C++ 63.50% C 36.50%
arduino avr easy-to-use esp32 esp8266 power-consumption scheduler sleep task-scheduler task-supervision watchdog

deepsleepscheduler's People

Contributors

prosenb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

deepsleepscheduler's Issues

Does not compile on DOIT ESP32 DEVKIT V1

I'm using Arduino IDE.
Followed installation instructions from readme.
What am i doing wrong?

In file included from /Users/untitled/Documents/Arduino/libraries/DeepSleepScheduler/DeepSleepScheduler.h:573:0,
from /Users/untitled/workplace/esp32/deepSleep/deepSleep/deepSleep.ino:2:
/Users/untitled/Documents/Arduino/libraries/DeepSleepScheduler/DeepSleepScheduler_esp.h: In static member function 'static void SchedulerEsp::isrWatchdogExpiredStatic()':
/Users/untitled/Documents/Arduino/libraries/DeepSleepScheduler/DeepSleepScheduler_esp.h:77:20: error: 'esp_restart_noos' was not declared in this scope
esp_restart_noos();
^
exit status 1
Error compiling for board DOIT ESP32 DEVKIT V1.

Documentation on used sleep mode

I was playing around with the AWAKE_INDICATION_PIN and wondered why my program never turned the LED off while the example (ShowSleep) did. The tiny but important difference was the sleep time. After quite some debugging I found:
DeepSleepScheduler_avr_implementation:132: // use SLEEP_MODE_IDLE for values less then SLEEP_TIME_1S
May I ask if you could add a hint to the documentation of "AVR specific options", #define SLEEP_MODE or the implementation notes or the example? Maybe it saves some others time for debugging.
By the way is there a specific reason why 1s is used and not e.g. 100ms? Just wondering.

Does not compile for DigiSpark Pro (AtTiny167)

Arduino: 1.6.9 (Mac OS X), Board: "Digispark Pro (Default 16 Mhz)"
...
In file included from /Users/flounder/OneDrive/Projects/XXX/V2/Sketches/Temperature/Temperature.ino:4:0:
/Users/flounder/Documents/Arduino/libraries/DeepSleepScheduler/DeepSleepScheduler.h: In member function 'Scheduler::SleepMode Scheduler::evaluateSleepModeAndEnableWdtIfRequired()':
/Users/flounder/Documents/Arduino/libraries/DeepSleepScheduler/DeepSleepScheduler.h:707:7: error: 'WDTCSR' was not declared in this scope
       WDTCSR |= (1 << WDCE) | (1 << WDIE);
       ^
/Users/flounder/Documents/Arduino/libraries/DeepSleepScheduler/DeepSleepScheduler.h:715:5: error: 'WDTCSR' was not declared in this scope
     WDTCSR |= (1 << WDCE) | (1 << WDIE);
     ^
Using library DeepSleepScheduler at version 2.0.0 in folder: /Users/flounder/Documents/Arduino/libraries/DeepSleepScheduler 
...
exit status 1
Error compiling for board Digispark Pro (Default 16 Mhz).

Note that this compiles for the Arduino UNO and the Adafruit 32U4 Feathers. The code appears to be consistent with the code shown on page 55 of the AtTiny167 data sheet, except for the name of the register (WDTCR) and the C-language interface (which I presume is a difference between the Atmel IDE and the Aduino IDE).

We are on a very short fuse to deliver a prototype, so an immediate reply would be greatly appreciated.
joe

swap SLEEP_MODE at run time?

Hi,
sorry not an Issue, but a question, will it be possible to change the SLEEP_MODE at runtime? Or what needs to be changed to have the option to change it at runtime? Will it be as simple as changing SLEEP_MODE from a #define to a bool or byte variable?

Background: I will use it for a device that will dim an LED (PWM, therefore no deep sleep) for some hours a day but could deep sleep most time of the day in the lowest sleep mode to save power.

Thanks for considering and sorry for the "issue" (I do not know how to ask questions at GitHub)
Best Regards

Compiler warnings

Setting compiler warnings to "more" on ATmega328 causes the following warnings.
Can they be fixed to avoid covering own issues?

Thanks for the cool library!

/Arduino/libraries/DeepSleepScheduler/DeepSleepScheduler.h: In member function 'void Scheduler::removeCallbacks(void (*)())':
/Arduino/libraries/DeepSleepScheduler/DeepSleepScheduler.h:511:18: warning: deleting object of abstract class type 'Scheduler::Task' which has non-virtual destructor will cause undefined behaviour [-Wdelete-non-virtual-dtor]
           delete taskToDelete;
                  ^
/Arduino/libraries/DeepSleepScheduler/DeepSleepScheduler.h: In member function 'void Scheduler::removeCallbacks(Runnable*)':
/Arduino/libraries/DeepSleepScheduler/DeepSleepScheduler.h:536:18: warning: deleting object of abstract class type 'Scheduler::Task' which has non-virtual destructor will cause undefined behaviour [-Wdelete-non-virtual-dtor]
           delete taskToDelete;
                  ^
/Arduino/libraries/DeepSleepScheduler/DeepSleepScheduler.h: In member function 'void Scheduler::execute()':
/Arduino/libraries/DeepSleepScheduler/DeepSleepScheduler.h:615:16: warning: deleting object of abstract class type 'Scheduler::Task' which has non-virtual destructor will cause undefined behaviour [-Wdelete-non-virtual-dtor]
         delete current;
                ^
/Arduino/libraries/DeepSleepScheduler/DeepSleepScheduler.h: In member function 'long unsigned int Scheduler::getScheduleTimeOfCurrentTask() const':
/Arduino/libraries/DeepSleepScheduler/DeepSleepScheduler.h:494:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^

NTP Daily task

hi there, thank you for making this awesome library
i have used in multiple fun projects but i am working on battery projected and i need to save some juice xD

i want to know that is it possible to make NTP based DeepSleepScheduler ?

like i can define time 11:00 AM and 11:00 PM of task then esp boots , fetch current time from NTP and see if its time to do task or not if its time then do the task or go back to sleep and increase boot count
we can use boot count to avoid connecting NTP again and again

thank you once again :)

MIN_WAIT_TIME_FOR_SLEEP

AVR specific options

#define MIN_WAIT_TIME_FOR_SLEEP: Specify the minimum wait time (until the next task will be executed) to put the CPU in sleep mode. Default is 1 second.

Does this exist? I couldn't find any references to this option in the code.

add scheduleOnce()

First of all, thanks for this great library, I've been using it on most of my Arduino projects :)

One thing I've been doing again-and-again is to schedule a task to process some interruption event. But if the interruption happens several times before the task has a chance to run, it just needs to run once.

So far I've been using this to ensure tasks are only schedule once:

scheduler.removeCallbacks(task);
scheduler.schedule(task);

I suggest we add a new function scheduleOnce(), which avoids this issue.
Makes sense? What do you think?

ESP8266 resetting

Hi,

my esp8266 keep resetting if i call scheduler.execute(); in loop, if i remove this line then it stops resetting.
ets Jan 8 2013,rst cause:4, boot mode:(3,6)

Here is how call back is registered
scheduler.scheduleDelayed(initializeModem, 60000);

Callback code
void initializeModem(){
SerialMon.println(F("Initializing modem..."));
}

loop method
void loop(void)
{
httpServer.handleClient();
MDNS.update();
handleMovement();
handleCall();
scheduler.execute();
}

Error printing to Serial Monitor

When my project enters DeepSleep and restarts it prints on the Serial Monitor a sequence of strange characters.

The project is being powered by batteries and needs to get into DeepSleep, to save batteries and this is being done and doing very well. But, I need the system to turn on every 30 seconds, light a led on pin 13 and go back to the DeepSleep function.

I tried to use another library, DeepSleepScheduler, and this one believes that it is doing what it is programmed to do, but when it prints in Serial, it shows a series of strange characters, as shown in the attached video.

Here is the code I am using for testing:

#include <DeepSleepScheduler.h>
#define BUTTON 2
#define BLUE_LED 6
#define DEEP_SLEEP_DELAY 2000

int AN[] = {A1, A2, A3, A4, A5};

void setup() {
  for(int i = 0; i < 14; i++){//Coloca todas as portas digitais em LOW
    digitalWrite(i,LOW);
  }
  for(int i = 1; i < 5; i++){//Coloca todas as portas analogicas em LOW
    digitalWrite(AN[i], LOW);
  }
  pinMode(BLUE_LED, OUTPUT);
  Serial.begin(1200);
  scheduler.schedule(executFuncoes);
}

void loop() {
  scheduler.execute();
}

void executFuncoes(){
  lerBlueLeds();
  Serial.println("Teste! ");
  scheduler.scheduleDelayed(executFuncoes, 5000);
}

void lerBlueLeds(){
  for(int i=0; i<=50; i++){
    digitalWrite(BLUE_LED,HIGH);
    delay(30);
    digitalWrite(BLUE_LED,LOW);
    delay(30);
  } 
}`

multiple definition of '****'

Hi, I try your library in my project but I got problem to compile it.
I use VS Code with Platform.io.

Linking .pioenvs\esp12e\firmware.elf
.pioenvs\esp12e\src\configuration.cpp.o: In function SchedulerEsp::taskWdtDisable()': configuration.cpp:(.text._ZN12SchedulerEsp14taskWdtDisableEv+0x8): multiple definition of SchedulerEsp::taskWdtDisable()'
.pioenvs\esp12e\src\callbackFunctions.cpp.o:callbackFunctions.cpp:(.text._ZN12SchedulerEsp14taskWdtDisableEv+0x8): first defined here
.pioenvs\esp12e\src\configuration.cpp.o: In function SchedulerEsp::taskWdtReset()': configuration.cpp:(.text._ZN12SchedulerEsp12taskWdtResetEv+0x8): multiple definition of SchedulerEsp::taskWdtReset()'
.pioenvs\esp12e\src\callbackFunctions.cpp.o:callbackFunctions.cpp:(.text._ZN12SchedulerEsp12taskWdtResetEv+0x8): first defined here
.pioenvs\esp12e\src\configuration.cpp.o: In function SchedulerEsp::taskWdtEnable(unsigned char)': configuration.cpp:(.text._ZN12SchedulerEsp13taskWdtEnableEh+0xc): multiple definition of SchedulerEsp::taskWdtEnable(unsigned char)'
.pioenvs\esp12e\src\callbackFunctions.cpp.o:callbackFunctions.cpp:(.text._ZN12SchedulerEsp13taskWdtEnableEh+0xc): first defined here
.pioenvs\esp12e\src\configuration.cpp.o: In function SchedulerEsp::sleepIfRequired()': configuration.cpp:(.text._ZN12SchedulerEsp15sleepIfRequiredEv+0x8): multiple definition of SchedulerEsp::sleepIfRequired()'
.pioenvs\esp12e\src\callbackFunctions.cpp.o:callbackFunctions.cpp:(.text._ZN12SchedulerEsp15sleepIfRequiredEv+0x8): first defined here
.pioenvs\esp12e\src\configuration.cpp.o: In function Scheduler::Scheduler()': configuration.cpp:(.text._ZN9SchedulerC2Ev+0x4): multiple definition of Scheduler::Scheduler()'
.pioenvs\esp12e\src\callbackFunctions.cpp.o:callbackFunctions.cpp:(.text._ZN9SchedulerC2Ev+0x4): first defined here
.pioenvs\esp12e\src\configuration.cpp.o: In function Scheduler::Scheduler()': configuration.cpp:(.text._ZN9SchedulerC2Ev+0x4): multiple definition of Scheduler::Scheduler()'
.pioenvs\esp12e\src\callbackFunctions.cpp.o:callbackFunctions.cpp:(.text._ZN9SchedulerC2Ev+0x4): first defined here
.pioenvs\esp12e\src\configuration.cpp.o: In function `Scheduler::scheduleAtFrontOfQueue(void (*)())':

Any suggest?

my includes.h

`/**

  • Includes file include all required libraries
    */
    #ifndef INCLUDES_H
    #define INCLUDES_H

#include <ESP8266WiFi.h>
#ifdef USE_MDNS
#include <DNSServer.h>
#include <ESP8266mDNS.h>
#endif
#ifdef WEB_SERVER_ENABLED
#include <ESP8266WebServer.h>
#endif

// Arduino OTA
#ifdef USE_ARDUINO_OTA
#include <ArduinoOTA.h>
#endif

//Other Libraries
#include <jled.h>
#include <EasyBuzzer.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <DeepSleepScheduler.h>

#endif //INCLUDES_H `

Interrupt doesn't work with rotary encoder

Description

I am trying to build a low power Arduino circuit with a rotary encoder as input. I need the system to go into deep sleep as much as possible to save battery power, apart from 2x conditions:

  1. A timed task needs to be executed
  2. User wakes up the system via the rotary encoder

Problem

I cannot get my attached interrupt to work when using DeepSleepScheduler. I have made sure that it works without:

// Rotary Encoder
#define CLK_PIN 2   // Generating interrupts using CLK signal
#define DT_PIN 3    // Reading DT signal
#define SW_PIN 4    // Reading Push Button switch

volatile boolean TurnDetected;  // need volatile for Interrupts
volatile boolean rotationdirection;  // CW or CCW rotation

// Interrupt routine runs if CLK goes from HIGH to LOW
void isr ()  {
  delay(4);  // delay for Debouncing
  if (digitalRead(CLK_PIN))
    rotationdirection= digitalRead(DT_PIN);
  else
    rotationdirection= !digitalRead(DT_PIN);
  TurnDetected = true;
}

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

  // rotary encoder
  pinMode(CLK_PIN, INPUT);
  pinMode(DT_PIN, INPUT);  
  pinMode(SW_PIN, INPUT_PULLUP);

  attachInterrupt(digitalPinToInterrupt(CLK_PIN), isr, FALLING);
}

void loop() {
  if (TurnDetected)  {
    Serial.println("Turn detected!");
    TurnDetected = false;
  }
}

But when I do it with DeepSleepScheduler, the interrupt never activates. I have verified that the timed schedule works. Just not the interrupt.

#define AWAKE_INDICATION_PIN LED_BUILTIN
#define TASK_TIME 5000

// Rotary Encoder
#define CLK_PIN 2   // Generating interrupts using CLK signal
#define DT_PIN 3    // Reading DT signal
#define SW_PIN 4    // Reading Push Button switch

#include <DeepSleepScheduler.h>

volatile boolean TurnDetected;  // need volatile for Interrupts
volatile boolean rotationdirection;  // CW or CCW rotation

void ledOn() {
  digitalWrite(LED_BUILTIN, HIGH);
  Serial.println("LED On");
  scheduler.scheduleDelayed(ledOff, 2000);
}

void ledOff() {
  digitalWrite(LED_BUILTIN, LOW);
  Serial.println("LED Off");
  attachInterrupt(digitalPinToInterrupt(CLK_PIN), isrInterruptPin, FALLING);
}

// Interrupt routine runs if CLK goes from HIGH to LOW
void measureRotation ()  {
  if (digitalRead(CLK_PIN))
    rotationdirection = digitalRead(DT_PIN);
  else
    rotationdirection = !digitalRead(DT_PIN);
  TurnDetected = true;
  Serial.println("Turn detected!");
  scheduler.schedule(ledOn);
}

void isrInterruptPin() {
  scheduler.scheduleOnce(measureRotation);
  // detach interrupt to prevent executing it multiple
  // times when touching more than once.
  detachInterrupt(digitalPinToInterrupt(CLK_PIN));
}

/*
 * Work should be done under only one of two conditions
 *   1) Rotary Encoder movement sends interrupt signal
 *   2) Task is previously set for a time
 */
void setup() {
  Serial.begin(9600);
  
  pinMode(LED_BUILTIN, OUTPUT);

  // rotary encoder
  pinMode(CLK_PIN, INPUT);
  pinMode(DT_PIN, INPUT);  
  pinMode(SW_PIN, INPUT_PULLUP);

  // 1) Rotary Encoder movement sends interrupt signal
  attachInterrupt(digitalPinToInterrupt(CLK_PIN), isrInterruptPin, FALLING);

  // 2) Task is previously set for a time
  scheduler.scheduleAt(ledOn, TASK_TIME);
}

void loop() {
  scheduler.execute();
}

If this is a misuse as appose to a bug, I apologies in advance. But any help would be much appreciated.

External Interrupt

Pete, good night!

The project I'm developing is a solution that needs to be triggered by external interruption and need to send a die every 30 seconds and go back to deep sleep.

As the solution was before using his library I was able to make use of the external interrupt, but I could not get him to wake up every 30 seconds.

Do you have any way to solve this problem?

Debounce Example

Description

I would find it very helpful if you provided a debounce example and how that works with DeepSleepScheduler. I have tried with my own intuition and have been so far unsuccessful.

Problem

I am trying to fire a single interrupt on pin 2 of my Elegoo Mega2560 using the CLK pin of a rotary encoder. My aim is to wake up my system from sleep with a turn of the rotary encoder, turning on an LCD display eta. When I attempt to implement this myself using DeepSleepScheduler, instead of the expected one interrupt on rotation of the rotary encoder, I get 2 (I also see sometimes 1 and 3, although less frequently).

Steps to Reproduce

I suspect this is due to debounce and my bad implementation of it in your library. Below I have the non-DeepSleepScheduler version which works, followed by non-working versions which use DeepSleepScheduler.

// Interrupt routine runs if CLK goes from HIGH to LOW
void isr ()  {
  delay(4);  // delay for Debouncing
  if (digitalRead(CLK_PIN))
    rotationdirection = digitalRead(DT_PIN);
  else
    rotationdirection = !digitalRead(DT_PIN);
  TurnDetected = true;
}

This is a working example that doesn't use the DeepSleepScheduler library and works correctly - firing only once for each turn of the rotary encoder.

void measure_rotation ()  {
  if (digitalRead(CLK_PIN))
    rotationdirection = digitalRead(DT_PIN);
  else
    rotationdirection = !digitalRead(DT_PIN);
  TurnDetected = true;
  attachInterrupt(CLK_PIN, isr, FALLING);
}

void isr() {
  scheduler.scheduleDelayed(measure_rotation, 4);
  // detach interrupt to prevent executing it multiple
  // times when touching more than once.
  detachInterrupt(digitalPinToInterrupt(CLK_PIN));
}

This is what I assumed the same code might look like using DeepSleepScheduler. Notice the scheduleDelayed with the same 4 milliseconds for debouncing. Increasing the value here made no difference. I also tried delayed re-attaching of the interrupt, and combination of scheduleOnce and scheduleDelayed to make sure only one measure_rotation call was ever in the job queue. However, nearly every time there was a second delayed measure_rotation call.

// Interrupt routine runs if CLK goes from HIGH to LOW
void measure_rotation ()  {
  uint32_t interrupt_time = scheduler.getMillis();

  if (interrupt_time - last_interrupt_time > DEBOUNCE_DELAY) {
    //  delay(4);
    if (digitalRead(CLK_PIN))
      rotationdirection = digitalRead(DT_PIN);
    else
      rotationdirection = !digitalRead(DT_PIN);
    TurnDetected = true;
    Serial.println("Turn detected!");
    check_inputs();
  }

  last_interrupt_time = interrupt_time;
  
}

void isr() {
  scheduler.scheduleOnce(measure_rotation);
//  // detach interrupt to prevent executing it multiple
//  // times when touching more than once.
//  detachInterrupt(digitalPinToInterrupt(CLK_PIN));
}

This example was an attempt inspired by EnableInterrupt's Debounce example. This, unfortunately, did not allow any interrupt calls.

Any advice or guidance would be much appreciated. Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.