Timed input routine not working

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
Post Reply
timmer
Posts: 2
Joined: Mon Feb 15, 2021 2:42 pm

Timed input routine not working

Post by timmer » Mon Feb 15, 2021 2:56 pm

Hi,
I took some code from the internet, as I want an input routine that waits for 5 seconds before continuing.
So, routine asks for input, if no input within 5 seconds, program shall continue.
If there is input, the entered string shall be the output. After entering any 1st character the timer shall stop.
I can't get this to work, any help is appreciated.
(Micro Python V1.14 on NodeMCU 8266)
Eric


import uasyncio
import usys
import uos


# asyncio.coroutine
def timed_input(prompt, timeout=5):
"""Wait for input from the user
Note that user input is not available until the user pressed the enter or
return key.
Arguments:
prompt - text that is used to prompt the users response
timeout - the number of seconds to wait for input
Raises:
An asyncio.futures.TimeoutError is raised if the user does not provide
input within the specified timeout period.
Returns:
A string containing the users response
"""
# Write the prompt to stdout
print("timed input 0")
usys.stdout.write(prompt)
print("timed input 1a")
usys.stdout.flush()
print("timed input started 1")
loop = uasyncio.get_event_loop()
print("timed input started 2")
queue = uasyncio.Queue()
print("timed input started 3")

# The response callback will receive the users input and put it onto the
# queue in an independent task.
def response():
loop.create_task(queue.put(sys.stdin.readline()))

# Create a reader so that the response callback is invoked if the user
# provides input on stdin.
loop.add_reader(sys.stdin.fileno(), response)

try:
# Wait for an item to be placed on the queue. The only way this can
# happen is if the reader callback is invoked.
return (yield from uasyncio.wait_for(queue.get(), timeout=timeout))

except uasyncio.futures.TimeoutError:
# Make sure that any output to stdout or stderr that happens following
# this coroutine, happens on a new line.
usys.stdout.write('\n')
usys.stdout.flush()
raise

finally:
# Whatever happens, we should remove the reader so that the callback
# never gets called.
loop.remove_reader(sys.stdin.fileno())


# asyncio.coroutine
def greet():
try:
print("greet 1")
name = yield from timed_input("What is your name? ", 5)
print("greet 2")
print("Hello, " + name)

# except uasyncio.futures.TimeoutError:
except uasyncio.TimeoutError:
print("What is the matter? Are you shy?")


print("Start")
loop = uasyncio.get_event_loop()
print("loop defined")
loop.run_until_complete(greet())

User avatar
pythoncoder
Posts: 5096
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Timed input routine not working

Post by pythoncoder » Tue Feb 16, 2021 1:55 pm

The problem is that the sys.stdin.read methods are blocking calls and are therefore incompatible with uasyncio. You need a nonblocking method which can check whether any characters are waiting on stdin (like the UART any method).

I don't know of a way of doing this.
Peter Hinch

timmer
Posts: 2
Joined: Mon Feb 15, 2021 2:42 pm

Re: Timed input routine not working

Post by timmer » Wed Feb 17, 2021 5:31 pm

Thank you Peter.
I will study further, I learned programming 35 years ago, and picked this up again as Covid gives me so much time. It is fun to do that in Micro Python on a NodeMCU. A lot to catch up indeed.

Post Reply