With a ESP8266 code I want to display an LCD for a few seconds when the user presses a button. Just to simplify I have replaced the LCD with LEDs.
In the code below even without pressing the push button to light up the LEDs for 3 seconds , the LEDS are are lighting up for 3 seconds always !! Not sure how the debounce logic fails... is there anything that I am missing ?
#include <ESP8266WiFi.h>
const int okLed = D6;
const int errLed = D7;
const int pbDisp = D5; // Push botton to invoke display routines.
int debounceTime = 25 ; // Time for debounce in millisecond
//$$$$$$$$$$$$$$$$$$$$$
void setup()
{
Serial.begin(9600);
pinMode(okLed, OUTPUT);
pinMode(errLed, OUTPUT);
digitalWrite(okLed, HIGH);
digitalWrite(errLed, HIGH);
delay(3000);
digitalWrite(okLed, LOW);
digitalWrite(errLed, LOW); // Just to know the LEDs are working !;
pinMode(pbDisp, INPUT);
digitalWrite(pbDisp, HIGH); // Invoke pull up..
//#######################################
void loop()
{
if (pbPressed(pbDisp)> debounceTime ) {
digitalWrite(errLed,HIGH);
digitalWrite(okLed, HIGH);
Serial.println("LOW");
delay(2000);
digitalWrite(errLed,LOW);
digitalWrite(okLed, LOW);
Serial.println("HIGH");
}
yield();
}
//#######################################
long pbPressed(int inPin) // return the time in milliseconds that the switch has been in pressed (LOW)
{
static unsigned long startTime = 0; // the time the switch state change wasfirst detected
static boolean state; // the current state of the switch
if (digitalRead(inPin) != state) // check to see if the switch has changed state
{
state = ! state; // yes, invert the state
startTime = millis(); // store the time
}
if ( state == LOW)
return millis() - startTime; // switch pushed, return time in milliseconds
else
return 0; // return 0 if the switch is not pushed (in the HIGH state);
}
//######################################
if you have an external pullup connecting the pullup-resistor one end to 3.3v other end to IO-pin is enough.
Then your switch has to be connected one connector to the IO-pin other end to ground.
So if buton is not pressed the IO-pin seesHIGH if button is pressed IO-Pin sees low.
every time you execute your function pbPressed
starttime is initialised with zero
the variable state is unintialised
then immediatly you do all the rest of the function only one time.
which needs less than a single millisecond,
then you do a delay of 2000 milliseconds
There is nothing in your code that would check after 25 to 50 milliseconds if the IO-pin state
calmed down on the same state as at the beginning.
To invoke the internal pull ups, both digitalWrite(pinX, HIGH ) and pinMode(pinX, INPUT_PULLUP) yield the same result. The later saves one statement line or that is what i believe
Nothing wrong with the de-bounce logic. The same code tweaked to run on a UNO works exactly as expected. One short press of the button, the led stays lit for 2 seconds and switches off.
const int okLed = 13;
const int pbDisp = 5; // Push botton to invoke display routines.
int debounceTime = 25 ; // Time for debounce in millisecond
//#######################################
void setup() {
Serial.begin(9600);
pinMode(okLed, OUTPUT);
pinMode(pbDisp, INPUT_PULLUP);
//pinMode(pbDisp, INPUT);
digitalWrite(pbDisp, HIGH); // Invoke pull up..
}
//#######################################
void loop() {
if (pbPressed(pbDisp) > debounceTime ) {
digitalWrite(okLed, HIGH);
Serial.println("LOW");
delay(2000);
digitalWrite(okLed, LOW);
Serial.println("HIGH");
}
}
//#######################################
long pbPressed(int inPin) { // return the time in milliseconds that the switch has been in pressed (LOW)
static unsigned long startTime = 0; // the time the switch state change wasfirst detected
static boolean state; // the current state of the switch
if (digitalRead(inPin) != state) // check to see if the switch has changed state
{
state = ! state; // yes, invert the state
startTime = millis(); // store the time
}
if ( state == LOW)
return millis() - startTime; // switch pushed, return time in milliseconds
else
return 0; // return 0 if the switch is not pushed (in the HIGH state);
}
//######################################
It is not the most transparant coding i've seen but i actually don't really see a reason why it should not work (as long as you are only using it with 1 button)
This was the method used in IDE 0.x before INPUT_PULLUP was added, does still work just fine.int debounceTime = 25 ;is not a lot !
How about actually printing the result from your debounce function
uint32_t deb = pbPressed(pbDisp);
if (deb > debounceTime ) {
digitalWrite(okLed, HIGH);
Serial.println(deb, DEC);
Serial.println("LOW");
for debugging purposes.
btw , passing the pin as an argument to the debounce function shows intent on using it for more than 1 pin, but that isn't going to work if 'state' & 'starttime' are not pin specific variables.
Deva_Rishi:
It is not the most transparant coding i've seen but i actually don't really see a reason why it should not work (as long as you are only using it with 1 button)
pinMode(pbDisp, INPUT);
digitalWrite(pbDisp, HIGH); // Invoke pull up..
This was the method used in IDE 0.x before INPUT_PULLUP was added, does still work just fine.`int debounceTime = 25 ;`is not a lot !
How about actually printing the result from your debounce function
uint32_t deb = pbPressed(pbDisp);
if (deb > debounceTime ) {
digitalWrite(okLed, HIGH);
Serial.println(deb, DEC);
Serial.println("LOW");
for debugging purposes.
btw , passing the pin as an argument to the debounce function shows intent on using it for more than 1 pin, but that isn't going to work if 'state' & 'starttime' are not pin specific variables.
The debounce function was actually got from the book Arduino Cookbook by Michael Margolis. And yes it meant for use with multiple switches.
long pbPressed(int inPin) // return the time in milliseconds that the switch has been in pressed (LOW)
{
static unsigned long startTime = 0; // the time the switch state change wasfirst detected
static boolean state; // the current state of the switch
if (digitalRead(inPin) != state) // check to see if the switch has changed state
{
state = ! state; // yes, invert the state
startTime = millis(); // store the time
}
if ( state == LOW)
return millis() - startTime; // switch pushed, return time in milliseconds
else
return 0; // return 0 if the switch is not pushed (in the HIGH state);
}
The debounce function was actually got from the book Arduino Cookbook by Michael Margolis. And yes it meant for use with multiple switches.
Yes but if you intent to use it for checking several buttons at once, you can tell that the variables 'state' & 'startTime' do not distinguish between pins. Where you got it from isn't really going to matter. Yes you can use it for more pins, but only if you are waiting for a result from one of them. If you are testing 2 pins, you press one, and the call to the function from the other pin resets the variables. If you make the function a part of a class, create an object that will call it's member function, then yes.. But that is not what you are doing. Of course for now you are not calling several pins, so there is no issue. Although you are asking people to fix code that was written by someone else. (mind you stating that it somehow is board specific, but still)
All in all, i don't see anything really wrong with the code other than what i have stated before, so actually , well, maybe you haven't wired it properly ?