I am attempting to modify a program written by someone else to use in my project. I have been looking through the forum for solutions for several hours and can't figure this out.
Situation: I am using 2 LDR's located on a bread board connected to an Arduino UNO (see attached image). When the light level decreases on LDR1, the power turns on and activates the LED light for 5 seconds and then turns off. After it runs once, I am attempting to set a boolean flag to true so it won't continue to loop. Right now, it continues to loop.
Goal: When the light level decreases, I want the power to turn on for 5 seconds and the loop to stop. Then when the light level increases as measured by LDR 2, I'd like to reset the flag for LDR 1 to "false" so the next time the light level decreases it will turn the power on to the LED for 5 seconds again...then set the flag to true so it only runs once and then continue to LDR2 and so forth.
My Ignorance (just a couple of many): 1) I can't get it to run once and stop. 2) Once I get this to happen, I need to figure out how to use LDR 2 to set the flag for the reduction in light level back to false so it will run again when the light decreases.
Obviously I am a beginner at this and more than happy to dig and search but I can't seem to find any related content for doing something which is probably easy for most of those on this forum. Any assistance you can provide is greatly appreciated. Thank you in advance.
/*
AnalogReadSerial
Reads an analog input on pin 0, prints the result to the serial monitor.
Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
This example code is in the public domain.
*/
int Lightlevel = 0;
int Currentlightlevel = 0;
int Currentlightlevel2 = 0;
int Lightlevel2 = 0;
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
pinMode(9,OUTPUT);
digitalWrite(9,LOW);
delay(1000); //safe separation time
Lightlevel = analogRead(A0);
Lightlevel2 = analogRead(A1);
}
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0:
Currentlightlevel = analogRead(A0);
Currentlightlevel2 = analogRead(A1);
if (Currentlightlevel < Lightlevel -20 == false)
{
Currentlightlevel < Lightlevel -20 == true;
}
digitalWrite(9,HIGH);
delay(5000);
digitalWrite(9,LOW);
delay(1000);
//Lightlevel = analogRead(A0);
//delay(100);
// if (Currentlightlevel > Currentlightlevel2);
// return;
}
// print out the value you read:
Serial.println(Currentlightlevel);
delay(500); //delay in between reads for stability
}
there are several problems with your code. i believe the following tested code will help you understand those problems clearly
you don't have a boolean "flag" keeping track of which state the code is in
Currentlightlevel < Lightlevel -20 == false is very confusing.
the result of the "<", Currentlightlevel < Lightlevel -20, is a boolean (true, false) and there is no need to further compare it to a boolean, false
but Lightlevel -20 would be clearer with parenthesis (see code below)
LightLevel and LightLevel2 are never updated and would remain the values read at the start of the program
because the code doesn't track state, it always turns on the LED for 5 seconds
the following tested code keeps track of state and either tests LDR1 or LDR2 depending on the state. when a light level changes appropriately and the state changes, this code turns the LED on for 5 seconds. the code to turn the LED on is a separate sub-function. Lightlevel and Lightlevel2 are updated each cycle.
i added prints and to avoid too many of them, i added a 1 second delay.
i created defines for the LED and LDRs so that i could easily change them (i.e. #if) for my hardware. my hardware has buttons tied to A1 and A2
i see no need for 2 LDRs, but i don't know what you're planning to do in the future.
/*
AnalogReadSerial
Reads an analog input on pin 0, prints the result to the serial monitor.
Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
This example code is in the public domain.
*/
int Lightlevel = 0;
int Lightlevel2 = 0;
int Currentlightlevel = 0;
int Currentlightlevel2 = 0;
bool lightOn = true;
#if 1
# define LED 9
# define LDR1 A0
# define LDR2 A1
#else // values for my hardware
# define LED 10
# define LDR1 A1
# define LDR2 A2
#endif
char s [80];
// -----------------------------------------------------------------------------
// the setup routine runs once when you press reset:
void setup () {
// initialize serial communication at 9600 bits per second:
Serial.begin (9600);
#if 1
pinMode (LDR1, INPUT);
pinMode (LDR2, INPUT);
#else
pinMode (LDR1, INPUT_PULLUP);
pinMode (LDR2, INPUT_PULLUP);
#endif
pinMode (LED, OUTPUT);
digitalWrite (LED,LOW);
delay (1000); //safe separation time
Lightlevel = analogRead (LDR1);
Lightlevel2 = analogRead (LDR2);
sprintf (s, "%s: L1 %d, L2 %d", __func__, Lightlevel, Lightlevel2);
Serial.println (s);
}
// -----------------------------------------------------------------------------
void blink (void)
{
digitalWrite (LED,HIGH);
delay (5000);
digitalWrite (LED,LOW);
}
// -----------------------------------------------------------------------------
// the loop routine runs over and over again forever:
void loop () {
// read the input on analog pin 0:
Currentlightlevel = analogRead (LDR1);
Currentlightlevel2 = analogRead (LDR2);
if (lightOn) {
if (Currentlightlevel < (Lightlevel -20))
{
lightOn = false;
blink ();
}
}
else {
if (Currentlightlevel2 > (Lightlevel2 +20)) {
lightOn = true;
blink ();
}
}
Lightlevel = Currentlightlevel;
Lightlevel2 = Currentlightlevel2;
sprintf (s, "%s: L1 %d, L2 %d", __func__, Lightlevel, Lightlevel2);
Serial.println (s);
delay (1000);
}
in the code above, the comparison is made to the previous light level which implies a sudden change. this approach probably wouldn't work if the light level changed more smoothly
one approach to handle this is to update LightLevel2 when the light change to off and update Lightlevel when the light changes to on.
Of course you can ask here in the forum. But then you have to wait for the answers. If you start to learn how coding works you become more and more independent of waiting for answers.
It is easy to understand and has a good mixture between explaining important concepts and example-codes to get you going. So give it a try and report your opinion about this tutorial.
I'm a somehow advanced programmer and this has the effect of beeing partially blind about beginners difficulties. But I would like to become an "expert" about beginners difficulties and therefore I appreciate feedback about that and to receive questions what is still hard to understand.
Thank you so much to both of you for your comments. Using GCJR's advice, we decided to use one LDR since two were not necessary.
First we tested the light values of the LDR when open versus closed using the serial printer. Once we knew those, we wrote the code and it is working perfectly. One thing we added was that if the LDR is exposed to light while the LED was on the LED would deactivate once the light level reached a certain level. Sharing the code below for anyone to review and benefit from.
Thanks once again for your assistance. You guys are fantastic!
boolean status1=0; // variable for flag
int ldr_pin=A0; // pin where LDR is connected
int ldr_value; // initializing the LDR value
int ledPin=9; // pin where LED is connected
unsigned long time_since_last_reset=0; // variable to keep check on time
void setup() {
Serial.begin(9600); // initializing serial monitor to read the values
pinMode(ledPin,OUTPUT); //declaring LED pin as output
pinMode(ldr_pin,INPUT); // declaring LDR pin as input since we will take values from this pin
digitalWrite(ledPin,LOW); // turning off LED at the start
}
void loop() {
ldr_value= analogRead(ldr_pin); // read the LDR value
if(ldr_value<10){ // check if light value is less than 10
delay(750); //add delay prior to activating LED
time_since_last_reset=millis(); // note time at this point for reference
while(((millis()-time_since_last_reset)<5000)&&(status1==0)) //time sensitive while loop starts here for five seconds since we need to turn on LED for 5 seconds
{
Serial.println("led on");
digitalWrite(ledPin,HIGH); // turn on LED
ldr_value= analogRead(ldr_pin); //read LDR value to confirm if light level has increased within the 5 second period
if(ldr_value>10){status1=1;} // If the light level increases during the 5 seconds LED cycle – Turn off LED light by setting the flag to break the loop
}
digitalWrite(ledPin,LOW);
status1=1; //flag is set in case it completes 5 second period
}
if(ldr_value>50)
{
status1=0; // Indicates light level increasing – resets the LED flag to the ready position
}
}