diff --git a/doc/02_encoder.md b/doc/02_encoder.md index 0507cb5..93f9448 100644 --- a/doc/02_encoder.md +++ b/doc/02_encoder.md @@ -13,12 +13,17 @@ Encoder-SW-Tasten laufen **nicht** durch diesen HAL, sondern durch den Matrix-Sc ``` Zustand = (A << 1) | B → 4 Bits: 00 / 01 / 10 / 11 -LUT[prev<<2 | cur] → +1 (CW), -1 (CCW), 0 (ungültig/Prellen) +LUT[prev<<2 | cur] → Roh-Vorzeichen, 0 (ungueltig/Prellen) ``` Mechanische Encoder erzeugen 4 Flanken pro Raste → Akkumulator zählt Halbschritte. Ein Event wird erst gefeuert wenn `|accum| >= 4` (= ein vollständiger Klick). +Die VersaPad-PCB-Verdrahtung liefert das Quadratur-Vorzeichen gegenueber der sichtbaren Drehrichtung invertiert. Deshalb bleibt die LUT konventionell, aber der HAL dreht das Vorzeichen vor dem Callback mit `ENCODER_DIRECTION_SIGN = -1`. Nach aussen gilt weiterhin: + +- `direction = +1` -> `ENC_CW` +- `direction = -1` -> `ENC_CCW` + ## ISR-Aufbau 8 ISR-Wrapper (je einer pro Pin, da `attachInterrupt` keinen Parameter unterstützt): diff --git a/src/hal/encoder.cpp b/src/hal/encoder.cpp index dd20c70..5712f36 100644 --- a/src/hal/encoder.cpp +++ b/src/hal/encoder.cpp @@ -8,7 +8,9 @@ // Bei jedem Flankenwechsel (CHANGE) auf A oder B wird der neue Zustand // bestimmt und mit dem vorherigen verglichen. // -// Lookup-Tabelle [prev<<2 | curr] → +1 (CW), -1 (CCW), 0 (ungültig/Prellen) +// Lookup-Tabelle [prev<<2 | curr] → Roh-Vorzeichen, 0 (ungültig/Prellen) +// Die physische CW/CCW-Bedeutung wird nach dem Akkumulator per +// ENCODER_DIRECTION_SIGN an die VersaPad-PCB-Verdrahtung angepasst. static const int8_t k_lut[16] = { // curr: 00 01 10 11 0, +1, -1, 0, // prev = 00 @@ -28,6 +30,10 @@ static encoder_cb_t s_cb = nullptr; static const uint8_t k_pin_a[ENCODER_COUNT] = { PIN_ENC0_A, PIN_ENC1_A, PIN_ENC2_A, PIN_ENC3_A }; static const uint8_t k_pin_b[ENCODER_COUNT] = { PIN_ENC0_B, PIN_ENC1_B, PIN_ENC2_B, PIN_ENC3_B }; +// The PCB wiring makes the quadrature sign opposite to the user-facing knob +// direction. Keep the lookup table conventional and invert once at the HAL edge. +static constexpr int8_t ENCODER_DIRECTION_SIGN = -1; + // Generischer Handler — wird von den 8 ISR-Wrappern unten aufgerufen. static void handle_encoder(uint8_t enc) { @@ -45,10 +51,10 @@ static void handle_encoder(uint8_t enc) // 4 Halb-Schritte = 1 vollständige Raste if (s_accum[enc] >= 4) { s_accum[enc] = 0; - if (s_cb) s_cb(enc, +1); + if (s_cb) s_cb(enc, +1 * ENCODER_DIRECTION_SIGN); } else if (s_accum[enc] <= -4) { s_accum[enc] = 0; - if (s_cb) s_cb(enc, -1); + if (s_cb) s_cb(enc, -1 * ENCODER_DIRECTION_SIGN); } }