From a618cb238fdbc4a9f09debb631aaee13ac16e0c7 Mon Sep 17 00:00:00 2001 From: lucavanstraaten Date: Tue, 28 Apr 2026 21:16:59 +0200 Subject: [PATCH] LED: show encoder position as hue after each read - Add setPositionColor(): maps SSI value to HSV hue (0=red, 120=green, 240=blue) - LED takes the position hue as its resting colour between reads - Blue during active read unchanged - All error paths now flash red before printing ERR --- src/main.cpp | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ac873bc..547f7e5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -27,6 +27,25 @@ void setStatus(uint8_t r, uint8_t g, uint8_t b) { led.show(); } +// Map encoder position to a colour on the HSV wheel (brightness fixed at ~20/255). +// hue 0-359: 0=red, 120=green, 240=blue +void setPositionColor(uint32_t value, uint32_t maxVal) { + if (maxVal == 0) { setStatus(16, 0, 16); return; } // magenta = unknown range + uint16_t hue = (uint16_t)(((uint32_t)value * 360) / maxVal); // 0-359 + // HSV → RGB with S=1, V=20 + uint8_t sector = hue / 60; + uint8_t frac = (uint8_t)(((hue % 60) * 255) / 60); + uint8_t v = 20, p = 0, q = (uint8_t)(v * (255 - frac) / 255), t = (uint8_t)(v * frac / 255); + switch (sector % 6) { + case 0: setStatus(v, t, p); break; + case 1: setStatus(q, v, p); break; + case 2: setStatus(p, v, t); break; + case 3: setStatus(p, q, v); break; + case 4: setStatus(t, p, v); break; + case 5: setStatus(v, p, q); break; + } +} + void ssi_pio_init(uint half_us) { // pioasm generates these helpers in ssi.pio.h ssi_offset = pio_add_program(ssi_pio, &ssi_master_program); @@ -85,6 +104,7 @@ uint32_t ssi_pio_read(uint8_t bits) { void handleCommand(const String& cmd) { if (!cmd.startsWith("READ ")) { + setStatus(16, 0, 0); // red = error Serial.println("ERR unknown command. Use: READ "); return; } @@ -92,6 +112,7 @@ void handleCommand(const String& cmd) { int firstSpace = cmd.indexOf(' '); int secondSpace = cmd.indexOf(' ', firstSpace + 1); if (secondSpace < 0) { + setStatus(16, 0, 0); // red = error Serial.println("ERR usage: READ "); return; } @@ -100,21 +121,25 @@ void handleCommand(const String& cmd) { int halfUs = cmd.substring(secondSpace + 1).toInt(); if (bits < 1 || bits > 32) { + setStatus(16, 0, 0); // red = error Serial.println("ERR bits must be 1..32 (PIO ISR limit)"); return; } if (halfUs < 1 || halfUs > 10000) { + setStatus(16, 0, 0); // red = error Serial.println("ERR half_us must be 1..10000"); return; } ssi_pio_reconfigure_speed(halfUs); - setStatus(0, 0, 16); + setStatus(0, 0, 16); // blue = reading uint32_t t0 = micros(); uint32_t value = ssi_pio_read((uint8_t)bits); uint32_t took = micros() - t0; - setStatus(0, 16, 0); + + // Show encoder position as hue (full range = 2^bits - 1) + setPositionColor(value, (1ul << bits) - 1); Serial.printf("OK bits=%d half_us=%d hex=0x%lX dec=%lu took=%luus\n", bits, halfUs, value, value, took);