Alight, I'm getting closer to a working sleep plan for my automated blind control. I was able to find a basic sleep sketch that I modified to work off a counter. When the counter reaches a certain value, the arduino goes to sleep. I can then wake the arduino with an external interrupt (momentary button) and the counter starts all over again. Ultimately, I will replace the momentary switch with a PIR sensor that wakes the arduino up if someone comes into the room and then puts it back to sleep after a period of detecting no motion. Below is the simple code that works as intended.
#include <avr/sleep.h>
// hardware interrupt
#define INT1 1
#define INT1_PIN 3
#define BLINK_PIN 13
int buttonPushed;
int sleepCounter = 0;
const int sleepDelay = 15;
void doWhileAwake()
{
digitalWrite(BLINK_PIN, HIGH);
delay(1000);
digitalWrite(BLINK_PIN, LOW);
delay(1000);
}
void prepareToSleep()
{
digitalWrite(BLINK_PIN, LOW);
}
void wake()
{
buttonPushed=0;
}
void toggle()
{
detachInterrupt(1);
if (buttonPushed ==0)
{
buttonPushed=1;
}
}
void sleep()
{
prepareToSleep();
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
attachInterrupt(INT1,wake,LOW);
sleep_mode(); // sleeping
}
void setup()
{
pinMode(INT1_PIN, INPUT);
attachInterrupt(INT1,toggle,LOW);
buttonPushed=1; // set to 1 = sleep after reset. 0 = run loop after reset
pinMode(BLINK_PIN, OUTPUT);
}
void loop()
{
if (sleepCounter >= sleepDelay)
{
sleepCounter = 0;
sleep();
}
else
{
attachInterrupt(INT1,toggle,LOW);
}
sleepCounter++;
doWhileAwake();
}
However, when I incorporate the above code into my automated blind controller sketch, the arduino immediately goes to sleep. Does anyone see something that might be causing it to skip directly to sleep mode?
#include <VarSpeedServo.h>
#include <IRremote.h>
#include <avr/sleep.h>
//CONFIGURATION
const int BLINK_PIN = 13;
const int PIN_LED = 10;
const int PIN_IR = 11; //Input for Seagate Media Player Remote
const int servoPin = 9; //Input pin for servo
IRrecv irrecv(PIN_IR);
decode_results results;
//hardware interrupt pins
#define INT0 0
#define INT0_PIN 2
#define INT1 1
#define INT1_PIN 3
//CONVERT IR REMOTE VALUES TO COMMON BUTTON TERMS
#define POWER 0x61471CE3
#define HOME 0x61479C63
#define UP_ARROW 0x614702FD
#define DOWN_ARROW 0x6147827D
#define LEFT_ARROW 0x6147E01F
#define RIGHT_ARROW 0x6147609F
#define OK 0x6147708F
#define BACK 0x6147D827
#define MENU 0x614758A7
#define INFO 0x6147E21D
#define REWIND 0x61474AB5
#define PLAY/PAUSE 0x6147F20D
#define FFWD 0x61478A75
#define STOP 0x61472AD5
#define PREVIOUS 0x61478C73
#define NEXT 0x61470CF3
#define MUTE 0x61479A65
#define UP_ZOOM 0x6147AC53
#define DOWN_ZOOM 0x614710EF
#define UP_VOLUME 0x61474CB3
#define DOWN_VOLUME 0x6147CC33
//VARIABLE FOR THE FUTABA S3003 CLONE SERVO ANGLE & SPEED OF ROTATION
int initial_ms = 2350; //On start millis angle for the servo
const int max_ms = 2350; //Millis angle for "Fully Closed - Down"
const int upA_ms = 1900; //Millis angle for "Partially Closed - Down"
const int mod_upA_ms = 1850; //Modified millis angle for clockwise rotation to "Partially Closed - Down"
const int mid_ms = 1468; //Millis angle for "Fully Open"
const int mod_mid_ms = 1420; //Modified millis angle for clockwsie rotation to "Fully Open"
const int downA_ms = 1050; //Millis angle for "Partially Closed - Up"
const int mod_downA_ms = 975; //Modified millis angle for clockwise rotation to "Partially Closed - Down"
const int min_ms = 600; //Variable for "Fully Closed - Up"
const int sleepDelay = 15;
int dest = 0; //Variable for Servo destination depending on IR Remote button pushed
const int spd = 20; //Variable to control the speed of the servo moving between positions; 5 is slow
VarSpeedServo myservo; //Create servo object to control a servo
int pos = 0; //Keep track of servo angle so we don't send signal to the servo without reason
int prevPos = 0; //Keeps history of prior state
int buttonPushed;
int sleepCounter = 0;
void doWhileAwake()
{
if (irrecv.decode(&results))
{
irrecv.resume();
if (results.value == DOWN_VOLUME)
{
sleepCounter = 0;
if (initial_ms == min_ms)
{
dest=mod_downA_ms;
initial_ms=downA_ms;
pos=1;
}
else if (initial_ms == downA_ms)
{
dest=mod_mid_ms;
initial_ms=mid_ms;
pos=2;
}
else if (initial_ms == mid_ms)
{
dest=mod_upA_ms;
initial_ms=upA_ms;
pos=3;
}
else if (initial_ms == upA_ms)
{
dest=max_ms;
initial_ms=max_ms;
pos=4;
}
}
if (results.value == UP_VOLUME)
{
sleepCounter = 0;
if (initial_ms == max_ms)
{
dest=upA_ms;
initial_ms=upA_ms;
pos=5;
}
else if (initial_ms == upA_ms)
{
dest=mid_ms;
initial_ms=mid_ms;
pos=6;
}
else if (initial_ms == mid_ms)
{
dest=downA_ms;
initial_ms=downA_ms;
pos=7;
}
else if (initial_ms == downA_ms)
{
dest=min_ms;
initial_ms=min_ms;
pos=8;
}
}
//IF the IR remote command is different from last sample then execute servo controls
if (pos != prevPos)
{
myservo.attach(servoPin); //Connect to servo
//Move servo to new position
//digitalWrite(ledColor, HIGH);
myservo.write(dest, spd, true);
//digitalWrite(ledColor, LOW);
myservo.detach(); //Detach servo to keep it from humming on strain
}
prevPos = pos; //Remember state so we can compare it again next round
}
}
void prepareToSleep()
{
// When the sleepCounter reaches the delay time
// do some prep before sleeping to get in the
// desired state
// digitalWrite(BLINK_PIN, LOW);
}
void wake()
{
// This is the callback that runs when the
// chip is waking up.
buttonPushed=0;
// Can set variables and check stuff. Cannot do fancy stuff.
// Program flow returns to line after 'sleep_mode()' in sleep.
// No code is required here.
}
void toggle()
{
// set a flag telling system to sleep on next loop iteration.
// this is the normal running state callback triggered by the
// switch.
detachInterrupt(1); // this seems to be allowed in callback
if (buttonPushed ==0) // just in case, ignore switch if already
{
buttonPushed=1; // doing it
}
}
void sleep()
{
prepareToSleep(); //application specific
// YOU ARE GETTING SLEEPY.....
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
attachInterrupt(INT1,wake,LOW); // rebind interrupt
sleep_mode(); // sleeping
// program returns here, after 'wake' callback
// now back to loop
}
void setup()
{
Serial.begin(9600);
pinMode(INT1_PIN, INPUT); // Set switch pin to input
attachInterrupt(INT1,toggle,LOW); // To limit current
buttonPushed=1; // Set to 1 = sleep after reset; 0 = run loop after rest
//pinMode(BLINK_PIN, OUTPUT);
myservo.attach(servoPin);
myservo.write(initial_ms, spd, true);
//pinMode(PIN_LED, OUTPUT);
//pinMode(PIN_IR, INPUT);
irrecv.enableIRIn();
}
void loop()
{
if (sleepCounter >= sleepDelay)
{
sleepCounter = 0;
sleep();
}
else
{
// reset button events to sleep
attachInterrupt(INT1,toggle,LOW);
}
sleepCounter++;
//Serial.println(sleepCounter);
// Control Blinds
doWhileAwake();
}
Thanks, Sean