/*
Project: Roof Controller
Description: Moves a retractable roof depending on rain
Includes an emergency stop button
Creation date: 12/15/23
Author: AnonEngineering
rafaaryas - Discord | Arduino | coding help 12/13/23 at 7:53 AM
So this is for my school project,
I'm trying to make a mini house automatic roof system
that closes when there's rain detected and opens back
when the rain is over
License: https://en.wikipedia.org/wiki/Beerware
*/
#include <AccelStepper.h>
#define MotorInterfaceType 1 // AccelStepper::DRIVER
// roof positions
const int OPEN_POS = 500;
const int CLOSED_POS = -500;
// pins
const int SENSOR_PIN = A0;
const int RUN_BTN_PIN = 2;
const int STOP_BTN_PIN = 3;
const int DIR_PIN = 4;
const int STEP_PIN = 5;
const int LED_PIN = 13;
// globals
volatile bool isEmergency = false;
bool isInitialized = false;
bool isNotified = false;
bool oldIsRaining = true;
AccelStepper stepper(MotorInterfaceType, STEP_PIN, DIR_PIN);
// interrupt routine
void eStop() {
if (stepper.isRunning()) {
isEmergency = true;
digitalWrite(LED_PIN, isEmergency);
}
}
void moveRoof(int position) {
stepper.moveTo(position);
while (stepper.isRunning()) {
if (isEmergency) {
if (!isNotified) Serial.println("Emergency stop!");
isNotified = true;
break;
}
stepper.run();
}
}
void notify() {
// notify if motion is complete
if (stepper.currentPosition() == CLOSED_POS && isNotified == false) {
Serial.println("Roof closed\n");
isNotified = true;
isInitialized = true;
}
if (stepper.currentPosition() == OPEN_POS && isNotified == false) {
Serial.println("Roof open\n");
isNotified = true;
}
}
void setup() {
Serial.begin(9600);
pinMode(RUN_BTN_PIN, INPUT_PULLUP);
pinMode(STOP_BTN_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
attachInterrupt(digitalPinToInterrupt(STOP_BTN_PIN), eStop, FALLING);
// Change these to suit your stepper
stepper.setMaxSpeed(100);
stepper.setAcceleration(20);
// Assuming the worst, initialize to closed
Serial.println("Initializing, moving to closed.");
moveRoof(CLOSED_POS);
notify();
}
void loop() {
bool isRaining = false;
// read run button (clear isEmergency)
int run = digitalRead(RUN_BTN_PIN);
if (!run && isEmergency) {
isEmergency = false;
isNotified = false;
digitalWrite(LED_PIN, LOW);
Serial.println("Problem solved, back to run mode.");
}
if (isInitialized) {
// read sensor
int sensorReading = analogRead(SENSOR_PIN);
// determine "raining" or "not raining" (pot CCW = wet, CW = dry)
(sensorReading < 512) ? isRaining = true : isRaining = false;
// print current condition if current condition has changed
if (isRaining != oldIsRaining && !isEmergency) {
oldIsRaining = isRaining;
Serial.println(isRaining ? "Raining, moving CCW" : "Not raining, moving CW");
isNotified = false;
}
// move stepper based on current condition
if (isRaining) {
moveRoof(CLOSED_POS);
} else {
moveRoof(OPEN_POS);
}
notify();
} else {
moveRoof(CLOSED_POS);
notify();
}
}
<< Wet - Dry>>
E-Stop
Run