I’m trying to use a LDR to monitor the light levels and if the LDR is covered and the button is pressed, the LED should switch on. I’m in the process of adding debouching but every time I run the code, the it goes in the if (val> 421) part the led is on, but the button hasn’t been pressed and the code stops.
I’m suspecting it may be a logic issue with the states. I’m using the millis function for the debouncing so the code should ignore the first 200ms of when the button is pressed. I just help in regard to the debouncing so when the LDR is covered and the switch is pressed , the LED should turn on.
The code is shown below:
const int buttonPin = 8;
const int ldrPin = 0;
const int LEDPin = 13;
boolean buttonState = 0;
boolean NEWbuttonState = 0;
boolean LEDState = 0;
int bounce_time = 200;
unsigned long my_time;
boolean on;
int val = 0;
void showValue(float myval)
{
Serial.print(myval);
Serial.print(" lightstatus ");
Serial.println(LEDState);
}
void setup()
{
pinMode(buttonPin, INPUT);
pinMode(LEDPin, INPUT_PULLUP);
on = false;
analogReference(DEFAULT);
pinMode(ldrPin, INPUT);
Serial.begin(9600);
my_time = millis();
}
void loop()
{
val = analogRead(ldrPin);
NEWbuttonState = digitalRead(buttonPin);
if ((millis() - my_time) > bounce_time)
{
digitalWrite(LEDPin, LOW);
if (buttonState != NEWbuttonState)
{
buttonState = NEWbuttonState;
//if button is pressed
if (NEWbuttonState == 1 && LEDState == 0)
{
buttonState = NEWbuttonState;
if (val > 421)
{
my_time = millis();
digitalWrite(LEDPin, 1);
LEDState = 1;
showValue(val);
Serial.print("button press");
}
if (val < 420)
{
my_time = millis();
digitalWrite(LEDPin, 0);
LEDState = 0;
showValue(val);
}
buttonState = 1;
}
else
{
if (NEWbuttonState == 0)
{
buttonState = 0;
}
}
}
}
}
1 Answer 1
Bouncing of a mechanical switch happens in very few milliseconds, faster than you can see a led shine.
So, for your task, you don't need any debouncing.
The description or your task lacks what should happen "if not". I assume the led should shine while both button is pressed and ldr is covered. If either button is not pressed, or ldr is lit, the led should remain off.
This one is too simple:
void loop() {
bool ldrDark = analogRead(A0) < MAX_LDRBRIGHT;
digitalWrite(led, ldrDark && digitalRead(buttonPin));
}
To add a delay (led goes on only when button is pressed some time) is easy as well.
const byte LED = LED_BUILTIN; // 13 on UNO
const byte BUTTON = 8; // Button connects to GND
const byte PRESSED = LOW; // due to INPUT_PULLUP
const int DELAY = 300; // ms
bool btnState; // true = HIGH when presse
const byte LDR = A0; // LDR to 5V, Resistor to GND : Low values when dark
const int MIN_LDRBRIGHT= 420; // depends on resistor and LDR
void setup() {
pinMode (LED, OUTPUT);
pinMode (BUTTON, INPUT_PULLUP);
}
void loop() {
static unsigned long lastOpen;
if (digitalRead(BUTTON) == PRESSED) {
if (millis() - lastOpen > DELAY)
btnState = HIGH;
else btnState = LOW;
} else {
lastOpen = millis(); // to remember last moment button was released
btnState = LOW;
}
bool ldrDark = analogRead(A0) < MIN_LDRBRIGHT;
digitalWrite(LED, ldrDark && btnState);
}
-
You should see led follow the covered ldr (while button remains pressed) faster than button changes. If that's the intention of this exercise.DataFiddler– DataFiddler2019年11月22日 18:09:01 +00:00Commented Nov 22, 2019 at 18:09
const int ldrPin = 0;
conflicts with Serial. Or, if it's intended for analogRead, you should avoidpinMode(ldrPin, INPUT);
Better useconst byte ldrPin = A0;