Hi All!
Yes, another beginner with another (hopefully easy to fix) problem...
So what am I trying to do? Well, I want to have my window blinds set up to open in close depending on the temperature inside, and brightness outside. For example, if it's cold inside, but sunny outside - open the blinds. But if it's too hot inside already, even though it's sunny, close the blinds.
Luckily for me, other people have wanted to do the same thing. So, I've managed to dissect parts of nicely written programs, and scramble them together to make a semi-functioning sketch. I say "semi-functioning" because now I want to add in an "override button"(everything else works as of now). Say, if I wanted to change my clothing during the day and wanted to close the blinds, or I wanted to open them at night to watch a meteor shower. This button is my stumbling block.
I want there to be only one button that basically moves my stepper motor the opposite of the current state of the blinds (eg. if blinds are open, closed them). I then want the program to wait until the same button is pressed a second time to engage the motor to step to the open position, before returning to the main loop to continue taking readings from the sensors.
Here's what I have so far - I am fairly new at this, so if there's anything that is obviously bad coding technique, I wouldn't mind hearing about it too. Any help is greatly appreciated!
#include <AccelStepper.h>
AccelStepper motor1(1,3,4); //step pin=3, dir pin=4
//start defines//
#define LIGHT_THRESHOLD 650 //This is where you set the ligth intensity to set the blinds im motion
#define TEMP_THRESHOLD 24 //This is where you set the temperature to set the blinds in motion
#define LIGHT_PIN 0 //set LDR as pin A0
#define TEMP_PIN 5 //set tmp36 thermometer as A5
#define ONBOARD_LED 13
#define TOGGLE_BUTTON 7
//end defines//
//variables//
int pos = 500000; //This is where you set the number of steps your stepper must move to reach the open position
int enable_pin = 8; //pin that toggles power on and off to driver board
int curtain_state = 1;
int light_status = 0;
const int button_pin = 7;
int buttonState = 0;
int lastButtonState = 0;
int buttonPresses = 0;
int main_button_state;
boolean daylight = true;
boolean warm = false;
//smoothing variables
const int numReadings = 10; //change this to adjust the number of values in your sample you want to average
int readings[numReadings]; // the readings from the analog input
int index = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average
//end variables//
/////////////////////////////////////////////////////////////////////////////////////////////
//start curtain subroutine - this is the main subroutine that controls the movement of the curtains
void Curtain(boolean curtain_state) {
digitalWrite(ONBOARD_LED, curtain_state ? HIGH : LOW);
if (curtain_state) {
digitalWrite(enable_pin, LOW);
Serial.println("Opening curtain...");
motor1.move(pos);
while (motor1.distanceToGo()!=0)
motor1.run();
digitalWrite(enable_pin, HIGH);
}else{
digitalWrite(enable_pin, LOW);
Serial.println("Closing curtain...");
motor1.move(-pos);
while (motor1.distanceToGo()!=0)
motor1.run();
digitalWrite(enable_pin, HIGH);
}
}
//end curtain subroutine//
//start button_press subroutine//
void button_press_darken(){
buttonState=digitalRead(TOGGLE_BUTTON);
if (buttonState != lastButtonState){
if (buttonState ==HIGH){
digitalWrite(enable_pin, LOW);
Serial.println("Manual Open");
motor1.move(-pos);
while (motor1.distanceToGo()!=0)
motor1.run();
digitalWrite(enable_pin, HIGH);
}
Serial.println("Open");
}
lastButtonState = buttonState;
if (buttonState==LOW){
digitalWrite(enable_pin, LOW);
Serial.println("Manual Close");
motor1.move(pos);
while (motor1.distanceToGo()!=0)
motor1.run();
digitalWrite(enable_pin, HIGH);
lastButtonState = buttonState;
}
}
void button_press_lighten(){
buttonState=digitalRead(TOGGLE_BUTTON);
if (buttonState != lastButtonState){
if (buttonState ==HIGH){
digitalWrite(enable_pin, LOW);
Serial.println("Manual Close");
motor1.move(-pos);
while (motor1.distanceToGo()!=0)
motor1.run();
digitalWrite(enable_pin, HIGH);
}
Serial.println("Closed");
}
lastButtonState = buttonState;
if (buttonState==LOW){
digitalWrite(enable_pin, LOW);
Serial.println("Manual Open");
motor1.move(pos);
while (motor1.distanceToGo()!=0)
motor1.run();
digitalWrite(enable_pin, HIGH);
lastButtonState = buttonState;
}
}
//end button subroutine//
//START:setup//
void setup() {
for (int thisReading = 0; thisReading < numReadings; thisReading++) //this is for smoothing temp
readings[thisReading] = 0; //this is for smoothing temp
pinMode (button_pin, INPUT);
//pinMode (TOGGLE_BUTTON, INPUT); //PIN 7 defined as an input
pinMode (enable_pin, OUTPUT); //defines enable_pin as an output
analogReference(INTERNAL); //sets vref to internal 1.1v
motor1.setMaxSpeed(10000); //set top limit speed of motor
motor1.setSpeed(9500); //set max speed you want it to run
motor1.setAcceleration(2000); //set acceleration of motor
Serial.begin(9600);
Serial.println("Setting up Curtain Automation...");
}
//END:setup//
//START:main_loop//
void loop(){
//temp smoothing loop
total= total - readings[index]; //subtract the last reading
readings[index] = analogRead(TEMP_PIN); //read the sensor
total= total + readings[index]; //add the reading to the total
index = index + 1; //advance to nex position in array
if (index >= numReadings) //if at end if array..
index = 0; //...wrap it
average = total / numReadings; //calculate average
//temp smoothing loop
digitalWrite(enable_pin, HIGH); //turns power off to driverboard to conserve power
light_status = analogRead(LIGHT_PIN); //check LDR and print to Serial Monitor
delay(2000);
Serial.print("Photocell value = ");
Serial.println(light_status);
Serial.println("");
float temp_Celsius = float(average) *110/1024; //check thermometer and print to Serial Monitor
float temp_Fahrenheit = (temp_Celsius * 9 / 5) + 32;
Serial.print("Temperature value (Celsius) = ");
Serial.println(temp_Celsius,1);
Serial.print("Temperature value (Fahrenheit) = ");
Serial.println(temp_Fahrenheit,1);
Serial.println("");
if (light_status > LIGHT_THRESHOLD)
daylight = true;
else
daylight = false;
if (temp_Celsius > TEMP_THRESHOLD)
warm = true;
else
warm = false;
switch (curtain_state)
{
case 0:
if (daylight && !warm)
// open curtain
{
curtain_state = 1;
Curtain(curtain_state);
}
main_button_state =digitalRead(TOGGLE_BUTTON);
if (main_button_state ==HIGH){
button_press_darken();
}
break;
case 1:
if (!daylight || warm)
// close curtain
{
curtain_state = 0;
Curtain(curtain_state);
}
main_button_state =digitalRead(TOGGLE_BUTTON);
if (main_button_state ==HIGH){
button_press_lighten();
}
break;
}
}
//END:main_loop