Connect with us

AVR: detecting various button presses

Discussion in 'Electronic Design' started by Pawel Paron, Oct 29, 2003.

Scroll to continue with content
  1. Pawel Paron

    Pawel Paron Guest

    I'm looking for example procedures (preferably in assembler), or any ideas
    how to do the following with tiny15:

    - detect single short button press
    - detect fast double-click
    - detect single long press

    All with the same single button, and without consuming all processor time
    inside idle counter loops. I'd like to use timer0 for regular interrupts to
    poll the button register, and timer1 for PWM (so no extra timer is available
    for time counting).

    Thanks in advance for any advices

  2. Dave VanHorn

    Dave VanHorn Guest

    Poll reasonably frequently
    Having detected the first one, and knowing that it's no longer pressed,
    start a timer byte that will still be non-zero if the button is pressed
    again in a short while. Decrement this timer byte to zero with something
    like the T0overflow ISR set to 10-100mS per
    Having detected button down, start incrementing a "held button" byte, each
    time you poll.
    If it gets high enough, you're there. If you detect "button not pressed",
    then zero the counter.

    You got ram dont you? :)
  3. Pawel,

    I don't expect you to find "ready for use" code and if you find something
    that looks like what you need, you may be trapped. It's often harder to
    modify excisting code then to write your own, especially if you do not fully
    understand that other code. Besides, the code itself will be short and
    simple. The problems you need to face are both timing and interrupt

    Let's treat timing.
    You have to decide whether your processor has to listen to the switch all
    the time or not but that has to do with its other tasks.
    You have to decide the bounds of your swiching times. How long should a
    single short pulse last, how long the time of the first of two pulses, the
    time of the pause between the first and the second etc. Once you defined
    this times you can decide the setting of your timer. Assume the shortest
    pulse you want to recognise is 100ms, your timer should be set to, let's
    say, 50ms. So you get an interrupt every 50ms. To complete the example, a
    short pulse may lasts 100-500ms, a long one 600ms-2s and the pause between
    two shorts 200-500ms.

    Interrupt handling.
    An interrupt routine should be as short as possible. In this particular
    case, basically all it has to do is reading the input pin and report its
    value to the main program. Treating the counting and the status can be done
    in the main program loop as long as this loop lasts no longer then 50ms.
    Otherwise you can succesfully do the counting in the interrupt routine. So
    you reserve a (RAM)byte for the ones and another for the zeros and increment
    the appropriate byte by the interrupt routine. Keep in mind to switch of the
    interrupt temperory when you read and reset this bytes in the main program

    In the main program you can keep track of the things happened using some
    other RAM places. For instance, a short pulse has occured and you're
    counting the time the switch has been released to decide whether or not a
    second short pulse has to be detected.

  4. Pawel Paron

    Pawel Paron Guest

    Thanks for help. Actually I finished this part yesterday, in the way very
    similar that you describe, using two registers as counters, increasing,
    decreasing and clearing them apropriately within timer interrupt routine.
    Wasn't that difficult like it seemed before.

  5. There are several AVR application notes dealing with keypads here is a
    link to one of them

Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day