Skip to content

Instantly share code, notes, and snippets.

@DoomHammer
Created August 4, 2023 16:23
Show Gist options
  • Save DoomHammer/f833ffb865d32649873a81f4b57f8ba9 to your computer and use it in GitHub Desktop.
Save DoomHammer/f833ffb865d32649873a81f4b57f8ba9 to your computer and use it in GitHub Desktop.
# Based on https://www.geeksforgeeks.org/create-stopwatch-using-python/
import tkinter as Tkinter
from datetime import datetime
import serial
from serial.tools import list_ports
import time
import threading
class ServerThread(threading.Thread):
def __init__(self, port):
threading.Thread.__init__(self)
self.is_server_running = False
self.daemon = True
self.port = port
def run(self):
global label
global running
global state
global pause
self.is_server_running = True
with serial.Serial(self.port, 115200, timeout=0) as ser:
while self.is_server_running:
s = ser.read(30)
# if s != b'':
# print(s)
try:
cmd = ""
message = s.decode("ascii").strip()
if len(message) > 0:
print(message)
if message[0] == "0":
cmd = "FREE"
pause = False
print("Unpaused")
elif message[0] == "1":
cmd = "START"
pause = False
print("Unpaused")
elif message[0] == "2" and not pause:
cmd = "RESET"
pause = True
print("Paused")
print(cmd)
else:
continue
if state == "BEGIN":
if cmd == "RESET":
label["text"] = "00:00.000"
state = "CONTEST_0"
elif state == "CONTEST_0":
if cmd == "RESET":
state = "CONTEST_0"
elif cmd == "START":
state = "STARTING"
ser.write(b"1")
elif state == "STARTING":
if cmd == "RESET":
state = "CONTEST_0"
if cmd == "FREE":
Start(label)
state = "RUNNING"
elif state == "RUNNING":
if cmd == "START":
Stop()
state = "CONTEST_F"
elif state == "CONTEST_F":
if cmd == "RESET":
Reset(label)
state = "CONTEST_0"
print(state)
except UnicodeDecodeError:
pass
welcome_message = "KolekTYw"
start_time = time.time_ns()
running = False
state = "BEGIN"
pause = False
serial_devices = []
def counter_label(label):
def count():
global running
if running:
global start_time
tt = (time.time_ns() - start_time) // (1000 * 1000)
dt = datetime.utcfromtimestamp(tt // 1000)
display = dt.strftime("%M:%S") + ".{:03d}".format(tt % 1000)
label["text"] = display # Or label.config(text=display)
# label.after(arg1, arg2) delays by
# first argument given in milliseconds
# and then calls the function given as second argument.
# Generally like here we need to call the
# function in which it is present repeatedly.
# Delays by 1ms and call count again.
label.after(1, count)
# Triggering the start of the counter.
count()
def Start(label):
print("START!")
global running
global start_time
for serial_device in serial_devices:
with serial.Serial(serial_device, 115200, timeout=0) as ser:
ser.write(b"S")
running = True
start_time = time.time_ns()
counter_label(label)
def Stop():
print("STOP!")
global running
for serial_device in serial_devices:
with serial.Serial(serial_device, 115200, timeout=0) as ser:
ser.write(b"Z")
running = False
def Reset(label):
print("RESTART!")
global counter
global running
for serial_device in serial_devices:
with serial.Serial(serial_device, 115200, timeout=0) as ser:
ser.write(b"R")
label["text"] = "00:00.000"
ports = list_ports.comports()
root = Tkinter.Tk()
root.title("Ninja Stopwatch")
root.configure(bg="#d41423")
root.attributes("-fullscreen", True)
f = Tkinter.Frame(root, width=300, height=300, bg="#d41423")
f.grid(row=0, column=0, sticky="NW")
label = Tkinter.Label(
root, text=welcome_message, bg="#d41423", fg="white", font="Courier 240 bold"
)
label.place(relx=0.5, rely=0.7, anchor=Tkinter.CENTER)
for port in ports:
print(f"Found a Serial port {port.device}")
serial_devices.append(port.device)
server_thread = ServerThread(port.device)
server_thread.start()
root.mainloop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment