// https://forum.arduino.cc/t/led-control-lights-for-a-slide-door-status/1114278
// https://wokwi.com/projects/361841946037651457
#include "math.h"
//#include <Dusk2Dawn.h> temporarily not using
#include <EEPROM.h>
#include <Wire.h>
#include <RTClib.h>
//Define what pins are used
const int doorUpSensorPin = 4; // reedswitch door open
const int doorDownSensorPin = 5; // reedswitch door down
const int doorDownMotorPin = 10; // wind motor down
const int doorUpMotorPin = 9; // wind motor up
const int builtInLEDRED = 12; // LED indicating door closed (microswitch on pin 5)
const int builtInLEDGREEN = 8; // LED indicating door OPEN ( microswitch on pin 4)
const int transitledAmber = 7; // LED indicating door in TRANSIT ( neither of the microswitches active)
const byte CloseDoorManual = 3; // Close door by hand
# define dayNightSwitch 11
# define heartBeatPin A3
int buttonstateclose = 0;
int currentMins;
int sunrise;
int sunset;
DateTime now;
# define PRESSED LOW
# define ACTIVE LOW
# define always if (1)
//# define
//Are We Debugging?
const bool debug = true;
//Are We Debugging?
const bool debugX = false;
//Do we need to set/adjust RTC?
const bool setRTC = true;
//Define RTC
RTC_DS1307 rtc;
//define the location / timezone for dusk2dawn (this is yourcity, countrycode 2 digit)
// change yourcity an fill in coordinates and timezone
//Dusk2Dawn Kapellen(51.31483014538207, 4.458376022992936,+1);
// the setup function runs once when you press reset or power the board
void setup() {
//...
setupSimulatedDoor();
//Set the mode the pins will operate in.
pinMode(doorUpMotorPin, OUTPUT);
pinMode(doorDownMotorPin, OUTPUT);
pinMode(CloseDoorManual, INPUT_PULLUP);
//Set Serial for Debugging
if (debug) {
Serial.begin(9600);
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
// rework debug logic... rtc.begin(); already
// //Lets just set the date/time when setRTC = true.
if (setRTC)
{
//write PC date and time while uploading and when setRTC = true
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
//uncomment line 71 to write date and time manually into RTC when line 38 setRTC = true. For testing sunset/sunrise
//rtc.adjust(DateTime(2020, 7, 23, 7, 9, 20));
}
}
//switches setup
pinMode(doorUpSensorPin, INPUT_PULLUP);
pinMode(doorDownSensorPin, INPUT_PULLUP);
pinMode(builtInLEDRED, OUTPUT);
pinMode(builtInLEDGREEN, OUTPUT);
pinMode(transitledAmber,OUTPUT);
pinMode(dayNightSwitch, INPUT_PULLUP);
Serial.println("FinishedSetup");
if (digitalRead(doorUpSensorPin) == ACTIVE)
{
Serial.println("Door is open");
}
if (digitalRead(doorDownSensorPin) == ACTIVE)
{
Serial.println("Door is closed");
}
delay(3000);
}
unsigned long myNow; // get over it.
// the loop function runs over and over again until power down or reset
void loop() {
myNow = millis();
digitalWrite(heartBeatPin, millis() % 500 > 100 ? LOW : HIGH);
runSimulatedDoor();
if (0)
delay(2000);
static unsigned long lastTime;
if (myNow - lastTime < 2000) return;
lastTime = myNow;
if (debug){ Serial.println(); Serial.println("SERVO LOOP");}
//Get the Date/Time from the RTC
now = rtc.now();
//Get Sunrise/Sunset for the current year/month/day as INT's that equate to minutes from midnight that he sunrise/sunset will occur (THE TRUE is passing in Daylight Savings Time!)
sunrise = 6 * 60; // Kapellen.sunrise(now.year(), now.month(), now.day(), true);
sunset = 18 * 60; // Kapellen.sunset(now.year(), now.month(), now.day(), true);
if (debug) {
Serial.println();
Serial.print(now.year());
Serial.print('/');
Serial.print(now.month());
Serial.print('/');
Serial.print(now.day());
Serial.print(" - ");
Serial.print(now.hour());
Serial.print(':');
Serial.print(now.minute());
Serial.print(':');
Serial.print(now.second());
}
buttonstateclose = digitalRead(CloseDoorManual);
if(buttonstateclose == PRESSED){
ManualClose();
}
//Lets get add the "now" Minutes and "now" hours*60 to see how many minutes from midnight we are
currentMins = ((now.hour()) * 60) + (now.minute());
Serial.println(currentMins);
// override RTC and take open or close decision from switch instead
// by stuffing 1:10 AM or 12:30 PM into current minutes
if (debug) {
Serial.print("switch "); Serial.print(digitalRead(dayNightSwitch));
currentMins = digitalRead(dayNightSwitch) ? 70 : 750;
Serial.print(" cur "); Serial.print(currentMins);
}
{
//lets start comparisons, if the door should be up....
//delay of 30 minutes after sunset time to make sure all chickens are inside before closing the door.
if ((sunrise - 45 < currentMins && currentMins < sunset + 20) && ( buttonstateclose != PRESSED)) {
Serial.println("Door state -- must be up");
while ( digitalRead(doorUpSensorPin) == !ACTIVE )
raiseDoor();
}
else {
Serial.println("Door state -- must be down");
while ( digitalRead(doorDownSensorPin) == !ACTIVE )
lowerDoor();
}
}
int DoorUp = digitalRead(doorUpSensorPin);
int DoorDown = digitalRead(doorDownSensorPin);
/* This is just temporary switch debug code*/
if (DoorUp == ACTIVE)
{
Serial.println("Door Full OPEN");
digitalWrite(builtInLEDRED, LOW);
digitalWrite(builtInLEDGREEN, HIGH);
digitalWrite(transitledAmber, LOW);
stopDoor();
}
if (DoorDown == ACTIVE)
{
Serial.println("Door Full CLOSED");
digitalWrite(builtInLEDRED, HIGH);
digitalWrite(builtInLEDGREEN, LOW);
digitalWrite(transitledAmber, LOW);
stopDoor();
}
if (DoorDown == !ACTIVE && DoorUp == !ACTIVE)
{
Serial.println("Door TRANSIT");
digitalWrite(builtInLEDRED, LOW);
digitalWrite(builtInLEDGREEN, LOW);
digitalWrite(transitledAmber, HIGH);
}
}
//Wind the Door Up
void raiseDoor() {
runSimulatedDoor(); // remove when no one blocks
digitalWrite(doorUpMotorPin, HIGH);
digitalWrite(doorDownMotorPin, LOW);
if (debugX) {
Serial.println("Door moving UP");
stopDoor();
}
}
//Wind The Door Down
void lowerDoor() {
runSimulatedDoor(); // remove when no one blocks
digitalWrite(doorDownMotorPin, HIGH);
digitalWrite(doorUpMotorPin, LOW);
if (debugX) {
Serial.println("Door moving DOWN");
stopDoor();
}
}
//Stop the Door
void stopDoor() {
digitalWrite(doorUpMotorPin, LOW);
digitalWrite(doorDownMotorPin, LOW);
if (debugX) {
Serial.println("Door Stop");
}
runSimulatedDoor(); // remove when no one blocks
}
void ManualClose() {
if (digitalRead(doorDownSensorPin) == ACTIVE) return; // already boss
digitalWrite(doorDownMotorPin, HIGH);
digitalWrite(doorUpMotorPin, LOW);
digitalWrite(transitledAmber, HIGH);
while ( digitalRead(doorDownSensorPin) == !ACTIVE) {
runSimulatedDoor(); // remove when no one blocks
}
}
# define sDoorDown A1
# define sDoorUp A2
# define doorX A0
# include <Adafruit_NeoPixel.h>
# define PIN 6 // the pin
# define NPIXELS 15 // number of LEDs on strip
Adafruit_NeoPixel doorBar(NPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setupSimulatedDoor()
{
pinMode(sDoorDown, OUTPUT);
pinMode(sDoorUp, OUTPUT);
doorBar.begin();
doorBar.setPixelColor(2, 0xff0000);
doorBar.show();
}
void runSimulatedDoorNew()
{
static int lPosition = 7;
int doorPosition = analogRead(A0);
// delay(20);
digitalWrite(sDoorDown, lPosition <= 1 ? LOW : HIGH); // active low
digitalWrite(sDoorUp, lPosition >= 13 ? LOW : HIGH);
static unsigned long lastTime;
if (millis() - lastTime < 100) return;
lastTime = millis();
static unsigned char dir;
doorBar.clear();
doorBar.setPixelColor(lPosition, 0xff0000);
doorBar.show();
if (0) {
lPosition += dir ? -1 : 1;
if ((lPosition == -1) || (lPosition == NPIXELS)) dir = !dir;
}
else {
if (digitalRead(doorDownMotorPin)) lPosition--;
if (digitalRead(doorUpMotorPin)) lPosition++;
}
if (lPosition == -1) lPosition = 0;
if (lPosition == NPIXELS) lPosition = NPIXELS - 1;
}
void runSimulatedDoor()
{
int doorPosition = analogRead(A0);
// delay(20);
digitalWrite(sDoorDown, doorPosition < 100 ? LOW : HIGH); // active low
digitalWrite(sDoorUp, doorPosition > 923 ? LOW : HIGH);
static unsigned long lastTime;
if (millis() - lastTime < 100) return;
lastTime = millis();
static int lPosition = 7;
static unsigned char dir;
doorBar.clear();
doorBar.setPixelColor(lPosition, 0xff0000);
doorBar.show();
if (0) {
lPosition += dir ? -1 : 1;
if ((lPosition == -1) || (lPosition == NPIXELS)) dir = !dir;
}
else {
if (digitalRead(doorDownMotorPin)) lPosition--;
if (digitalRead(doorUpMotorPin)) lPosition++;
}
if (lPosition == -1) lPosition = 0;
if (lPosition == NPIXELS) lPosition = NPIXELS - 1;
}
/*
void xprintf(const char *format, ...)
{
char buffer[256];
va_list args;
va_start(args, format);
vsprintf(buffer, format, args);
va_end(args);
Serial.print(buffer);
}
*/
/*
# define sDoorDown A1
# define sDoorUp A2
# define doorX A0
# include <Adafruit_NeoPixel.h>
# define PIN 6 // the pin
# define NPIXELS 15 // number of LEDs on strip
Adafruit_NeoPixel doorBar(NPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setupSimulatedDoor()
{
pinMode(sDoorDown, OUTPUT);
pinMode(sDoorUp, OUTPUT);
doorBar.begin();
doorBar.setPixelColor(2, 0xff0000);
delay(777);
}
void runSimulatedDoor0()
{
int doorPosition = analogRead(A0);
// delay(20);
digitalWrite(doorDownMotorPin, HIGH);
// delay(20);
digitalWrite(sDoorDown, doorPosition < 100 ? LOW : HIGH); // active low
digitalWrite(sDoorUp, doorPosition > 923 ? LOW : HIGH);
static unsigned long lastTime;
if (myNow - lastTime < 100) return;
lastTime = myNow;
// auto door time slot here
}
void runSimulatedDoor()
{
static int doorPosition;
static unsigned long lastTime;
if (myNow - lastTime < 222) return;
lastTime = myNow;
if (digitalRead(doorDownMotorPin)) doorPosition++;
if (digitalRead(doorUpMotorPin)) doorPosition--;
if (doorPosition < 0) doorPosition = 0;
while (doorPosition >= NPIXELS) doorPosition = 0;
digitalWrite(sDoorDown, doorPosition <= 1); // active low
digitalWrite(sDoorUp, doorPosition >= NPIXELS - 2);
doorBar.clear();
doorBar.setPixelColor(doorPosition, 0xff0000);
doorBar.show();
}
*/DAY/NIGHT
MANUAL
_CLOSE