So I'm working on a project to open and close the curtains in my room when the sun rises or sets. I can get the motor to activate once the voltage from a PV cell exceeds a certain voltage (as it would as the sun rises). However, I can't figure out how to get it to stop looping once the voltage exceeds that critical value.
Basically, I need the motor to turn for a period of time once the board detects that the sun has risen, then stop and just wait until the voltage is below a certain voltage before it turns again to close the curtain.
I've tried if/else, do while, but I just can't figure out how to get those to do what I need to do.
cdcoursey:
So I'm working on a project to open and close the curtains in my room when the sun rises or sets. I can get the motor to activate once the voltage from a PV cell exceeds a certain voltage (as it would as the sun rises). However, I can't figure out how to get it to stop looping once the voltage exceeds that critical value.
Basically, I need the motor to turn for a period of time once the board detects that the sun has risen, then stop and just wait until the voltage is below a certain voltage before it turns again to close the curtain.
I've tried if/else, do while, but I just can't figure out how to get those to do what I need to do.
Use a 'flag' variable. Eg. int flag = 0;
When you want the motor to move for the first time, then just move it as usual.....using this if statement...
if (flag == 0){
//move motor;
flag = 1;
}
You can also use other flags, or could use other values for this same flag (eg. flag = 2, flag = 3 etc) - for keeping track of what state your system is in. Eg.... if another sensor senses that light levels are really low enough, then set some flag so that your system can do something.
Maybe you have heard of it already .... this following word "hysteresis". If not, then read up on this one, as it can stop erratic on/off 'chatter'. Eg.... close curtain when the voltage level is greater or equal to 1.5 volt. Open curtain when the voltage level less than or equal to 0.8 volt. Basically....don't make the open and closing voltage equal to the same value.
Flags are good but I would set one to say if curtains are open or not. Then it's all fairly logical.
If light is above dawn threshold and curtains are not open, open curtains. If curtains are open, do nothing.
If light is below dusk threshold and curtains are open, close curtains. If curtains are not open, do nothing.
Steve
Thanks so much! Flags solved this issue for me. I'll post my code in case anybody stumbles across this thread.
I'm using the built in LED in place of my motor as that's much easier for testing.
int analogPin = 0;
int sun = 0; // Sun up = 1, Sun down = 2
int curtain = 1; // 1 = closed, 2 = open
void setup() {
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
// read the raw data coming in on analog pin 0:
int lightLevel = analogRead(analogPin);
// Convert the raw data value (0 - 1023) to voltage (0.0V - 5.0V):
float voltage = lightLevel * (5.0 / 1024.0);
// write the voltage value to the serial monitor:
Serial.println(voltage);
if (voltage > 0.10){
sun = 1;
}
if (voltage < 0.14) {
sun = 2;
}
if (sun == 1 && curtain == 1) {
digitalWrite(LED_BUILTIN, HIGH);
delay(10000);
curtain = 2;
}
if (sun == 1 && curtain == 2) {
digitalWrite(LED_BUILTIN, LOW);
}
if (sun == 2 && curtain == 2) {
digitalWrite (LED_BUILTIN, HIGH);
delay(10000);
curtain = 1;
}
if (sun == 2 && curtain == 1) {
digitalWrite(LED_BUILTIN, LOW);
}
}