Page 1 of 2
Differentiate Double & Single Click of a button
Posted: Wed May 27, 2020 7:48 pm
by Mrfittingin
Hey guys
I have started to learn MicroPython recently, there is one problem I struggled for a while, I have been searching for solutions online and still have no clew what to do. Please help, Thanks.
This is the code, I have used aswitch.py module, I wish to achieve when I am double click the button, only the Yellow LED lights up( the Blue LED has no reaction while there is a double click of the button). and When this is long press, only the Green LED lights up. ( the Blue LED has no reaction while there is a long press of the button)
How should I change the Code to reach this function?
Code: Select all
from pyb import LED
from machine import Pin
import uasyncio as asyncio
from aswitch import Pushbutton
def toggle(led):
led.toggle()
async def my_app():
await asyncio.sleep(600)
pin = Pin('X1', Pin.IN, Pin.PULL_UP) # Pushbutton to gnd
blue = LED(4)
yellow = LED(3)
green = LED(2)
pb = Pushbutton(pin)
pb.press_func(toggle, (blue,)) # Note how function and args are passed
pb.double_func(toggle, (yellow,)) # Note how function and args are passed
pb.long_func(toggle, (green,)) # Note how function and args are passed
loop = asyncio.get_event_loop()
loop.run_until_complete(my_app()) # Run main application code
Re: Differentiate Double & Single Click of a button
Posted: Wed May 27, 2020 9:18 pm
by kevinkk525
pb = Pushbutton(pin, suppress=True)
Should solve your problem.
Re: Differentiate Double & Single Click of a button
Posted: Thu May 28, 2020 12:17 pm
by Mrfittingin
Hey Kiven
Thank you for you help, I have added pb = Pushbutton(pin, suppress=True) into my code, but it did not work as I expected, the blue light always light up when the first click was pushed of the double click (same for the long press as well).
I wonder if there is any delay function or time frame interval function to let the full signal to go through, then start to process it?
I pasted the code down below.
Thank you!
Code: Select all
from pyb import LED
from machine import Pin
import uasyncio as asyncio
from aswitch import Pushbutton
def toggle(led):
led.toggle()
async def my_app():
await asyncio.sleep(600)
pin = Pin('X1', Pin.IN, Pin.PULL_UP) # Pushbutton to gnd
blue = LED(4)
yellow = LED(3)
green = LED(2)
pb = Pushbutton(pin, suppress=True)
pb.double_func(toggle, (yellow,)) # Note how function and args are passed
pb.long_func(toggle, (green,)) # Note how function and args are passed
pb.press_func(toggle, (blue,)) # Note how function and args are passed
loop = asyncio.get_event_loop()
loop.run_until_complete(my_app()) # Run main application code
Re: Differentiate Double & Single Click of a button
Posted: Fri May 29, 2020 10:20 am
by pythoncoder
@Mrfittingin I think you have misunderstood the
docs.
For a callback which occurs only on a single short press, you need to assign it to
release_func and set
suppress=True. As you have found,
press_func still occurs on initial button press; this is by design. The reasoning is explained in the above doc. Note that response is necessarily delayed: this is also explained in the doc.
Re: Differentiate Double & Single Click of a button
Posted: Fri May 29, 2020 10:37 am
by kevinkk525
oh yes, thanks @pythoncoder. I missed the detail about having to use the release_func
Re: Differentiate Double & Single Click of a button
Posted: Mon Jun 01, 2020 2:24 pm
by Mrfittingin
Thank you so much for your help, problem solved!
Re: Differentiate Double & Single Click of a button
Posted: Fri Mar 05, 2021 2:51 am
by aerolite
Hello, I am new to micropython and have the same question for ESP32 board. Could anyone help me? I am using the M5ATOM stepper
https://docs.m5stack.com/#/en/atom/atomic_step_motor I'd like to use single click to control the direction and double click to increase the speed.
thx
Code: Select all
import stepper
import lite
import machine
import time
last_button_press = 0
if (stepper.dcInput() == 0):
lite.flashRed()
else:
lite.flashGreen()
def move(irq):
print(stepper.dcInput(),stepper.EN, stepper.DIR)
if (stepper.dcInput() == 0):
stepper.enable(False)
stepper.setSpeed(1)
lite.flashOFF()
lite.flashRed()
return
if (stepper.EN == 0 ):
stepper.enable()
lite.flashOFF()
lite.greenON(1)
if (stepper.DIR == 0):
stepper.direction(1)
lite.flashOFF()
lite.greenON(1)
else:
stepper.direction(0)
lite.flashOFF()
lite.blueON(1)
print("button pressed"+str(stepper.DIR))
def double_click(inq):
global last_button_press
# Get the current date in milliseconds
time_ms = time.ticks_ms()
# Compute the elapsed time since the last interrupt
delay = time.ticks_diff(time_ms, last_button_press)
# If the delay is shorter than 200ms (your mileage may vary), consider this as a bounce
if (delay < 200) :
return
# Else, we update the time of the last interrupt
last_button_press = time_ms
# If the delay is greater than 500ms (to be adjusted), it is a simple clock
if delay > 600: # simple click
move(1)
else:
stepper.setSpeed(stepper.SPEED+1)
button = machine.Pin(39, machine.Pin.IN, machine.Pin.PULL_UP)
button.irq(trigger = machine.Pin.IRQ_FALLING, handler = double_click)
Re: Differentiate Double & Single Click of a button
Posted: Fri Mar 05, 2021 10:40 am
by pythoncoder
See
this doc which describes a Pushbutton class where you can define callbacks for single and double clicks.
Re: Differentiate Double & Single Click of a button
Posted: Mon Mar 29, 2021 1:49 am
by aerolite
Thank you for the information. But I still can't differentiate them. I use press and long function. when I long press the the press function still called. Here is my code and output. single press is good, but long press is not.
Code: Select all
def toggleRed():
if (lite.lightStat()[0] == 0):
lite.redON(1)
else:
lite.lightOFF(0)
print( "red", lite.lightStat()[0] )
def toggleGreen():
if (lite.lightStat()[1] == 0):
lite.greenON(1)
else:
lite.lightOFF(0)
print( "green", lite.lightStat()[1] )
async def my_app():
await asyncio.sleep(60) # Dummy
pin = Pin(39, Pin.IN, Pin.PULL_UP) # Pushbutton to gnd
pb = Pushbutton(pin)
pb.press_func(toggleRed) # Note how function and args are passed
#pb.double_func(toggleGreen)
pb.long_func(toggleGreen)
asyncio.run(my_app()) # Run main application code
red 64
red 0
red 64
red 0
red 64
red 0
red 64
red 0
red 64
green 64
red 64
green 64
red 64
green 64
red 64
green 64
red 64
green 64
Re: Differentiate Double & Single Click of a button
Posted: Mon Mar 29, 2021 6:35 am
by pythoncoder
when I long press the the press function still called.
This is a) inevitable and b) explained in the docs. At the time when you press a button, the driver doesn't yet "know" if the press is going to be a long one. See section 4.1.1, the "suppress" constructor arg.
As for your code, I suggest you start with the demo program making the minimum changes to accommodate ESP32 pin numbers. Then start adapting it for your own ends.