Oct-11-2018, 08:04 AM
Hi all,
I'm trying to build a simple command-line interface that has a normal task running, and responds to a key pressed by the user. But I'm not getting it right, and I might be over-complicating it..
The goal is a command-line tool to update the clock of an Arduino with RTC module. The Arduino sends it current time every second. What I want to achieve is that the command line looks something like below: user connects, the system time and Arduino time are shown (updated every second over the same line). If the user presses 'u' or 'q', the program updates or stops, respectively. The user input can be with or without return, I don't mind.
I attempted now to do it with two threads and input() and that sort of works. I also tried getch() and sys.stdin.read(1), but input() is so far most successful. What happens now is that the input-thread is started right away and the input '>' is not in the right spot. For elegance I looked into registering key presses rather than input(), but most solutions I found online use unnecessarily large libraries for this.
Any thoughts on how I should approach this are welcome :)
I'm trying to build a simple command-line interface that has a normal task running, and responds to a key pressed by the user. But I'm not getting it right, and I might be over-complicating it..
The goal is a command-line tool to update the clock of an Arduino with RTC module. The Arduino sends it current time every second. What I want to achieve is that the command line looks something like below: user connects, the system time and Arduino time are shown (updated every second over the same line). If the user presses 'u' or 'q', the program updates or stops, respectively. The user input can be with or without return, I don't mind.
I attempted now to do it with two threads and input() and that sort of works. I also tried getch() and sys.stdin.read(1), but input() is so far most successful. What happens now is that the input-thread is started right away and the input '>' is not in the right spot. For elegance I looked into registering key presses rather than input(), but most solutions I found online use unnecessarily large libraries for this.
Any thoughts on how I should approach this are welcome :)
1 2 3 4 5 6 7 8 9 |
COM Ports available: COM1, COM2, COM3 Select COM port to connect: <user input > Connected to COM - port. Press 'u' to update or 'q' to quit. System date / time: 2018 - 10 - 11 09 : 44 : 00 < - - these lines are constantly updated Arduino date / time: 2001 - 01 - 01 00 : 00 : 00 < - - > (optional line where it waits for user input ) Updating... System date / time: 2018 - 10 - 11 09 : 44 : 02 Arduino date / time: 2018 - 10 - 11 09 : 44 : 02 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
import time import threading data_ready = threading.Event() kill_flag = threading.Event() def keyboard_poller(): global key_pressed loop = True while loop: time.sleep( 0.1 ) if kill_flag.isSet(): loop = False ch = input ( ">" ) if ch: key_pressed = ch data_ready. set () def main(): curr_millis = time.time() * 1000 prev_millis = curr_millis poller = threading.Thread(target = keyboard_poller) poller.start() loop = True while loop: curr_millis = time.time() * 1000 if (curr_millis - prev_millis) > = 1000 : print ( "Another second passed..." + str (curr_millis) + "\r" ) prev_millis = curr_millis # Do some extra stuff here if data_ready.isSet(): if key_pressed.lower() = = "q" : kill_flag. set () loop = False else : print ( "You pressed: " + key_pressed) data_ready.clear() if __name__ = = "__main__" : print ( "Started.." ) main() input ( "Press any key to exit..." ) exit() |