From 0d13c7604f6bd4e388d0c22f4c43f9a459068d41 Mon Sep 17 00:00:00 2001 From: Kai Vogelgesang Date: Wed, 21 Dec 2022 16:53:06 +0100 Subject: [PATCH] Add hot reload example --- microcontroller/.gitignore | 3 +- microcontroller/ctrl.py | 29 +++++++-------- microcontroller/hotreload.py | 69 ++++++++++++++++++++++++++++++++++++ microcontroller/scene.py | 29 +++++++++++++++ 4 files changed, 115 insertions(+), 15 deletions(-) create mode 100644 microcontroller/hotreload.py create mode 100644 microcontroller/scene.py diff --git a/microcontroller/.gitignore b/microcontroller/.gitignore index 1cbef32..c392fab 100644 --- a/microcontroller/.gitignore +++ b/microcontroller/.gitignore @@ -1,4 +1,5 @@ .vscode .mypy_cache venv -build \ No newline at end of file +build +__pycache__ diff --git a/microcontroller/ctrl.py b/microcontroller/ctrl.py index 9fd4646..1fff61d 100644 --- a/microcontroller/ctrl.py +++ b/microcontroller/ctrl.py @@ -5,24 +5,25 @@ import colorsys import sys channels = [ - 192, # pan - 0, # tilt - 134, # dimmer - 255, # R - 0x88, # G - 0, # B - 0, # W - 1, # movement speed - 0, # RST + 255, # dimmer + 0, # R + 0, # G + 0, # B + 0, # W + 0, # A + 0, # UV + 0, # Strobe + 0, # function + 0, # function speed ] -start_addr = 10 +start_addr = 1 with serial.Serial("/dev/ttyUSB0", 500000) as ser: payload = bytearray(512) - FPS = 30 + FPS = 50 if len(sys.argv) > 1: FPS = int(sys.argv[1]) @@ -46,9 +47,9 @@ with serial.Serial("/dev/ttyUSB0", 500000) as ser: r, g, b = colorsys.hls_to_rgb(t, 0.5, 1) - channels[3] = int(255 * r) - channels[4] = int(255 * g) - channels[5] = int(255 * b) + channels[1] = int(255 * r) + channels[2] = int(255 * g) + channels[3] = int(255 * b) payload[(start_addr - 1) : (start_addr - 1 + len(channels))] = channels diff --git a/microcontroller/hotreload.py b/microcontroller/hotreload.py new file mode 100644 index 0000000..5226364 --- /dev/null +++ b/microcontroller/hotreload.py @@ -0,0 +1,69 @@ +import importlib +import time +import os +import sys +import traceback + +import serial +import scene + +start_addr = 1 + +with serial.Serial("/dev/ttyUSB0", 500000) as ser: + + payload = bytearray(512) + + FPS = 50 + if len(sys.argv) > 1: + FPS = int(sys.argv[1]) + + FRAME_TIME = 1 / FPS + t = 0 + + def sync(): + # wait for sync + while True: + b = ser.readline() + if b.strip() == b"Sync.": + return + + sync() + + print("initial sync.") + + last_edit_timestamp = os.stat(scene.__file__).st_mtime_ns + while True: + + loop_start = time.time() + + try: + timestamp = os.stat(scene.__file__).st_mtime_ns + if timestamp > last_edit_timestamp: + print("[importlib.reload]") + importlib.reload(scene) + last_edit_timestamp = timestamp + scene.display(t, payload) + except Exception: + traceback.print_exc() + + ser.write(payload) + ser.flush() + + response = ser.readline() + if response.strip() != b"Ack.": + print(f"received bad response: {response!r}") + sync() + continue + + t += FRAME_TIME + t %= 1 + + loop_time = time.time() - loop_start + if loop_time < FRAME_TIME: + time.sleep(FRAME_TIME - loop_time) + else: + print("loop took too long!") + + print(f"loop time: {1000 * loop_time:0.2f}ms busy, {1000 * (time.time() - loop_start):0.2f}ms total") + + # print(ser.read_all()) diff --git a/microcontroller/scene.py b/microcontroller/scene.py new file mode 100644 index 0000000..c61bd9a --- /dev/null +++ b/microcontroller/scene.py @@ -0,0 +1,29 @@ +import colorsys + +channels = [ + 255, # dimmer + 0, # R + 0, # G + 0, # B + 0, # W + 0, # A + 0, # UV + 0, # Strobe + 0, # function + 0, # function speed +] + +start_addr = 1 + +def display(t, payload): + r, g, b = colorsys.hls_to_rgb(t, 0.5, 1) + + #channels[1] = int(255 * r) + #channels[2] = int(255 * g) + #channels[3] = int(255 * b) + channels[4] = 0 + channels[5] = 0 + channels[6] = 255 + channels[7] = 0 + + payload[(start_addr - 1) : (start_addr - 1 + len(channels))] = channels \ No newline at end of file