How Restore Power to a Motor after a Switch Toggles

For a school project I need to create something that roughly relates to my career choice. I decided to create an automatic chicken coop door that would use a photo resistor to trigger the opening/closing of the chicken coop door. My circuit has a series of relays controlling the polarity and power to the motor that will open/close the coops door. The issue I'm running into is with the switches that read whether or not the door is open/closed. I can't figure out how to tell the Arduino that the door is closed but it's OK to reopen door. What I mean is I only figure out how to tell the Arduino to turn off the motor when the switch closes. I can't figure out how to tell the Arduino it can reopen when it's light again while the switch is closed.

So my question is how do I code the Arduino so it does that?

~I looked into swithCase and it looks like it might solve the problem, but I don't know how to properly execute the code.~

Thanks any help is appreciated!
(I fixed the way I put the code into the question and created a schematic)


V6 has the code with the switch problem

int photocellPin = 0;     
int upswitchReading;
int downswitchReading;
int photocellReading;
int powerDown = 11;  
int powerUp = 9;



void setup(void) {
  pinMode(powerDown, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(powerDown,OUTPUT);

  Serial.begin(9600);   
}
 
void loop(void) {
  digitalWrite(powerDown, HIGH);
  digitalWrite(powerUp, HIGH);

 
  Serial.print("Up Stop reading = ");
  upswitchReading = analogRead(2);
  Serial.print(upswitchReading);     

  Serial.print("Down Stop reading = ");
  downswitchReading = analogRead(4);
  Serial.print(downswitchReading);  
  
  Serial.print("  Photocell reading = ");
  photocellReading = analogRead(photocellPin);  
  Serial.print(photocellReading);     
 

  if (photocellReading < 10) {
    Serial.println(" - Dark");
  } else if (photocellReading < 200) {
    Serial.println(" - Dim");
  } else if (photocellReading < 500) {
    Serial.println(" - Light");
  } else if (photocellReading < 800) {
    Serial.println(" - Bright");
  } else {
    Serial.println(" - Very bright");
}
if (photocellReading < 200) 
{ 
  digitalWrite (6,HIGH); //On Motor 
  digitalWrite (5,LOW);    // Polarity of Motor (if pin 5 is LOW motor polarity is Positive)
}
else 
{
  digitalWrite (6,HIGH); //On Motor 
  digitalWrite (5,HIGH); // Polarity of Motor (if pin 5 if HIGH motor polarity is Negative)
}
if (downswitchReading > 1015)
    digitalWrite (6,LOW); //Off Detection for Motor (Door Going Down)
if (upswitchReading > 1015)
    digitalWrite (6,LOW); //Off Detection for Motor (Door Going Up)
  delay(1000);
}

V7 has what I think a switchCase would look like. ( I get this error though = expected unqualified-id before 'switch')

int photocellPin = 0;     
int upswitchReading;
int downswitchReading;
int photocellReading;
int powerDown = 11;  
int powerUp = 9;

 
void setup(void) {
  pinMode(powerDown, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(powerDown,OUTPUT);

  Serial.begin(9600);   
}
 
void loop(void) {
  digitalWrite(powerDown, HIGH);
  digitalWrite(powerUp, HIGH);
  
  int photocellReading = analogRead(photocellPin / 3);
  int readingReal = map(photocellReading,54,974,0,100);
  
  
  Serial.println("Up Stop reading = ");
  upswitchReading = analogRead(2);
  Serial.println(upswitchReading);     

  Serial.println("Down Stop reading = ");
  downswitchReading = analogRead(4);
  Serial.println(downswitchReading);  
  
  Serial.println("  Photocell reading = ");
  Serial.println(readingReal);     

}
switch (readingReal)
{
  case 0:
  digitalWrite (6,LOW);        //On Motor 
  digitalWrite (5,LOW);         // Polarity of Motor (if pin 5 is LOW motor polarity is Positive)
break;
  case 1:
  digitalWrite (6,HIGH);      //On Motor 
  digitalWrite (5,LOW);         // Polarity of Motor (if pin 5 is LOW motor polarity is Positive)
  if (upswitchReading > 1015)
    digitalWrite (6,LOW);     //Off Detection for Motor (Door Going Up)
break;
  case 2:
  digitalWrite (6,LOW);       //On Motor 
  digitalWrite (5,LOW);         // Polarity of Motor (if pin 5 is LOW motor polarity is Positive)
break;

  case 3: 
  digitalWrite (6,HIGH);      //On Motor 
  digitalWrite (5,LOW);         // Polarity of Motor (if pin 5 is LOW motor polarity is Positive)
  if (upswitchReading > 1015)
    digitalWrite (6,LOW);     //Off Detection for Motor (Door Going Up)
break;
  default:
  digitalWrite (6,LOW);       //On Motor 
  digitalWrite (5,LOW);         // Polarity of Motor (if pin 5 is LOW motor polarity is Positive)
delay(1000);
}

The jpg is a photo of my schematic There's supposed to be a ground connected to the polarity switching relay. I'm also going to add some transistors to control the relays. D11 is being used as a power source, I was told to instead run the switches from the input pin by using the command INPUT_PULLUP.

There is a second schematic that was created by a forum member that may be easier understand. (2017-10 ect.)

The switch() has to be within the loop.

int photocellPin = 0;     
int upswitchReading;
int downswitchReading;
int photocellReading;
int powerDown = 11;  
int powerUp = 9;

 
void setup(void) {
  pinMode(powerDown, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(powerDown,OUTPUT);

  Serial.begin(9600);   
}
 
void loop(void) {
  digitalWrite(powerDown, HIGH);
  digitalWrite(powerUp, HIGH);
  
  int photocellReading = analogRead(photocellPin / 3);
  int readingReal = map(photocellReading,54,974,0,100);
  
  
  Serial.println("Up Stop reading = ");
  upswitchReading = analogRead(2);
  Serial.println(upswitchReading);     

  Serial.println("Down Stop reading = ");
  downswitchReading = analogRead(4);
  Serial.println(downswitchReading);  
  
  Serial.println("  Photocell reading = ");
  Serial.println(readingReal);     
switch (readingReal)
{
  case 0:
  digitalWrite (6,LOW);        //On Motor 
  digitalWrite (5,LOW);         // Polarity of Motor (if pin 5 is LOW motor polarity is Positive)
break;
  case 1:
  digitalWrite (6,HIGH);      //On Motor 
  digitalWrite (5,LOW);         // Polarity of Motor (if pin 5 is LOW motor polarity is Positive)
  if (upswitchReading > 1015)
    digitalWrite (6,LOW);     //Off Detection for Motor (Door Going Up)
break;
  case 2:
  digitalWrite (6,LOW);       //On Motor 
  digitalWrite (5,LOW);         // Polarity of Motor (if pin 5 is LOW motor polarity is Positive)
break;

  case 3: 
  digitalWrite (6,HIGH);      //On Motor 
  digitalWrite (5,LOW);         // Polarity of Motor (if pin 5 is LOW motor polarity is Positive)
  if (upswitchReading > 1015)
    digitalWrite (6,LOW);     //Off Detection for Motor (Door Going Up)
break;
  default:
  digitalWrite (6,LOW);       //On Motor 
  digitalWrite (5,LOW);         // Polarity of Motor (if pin 5 is LOW motor polarity is Positive)
delay(1000);
}

}

HOWEVER
The analog reading (readingReal) returns something between 1 and 100, so how will that work if it is switching 0, 1, 2, 3?
The switch function takes the input variable, in this case readingReal, and compares it to all the

case 1:
doStuff;
case 2: 
doOtherStuff;

etc. and when it matches one it goes through that micro-function.
So that is only comparing readingReal to 0, 1, 2 and 3.

So with the code I have right now I'm only defining 4 functions (0,1,2,3) out of 100?

So should I instead define what a bright reading is (lets say 99/100) and what a dark reading is (lets say 20/100) then create a default that's off for the rest?

How could I implement something like to enable me to turn the motor back on if the door reading switch is still off?

What you want is something like

if(door is closed && realReading > 80){
open the door
}

Would that look like this?

if (downswitchReading > 1015) && (realReading > 80)
 digitalWrite (6,HIGH);      //On Motor 
 digitalWrite (5,LOW);         // Polarity of Motor (if pin 5 is LOW motor polarity is Positive)

or would it be under its own case?

@Watson221, I think you will find it much easier to manage your program if you separate the motor control code from the other code so that you have (say) a motorUp() function and a motorDown() function. And also create a variable that keeps track of the state of the system. Your states might be Shutting, Opening, LockedShut, Morning and Evening (S, O, L, M and E). There could be another variable to record whether the door is Up or Down

Then the control of the motor would depend on the state and the switch values would be used to change the values of the state rather than to control the motor directly.

I am thinking of logic that is something like this snippet of pseudo code

if state == 'L' and it is daylight
  state = 'M'
void motorUp() {
  if state == 'M' and door == 'U'
    // code to make motor move door up
  }
}

...R
Planning and Implementing a Program

Ok cool I'll try this out and see how it goes!

So this is what I have now. I'm not sure how necessary creating a morning/ night state would be or really how to implement that into the the motorUp and motorDown states~

int photocellPin = 0;     
int upswitchReading;
int downswitchReading;
int photocellReading;
int powerDown = 11;  
int powerUp = 9;

 
void setup(void) {
  pinMode(powerDown, INPUT_PULLUP);
  pinMode(powerUp, INPUT_PULLUP);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);


  Serial.begin(9600);   
}
 
void loop(void) {
  
  Serial.println("Up Stop reading = ");
  upswitchReading = digitalRead(powerUp);
  Serial.println(upswitchReading, DEC);
  
  Serial.println("Down Stop reading = ");
  downswitchReading = digitalRead(powerDown);
  Serial.println(downswitchReading, DEC);
  
  Serial.println("  Photocell reading = ");
  photocellReading = analogRead(photocellPin);  
  Serial.println(photocellReading);     
 

  if (photocellReading < 10) {
    Serial.println(" - Dark");
  } else if (photocellReading < 200) {
    Serial.println(" - Dim");
  } else if (photocellReading < 500) {
    Serial.println(" - Light");
  } else if (photocellReading < 800) {
    Serial.println(" - Bright");
  } else {
    Serial.println(" - Very bright"); 
}
    //light();					//Unnecessary? 
    //dark();					//Unnecessary? 
    motorUp();
    motorDown();
    //upSwitch();  				//Unnecessary? 
    //downSwitch();				//Unnecessary?
    systemState();
    
}
/*  
void light(){
(photocellReading > 200)
{

  void Dark (){
(photocellReading < 200)
} */

  void motorUp(){
if (downswitchReading == 0 && photocellReading > 200)			
  digitalWrite (6,HIGH);			      						// On Motor 
  digitalWrite (5,LOW);			  	// Polarity of Motor (if pin 5 is LOW motor polarity is Positive)
if (downswitchReading == 0)
  digitalWrite (6,LOW);			      							// Off Motor 
  digitalWrite (5,LOW);	  		       // Polarity of Motor (if pin 5 is LOW motor polarity is Positive)
}  
   
   void motorDown(){
if (upswitchReading == 0 && photocellReading < 200)
  digitalWrite (6,HIGH);			      						// On Motor 
  digitalWrite (5,HIGH);			    // Polarity of Motor (if pin 5 is HIGH motor polarity is Negative)
if (downswitchReading == 0)
  digitalWrite (6,LOW);			      							// Off Motor 
  digitalWrite (5,LOW);		           // Polarity of Motor (if pin 5 is LOW motor polarity is Positive)
  
}
  
    void systemState(){
if (downswitchReading == 1)
  Serial.print("Door is Down");	//Would make Serial Monitor very cluttered. How necessary is it?
if (upswitchReading == 1)
  Serial.print ("Door is Up");
}
  
  delay(1000);
}

I'm getting this error however~

Error: expected constructor, destructor, or type conversion before '(' token

Thanks so much for your help with this project!

Try something like this:

boolean light = 0;
//then in the loop check this
if(photocellReading > 800){
    light = 1;
}
else
{
light = 0;
}
if(light){
    openDoor();
} else {
closeDoor();
}

Of course that will have to be put into the loop.
note: when you run openDoor() don't check the brightness level, just run the motor till the sensor switch is hit, using a while loop.

Why is it important to have the light state?

Or rather why is it better than including the photocellReading check inside motorUp and motorDown?

And I don't fully understand why I don't need to check the photocellReading for motorUp, because what would trigger the opening of the door in the morning?

Also do you know what caused the error? I checked around and I couldn't find any missing (), ; , or {}. so I'm a little in the dark there.

Watson221:
I'm getting this error however~

Error: expected constructor, destructor, or type conversion before '(' token

What line is the error on?

You will probably find a typo before the ( - maybe on the preceding line.

...R

It's highlighting the code

delay(1000);
}

error: expected constructor, destructor, or type conversion before '(' token

error: expected declaration before '}' token

So I'm kinda in the dark...

Ey! I figured it out!

I had my delay in the wrong place! So I'm still kinda confused about that stuff. I couldn't find a good answer online.

Why is it important to have the light state?

Or rather why is it better than including the photocellReading check inside motorUp and motorDown?

And I don't fully understand why I don't need to check the photocellReading for motorUp, because what would trigger the opening of the door in the morning?

Watson221:
Why is it important to have the light state?

Or rather why is it better than including the photocellReading check inside motorUp and motorDown?

If you get into the habit of thinking about a program as a collection of short single-purpose functions it will make it much easier to develop and to debug. It should be possible to test each function in isolation from the rest of the code and then say "that works, I can forget about it and concentrate on something else"

It also means that the flow of logic through the program is separate from the details of the actions. The concept of "state machine" (Google it) is a rather grand name for a very useful idea - indeed an indispensable idea when your program gets past the trivial stage. The idea is that you have variables to keep track of where you are within the logic of the problem - for example fuel gauge low, visiting filling station, paying for petrol. You can design a program with a series of statements like that and then sit down and implement it as a series of actions (inputs or outputs) that move you from one state to the next.

IMHO at least 75% of the time spent on program development has little or nothing to do with writing code. It is the time needed to think out and decide the series of steps that are necessary to solve the problem. The code can then be implemented in any computer language that is feasible - in the case of the Arduino, of course, there is only C/C++.

...R

Hey so I tried to put that all together and worked partially. For some reason the motorUp(); state doesn't work. I am missing the systemState command right now but as soon as i figure out how to get my motor running in both directions I'll add it!

For the sake of prototyping I've been using TinkerCad (the new circuit.io) to get everything smoothed out before I start the actual build.

That link should let you guys edit pretty much everything.

I really have no clue why motorDown(); works but motorUp(); won't. So that should give y'all some extreme critiquing power.

Also that's my code as of now

int photocellPin = 0;     
int upswitchReading;
int downswitchReading;
int photocellReading;
int powerDown = 11;  
int powerUp = 9;

 
void setup(void) {
  pinMode(powerDown, INPUT_PULLUP);
  pinMode(powerUp, INPUT_PULLUP);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);


  Serial.begin(9600); 
  
  delay(1000);
}
 
void loop(void) {
  
  Serial.println("Up Stop reading = ");
  upswitchReading = digitalRead(powerUp);
  Serial.println(upswitchReading, DEC);
  
  Serial.println("Down Stop reading = ");
  downswitchReading = digitalRead(powerDown);
  Serial.println(downswitchReading, DEC);
  
  Serial.println("  Photocell reading = ");
  photocellReading = analogRead(photocellPin);  
  Serial.println(photocellReading);     
 

  if (photocellReading < 10) {
    Serial.println(" - Dark");
  } else if (photocellReading < 200) {
    Serial.println(" - Dim");
  } else if (photocellReading < 500) {
    Serial.println(" - Light");
  } else if (photocellReading < 800) {
    Serial.println(" - Bright");
  } else {
    Serial.println(" - Very bright"); 
}
    light();        
    motorUp();
    motorDown();
    
}
     void motorDown(){
  digitalWrite (6,HIGH);                        // On Motor 
  digitalWrite (5,HIGH);                      // Polarity of Motor (if pin 5 is HIGH motor polarity is Negative)
if (downswitchReading == 0)
  digitalWrite (6,LOW);                         // Off Motor 
  digitalWrite (5,LOW);                         // Polarity of Motor (if pin 5 is LOW motor polarity is Positive)
  
}
  
   void motorUp(){  
  digitalWrite (6,HIGH);                        // On Motor 
  digitalWrite (5,LOW);                         // Polarity of Motor (if pin 5 is LOW motor polarity is Positive)
if (upswitchReading == 0)
  digitalWrite (6,LOW);                         // Off Motor 
  digitalWrite (5,LOW);                       // Polarity of Motor (if pin 5 is LOW motor polarity is Positive)
}   
       void light(){
boolean light = 0;          
if(photocellReading > 600){
    light = 1;
}
else
{
light = 0;
}
if(light== 1 && downswitchReading == 0){
    motorUp();
} else {
motorDown();
}
       }

Please use the AutoFormat tool to indent your code consistently - it makes it much easier to read and to spot mistakes. I have done it manually for you on this occasion. I have also added a few comments on errors I spotted. I deleted your comments just to make it easier to see mine

int photocellPin = 0;     
int upswitchReading;
int downswitchReading;
int photocellReading;
int powerDown = 11; 
int powerUp = 9;

 
void setup(void) {
    pinMode(powerDown, INPUT_PULLUP);
    pinMode(powerUp, INPUT_PULLUP);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);


    Serial.begin(9600);
 
    delay(1000);
}
 
void loop(void) {
 
    Serial.println("Up Stop reading = ");
    upswitchReading = digitalRead(powerUp);
    Serial.println(upswitchReading, DEC);
 
    Serial.println("Down Stop reading = ");
    downswitchReading = digitalRead(powerDown);
    Serial.println(downswitchReading, DEC);
 
    Serial.println("  Photocell reading = ");
    photocellReading = analogRead(photocellPin); 
    Serial.println(photocellReading);     
 

    if (photocellReading < 10) {
        Serial.println(" - Dark");
    } 
    else if (photocellReading < 200) {
        Serial.println(" - Dim");
    } 
    else if (photocellReading < 500) {
        Serial.println(" - Light");
    } 
    else if (photocellReading < 800) {
        Serial.println(" - Bright");
    } 
    else {
        Serial.println(" - Very bright");
    }
    readSwitches(); // you seem to be missing any code to update the value of downswitchReading
    light();       
    motorUp();
    motorDown();
    
}

void motorDown(){
    digitalWrite (6,HIGH);
    digitalWrite (5,HIGH);
    if (downswitchReading == 0) // this does nothing as it has no {}
    digitalWrite (6,LOW); 
    digitalWrite (5,LOW); 
 
}
 
void motorUp(){ 
    digitalWrite (6,HIGH);
    digitalWrite (5,LOW);
    if (upswitchReading == 0) // this does nothing
    digitalWrite (6,LOW); 
    digitalWrite (5,LOW);                       
}


void light(){
    boolean light = 0;         
    if(photocellReading > 600){
        light = 1;
    }
    else
    {
    light = 0;
    }
        // MOVE the following lines to loop()
    if(light== 1 && downswitchReading == 0){
        motorUp(); 
    } else {
        motorDown(); 
    }
        // down to here
}

...R

Could you explain what you meant by saying

you seem to be missing any code to update the value of downswitchReading

I thought downswitchReading was being updated in the loop because it's being printed.

I'm also getting this error
error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
for
if(light== 1 && downswitchReading == 0){

I'm also getting this error
error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
for
if(light== 1 && downswitchReading == 0){

light() is a function. You can't compare a function to a number.

That is the code right now and im getting a ton of errors.

In function 'void loop()':
52:16: error: 'downSwitch' was not declared in this scope
53:13: error: 'upSwitch' was not declared in this scope
58:14: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
At global scope:
66:10: error: 'boolean downSwitch' redeclared as different kind of symbol
65:6: error: previous declaration of 'void downSwitch()'
67:5: error: expected unqualified-id before 'if'
70:5: error: expected unqualified-id before 'else'
74:1: error: expected declaration before '}' token

int photocellPin = 0;     
int upswitchReading;
int downswitchReading;
int photocellReading;
int powerDown = 11; 
int powerUp = 9;

 
void setup(void) {
    pinMode(powerDown, INPUT_PULLUP);
    pinMode(powerUp, INPUT_PULLUP);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);


    Serial.begin(9600);
 
    delay(1000);
}
 
void loop(void) {
 
    Serial.println("Up Stop reading = ");
    upswitchReading = digitalRead(powerUp);
    Serial.println(upswitchReading, DEC);
 
    Serial.println("Down Stop reading = ");
    downswitchReading = digitalRead(powerDown);
    Serial.println(downswitchReading, DEC);
 
    Serial.println("  Photocell reading = ");
    photocellReading = analogRead(photocellPin); 
    Serial.println(photocellReading);     
 

    if (photocellReading < 10) {
        Serial.println(" - Dark");
    } 
    else if (photocellReading < 200) {
        Serial.println(" - Dim");
    } 
    else if (photocellReading < 500) {
        Serial.println(" - Light");
    } 
    else if (photocellReading < 800) {
        Serial.println(" - Bright");
    } 
    else {
        Serial.println(" - Very bright");
    }
    downSwitch(); // you seem to be missing any code to update the value of downswitchReading
  	upSwitch();
    light();       
    motorUp();
    motorDown();
    
  if(light== 1 && downSwitch == 1){
        motorUp(); 
    } else {
        motorDown(); 
    }
}

void downSwitch();
	boolean downSwitch = 0;         
    if(downswitchReading == 0){
        downSwitch = 1;
    }
    else
    {
    downSwitch = 0;
    }
}

void upSwitch();
	boolean upSwitch = 0;         
    if(upswitchReading == 0){
        upSwitch = 1;
    }
    else
    {
    upSwitch = 0;
    }
}


void motorDown(){
    digitalWrite (6,HIGH);
    digitalWrite (5,HIGH);
  
  if (downSwitch == 1){			 // this does nothing as it has no {}
    digitalWrite (6,LOW); 
    digitalWrite (5,LOW); 
  }
}
 
void motorUp(){ 
    digitalWrite (6,HIGH);
    digitalWrite (5,LOW);
  
  if (upSwitch == 1){				// this does nothing
    digitalWrite (6,LOW); 
    digitalWrite (5,LOW);  
  }
}


void light(){
    boolean light = 0;         
    if(photocellReading > 600){
        light = 1;
    }
    else
    {
    light = 0;
    }

}

In this section I compared a function to a function and still got the error PaulS. So how do I fix the function?

Don't compare a function to a function. Make the function change a global variable and then compare those global variables.