I am having trouble adding an LDR to my project. My project requires that the device sleep when the light levels drop below a certain threshold, so it is critical to my project.
I have attached a crudely drawn (sorry!) circuit diagram to this post. The circuit was made following a few online examples. When connection A is made, the LEDs cease to function.
I am also getting unexpected values from analogRead(A0) (the LDR). The readings never drop below what I deemed high light levels in my tests (750) no matter what the actual light level is.
The test was performed using the left side of the circuit. i.e. no buzzer or LEDs connected.
Well lit room = 750+
Low light conditions (dark with TV, or distant light on) = 100-
What is happening here, and how can I remedy it?
Would a photodiode be better suited to this application?
Here is the code I am trying to run, if it is useful.
#include <LowPower.h>
// set output pins
const int RED = 13; // Red LED
const int GRN = 12; // Green LED
const int BZZ = 8; // Buzzer
const int LDR = A0; // Light Detecting Resistor
// set constants
const int MAXLIGHT = 300; // awakeness
const int MINLIGHT = 40;
const int SHORTMIN = 1; // short sleep
const int SHORTMAX = 2;
const int LONGMIN = 5; // long sleep
const int LONGMAX = 6;
const int READDELAY = 300; // delay between LED on and read (LED OFF)
const int FREQMOD = 20; // used to modify frequency values
const int FREQMOD2 = 50; // minimum freq-FREQMOD
const int FREQRANGE = 17; // num possible notes
const int DURMOD = 15; // modify durations
const int DURRANGE = 20; // num possible durations
const int DELAYRANGE = 8; // num possible of delays (between sounds)
// set variables
int soundDelay = 200; // delay between notes
int soundArray[16]; // 8 freqs, 8 durs. F,D,F,D...
int lightArray[8]; // 4 variations
int sleepCount = 0; // sleep time
int lightLevel = 0;
//Startup routine (run once)
void setup(){ // set output pins
pinMode(RED, OUTPUT);
pinMode(GRN, OUTPUT);
pinMode(BZZ, OUTPUT);
Serial.begin(9600);
randomSeed(analogRead(A0)); //set random seed. helps to randomize better.
}
//Main loop. runs repeatedly
void loop() {
digitalWrite(RED, HIGH);
Serial.println("RED");
delay(READDELAY); // blink LED
analogRead(LDR); // switch to channel to read. supposed to make result more accurate (settle). Are the next ones necessary?
lightLevel = analogRead(LDR);
Serial.println(lightLevel);
lightLevel = analogRead(LDR);
Serial.println(lightLevel);
lightLevel = analogRead(LDR);
Serial.println(lightLevel);
lightLevel = analogRead(LDR); // get light reading
Serial.println(lightLevel);
if (lightLevel<MINLIGHT){ // low light
Serial.println("low light");
digitalWrite(RED, LOW);
sleepCount = random(LONGMIN, LONGMAX);
}
else if (lightLevel>MAXLIGHT){ // high light
Serial.println("high light");
soundLightPatternGen();
soundLightExecution();
sleepCount = random(SHORTMIN, SHORTMAX);
}
else{ // medium light
Serial.println("med light");
soundLightPatternGen();
soundLightExecution();
sleepCount = random(SHORTMAX, LONGMIN);
}
digitalWrite(RED, LOW);
digitalWrite(GRN, LOW);
timedSleep(sleepCount);
}
//Functions
void soundLightPatternGen(){
//Serial.println("Pattern gen");
for (int i = 0; i<16; i+=2){
soundArray[i] = (random(FREQRANGE)); // Frequency
//Serial.println(soundArray[count]);
soundArray[i+1] = random(1,DURRANGE)*DURMOD; // Duration
//Serial.println(soundArray[count+1]);
lightArray[i/2] = random(4); // LED
//Serial.println(lightArray[count/2]);
}
}
void soundLightExecution(){
for (int i=0; i<16; i+=2){
//Serial.println("LED EXEC");
funcLED(i/2);
//Serial.println("sound exec");
if (soundArray[i] == 0){ // Null Frequency
delay((soundArray[i+1])*10);
}
else
{
tone(BZZ, (((soundArray[i])*FREQMOD)+FREQMOD2), soundArray[i+1]);
soundDelay = random(1, DELAYRANGE);
delay(soundDelay*50);
}
}
}
void funcLED(int x){
digitalWrite(RED, LOW);
digitalWrite(GRN, LOW);
//Serial.println("well, the function was called.");
//Serial.println(x);
switch(lightArray[x]){
case 0:
//Serial.println("NONE");
break;
case 1:
digitalWrite(RED, HIGH);
//Serial.println("RED");
break;
case 2:
//Serial.println("GREEN");
digitalWrite(GRN, HIGH);
break;
case 3:
digitalWrite(RED, HIGH);
digitalWrite(GRN, HIGH);
//Serial.println("BOTH");
break;
default:
//Serial.println("WTF");
break;
}
}
void timedSleep(int x){
for (int i=0; i<x; i++){
LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
}
//delay(x*1000); // used instead of powerDown for test
}
Thanks in advance
EDIT: adding a 1N4001 diode between the resistor (connected to LDR) and ground allows the LEDs to function, but I am still getting strange reads from A0. No matter what the lighting conditions are, values remain in the 350-400 range and do not seem to respond to light changes.
EDIT 2: Solved it myself! Combination of breadboard error and too large of a photoresistor. Thanks anyway!