const int buttonForwardPin = 2;
const int buttonBackwardPin = 3;
const int buttonStopPin = 4;
const int endSwitchForwardPin = 5;
const int endSwitchBackwardPin = 6;
const int ledForwardPin = 7;
const int ledBackwardPin = 8;
bool movingForward = false;
bool movingBackward = false;
unsigned long lastSwitchTime = 0;
const unsigned long switchDelay = 5000; // 5 seconds
unsigned long programStartMillis = 0;
const unsigned long programDuration = 10000; // Duration of the movement program
bool winterProgramActive = false;
void setup() {
pinMode(buttonForwardPin, INPUT_PULLUP);
pinMode(buttonBackwardPin, INPUT_PULLUP);
pinMode(buttonStopPin, INPUT_PULLUP);
pinMode(endSwitchForwardPin, INPUT_PULLUP);
pinMode(endSwitchBackwardPin, INPUT_PULLUP);
pinMode(ledForwardPin, OUTPUT);
pinMode(ledBackwardPin, OUTPUT);
digitalWrite(ledForwardPin, LOW);
digitalWrite(ledBackwardPin, LOW);
Wire.begin();
rtc.begin();
bme.begin(0x76); // Check the I2C address of your BME280
// Set the time and date (uncomment to set the RTC initially, then comment out again)
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
void loop() {
DateTime now = rtc.now();
float temperature = bme.readTemperature();
if (isSummer(now)) {
if (now.hour() >= 7 && now.hour() < 20 && now.hour() % 2 == 0 && now.minute() == 0 && now.second() == 0) {
startMovingForward();
programStartMillis = millis();
}
} else if (temperature < -5) {
if (now.minute() == 0 && now.second() == 0 && !winterProgramActive) {
winterProgramActive = true;
runWinterProgram(now);
}
}
if (movingForward && millis() - programStartMillis >= programDuration / 2) {
triggerEndSwitchForward();
}
if (movingBackward && millis() - programStartMillis >= programDuration) {
triggerEndSwitchBackward();
}
// Manual controls
if (digitalRead(buttonForwardPin) == LOW && !movingForward && (millis() - lastSwitchTime >= switchDelay)) {
startMovingForward();
} else if (digitalRead(buttonBackwardPin) == LOW && !movingBackward && (millis() - lastSwitchTime >= switchDelay)) {
startMovingBackward();
} else if (digitalRead(buttonStopPin) == LOW) {
stopMoving();
} else if (digitalRead(endSwitchForwardPin) == LOW && movingForward) {
triggerEndSwitchForward();
} else if (digitalRead(endSwitchBackwardPin) == LOW && movingBackward) {
triggerEndSwitchBackward();
}
}
void startMovingForward() {
movingForward = true;
movingBackward = false;
digitalWrite(ledForwardPin, HIGH);
digitalWrite(ledBackwardPin, LOW);
lastSwitchTime = millis();
}
void startMovingBackward() {
movingBackward = true;
movingForward = false;
digitalWrite(ledBackwardPin, HIGH);
digitalWrite(ledForwardPin, LOW);
lastSwitchTime = millis();
}
void stopMoving() {
movingForward = false;
movingBackward = false;
digitalWrite(ledForwardPin, LOW);
digitalWrite(ledBackwardPin, LOW);
}
void triggerEndSwitchForward() {
stopMoving();
delay(switchDelay);
startMovingBackward();
}
void triggerEndSwitchBackward() {
stopMoving();
delay(switchDelay);
startMovingForward();
}
void runWinterProgram(DateTime now) {
// Check if summer program is due at the same time
if (!(isSummer(now) && now.hour() >= 7 && now.hour() < 20 && now.hour() % 2 == 0)) {
digitalWrite(ledForwardPin, HIGH);
delay(5000);
digitalWrite(ledForwardPin, LOW);
delay(5000);
digitalWrite(ledBackwardPin, HIGH);
delay(5000);
digitalWrite(ledBackwardPin, LOW);
}
}
bool isSummer(DateTime now) {
// Define summer as between 21st June and 21st September
DateTime summerStart(now.year(), 6, 21, 0, 0, 0);
DateTime summerEnd(now.year(), 9, 21, 23, 59, 59);
return now >= summerStart && now <= summerEnd;
}