debounce

Hi there,

first post around here!!

I'm having some issues with a debounce program that i want to write.

Let me explain first how it should work.

I want an array of 4 bools to get everything i want from a future debounce function.

bool 0 = input, coupled to a input pin
bool 1 = input detected, will be reset after some time after bool 0 is released
bool 2 = just a single cycle pulse
bool 3 = output that should flip flop each time bool 1 becomes high

Now i have two major issues with my scetch.

1 bool 2 does not seem to come high at all.
2 the timer function does not work at all.

I suspect it has something to do with scopes, but i can't figure it out by myself.

Some tips, or a little help would be very welcome!!!

Thanks!

int input = 22;

byte button [4] = {0, 0, 0, 0};
int i = 0;
unsigned long startTime = 0;
const unsigned long delayTime = 100;
void setup() {
pinMode (input, INPUT_PULLUP);
Serial.begin(9600);
}

void loop() {
button [0] = !digitalRead (input);

if (button [0] == true) {
button [1] = true;}

if (button [1] == true){
i++;
if (i == 1){
button [3] = !button[3];}

if (i == 2){
button [2] == true;}}
//else {button [2] == false;}

if (( button [1] == true) && (button [0] == false)){

startTime = millis();
if (( millis() - startTime) > delayTime){
Serial.println(startTime);
button [1] = false;
i = 0;}}

Serial.print (button[1]);
Serial.print (" ");
Serial.print (button[2]);
Serial.print (" ");
Serial.print (button[3]);
Serial.print (" ");
Serial.println(i);

}

Step 1 : read read this before posting a programming question

Step 2: post your code using code tags

UKHeliBob:
Step 2: post your code using code tags

Cuz if you don't it looks like this on my screen:

use code tags.PNG

use code tags.PNG

dougp:
Cuz if you don't it looks like this on my screen:

use code tags.PNG

I like it when untagged code makes smilies with sunglasses.

I don't understand what the variable 'i' is being used for and what the various values mean. Perhaps you can think of a better name and make it a ENUM so the values can be given names, too.

int input = 22;   // Shouldn't this be 'const byte' since it represents a pin number?
byte button [4] = {0, 0, 0, 0};  // Why are your 'bool' values declared 'byte' and not 'bool'?
int i = 0;  // What is this variable used for?
unsigned long startTime = 0;
const unsigned long delayTime = 100;
void setup()
{
  pinMode (input, INPUT_PULLUP);
  Serial.begin(9600);  // It's not 1974 anymore.  I recommend 115200 baud
}
void loop()
{
  button [0] = !digitalRead (input);
  if (button [0] == true)
  {
    button [1] = true;
  }

  if (button [1] == true)
  {
    i++;  // Counting the number of times the button was found to be pressed?
    if (i == 1)
    {
      button [3] = !button[3];  // First time, toggle #3
    }

    if (i == 2)
    {
      button [2] == true;
    }
  }
  //else {button [2] == false;}
  if (( button [1] == true) && (button [0] == false))
  {
    startTime = millis();
    if (( millis() - startTime) > delayTime)   // This is never going to be true.  mllis()-millis() will almost never be above 0 and never above 100.
    {
      Serial.println(startTime);
      button [1] = false;
      i = 0;
    }
  }
  Serial.print (button[1]);
  Serial.print ("  ");
  Serial.print (button[2]);
  Serial.print ("  ");
  Serial.print (button[3]);
  Serial.print ("  ");
  Serial.println(i);
}

johnwasser:
I don't understand what the variable 'i' is being used for and what the various values mean. Perhaps you can think of a better name and make it a ENUM so the values can be given names, too.

int input = 22;   // Shouldn't this be 'const byte' since it represents a pin number?

byte button [4] = {0, 0, 0, 0};  // Why are your 'bool' values declared 'byte' and not 'bool'?
int i = 0;  // What is this variable used for?
unsigned long startTime = 0;
const unsigned long delayTime = 100;
void setup()
{
  pinMode (input, INPUT_PULLUP);
  Serial.begin(9600);  // It's not 1974 anymore.  I recommend 115200 baud
}
void loop()
{
  button [0] = !digitalRead (input);
  if (button [0] == true)
  {
    button [1] = true;
  }

if (button [1] == true)
  {
    i++;  // Counting the number of times the button was found to be pressed?
    if (i == 1)
    {
      button [3] = !button[3];  // First time, toggle #3
    }

if (i == 2)
    {
      button [2] == true;
    }
  }
  //else {button [2] == false;}
  if (( button [1] == true) && (button [0] == false))
  {
    startTime = millis();
    if (( millis() - startTime) > delayTime)  // This is never going to be true.  mllis()-millis() will almost never be above 0 and never above 100.
    {
      Serial.println(startTime);
      button [1] = false;
      i = 0;
    }
  }
  Serial.print (button[1]);
  Serial.print ("  ");
  Serial.print (button[2]);
  Serial.print ("  ");
  Serial.print (button[3]);
  Serial.print ("  ");
  Serial.println(i);
}

johnwasser:
I don't understand what the variable 'i' is being used for and what the various values mean. Perhaps you can think of a better name and make it a ENUM so the values can be given names, too.

int input = 22;   // Shouldn't this be 'const byte' since it represents a pin number?

byte button [4] = {0, 0, 0, 0};  // Why are your 'bool' values declared 'byte' and not 'bool'?
int i = 0;  // What is this variable used for?
unsigned long startTime = 0;
const unsigned long delayTime = 100;
void setup()
{
  pinMode (input, INPUT_PULLUP);
  Serial.begin(9600);  // It's not 1974 anymore.  I recommend 115200 baud
}
void loop()
{
  button [0] = !digitalRead (input);
  if (button [0] == true)
  {
    button [1] = true;
  }

if (button [1] == true)
  {
    i++;  // Counting the number of times the button was found to be pressed?
    if (i == 1)
    {
      button [3] = !button[3];  // First time, toggle #3
    }

if (i == 2)
    {
      button [2] == true;
    }
  }
  //else {button [2] == false;}
  if (( button [1] == true) && (button [0] == false))
  {
    startTime = millis();
    if (( millis() - startTime) > delayTime)  // This is never going to be true.  mllis()-millis() will almost never be above 0 and never above 100.
    {
      Serial.println(startTime);
      button [1] = false;
      i = 0;
    }
  }
  Serial.print (button[1]);
  Serial.print ("  ");
  Serial.print (button[2]);
  Serial.print ("  ");
  Serial.print (button[3]);
  Serial.print ("  ");
  Serial.println(i);
}

I is the counter variable. This is just a test, it will be cleaned up after it works as it should.

Instead of numbers, name these options. It will make this into something useful in the future.

button[isPressed]

button[shortPress]

button[becamePressedSinceLastTime]

button[longPress]

Make up your own names for your own purposes.

How can you initialise this in one array?

You have to define those variables somewhere.

const int isPressed = 0;

Or, a slightly better way is to use an enum. (Look it up.)

Note that const int generally won't use up any precious SRAM because the compiler can see that it is a constant and stores that value in PROGMEM.

JimmyTheGuitarman:
I is the counter variable. This is just a test, it will be cleaned up after it works as it should.

Readable code is most useful during development and debugging.

Use a state machine with a single enum for the state variable, not lots of bools, the code will
be far clearer to think about and to read. After all a button is only ever in one state at a time,
and its far easier to name a state than to name a pattern of several bools.

Take the toggle state outside the debounce code, its nothing to do with debouncing, its part of
the use of the button at a higher level.

It seems to me the states you need are:
INACTIVE
PRESSED
PRESSED_CONFIMED

pressing the button moves from INACTIVE to PRESSED and records the time
releasing the button moves back to INACTIVE
being in the PRESSED state when the time since the press was recorded becomes greater than
some threshold transitions from PRESSED to PRESSED_CONFIRMED and does a callback to the
client code. For you the client code callback should toggle your boolean.

So something like:

  if (digitalRead (button))
  {
    if (state == INACTIVE)
    {
      state = PRESSED ;
      start_time = millis() ;
    }
    else
      state = INACTIVE ;
  }
  if (state == PRESSED && millis() - start_time > delay_time)
  {
    state = PRESSED_CONFIRMED ;
    callback () ;
  }