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
This commit is contained in:
lucavanstraaten 2026-04-28 21:18:35 +02:00
parent 58a2d37b38
commit 1a2ce7e7c0

View file

@ -41,6 +41,24 @@ 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(uint64_t value, uint64_t maxVal) {
if (maxVal == 0) { setStatus(16, 0, 16); return; } // magenta = unknown range
uint16_t hue = (uint16_t)((value * 360) / maxVal); // 0-359
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;
}
}
// =========================================================================
// CORE 1: SSI worker
// =========================================================================
@ -105,6 +123,7 @@ void requestSsiRead(uint8_t bits, uint16_t half_us, uint64_t& outValue, uint32_t
void handleCommand(const String& cmd) {
if (!cmd.startsWith("READ ")) {
setStatus(16, 0, 0); // red = error
Serial.println("ERR unknown command. Use: READ <bits> <half_us>");
return;
}
@ -112,6 +131,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 <bits> <half_us>");
return;
}
@ -120,19 +140,24 @@ void handleCommand(const String& cmd) {
int halfUs = cmd.substring(secondSpace + 1).toInt();
if (bits < 1 || bits > 64) {
setStatus(16, 0, 0); // red = error
Serial.println("ERR bits must be 1..64");
return;
}
if (halfUs < 1 || halfUs > 10000) {
setStatus(16, 0, 0); // red = error
Serial.println("ERR half_us must be 1..10000");
return;
}
setStatus(0, 0, 16); // blue = reading
setStatus(0, 0, 16); // blue = reading
uint64_t value;
uint32_t took;
requestSsiRead((uint8_t)bits, (uint16_t)halfUs, value, took);
setStatus(0, 16, 0); // green = idle
// Show encoder position as hue (full range = 2^bits - 1)
uint64_t maxVal = (bits < 64) ? ((1ull << bits) - 1) : UINT64_MAX;
setPositionColor(value, maxVal);
Serial.printf("OK bits=%d half_us=%d hex=0x%llX dec=%llu took=%luus\n",
bits, halfUs, value, value, took);