DETECT LONGPRESS AND SHORTPRESS IN BUTTONS!

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

How to Detect Longpress and Shortpress buttons in Atxmega256a3bu xplained board?. Can anyone help me with it?

Nitin Shenoy

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

Tell and show us what you have done so far, and explain where you are stuck.

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274

 

 

 

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

Post your code that doesn't work.  If you don't have any code, post your ideas on an algorithm that would solve the problem.

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

the general idea is that when a keypress is detected, you start a timer, after timer overflow if it still pressed . . its a longpress

 

however if you stuck somewhere, just post your idead - work so far - code as already mention by

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

Set a timer interrupt to fire every 1ms or so.

Inside the ISR:

If the button is pressed, increase a counter.

When the button isn't pressed and the counter isn't zero, see how high it is to find out how long the button was pressed.

Set the respective flag(volatile!) and reset the counter.

Outside of the ISR, do what ever needs to be done and reset the flag.

 

If you set the threshold for a short press at more than one (e.g. five to ten), you get debouncing.

 

-Patrick

"Some people die at 25 and aren't buried until 75." -Benjamin Franklin

 

What is life's greatest illusion?"  "Innocence, my brother." -Skyrim

 

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

#include <avr/io.h>
#include "tc.h"
static void my_callback(void);

int main(void)
{
   pmic_init();
   sysclk_init();
   tc_enable(&TCC0);

   tc_set_overflow_interrupt_callback(&TCC0, my_callback);
   tc_set_wgm(&TCC0, TC_WG_NORMAL);
   tc_write_period(&TCC0, 624);
   tc_set_overflow_interrupt_level(&TCC0, TC_INT_LVL_LO);
   cpu_irq_enable();
   tc_write_clock_source(&TCC0, TC_CLKSEL_DIV256_gc);
   
   PORTR_DIRSET= 0x02;
                
    while (1) 
    {
    };
}

static void my_callback()
{
    
    if(TCC0.CNT == 624)
    {
        PORTR_OUTSET=0x02;
    }
    
    // User code to execute when the overflow occurs here
    //Important to clear Interrupt Flag
    tc_clear_overflow(&TCC0);
}

 

i have written this code currently to just turn off the led if the count is 624, but the program seems to get stuck in while loop.Is the idea correct?

Nitin Shenoy

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

TCC0.CNT is not going to be 624 in the overflow callback, it's reset to 0 before that (and with fast enough clocking it could already be >  0).

EDIT: btw, why check anyway? You already know there was an overflow, this is the overflow callback after all.

/Lars

Last Edited: Tue. Jan 1, 2019 - 11:48 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include <avr/io.h>
#include <util/delay.h>
#include <asf.h>
#include "tc.h"
static void my_callback(void);


int main(void)
{
   pmic_init();
   sysclk_init();
   board_init();
   PORTR_DIRSET= 0x03;
   PORTE_DIRCLR = 0x20;
   
	   	tc_enable(&TCC0);
	   	cpu_irq_enable();
	   	tc_set_wgm(&TCC0,TC_WG_NORMAL);
		tc_set_overflow_interrupt_level(&TCC0,TC_INT_LVL_LO);
	   	
	 while(1)
	 {
		if (!(PORTE.IN & PIN5_bm))
		{  
		    tc_set_resolution(&TCC0, 31250);
			tc_set_overflow_interrupt_callback(&TCC0, my_callback);
			tc_write_period(&TCC0, 2000);
		}

	 }
}

static void my_callback(void)
{
	if (!(PORTE.IN & PIN5_bm))
	{
		PORTR_OUTCLR = PIN0_bm;
		_delay_ms(400);
		PORTR_OUTSET = PIN0_bm;
		tc_clear_overflow(&TCC0);
	}
	// User code to execute when the overflow occurs here
	else 
	{
		PORTR_OUTCLR = PIN1_bm;
		_delay_ms(400);
		PORTR_OUTSET = PIN1_bm;
		tc_clear_overflow(&TCC0);
	}
}

Tried this but only PIN 0 keeps on glowing.

Nitin Shenoy

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

Suggest you take a step back and consider the design of this first before rushing to implementation. Your current code is muddled.

 

Consider the occasion when E.5 is active for 100ms. How many times will:

	 while(1)
	 {
		if (!(PORTE.IN & PIN5_bm))
		{  
		    tc_set_resolution(&TCC0, 31250);
			tc_set_overflow_interrupt_callback(&TCC0, my_callback);
			tc_write_period(&TCC0, 2000);
		}

the code in the conditional block be executed over and over again?