Trying to make a servo flip a switch.

Hello

Currently I am having a problem with my project, and need help. I am making a servo turn on a light switch with a photoresistor. The photo resistor reads fine but when adding the servo elements to it, the servo will not move. The servo I am using is a towerpro micro servo. It works when i use a button press sketch, but will not work with the photo resistor(granted the photoresistor sketch is a different one from the button press).

This will turn on the front porch light automatically when i forget to turn it on, it will stay on until sunrise. I figure i wouldnt need any timers with this but I am thinking i might need them.

#include <Servo.h>

// servo set up
Servo servo1;

//light sensor set up
const int photoSen = 0; //photoresistor pin
const int sunny = 70; // light val for sunny, can be changed
int lightLevel; //light level

void setup() {
  // put your setup code here, to run once:
pinMode(photoSen, INPUT);
lightLevel = analogRead(photoSen);
servo1.attach(9);

}

void loop() {
  // put your main code here, to run repeatedly:
 int position;

 if(lightLevel >= sunny){ //stays off if sunny
  servo1.write(180);
 }
  else(lightLevel <= sunny);{//turn on
  servo1.write(120);
 }

}

Thanks for looking.

  1. pins 0 and 1 are not good pins to use because these are also used for serial communications. For example, you may want to add Serial.print() debug statements so you can see how far your sketch progresses.

  2. You read the light sensor only in setup. Any changes in light during the day will be ignored.

Post the code you say works with just a switch.

State what type of light sensor you are using. An LDR, for example, requires an additional resistor to form a potential divider. Better, post also a wiring diagram

You read the light level once in setup(). I think you should be reading it more often than that.

You declared a variable called position but never used it.

You have an expression () directly following the else. Perhaps you meant to write another if() there? Then there's a semicolon after that so simply changing to "if" won't make any difference to the block {} of code that follows.

Add some hysteresis. Turn on when it's darker than 'dark' and turn off when lighter than 'sunny'. Make those two different numbers.

Continuing from 6v6gt's first point, analogRead(0) will read from pin A0. pinMode(0) will set the pin mode of digital pin 0. These are not the same pin.

Try to use the names printed on the Arduino board. "A0" instead of "0" for the first analog pin. Some Arduinos have pins like RX_LED that can be used in the code with those names.

here is the working code with the button. I did follow a guide i found online (forgot to bookmark it)

#include <Servo.h>;
 
 // pushbutton pin
 const int buttonPin = 2;
 // servo pin
 const int servoPin = 9;
 Servo servo;
//create a variable to store a counter and set it to 0
int counter = 0;
void setup()
{
  servo.attach (servoPin);
  
  // Set up the pushbutton pins to be an input:
  pinMode(buttonPin, INPUT);
}
void loop()
{
 // local variable to hold the pushbutton states
  int buttonState;  
  //read the digital state of buttonPin with digitalRead() function and store the           //value in buttonState variable
  buttonState = digitalRead(buttonPin);
  //if the button is pressed increment counter and wait a tiny bit to give us some          //time to release the button
  if (buttonState == LOW) // light the LED
  {
    counter++;
    delay(150);
  }
  if(counter == 0)
    servo.write (175);  // zero degrees
  else if(counter == 1)
    servo.write(120);

  //else reset the counter to 0 which resets thr servo to 0 degrees
  else
   counter = 0;
}

the new code. I think i added the light level correctly. All it does is make the servo jitter from 120deg to 180 deg

#include <Servo.h>

// servo set up
Servo servo1;

//light sensor set up
const int photoSen = A0; //photoresistor pin
const int sunny = 70; // light val for sunny, can be changed
int lightLevel; //light level

void setup() {
  // put your setup code here, to run once:
pinMode(photoSen, INPUT);
lightLevel = analogRead(photoSen);
servo1.attach(9);

}

void loop() {
  // put your main code here, to run repeatedly:

 int position;
lightLevel = analogRead(photoSen);

 if(lightLevel > sunny){ //stays off if sunny
  servo1.write(180);
 }
  if(lightLevel < sunny);{//turn on
  servo1.write(120);
 }
 if(lightLevel == sunny);{
  servo1.write(120);
 }

}

I added a serial print function so i can check if my photoresistor is working. it is.

void loop() {
  // put your main code here, to run repeatedly:
lightLevel = analogRead(photoSen);
Serial.println("lightLevel");
Serial.println(lightLevel);
delay(5000);
if(lightLevel < sunny);


 if(lightLevel == sunny);

Whoops

Why do those ifs look different to the others?

In case it's too subtle: the semicolons (:wink: don't belong on the end of if()

romz26:
... I figure i wouldnt need any timers with this but I am thinking i might need them. ...

You might need some timers. If the way it works is: turn the light on if it's dark, and off if it's light. Any light would cycle the light off then on, which is not what you want I'm sure. Use a timer: it should be light for 30 seconds or so before turning off the light. Don't use delay, or it will still flash.

If you give your LDR an appropriate resistor you can condense loop() into two lines. The digital input, being a Schmitt trigger, takes care of the hysteresis. A 10k resistor is a good starting point.

void loop() {
  servo.write((digitalRead(photoSen)) ? 120 : 180);
  delay(5000);
}

You may have to switch the 120 and 180 to make it work the correct way around.

MorganS:
In case it’s too subtle: the semicolons (:wink: don’t belong on the end of if()

thanks for catching that. Did not realize that I did that.

ChrisTenone:
You might need some timers. If the way it works is: turn the light on if it’s dark, and off if it’s light. Any light would cycle the light off then on, which is not what you want I’m sure. Use a timer: it should be light for 30 seconds or so before turning off the light. Don’t use delay, or it will still flash.

Oh man, adding delays(not how i wanted to do it) worked. Is it possible to have a delay at the start (of being dark 4hours) then having another statement to keep it dark without having a delay, so the when it passes to be sunny the light will turn off(so it will be more dynamic)?

#include <Servo.h>

// servo set up
Servo servo1;

//light sensor set up
const int photoSen= 0; //photoresistor pin
const int sunny= 70; // light val for sunny, can be changed
int lightLevel; //light level

void setup() {
  // put your setup code here, to run once:
pinMode(photoSen, INPUT);
servo1.attach(9);
//serial monitor
Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:
lightLevel = analogRead(photoSen);
Serial.println("lightLevel");
Serial.println(lightLevel);

 if(lightLevel > sunny){ //stays off if sunny
  servo1.write(180);
  //delay(5000);
 }
 if(lightLevel <= sunny){//turn on
  servo1.write(120);
  delay(5000);
 }
}

this is for front porch lighting. basically what i want it to do is

this is not actual code
lightlevel>sunny: lights off
lightlevel<sunny, delay(4hr): lights on for 4hr for when there are lights on in the house
lightlevel<sunny, nodelay: keep lights on after delay without the delay to turn off the light when sunny>lightlevel

wvmarle:
If you give your LDR an appropriate resistor you can condense loop() into two lines. The digital input, being a Schmitt trigger, takes care of the hysteresis. A 10k resistor is a good starting point.

void loop() {

servo.write((digitalRead(photoSen)) ? 120 : 180);
 delay(5000);
}




You may have to switch the 120 and 180 to make it work the correct way around.

what is the question mark for?

? is called the ternary operator

It is rarely used as it is easy to mis-read. It is usually better to use an if().

A shorthand if statement. Quite convenient in this kind of simple switch situations.

[conditional] ? [do this if true] : [do this if false];