Here is an explanation of the princples behind LED light sensingk
/* LED sensor. By having an led wired up with the anodePin to the
LED's long leg and the cathodePin to a resistor and then to the short
leg of the LED, the LED will blink quickly, but slow enough to be percieved
and then measure the amount of ambient light based on how long it takes for
charge to disperse from the cathode leg.
Note, in this code the average read
of the LED is with N=10. However, the read function has a minimum use of 50 us.
Meaning I use half a second for the reading of the funciton. This code was used for
proof of concept. N should be reduced to a lower number if you need a quick response.
However, a greater N means less garbage and more reliable data. Choose your N wisely.
*/
#include <Servo.h>
Servo servo;
int anodePin = 2; //vcc
int cathodePin = 8; //ground
int threshold=30; //set threshold--depends on ambient light conditions
void setup()
{
//deactivates pullup resistors
_SFR_IO8(0x35) |= 4;
_SFR_IO8(0x35) |= (1<<4);
threshold= 30; //under this value the servo will move
pinMode(anodePin, OUTPUT);
pinMode(cathodePin, OUTPUT);
Serial.begin(9600);
servo.attach(9);
}
void loop(){
int value=0; //initialize reading
int N=10; //number of readings to be averaged
servo.write(0); //set initial postion of servo, in subsequent loops returns to initial position or does nothing
//take reading N times and then take the average to avoid garbage data
for(int i=0; i<N; i++){
value=value+read();
}
value=value/N;
if((value<threshold)&&(value>0)){
servo.write(90); //if the average value read is not negative and is less than the threshold move the servo
delay(3000);
}
Serial.print("value is"); //tells you the average value
Serial.println(value); //on a new line
delay(1000);
}
int read(void){
int val = 0; //sets reading to zero
//emit light
digitalWrite(anodePin, HIGH);
digitalWrite(cathodePin, LOW);
delay(50);
//switch potentials -- charge LED to -5V
digitalWrite(anodePin, LOW);
digitalWrite(cathodePin, HIGH);
//switch pinmode--i.e. stop outputing high and now measure the pin
pinMode(cathodePin, INPUT);
//measure time it takes for cathodePin to go to zero/for the charge on the ground side of the led to disperse
while(digitalRead(cathodePin) != 0){
val++;
delay(1);//allows for val to be a number in the range of an int--no overflow
}
//make the cathodePin back into an output
pinMode(cathodePin, OUTPUT);
//emit light--lets the led be on when the reading is not being done--not necessary for the code to work
digitalWrite(anodePin, HIGH);
digitalWrite(cathodePin, LOW);
//print out the value
Serial.println(val, DEC);
return val;
}