Help with sensors

I am having a hard time trying to get my code to continue after my while loop. What I am doing is I have a photosensor and a motion sensor. I have it so when it is dark and detects motion my servo will run. This in life is going to close a gate. Once the gate is closed I don't want it to open again until my photosensor detects daylight. Which would make my servo run to get my gate back up. I put a while loop in my code and it makes it so even if there is still motion my servo doesn't run. Although it no longer reads any more of my code after the while loop so it doesn't count. I have the code below.

#define sensorPin 4
#define pirSensor 2
#define servo 6
unsigned int lightLevel = 0, high=0, low=1023;// Putting perameters on my light sensor
unsigned int sensorVal1 = 0;
unsigned int sensorVal = 0;
#include <Servo.h>// Library for servo
#include <LiquidCrystal.h>// Library for lcd moniter
Servo myServo;//creating my servo
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);//Which pins my lcd screen is wired to
int count=0;
int prevsensorVal=0;
int mspeed=1500;//This sets variable for the speed of my servo
void setup(){
  Serial.begin(9600);
  pinMode(pirSensor, INPUT);
  pinMode(servo, OUTPUT);
  myServo.attach(6);//attaches the servo on pin 6 to my servo
  lcd.begin(16,2);//the number of columns and rows in my lcd screen
  lcd.setCursor(0,0);//Where my count number is located in my screen
  lcd.print("Times Gates Opended");
}

void loop() {
 sensorVal1 = digitalRead(4);//reading the input from the photosensor
 sensorVal = digitalRead(pirSensor);//reading the input from the motion sensor
 if(sensorVal1 == LOW&&sensorVal==HIGH){ //If it's dark out and if the motion sensor is high then
     Serial.println("Motion Detected");// Say motion is detected
     digitalWrite(servo, HIGH);// Allowing power to my servo
     mspeed=900;// This is how fast my servo will go
     myServo.writeMicroseconds(mspeed);//Makes my servo turn counter clockwise to put the gate down
     delay(1000);//This is the amount of time it takes for my gate to be completely lowered 
     mspeed=1500;//This is the speed that stops my servo
      myServo.writeMicroseconds(mspeed);//This stops my servo from running
      //while(sensorVal1==LOW){
     //digitalRead(4);//This is so once my gate closes for the night it remains closed tell its light again
   //} 
       
 }else{
      Serial.println("No Motion Detected");
   }
      
   
   if(sensorVal != prevsensorVal){
   if(sensorVal1==LOW&&sensorVal==HIGH){
     count=count+1;
     lcd.setCursor(8,1);
     lcd.print(count);
   }
   }
   prevsensorVal=sensorVal;
   
   }
void manualTune()
{
 lightLevel = map(lightLevel, 1023, 0, 0, 255);
}

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

epivik:
I am having a hard time trying to get my code to continue after my while loop.

That's because you didn't write your while loop so that the value of sensorVal1 can ever change. Try this instead:

while(sensorVal1==LOW){
  sensorVal1 = digitalRead(4);//This is so once my gate closes for the night it remains closed tell its light again
}

When you post code or error/warning messages please use code tags(the </> button on the toolbar). You should always use Tools > Auto Format because it will make it easier for you to spot bugs and make it easier for us to read your code.

You also forgot to set the pinMode of your sensor pin.

One thing that is really sloppy about your code is you define the pins:

epivik:

#define sensorPin 4

#define pirSensor 2
#define servo 6

But then you only randomly use those definitions:

epivik:

   pinMode(servo, OUTPUT);

myServo.attach(6);//attaches the servo on pin 6 to my servo

epivik:

  sensorVal1 = digitalRead(4);//reading the input from the photosensor

sensorVal = digitalRead(pirSensor);//reading the input from the motion sensor

Pert what you said to do with my while loop worked. So I added more code so once it detects light my servo will run once again and bring my gate back up. The problem I have know is if its dark and it doesn't detect motion my servo runs continuously until motion is detected. Once motion is detected then the servo stops. I want this the exact opposite so once it is dark and it detects motion is runs once. It is good though that once it detects motion it doesn't do anything until its light then my servo runs once to lift my gate. Once that is done it doesn't do anything tell its dark again where I have my problem. Thanks for the initial help. Here is my code.

//Final Project
#define sensorPin 4
#define pirSensor 2
#define servo 6
unsigned int lightLevel = 0, high=0, low=1023;// Putting perameters on my light sensor
unsigned int sensorVal1 = 0;
unsigned int sensorVal = 0;
#include <Servo.h>// Library for servo
#include <LiquidCrystal.h>// Library for lcd moniter
Servo myServo;//creating my servo
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);//Which pins my lcd screen is wired to
int count=0;
int prevsensorVal=0;
int mspeed=1500;//This sets variable for the speed of my servo
void setup(){
  Serial.begin(9600);
  pinMode(pirSensor, INPUT);
  pinMode(servo, OUTPUT);
  myServo.attach(6);//attaches the servo on pin 6 to my servo
  lcd.begin(16,2);//the number of columns and rows in my lcd screen
  lcd.setCursor(0,0);//Where my count number is located in my screen
  lcd.print("Times Gates Opended");
}

void loop() {
 sensorVal1 = digitalRead(4);//reading the input from the photosensor
 sensorVal = digitalRead(pirSensor);//reading the input from the motion sensor
 if(sensorVal1 == LOW&&sensorVal==HIGH){ //If it's dark out and if the motion sensor is high then
     Serial.println("Motion Detected");// Say motion is detected
     digitalWrite(servo, HIGH);// Allowing power to my servo
     mspeed=900;// This is how fast my servo will go
     myServo.writeMicroseconds(mspeed);//Makes my servo turn counter clockwise to put the gate down
     delay(1000);//This is the amount of time it takes for my gate to be completely lowered 
     mspeed=1500;//This is the speed that stops my servo
      myServo.writeMicroseconds(mspeed);//This stops my servo from running
      while(sensorVal1==LOW){
     sensorVal1=digitalRead(4);//This is so once my gate closes for the night it remains closed tell its light again
   } 
       
 }else{
   digitalWrite(servo,HIGH);//Allowing power to my servo
   mspeed=900;//This is how fast my servo will go
   myServo.writeMicroseconds(mspeed);//Makes my servo turn counter closkwise once again to pull the gate back up
   delay(1000);//This is the amount of time it takes for my gate to be completely raised
   mspeed=1500;//This is the speed that stops my servo
   myServo.writeMicroseconds(mspeed);//This stops my servo from running
   while(sensorVal1==HIGH){
     sensorVal1=digitalRead(4);//This is so once my gate opens for the day it remains open tell its dark again
   }
      Serial.println("No Motion Detected");
   }
      
   
   if(sensorVal != prevsensorVal){
   if(sensorVal1==LOW&&sensorVal==HIGH){
     count=count+1;
     lcd.setCursor(8,1);
     lcd.print(count);
   }
   }
   prevsensorVal=sensorVal;
   
   }
void manualTune()
{
 lightLevel = map(lightLevel, 1023, 0, 0, 255);
}

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

First of all, you forgot to follow my suggestions:

pert:
When you post code or error/warning messages please use code tags(the </> button on the toolbar). You should always use Tools > Auto Format because it will make it easier for you to spot bugs and make it easier for us to read your code.

There is a sticky post at the top of each forum section: How to use this forum - please read. Please be respectful of the rules of the forum.

You also didn't change the issues with your pin numbers I pointed out. Even if you don't care it would really make it easier for other people like me who are trying to read your code.

Ok, now that's out of the way lets see if I can help you with your problem:

epivik:
if its dark and it doesn't detect motion my servo runs continuously until motion is detected.

So that translates to:

epivik:
if its dark

sensorVal1 == LOW

epivik:
doesn't detect motion

sensorVal==LOW

Now lets look at what those conditions will cause your program to do. First you have

if(sensorVal1 == LOW&&sensorVal==HIGH){ //If it's dark out and if the motion sensor is high then

So that doesn't match your conditions because motion was not detected so sensorVal isn't HIGH so instead what runs is:

  else {
    digitalWrite(servo, HIGH); //Allowing power to my servo
    mspeed = 900; //This is how fast my servo will go
    myServo.writeMicroseconds(mspeed);//Makes my servo turn counter closkwise once again to pull the gate back up
    delay(1000);//This is the amount of time it takes for my gate to be completely raised
    mspeed = 1500; //This is the speed that stops my servo
    myServo.writeMicroseconds(mspeed);//This stops my servo from running
    while (sensorVal1 == HIGH) {
      sensorVal1 = digitalRead(4); //This is so once my gate opens for the day it remains open tell its dark again
    }
    Serial.println("No Motion Detected");
  }

Maybe you want to use an else if() there instead.

I read through your link of how to use this forum. I define those pins because I have to define them in order for my code to work this is the first time I have ever messed with and arduino. My code works exactly like it should it just runs my servo continuously until motion is detected which it should not move until motion is detected and then it should run once. I will uploaded my and use the toolbar thing sorry I have never done any of this before. I did change my sensor for motion to low and it didn't do anything it made it do all sorts of on off stuff. So I changed it back to high cause if motion is detected then it should be putting a high signal out. I didn't unsterstand your else if statement or where it should go.

//Final Project
#define sensorPin 4
#define pirSensor 2
#define servo 6
unsigned int lightLevel = 0, high=0, low=1023;// Putting perameters on my light sensor
unsigned int sensorVal1 = 0;
unsigned int sensorVal = 0;
#include <Servo.h>// Library for servo
#include <LiquidCrystal.h>// Library for lcd moniter
Servo myServo;//creating my servo
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);//Which pins my lcd screen is wired to
int count=0;
int prevsensorVal=0;
int mspeed=1500;//This sets variable for the speed of my servo
void setup(){
   Serial.begin(9600);
   pinMode(pirSensor, INPUT);
   pinMode(servo, OUTPUT);
   myServo.attach(6);//attaches the servo on pin 6 to my servo
   lcd.begin(16,2);//the number of columns and rows in my lcd screen
   lcd.setCursor(0,0);//Where my count number is located in my screen
   lcd.print("Times Gates Opended");
}

void loop() {
  sensorVal1 = digitalRead(4);//reading the input from the photosensor
  sensorVal = digitalRead(pirSensor);//reading the input from the motion sensor
  if(sensorVal1 == LOW&&sensorVal==HIGH){ // If is dark out and then motion is detected then move on
      Serial.println("Motion Detected");// Say motion is detected
      digitalWrite(servo, HIGH);// Allowing power to my servo
      mspeed=900;// This is how fast my servo will go
      myServo.writeMicroseconds(mspeed);//Makes my servo turn counter clockwise to put the gate down
      delay(1000);//This is the amount of time it takes for my gate to be completely lowered 
      mspeed=1500;//This is the speed that stops my servo
       myServo.writeMicroseconds(mspeed);//This stops my servo from running
       while(sensorVal1==LOW){
      sensorVal1=digitalRead(4);//This is so once my gate closes for the night it remains closed tell its light again
    } 
        
  }else{
    digitalWrite(servo,HIGH);//Allowing power to my servo
    mspeed=900;//This is how fast my servo will go
    myServo.writeMicroseconds(mspeed);//Makes my servo turn counter closkwise once again to pull the gate back up
    delay(1000);//This is the amount of time it takes for my gate to be completely raised
    mspeed=1500;//This is the speed that stops my servo
    myServo.writeMicroseconds(mspeed);//This stops my servo from running
    while(sensorVal1==HIGH){
      sensorVal1=digitalRead(4);//This is so once my gate opens for the day it remains open tell its dark again
    }
       Serial.println("No Motion Detected");
    }
    if(sensorVal != prevsensorVal){
    if(sensorVal1==LOW&&sensorVal==HIGH){
      count=count+1;
      lcd.setCursor(8,1);
      lcd.print(count);
    }
    }
    prevsensorVal=sensorVal;
    
    }
void manualTune()
{
  lightLevel = map(lightLevel, 1023, 0, 0, 255);
}
/code]

FInal2.ino (2.65 KB)

epivik:
I read through your link of how to use this forum.

Thanks!

epivik:
I define those pins because I have to define them in order for my code to work

Do you understand what defining the pins does? Imagine if you decide to move the photoresistor to pin 5, so you change the line

#define sensorPin 4

to

#define sensorPin 5

That was easy enough but then your code stops working because all the lines

sensorVal1=digitalRead(4);

are still reading from pin 4(this is known as a magic number in programming speak). If you changed it to:

sensorVal1=digitalRead(sensorPin);

Then you can reconfigure your program by only changing a single line of code. This might not seem like a big deal but as your program gets more complex it can be very difficult to find all the magic numbers that need to be changed. This is why using constants instead of magic numbers is considered a much better programming practice, especially when you already have the constant defined.

epivik:
My code works exactly like it should it just runs my servo continuously until motion is detected which it should not move until motion is detected and then it should run once.

What part of your code do you want to run when it's dark and it doesn't detect motion?

So say I get rid of my define sensor pins and say sensorval1=sensorpin, I still need to tell it somehow which pin to read for my sensor correct? Would I then say sensorpin=5? So When it is dark out and no motion is detected I don't want it to do anything. Just sit there and once motion is detected make my servo run. This will lower my gate. So once that servo has ran once I want it to not do anything again until it detects light. Once it detects light I want my servo to run and this will open up my gate. Once it has ran once I want it to not do anything again until it is dark again and detects motion. I want this so it could go day to day doing this.

Here's how to write the code without Magic Numbers for the pins:

//Final Project
#define sensorPin 4
#define pirSensor 2
#define servo 6
unsigned int lightLevel = 0, high = 0, low = 1023; // Putting perameters on my light sensor
unsigned int sensorVal1 = 0;
unsigned int sensorVal = 0;
#include <Servo.h>  // Library for servo
#include <LiquidCrystal.h>  // Library for lcd moniter
Servo myServo;//creating my servo
LiquidCrystal lcd(7, 8, 9, 10, 11, 12); //Which pins my lcd screen is wired to
int count = 0;
int prevsensorVal = 0;
int mspeed = 1500; //This sets variable for the speed of my servo
void setup() {
  Serial.begin(9600);
  pinMode(pirSensor, INPUT);
  pinMode(servo, OUTPUT);
  myServo.attach(servo);  //attaches the servo
  lcd.begin(16, 2); //the number of columns and rows in my lcd screen
  lcd.setCursor(0, 0); //Where my count number is located in my screen
  lcd.print("Times Gates Opended");
}

void loop() {
  sensorVal1 = digitalRead(sensorPin);  //reading the input from the photosensor
  sensorVal = digitalRead(pirSensor); //reading the input from the motion sensor
  if (sensorVal1 == LOW && sensorVal == HIGH) { // If is dark out and then motion is detected then move on
    Serial.println("Motion Detected");  // Say motion is detected
    digitalWrite(servo, HIGH);  // Allowing power to my servo
    mspeed = 900; // This is how fast my servo will go
    myServo.writeMicroseconds(mspeed);  //Makes my servo turn counter clockwise to put the gate down
    delay(1000);  //This is the amount of time it takes for my gate to be completely lowered
    mspeed = 1500; //This is the speed that stops my servo
    myServo.writeMicroseconds(mspeed);  //This stops my servo from running
    while (sensorVal1 == LOW) {
      sensorVal1 = digitalRead(sensorPin); //This is so once my gate closes for the night it remains closed tell its light again
    }
    
  } else {
    digitalWrite(servo, HIGH); //Allowing power to my servo
    mspeed = 900; //This is how fast my servo will go
    myServo.writeMicroseconds(mspeed);  //Makes my servo turn counter closkwise once again to pull the gate back up
    delay(1000);  //This is the amount of time it takes for my gate to be completely raised
    mspeed = 1500; //This is the speed that stops my servo
    myServo.writeMicroseconds(mspeed);  //This stops my servo from running
    while (sensorVal1 == HIGH) {
      sensorVal1 = digitalRead(sensorPin); //This is so once my gate opens for the day it remains open tell its dark again
    }
    Serial.println("No Motion Detected");
  }
  if (sensorVal != prevsensorVal) {
    if (sensorVal1 == LOW && sensorVal == HIGH) {
      count = count + 1;
      lcd.setCursor(8, 1);
      lcd.print(count);
    }
  }
  prevsensorVal = sensorVal;

}
void manualTune()
{
  lightLevel = map(lightLevel, 1023, 0, 0, 255);
}

What I did was change line 19 from:

myServo.attach(6);

to:

myServo.attach(servo);

line 26 from:

sensorVal1 = digitalRead(4);

to:

sensorVal1 = digitalRead(sensorPin);

line 37 from:

sensorVal1 = digitalRead(4);

to:

sensorVal1 = digitalRead(sensorPin);

and line 48 from:

sensorVal1 = digitalRead(4);

to:

sensorVal1 = digitalRead(sensorPin);

I also did a Tools > Auto Format
So now if you wanted to change the wiring all you need to do is change a single pin definition instead of trying to find every part of your code that used that pin.

There are other Magic Numbers in your code but the pins were the most glaring issue since the definitions were being inconsistently used.

Another suggestion I have for you is to use better variable names, for example:

#define sensorPin 4

You have two different sensors, the light sensor and the PIR sensor so this is confusing, why not call it lightSensorPin instead?

Maybe use the same naming conventions, instead of:

#define lightSensorPin 4
#define pirSensor 2
#define servo 6

something like this:

#define lightSensorPin 4
#define pirSensorPin 2
#define servoPin 6

instead of:

sensorVal1 = digitalRead(lightSensorPin);  //reading the input from the photosensor
sensorVal = digitalRead(pirSensorPin); //reading the input from the motion sensor

maybe this:

lightSensorVal = digitalRead(lightSensorPin);  //reading the input from the photosensor
pirSensorVal = digitalRead(pirSensor); //reading the input from the motion sensor

Ok, getting a little off topic there, now back to your other question:

epivik:
When it is dark out and no motion is detected I don't want it to do anything.

The problem is your code gives two options of what can happen. If the conditions for:

if (sensorVal1 == LOW && sensorVal == HIGH) {

are not met then it runs the code in the else:

else {
    digitalWrite(servo, HIGH); //Allowing power to my servo
    mspeed = 900; //This is how fast my servo will go
    myServo.writeMicroseconds(mspeed);  //Makes my servo turn counter closkwise once again to pull the gate back up
    delay(1000);  //This is the amount of time it takes for my gate to be completely raised
    mspeed = 1500; //This is the speed that stops my servo
    myServo.writeMicroseconds(mspeed);  //This stops my servo from running
    while (sensorVal1 == HIGH) {
      sensorVal1 = digitalRead(sensorPin); //This is so once my gate opens for the day it remains open tell its dark again
    }
    Serial.println("No Motion Detected");
  }

You don't give an option to do nothing. It's like telling someone "if you're thirsty and you like coffee then I'll serve you coffee. Otherwise I'll serve you soda". What if they aren't thirsty, you didn't ever give them an option to not have a beverage. So more polite would be to say ""if you're thirsty and you like coffee then I'll serve you coffee. If you're thirsty but you don't like coffee I'll serve you soda, Otherwise I'll serve you nothing".

So instead of using an else, which will just run any time the conditions of the if are not met, you can specify the conditions to run the code that was in the else, maybe:

else if (sensorVal1 == HIGH) {

That way that code will only run when it is light. When it is dark and there is no motion neither one will run.

Thank you so much this helped me out a ton. I changed everything you told me to on my code to make it easier to understand. I had a hard time just figuring out how to get my continuous rotation servo to even work in the beginning but I got it know it just goes one way to raise my gate which is clockwise. Is there a way to tell this to go counterclockwise. The servo is a hi ted HSR-2645CR.

//Final Project
#define lightSensorPin 4
#define pirSensorPin 2
#define servoPin 6
unsigned int lightLevel = 0, high=0, low=1023;// Putting perameters on my light sensor
unsigned int lightSensorVal = 0;
unsigned int pirSensorVal = 0;
#include <Servo.h>// Library for servo
#include <LiquidCrystal.h>// Library for lcd moniter
Servo myServo;//Creating my servo
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);//Which pins my lcd screen is wired to
int count=0;
int prevsensorVal=0;
int mspeed=1500;//This sets variable for the speed of my servo
void setup(){
   Serial.begin(9600);
   pinMode(pirSensorPin, INPUT);
   pinMode(servoPin, OUTPUT);
   myServo.attach(servoPin);//attaches the servo on pin 6 to my servo
   lcd.begin(16,2);//the number of columns and rows in my lcd screen
   lcd.setCursor(0,0);//Where my count number is located in my screen
   lcd.print("Times Gates Opended");
}

void loop() {
  lightSensorVal = digitalRead(lightSensorPin);//reading the input from the photosensor
  pirSensorVal = digitalRead(pirSensorPin);//reading the input from the motion sensor
  if(lightSensorVal == LOW&&pirSensorVal==HIGH){ // If is dark out and then motion is detected then move on
      Serial.println("Motion Detected");// Say motion is detected
      digitalWrite(servoPin, HIGH);// Allowing power to my servo
      mspeed=900;// This is how fast my servo will go
      myServo.writeMicroseconds(mspeed);//Makes my servo turn counter clockwise to put the gate down
      delay(1000);//This is the amount of time it takes for my gate to be completely lowered 
      mspeed=1500;//This is the speed that stops my servo
       myServo.writeMicroseconds(mspeed);//This stops my servo from running
       while(lightSensorVal==LOW){
      lightSensorVal=digitalRead(lightSensorPin);//This is so once my gate closes for the night it remains closed tell its light again
    } 
        
  }else if(lightSensorVal==HIGH){
    digitalWrite(servoPin,HIGH);//Allowing power to my servo
    mspeed=900;//This is how fast my servo will go
    myServo.writeMicroseconds(mspeed);//Makes my servo turn counter closkwise once again to pull the gate back up
    delay(1000);//This is the amount of time it takes for my gate to be completely raised
    mspeed=1500;//This is the speed that stops my servo
    myServo.writeMicroseconds(mspeed);//This stops my servo from running
    while(lightSensorVal==HIGH){
      lightSensorVal=digitalRead(4);//This is so once my gate opens for the day it remains open tell its dark again
    }
       Serial.println("No Motion Detected");
    }
    if(pirSensorVal != prevsensorVal){
    if(pirSensorVal==HIGH){
      count=count+1;
      lcd.setCursor(8,1);
      lcd.print(count);
    }
    }
    prevsensorVal=pirSensorVal;
    
    }
void manualTune()
{
  lightLevel = map(lightLevel, 1023, 0, 0, 255);
}
/code]

epivik:
Thank you so much this helped me out a ton.

Glad I was able to help. Is it working correctly when it's dark and there's no motion?

epivik:
I had a hard time just figuring out how to get my continuous rotation servo to even work in the beginning but I got it know it just goes one way to raise my gate which is clockwise. Is there a way to tell this to go counterclockwise.

from http://www.arduino.cc/en/Reference/ServoWriteMicroseconds:

Continuous-rotation servos will respond to the writeMicrosecond function in an analogous manner to the write function.

from http://www.arduino.cc/en/Reference/ServoWrite:

On a continuous rotation servo, this will set the speed of the servo (with 0 being full-speed in one direction, 180 being full speed in the other, and a value near 90 being no movement).

now back to http://www.arduino.cc/en/Reference/ServoWriteMicroseconds to see what the equivalent statement is:

On standard servos a parameter value of 1000 is fully counter-clockwise, 2000 is fully clockwise, and 1500 is in the middle.

So it's kind of confusing but I take this to mean that since myServo.writeMicroseconds(900) is making it turn one way for you, myServo.writeMicroseconds(2000) should turn it the other direction. That text indicates that 900 should be counter-clockwise but you say it's clockwise so I'm not sure what's going on there.

Also note that it says this:

Note that some manufactures do not follow this standard very closely so that servos often respond to values between 700 and 2300. Feel free to increase these endpoints until the servo no longer continues to increase its range. Note however that attempting to drive a servo past its endpoints (often indicated by a growling sound) is a high-current state, and should be avoided.

So you might need to just experiment around with different values until you find the full range of your servo.

It works perfect now and I can rotate both ways thank you for all your help and my beginner status.

Glad to hear it's working!
Per