I need help with logic relating to time intervals. I have successfully written code that will open and close a door every 12 hours as needed.
In the EVENING, the code checks to see if the door is OPEN and if it is, it will CLOSE the door. If the door is already CLOSED the code does nothing.
In the MORNING, the code checks to see if the door is CLOSED and if it is, it will OPEN the door. If the door is already OPEN the code does nothing.
The code works perfectly on the 12 intervals.
Now that it is summer, I need the door to stay open longer while the sun is out (please don’t suggest sunlight sensor
). I split the 12-hour interval into two intervals: 15 hours for day and 9 hours for night.
When I run the summertime code, the door CLOSES as expected but then it continuously OPENS and CLOSES.
What am I missing and where did I go wrong?
Thanks!!
12-hour code that works perfectly:
/* Coop_Door_Rotation
Opens the coop door in one direction and then waits some time to close it.
*/
#include <Wire.h>
#include <Adafruit_MotorShield.h>
// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Connect one stepper w/xxx steps to the bottom shield
Adafruit_StepperMotor *myMotor = AFMS.getStepper(2048, 1);
unsigned long CurrentTime = 0; // Starts the clock
unsigned long DoorTime = -43170000; // will store last time door moved, -43170000 begins T-30 seconds
unsigned long DoorStatus = 0; // 0 = open, 1 = closed
unsigned long DailyStatus = 0; // 0 = Evening, 1 = Morning
const long DoorInterval = 43200000; // Door interval; 12 hrs or 43,200,000 milliseconds
int LimitPin = 10; // Limit switch
int ButtonPin = 11; // Button
void setup() {
Serial.begin(9600);
Serial.println("Coop_Door_Rotation");
AFMS.begin(); // create with the default frequency 1.6KHz
myMotor->setSpeed(6); // 10 rpm
pinMode(LimitPin, INPUT); // limit as input
digitalWrite(LimitPin, HIGH); // turns on pull-up resistor after input
pinMode(ButtonPin, INPUT); // button as input
digitalWrite(ButtonPin, HIGH); // turns on pull-up resistor after input
}
void loop() {
CurrentTime = millis();
// DAILY Status Updates
//If EVENING and CLOSED do nothing and advance the clock
if (CurrentTime - DoorTime >= DoorInterval && DailyStatus == 0 && DoorStatus == 1)
{
DoorTime += DoorInterval;
DailyStatus = 1; // Next action is in the MORNING
}
//If MORNING and OPEN do nothing and advance the clock
if (CurrentTime - DoorTime >= DoorInterval && DailyStatus == 1 && DoorStatus == 0)
{
DoorTime += DoorInterval;
DailyStatus = 0; // Next action is in the EVENING
}
// CLOSE door if EVENING and OPEN
if (CurrentTime - DoorTime >= DoorInterval && DailyStatus == 0 && DoorStatus == 0) {
{
while (digitalRead(LimitPin) == HIGH) // when pin goes HIGH/Switch is open
myMotor->step(1, BACKWARD, SINGLE); //run the stepper
}
myMotor->release(); //power down the stepper
DoorTime += DoorInterval;
DailyStatus = 1; // Next action is in the MORNING
DoorStatus = 1; // Door is CLOSED
}
// OPEN door if MORNING and CLOSED
if ((CurrentTime - DoorTime >= DoorInterval) && (DailyStatus == 1 || DoorStatus == 1))
{
myMotor->step(10250, FORWARD, SINGLE); //run the stepper
myMotor->release(); //power down the stepper
DoorTime += DoorInterval;
DailyStatus = 0; //Next action is in the EVENING
DoorStatus = 0; // Door is OPEN
}
// CLOSE door if BUTTON is pushed and door is OPEN
if (digitalRead(ButtonPin) == LOW && DoorStatus == 0) {
{
while (digitalRead(LimitPin) == HIGH) // when pin goes HIGH/Switch is open
myMotor->step(1, BACKWARD, SINGLE); //run the stepper
}
myMotor->release(); //power down the stepper
DoorStatus = 1; // Door is CLOSED
}
// OPEN door if BUTTON is pushed and door is CLOSED
if (digitalRead(ButtonPin) == LOW && DoorStatus == 1) {
myMotor->step(10250, FORWARD, SINGLE); //run the stepper
myMotor->release(); //power down the stepper
DoorStatus = 0; // Door is OPEN
}
}
Summertime code that does not work as expected:
/* Coop_Door_Rotation_Summer
Opens the coop door in one direction and then waits some time to close it.
*/
#include <Wire.h>
#include <Adafruit_MotorShield.h>
// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Connect one stepper w/xxx steps to the bottom shield
Adafruit_StepperMotor *myMotor = AFMS.getStepper(2048, 1);
unsigned long CurrentTime = 0; // Starts the clock
unsigned long DoorTime = -53970000; // will store last time door moved, -53970000 begins T-30 seconds
unsigned long DoorStatus = 0; // 0 = open, 1 = closed
unsigned long DailyStatus = 0; // 0 = Evening, 1 = Morning
const long DoorIntervalDay = 54000000; // Door interval; 15 hrs or 54,000,000 milliseconds
const long DoorIntervalNight = 32400000; // Door interval; 9 hrs or 32,400,000 milliseconds
int LimitPin = 10; // Limit switch
int ButtonPin = 11; // Button
void setup() {
Serial.begin(9600);
Serial.println("Coop_Door_Rotation");
AFMS.begin(); // create with the default frequency 1.6KHz
myMotor->setSpeed(6); // 10 rpm
pinMode(LimitPin, INPUT); // limit as input
digitalWrite(LimitPin, HIGH); // turns on pull-up resistor after input
pinMode(ButtonPin, INPUT); // button as input
digitalWrite(ButtonPin, HIGH); // turns on pull-up resistor after input
}
void loop() {
CurrentTime = millis();
// DAILY Status Updates
//If EVENING and CLOSED do nothing and advance the clock
if (CurrentTime - DoorTime >= DoorIntervalDay && DailyStatus == 0 && DoorStatus == 1)
{
DoorTime += DoorIntervalNight;
DailyStatus = 1; // Next action is in the MORNING
}
//If MORNING and OPEN do nothing and advance the clock
if (CurrentTime - DoorTime >= DoorIntervalNight && DailyStatus == 1 && DoorStatus == 0)
{
DoorTime += DoorIntervalDay;
DailyStatus = 0; // Next action is in the EVENING
}
// CLOSE door if EVENING and OPEN
if (CurrentTime - DoorTime >= DoorIntervalDay && DailyStatus == 0 && DoorStatus == 0) {
{
while (digitalRead(LimitPin) == HIGH) // when pin goes HIGH/Switch is open
myMotor->step(1, BACKWARD, SINGLE); //run the stepper
}
myMotor->release(); //power down the stepper
DoorTime += DoorIntervalNight;
DailyStatus = 1; // Next action is in the MORNING
DoorStatus = 1; // Door is CLOSED
}
// OPEN door if MORNING and CLOSED
if ((CurrentTime - DoorTime >= DoorIntervalNight) && (DailyStatus == 1 || DoorStatus == 1))
{
myMotor->step(10250, FORWARD, SINGLE); //run the stepper
myMotor->release(); //power down the stepper
DoorTime += DoorIntervalDay;
DailyStatus = 0; //Next action is in the EVENING
DoorStatus = 0; // Door is OPEN
}
// CLOSE door if BUTTON is pushed and door is OPEN
if (digitalRead(ButtonPin) == LOW && DoorStatus == 0) {
{
while (digitalRead(LimitPin) == HIGH) // when pin goes HIGH/Switch is open
myMotor->step(1, BACKWARD, SINGLE); //run the stepper
}
myMotor->release(); //power down the stepper
DoorStatus = 1; // Door is CLOSED
}
// OPEN door if BUTTON is pushed and door is CLOSED
if (digitalRead(ButtonPin) == LOW && DoorStatus == 1) {
myMotor->step(10250, FORWARD, SINGLE); //run the stepper
myMotor->release(); //power down the stepper
DoorStatus = 0; // Door is OPEN
}
}