Many Ways to Blink 3: Light Sensor to Servo

In Tutorial 3 we are going to replace the LED with a servo and make it “blink”. What “blink” means in the case is that the servo will switch back and forth between two difference positions. A servo has a PWM interface so we will have to generate a PWM signal from the Arduino. You can click on the link to read more about PWM and how it works if you want to. The Uno can generate a PWM signal from pins 11,10,9,6,5, and 3. In this case we will be using pin 9. The other important thing using a servo is that is it easiest to use a library to control it. This prebuilt code means we can tell the servo to move to the 105 degree positon and not worry about exactly what PWM duty cycle is needed to do that. Conveniently, a library for exactly that comes built into Arduino. It is called Servo. To use the library we will have to add some lines of code to the sketch which you will see in the Code section.

Block Diagram

Light Sensor to Servo System

Circuit

Servo Pinout

Code Steps

#include <Servo.h>

to the Included Library section.

Servo myservo;  

to the Library Initialization Section. The line above tells Arduino to create the object and name it “myservo”.

myservo.attach(9);  // attaches the servo on pin 9 to the servo object

to the Hardware Declaration Section . It tell the arduino that the servo is connected to pin 9 and to generate the PWM signal there.

delayTime = map (sensorValue, minValue, maxValue, 0, 1023);

to

delayTime = map (sensorValue, minValue, maxValue, 200, 1023);

This sets the minimum delay to 200ms. The reason why we need to do this is because the servo responds much slower that the LED. Therefore if you had delays less than 200ms the servo would not have enough time to move between positions and it would not “blink”

digitalWrite(ledPin, HIGH); // turn the ledPin on
delay(delayTime);          
digitalWrite(ledPin, LOW);   // turn the ledPin off
delay(delayTime);

to

myservo.write(155); 
delay(delayTime); 
myservo.write(30);
delay(delayTime);

This code will move the servo between 30 degrees and 155 degree. The reason why it is not between 0 and 180 degrees is that this specific servo does not have that wide a range. Other servo can go the full range and some even can turn continuously in one direction.

int ledPin = 13;      // select the pin for the LED

and the line

 pinMode(ledPin, OUTPUT);  

This means we will not be confused when we look at the code later.

Full Code

/*
  Adapted From: Analog Input by David Cuartielles and Tom Igoe
  Author: Malcolm Knapp
  Project: Light Sensor to Servo
  Date: 4/10/14
  Version: 0.1
  Description: This code shows how to use a light sensor to control
               the "blink" rate of a servo. In this case "blink" means
               moving between two positions.

 */
// ---------- included libraries ------------ 
#include <Servo.h>

// ---------- hardware pin defines  ----------- 
int sensorPin = A0;    // select the input pin for the potentiometer

// ---------- variable initialization  ----------- 
int sensorValue = 0;  // variable to store the value coming from the sensor
int delayTime = 0; //variable that holds the delay time in milliseconds
int scaling = 1;
int maxValue = 750;
int minValue = 300;


// ---------- library initialization  -----------  
Servo myservo;  // create servo object to control a servo a maximum of eight servo objects can be created 

void setup() {
  Serial.begin(9600);
  // declare hardware connections
   myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop() {
  // Input
  sensorValue = analogRead(sensorPin); 
  // Debugging
  Serial.print("Sensor value: ");  Serial.println(sensorValue);


  // Processing
  //Scaling
  delayTime = map (sensorValue, minValue, maxValue, 200, 1023);
  Serial.print ("Delay in milliseconds: "); Serial.println (delayTime);
  // Modes
  // None - put new modes here 

  // Output 
  myservo.write(155); 
  delay(delayTime); 
  myservo.write(30);
  delay(delayTime);    
}