python script

This commit is contained in:
lucordes 2025-07-12 19:39:05 +02:00
parent d50fda1b23
commit 4b5e25f05e
2 changed files with 159 additions and 21 deletions

View File

@ -101,13 +101,19 @@ void handle_menu(void *argument);
/* USER CODE BEGIN 0 */ /* USER CODE BEGIN 0 */
int run_snake = 0; int run_snake = 0;
int run_menu = 1; int run_menu = 1;
int redraw_menu_pending;
#define RX_BUFFER_SIZE 1 #define RX_BUFFER_SIZE 1
#define LINE_BUFFER_SIZE 128 #define LINE_BUFFER_SIZE 128
uint8_t rx_buffer[RX_BUFFER_SIZE]; uint8_t rx_buffer[RX_BUFFER_SIZE];
char line_buffer[LINE_BUFFER_SIZE]; char line_buffer[LINE_BUFFER_SIZE];
uint16_t line_pos = 0; uint16_t line_pos = 0;
//menu
int redraw_menu_pending;
#define GRID_X 2
#define GRID_Y 3
uint8_t menu_status[GRID_X][GRID_Y] = { 0 };
void process_line(const char *line) { void process_line(const char *line) {
if (strncmp(line, "ABS:", 4) == 0) { if (strncmp(line, "ABS:", 4) == 0) {
char axis[32]; char axis[32];
@ -128,12 +134,19 @@ void process_line(const char *line) {
int state; int state;
if (sscanf(line, "KEY:%31[^:]:%d:", key, &state) == 2) { if (sscanf(line, "KEY:%31[^:]:%d:", key, &state) == 2) {
// Handle button press/release // Handle button press/release
//we only care about presses
if (state) {
char dir; char dir;
dir = key[0]; dir = key[0];
osStatus_t status = osMessageQueuePut(pressesHandle, &dir, 0, 0); osStatus_t status = osMessageQueuePut(pressesHandle, &dir, 0,
0);
if (status != osOK) { if (status != osOK) {
// Optional: Handle error // Optional: Handle error
} }
}
if (key[0] == 'B' && state == 1) { // B goes to the menu if (key[0] == 'B' && state == 1) { // B goes to the menu
run_snake = 0; run_snake = 0;
run_menu = 1; run_menu = 1;
@ -736,8 +749,6 @@ void snakegame(void *argument) {
* @param argument: Not used * @param argument: Not used
* @retval None * @retval None
*/ */
#define GRID_X 2
#define GRID_Y 3
#define CELL_WIDTH 120 // Adjust as needed for your screen #define CELL_WIDTH 120 // Adjust as needed for your screen
#define CELL_HEIGHT 40 #define CELL_HEIGHT 40
@ -747,6 +758,8 @@ void snakegame(void *argument) {
#define COLOR_TEXT BLACK #define COLOR_TEXT BLACK
#define COLOR_BG WHITE #define COLOR_BG WHITE
#define COLOR_SELECTED GREEN #define COLOR_SELECTED GREEN
#define COLOR_ACTIVATED RED
#define COLOR_ACTIVATED_AND_SELECTED MAGENTA
int sel_x; int sel_x;
int sel_y; int sel_y;
@ -755,6 +768,7 @@ int sel_y;
// Customize grid labels as needed // Customize grid labels as needed
const char *grid_labels[GRID_X][GRID_Y] = { { "Snake", "Options", "About" }, { const char *grid_labels[GRID_X][GRID_Y] = { { "Snake", "Options", "About" }, {
"Highscore", "Credits", "Exit" } }; "Highscore", "Credits", "Exit" } };
void redraw_menu() { //only done onece saves resources void redraw_menu() { //only done onece saves resources
// Redraw grid // Redraw grid
if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { if (osMutexAcquire(displayHandle, osWaitForever) == osOK) {
@ -765,8 +779,25 @@ void redraw_menu() { //only done onece saves resources
for (int j = 0; j < GRID_Y; j++) { for (int j = 0; j < GRID_Y; j++) {
uint16_t x = START_X + i * CELL_WIDTH; uint16_t x = START_X + i * CELL_WIDTH;
uint16_t y = START_Y + j * CELL_HEIGHT; uint16_t y = START_Y + j * CELL_HEIGHT;
uint16_t bg =
(i == sel_x && j == sel_y) ? COLOR_SELECTED : COLOR_BG; uint16_t bg;
if (menu_status[i][j]) {
if (i == sel_x && j == sel_y) {
bg = COLOR_ACTIVATED_AND_SELECTED;
} else {
bg = COLOR_ACTIVATED;
}
} else {
if (i == sel_x && j == sel_y) {
bg = COLOR_SELECTED;
} else {
bg = COLOR_BG;
}
}
if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { if (osMutexAcquire(displayHandle, osWaitForever) == osOK) {
ILI9341_DrawText(grid_labels[i][j], FONT2, x, y, COLOR_TEXT, ILI9341_DrawText(grid_labels[i][j], FONT2, x, y, COLOR_TEXT,
bg); bg);
@ -798,13 +829,21 @@ void handle_menu(void *argument) {
run_snake = 1; run_snake = 1;
run_menu = 0; run_menu = 0;
} }
menu_status[sel_x][sel_y] = !menu_status[sel_x][sel_y];
} }
if (dir == 'U' || dir == 'D' || dir == 'L' || dir == 'R') { if (dir == 'U' || dir == 'D' || dir == 'L' || dir == 'R') {
if (menu_status[sel_x][sel_y]) {
ILI9341_DrawText(grid_labels[sel_x][sel_y], FONT2,
START_X + sel_x * CELL_WIDTH,
START_Y + sel_y * CELL_HEIGHT, COLOR_TEXT,
COLOR_ACTIVATED);
} else {
ILI9341_DrawText(grid_labels[sel_x][sel_y], FONT2, ILI9341_DrawText(grid_labels[sel_x][sel_y], FONT2,
START_X + sel_x * CELL_WIDTH, START_X + sel_x * CELL_WIDTH,
START_Y + sel_y * CELL_HEIGHT, COLOR_TEXT, START_Y + sel_y * CELL_HEIGHT, COLOR_TEXT,
COLOR_BG); COLOR_BG);
} }
}
if (dir == 'U' && sel_y > 0) if (dir == 'U' && sel_y > 0)
sel_y--; sel_y--;
else if (dir == 'D' && sel_y < GRID_Y - 1) else if (dir == 'D' && sel_y < GRID_Y - 1)
@ -814,10 +853,17 @@ void handle_menu(void *argument) {
else if (dir == 'R' && sel_x < GRID_X - 1) else if (dir == 'R' && sel_x < GRID_X - 1)
sel_x++; sel_x++;
} }
if (menu_status[sel_x][sel_y]) {
ILI9341_DrawText(grid_labels[sel_x][sel_y], FONT2,
START_X + sel_x * CELL_WIDTH, START_Y + sel_y * CELL_HEIGHT,
COLOR_TEXT,
COLOR_ACTIVATED_AND_SELECTED);
} else {
ILI9341_DrawText(grid_labels[sel_x][sel_y], FONT2, ILI9341_DrawText(grid_labels[sel_x][sel_y], FONT2,
START_X + sel_x * CELL_WIDTH, START_Y + sel_y * CELL_HEIGHT, START_X + sel_x * CELL_WIDTH, START_Y + sel_y * CELL_HEIGHT,
COLOR_TEXT, COLOR_TEXT,
COLOR_SELECTED); COLOR_SELECTED);
}
if (redraw_menu_pending) { if (redraw_menu_pending) {
redraw_menu(); redraw_menu();
redraw_menu_pending = 0; redraw_menu_pending = 0;

92
Core/Src/script.py Normal file
View File

@ -0,0 +1,92 @@
#!/usr/bin/env python3
import evdev
from evdev import InputDevice, categorize, ecodes
import glob
import serial
import time
# Controller
#device_candidates = glob.glob('/dev/input/by-id/usb-8BitDo*-event*')
device_candidates = glob.glob('/dev/input/by-id/usb-8Bit*')
if not device_candidates:
print("Error: No matching 8BitDo input device found.")
sys.exit(1)
device_path = device_candidates[0]
#device_path = '/dev/input/by-id/usb-8BitDo_8BitDo_Ultimate_Controller_6fdf5bd817e4-event-joystick' #or just put it in
# UART
serial_port = '/dev/ttyUSB0'
baudrate = 115200
device = InputDevice(device_path)
print(f"Listening on {device.name} ({device_path})")
ser = serial.Serial(serial_port, baudrate, timeout=1)
print(f"UART opened on {serial_port} at {baudrate} bps")
# diganostic time stamps
def timestamp_ms():
return int(time.time() * 1000)
import select
button_map = {
'BTN_SOUTH': 'B',
'BTN_EAST': 'A',
'BTN_NORTH': 'Y',
'BTN_WEST': 'X',
}
try:
while True:
r, w, x = select.select([device.fd], [], [], 0.005) # timeout = 10ms
if device.fd in r:
for event in device.read():
ts = timestamp_ms()
if event.type == ecodes.EV_KEY:
key_event = categorize(event)
k = key_event.keycode
if isinstance(k, tuple):
name = next((button_map[x] for x in k if x in button_map), str(k))
else:
name = button_map.get(k, k)
msg = f"KEY:{name}:{key_event.keystate}\n"
ser.write(msg.encode('utf-8'))
print(f"[{ts}] Sent: {msg.strip()}")
elif event.type == ecodes.EV_ABS:
axis = ecodes.ABS.get(event.code, f"ABS_{event.code}")
val = event.value
if axis == 'ABS_HAT0Y' or axis == 'ABS_HAT0X':
if axis == 'ABS_HAT0Y':
if val == -1:
ser.write(b"KEY:U:1\r\n")
print(f"[{ts}] Sent: KEY:U:1:")
elif val == 1:
ser.write(b"KEY:D:1\r\n")
print(f"[{ts}] Sent: KEY:D:1:")
elif val == 0:
#ser.write(b"KEY:U:0\r\nKEY:D:0\r\n")
print(f"[{ts}] Sent: KEY:U:0\n[{ts}] Sent: KEY:D:0")
elif axis == 'ABS_HAT0X':
if val == -1:
ser.write(b"KEY:L:1\r\n")
print(f"[{ts}] Sent: KEY:L:1:")
elif val == 1:
ser.write(b"KEY:R:1\r\n")
print(f"[{ts}] Sent: KEY:R:1:")
elif val == 0:
#ser.write(b"KEY:L:0\r\nKEY:R:0\r\n")
print(f"[{ts}] Sent: KEY:L:0\n[{ts}] Sent: KEY:R:0")
else:
msg = f"ABS:{axis}:{event.value}:\r\n"
ser.write(msg.encode('utf-8'))
print(f"[{ts}] Sent: {msg.strip()}")
except KeyboardInterrupt:
print("\nExiting...")
finally:
ser.close()
print("UART closed.")