You must be logged in to reply.

Page 1 of 1 out of 4 messages.

Detecting Double-Click Via Interrupt Driven Momentary Button

Posted 2yr ago
by Gismofx | Senior | 1,322 exp
Posted 2yr ago
by Gismofx | Senior | 1,322 exp
I've been mulling it over for quite some time and haven't uncovered any "simple" way to detect a double click via a momentary push button.

I've got a momentary button, hardware debounced, and I can detect a single-click and a "press and hold" events, but double-click has me stumped. Are there an techniques to facilitate this? (Detecting a double-click without running a single-click event twice)

What I'm thinking of is looking into the interrupt queue when I get a single click to see if there's another interrupt pending/queued and within a specific time to detect a double-click.

Is this possible? If so, how can it be implemented?
2 likes
Reply #1 — Posted 2yr ago (modified)
by glx | Senior | 3,332 exp
Reply #1 — Posted 2yr ago (modified)
by glx | Senior | 3,332 exp
Well, after I read this, I also wanted to know, how it can be done Thinking Cheesy
I thought this would be a solution:

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHI.Pins;

namespace MFCTestApp002
{
    public class Program
    {
        public static void Main()
        {
            Debug.Print(Resources.GetString(Resources.StringResources.String1));
            InterruptPort inter = new InterruptPort(G80.Gpio.PE4, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeLow);
            inter.OnInterrupt += new NativeEventHandler(buttonevent);
            
            Thread.Sleep(-1);
        }

        static int wasclicked = 0;
        private static void buttonevent(uint port, uint state, DateTime time)
        {
            wasclicked += 1; //when the event is fired, raise the counter by one
            Debug.Print("Event clicks: " + wasclicked.ToString());
            new Thread(() =>
            {
                Thread.Sleep(500); //the time to collect the clicks
                if (wasclicked == 1)
                {
                    wasclicked = 0;
                    Debug.Print("Singleclick"); //or any code you like to do with one click
                }
                else if (wasclicked == 2)
                {
                    wasclicked = 0;
                    Debug.Print("DoubleClick"); //or any code you like to do with two clicks
                }
                else if (wasclicked == 3)
                {
                    wasclicked = 0;
                    Debug.Print("TrippleClick"); //or any code you like to do with three clicks
                }
                else //these are all invalid counts
                {
                    wasclicked = 0; //reset the counter, so the other threads don't do anything
                }
            }).Start();
        }

    }
}


The new thread waits 500ms to collect the number of clicks, before it decides what line of code to execute (maybe that could be done more beautyful with delegates or something), before executing the code it resets the counter, so if there is complex code, the other threads don't also execute anything. if there was clicked an invalid number of times, nothing happens. The only disadvantage you could find is, that the time begins to tick from the first click you did, so its hard to reach maybe five clicks, so it's a bit limited how many different things you can execute with one button.

Event clicks: 1
Singleclick
The thread '<No Name>' (0x2e) has exited with code 0 (0x0).
Event clicks: 1
Event clicks: 2
DoubleClick
The thread '<No Name>' (0x2f) has exited with code 0 (0x0).
The thread '<No Name>' (0x30) has exited with code 0 (0x0).
Event clicks: 1
Event clicks: 2
Event clicks: 3
TrippleClick
The thread '<No Name>' (0x31) has exited with code 0 (0x0).
The thread '<No Name>' (0x32) has exited with code 0 (0x0).
The thread '<No Name>' (0x33) has exited with code 0 (0x0).
Event clicks: 1
Event clicks: 2
Event clicks: 3
Event clicks: 4
The thread '<No Name>' (0x34) has exited with code 0 (0x0).
The thread '<No Name>' (0x35) has exited with code 0 (0x0).
The thread '<No Name>' (0x36) has exited with code 0 (0x0).
The thread '<No Name>' (0x37) has exited with code 0 (0x0).
Reply #2 — Posted 2yr ago
by willgeorge | King | 33,998 exp
Reply #2 — Posted 2yr ago
by willgeorge | King | 33,998 exp
@Gismofx -

I liked glx post.. Pretty slick.

You could also use something like this for gadgeteer.

button2.ButtonPressed += button2_ButtonPressed;
button2.TurnLedOff();

static bool isfirstclick = true;
static bool issecondclick = false;

void button2_ButtonPressed(GMG.Button sender, GMG.Button.ButtonState state)
{
	while (button2.Pressed)
	{
		button2.TurnLedOn();
	}

	if (isfirstclick)
	{
		button2.TurnLedOff();
		Debug.Print("\r\nButton 2 pressed first time.  isfirstclick = " + isfirstclick.ToString());
		Debug.Print("issecondclick = " + issecondclick.ToString());
		isfirstclick = false;
	}
	else
	{
		issecondclick = true;

		Debug.Print("\r\nButton 2 pressed second time.  isfirstclick = " + isfirstclick.ToString());
		Debug.Print("issecondclick = " + issecondclick.ToString());
		Debug.Print("Do something on second click of button");

		isfirstclick = true;
		issecondclick = false;
		DoSomething();
	}   
}
//

void DoSomething()
{
	button2.TurnLedOff();
	Thread.Sleep(300);
	button2.TurnLedOn();
	Thread.Sleep(300);
	button2.TurnLedOff();
	Thread.Sleep(300);
	button2.TurnLedOn();
	Thread.Sleep(300);
	button2.TurnLedOff();

	Debug.Print("DoSomething blinks button led off/on.");
}
//


Debug Output:

Button 2 pressed first time.  isfirstclick = True
issecondclick = False

Button 2 pressed second time.  isfirstclick = False
issecondclick = True
Do something on second click of button
DoSomething blinks button led off/on.

Button 2 pressed first time.  isfirstclick = True
issecondclick = False

Button 2 pressed second time.  isfirstclick = False
issecondclick = True
Do something on second click of button
DoSomething blinks button led off/on.
Reply #3 — Posted 2yr ago
by stotech | Senior | 1,926 exp
Reply #3 — Posted 2yr ago
by stotech | Senior | 1,926 exp
Nice I've been wondering how to do this for my next project, perfect timing.

Thanks heaps.

Page 1 of 1 out of 4 messages.

You must be logged in to reply.