Debouncing several inputs in Arduino world

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey All,

I have 4 digital inputs connected to my UNO.  I want to do a little debouncing(oh goodie here we go again), but from what I see in the Arduino examples, they show a single input sitting in the main loop and the code runs through that code.

 

I am thinking I could sense the input state change, and then pass the ID of the input I am monitoring to a function and have the function do the debounce and then activate a BOOL flag to be returned to the main loop for processing....

 

Am I making this more complicated than it needs to be? 

 

Jim

 

EDIT:

For reference:

https://arduinogetstarted.com/tu...

This topic has a solution.

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

Last Edited: Mon. Mar 1, 2021 - 04:26 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jgmdesign wrote:
I am thinking I could sense the input state change, and then pass the ID of the input I am monitoring to a function and have the function do the debounce and then activate a BOOL flag to be returned to the main loop for processing....

so something similar to the ezButton() function in the example reference? 

 

Flyover Jim

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ki0bk wrote:

so something similar to the ezButton() function in the example reference? 

 

 

OH HELL!!!

 

In my near sightedness I did not scroll down far enough.

 

That will work for now.

 

THANKS!

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the reference, I've added that to my library too! smiley

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jgmdesign wrote:
I want to do a little debouncing(oh goodie here we go again), but from what I see in the Arduino examples, they show a single input sitting in the main loop and the code runs through that code.
I'm not saying it's great but I wanted debounced buttons here:

 

https://github.com/wrightflyer/s...

 

Some of the pins are bouncy buttons (for example):

///////////// PORT A //////////////
DualJoystick joy(0, 1, 64); // on A0/A1
// A2 - unused
Button  butJoy(&PORTA, 3, Button::NO_PULL_UP);
Button  but1(  &PORTA, 4, Button::NO_PULL_UP);
Button  but2(  &PORTA, 5, Button::NO_PULL_UP);
Button  but3(  &PORTA, 6, Button::NO_PULL_UP);
Button  but4(  &PORTA, 7, Button::NO_PULL_UP);

Each uses:

 

https://github.com/wrightflyer/s...

and

https://github.com/wrightflyer/s...

 

That relies on the main() code also doing:

    tim.start(64);
    tim.attachInterrupt(Timer0::TIM0_COMP_ISR, timerUpdate);

and then my ISR callback is:

void timerUpdate(void) {
    enc1.intUpdate();
    enc2.intUpdate();
    enc3.intUpdate();
    enc4.intUpdate();
    enc5.intUpdate();
    enc6.intUpdate();
    enc7.intUpdate();
    enc8.intUpdate();
    but1.update();
    but2.update();
    but3.update();
    but4.update();
    but5.update();
    but6.update();
    but7.update();
    but8.update();
}

The update code being run for each button is then:


// this called back from timer interrupt.
void Button::update() {
    uint8_t in;
    in = *mPIN;
    //printf("raw=%02X ", in);
    in = in & mPinMask;
    //printf("masked=%02X, prev=%02X\r\n", in, mPrev);
    if (in == mPrev) {
        mCount++;
        if (mCount >= 4) {
            //printf("state=%02X\r\n", in);
            mState = in;
            mCount = 0;
        }
    }
    else {
        mCount = 0;
        mPrev = in;
    }
}

Because the class for each button holds a "prev" state fort the button and a "count" then it just compares current state with prev state and counts how many times it has seen that - if more than 4 consecutive inputs the button is pressed.

 

Now sure this is not as slick as Danni/Lee's solutions for bouncing which pack multiple button states into bytes and so on. This class wastefully holds a whole byte for each of:

    uint8_t mCount;
    uint8_t mPrev;
    uint8_t mState;

but the advantage is that you can instantiate as many of these as you have buttons and each instance of the class independently just handles the "memory" of each individual button. But it's not efficient and could most easily be described as wasteful. But it is simple and does the job.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Interesting way to do this Cliff.

 

I think for what is happening here, I will go with 'other Jims' find.  That I missed.

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I like to do it the way the original Nintendo did, with a shift register.  Poll the shift registers at 50Hz and you've got a 20ms debounce filter.  10ms is usually sufficient.

 

I have no special talents.  I am only passionately curious. - Albert Einstein

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Whether you use a shift or inc/dec, its probably much the same cost. Using a downcount, the test becomes a breq rather than a compare. Swings and roundabouts really.