Python Forum
Read a single event (keypress) from asyncio
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Read a single event (keypress) from asyncio
#1
I'm using asyncio library to read input from a Infra Red remote control.
This is python 3.7 branch on an Orange Pi Zero, using the built in IR receiver as
the event loop.

The problem is asyncio is so fast that a single keypress will often read multiple times.
Is there any way to read a single event, or perhaps wait 50 milliseconds ?

Below is the python Code

import asyncio
from evdev import InputDevice
irr = InputDevice('/dev/input/event0')

#  Receive keypress from IRR and store as 'code'
async def rec_code():
    await asyncio.sleep(0.1)
    async  for event in irr.async_read_loop():
        if event.type == 4:
            global code
            await asyncio.sleep(0.2)	# small delay to prevent two keypresses 
            code = event.value
            await asyncio.sleep(0.2)	# small delay to prevent two keypresses 
            print("IRC Code ",code)

async def delay5():
    while True:
        await asyncio.sleep(5)
        print("5 sec delay")

#  Create asyncio loop run two independent timer loops and  IR receiver function
loop= asyncio.get_event_loop()
loop.create_task(delay5())
loop.create_task(rec_code())
loop.run_forever()
Below is the output:
IRC Code 5
IRC Code 5
IRC Code 2
IRC Code 4

So sometimes a single keypress i.e. 2 or 4 is displayed, but mostly it will report multiple
reads as button 5 has been reported twice.
Wanted Output:
IRC Code 5
IRC Code 2
IRC Code 4

I would like some way to catch just one keypress.
I've tried to slow down event loop reading with multiple
await asyncio.sleep(0.1)

lines, but Im still reading same key twice.

Thanks in advance for any help
Reply
#2
This is a difficult question to answer without knowing more about the messages sent by the remote. Does it send a button release message? If so, you can ignore button presses (repeats) between the initial press and the release. If it doesn't send a release you could do something like record the time for each button press event and ignore the press if it occurred to soon after the prior event.
Reply
#3
(May-26-2021, 03:38 PM)deanhystad Wrote: This is a difficult question to answer without knowing more about the messages sent by the remote. Does it send a button release message? If so, you can ignore button presses (repeats) between the initial press and the release. If it doesn't send a release you could do something like record the time for each button press event and ignore the press if it occurred to soon after the prior event.

Thanks for your help. The remote control uses RC5 protocol, and I modified the code to print all events as below:

import asyncio
from evdev import InputDevice
irr = InputDevice('/dev/input/event0')
list = []
#  Receive keypress from IRR and store as 'code'
async def rec_code():
    await asyncio.sleep(0.2)
    async  for event in irr.async_read_loop():
        await asyncio.sleep(0.2)    # small delay to prevent two keypresses 
        print (event)
        if event.type == 4:
            code = event.value
            await asyncio.sleep(0.05)	# small delay to prevent two keypresses 
            print("IRC Code ",code)
async def delay5():
    while True:
        await asyncio.sleep(5)
        print("5 sec delay")

#  Create asyncio loop run two independent timer loops and  IR receiver function
loop= asyncio.get_event_loop()
loop.create_task(delay5())
loop.create_task(rec_code())
loop.run_forever()
The output is shown below, a key pressed generated a type 04 event and a release
generates a type 00 event as below


event at 1622048234.443833, code 04, type 04, val 02
IRC Code 2
event at 1622048234.443833, code 00, type 00, val 00
event at 1622048234.554707, code 04, type 04, val 02
IRC Code 2
event at 1622048234.554707, code 00, type 00, val 00
event at 1622048236.268338, code 04, type 04, val 04
IRC Code 4
event at 1622048236.268338, code 00, type 00, val 00
event at 1622048236.379183, code 04, type 04, val 04
IRC Code 4
event at 1622048236.379183, code 00, type 00, val 00

The output is from keys '2' and '4' pressed on the remote.
The asyncio is processing so fast and I've slowed down the Orange Pi
to run at 400Mhz.

I think the problem is even with the delays in asyncio loop it is asynchronously
collecting events.
Reply
#4
Remove all the waits while continuing to print the events. If the code shows the event toggling between 04 and 00 it means that there are multiple events sent and you are not looking at the same event over and over.

Unless my understanding of evdev.InputDevice is wrong, putting a delay in your event processor (rec_code()) will not change the number of button press events. The events will remain in the event queue until read. The only thing the wait does is make your code take a longer time to process all the events. It sounds like you came to the same conclusion.

With your code set up to print all events, press and hold a button. Do you get a stream of 4, 0, events or just one? If you get many events my guess is the remote does the same thing as key-repeat on a keyboard; it is generating press/release events as long as hold the button down. Is the delay the same between each 04 event? To make this easier to spot I would print the elapsed time since last event. Something like this:
async def rec_code():
    end_time = time()
    async for event in irr.async_read_loop():
        start_time, end_time =endtime,  time()
        print (end_time - start_time, event)
Once you know the delay between these repeat events you can use elapsed time to filter them out.
async def rec_code():
    end_time = time()
    async for event in irr.async_read_loop():
        start_time, end_time =endtime,  time()
        if end_time - start_time > repeat_time:
            # Process button press
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [GPX] Read all trkpt, and merge into single track? Winfried 0 1,521 Jan-30-2020, 04:08 PM
Last Post: Winfried
  Asyncio StreamReader read method doesn't respect timeout when using SSL dukadahake 0 3,451 Jul-24-2019, 11:55 AM
Last Post: dukadahake
  Keypress when running a python app in a console on windows Stephen 6 8,880 Apr-16-2019, 12:38 PM
Last Post: Stephen
  Using asyncio to read text file and load GUI QueenSvetlana 1 4,764 Nov-09-2017, 02:55 PM
Last Post: heiner55

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020