7.1 KiB
7.1 KiB
Rotary Encoder — Setpoint Control Wiring
Adds an EC11-class incremental rotary encoder to the kttl controller so the temperature setpoint can be dialled in live, and so the encoder's push-switch acts as the on-switch (identical to the board's B1 button).
Target board: STM32F4-Discovery (STM32F411VE). Firmware: src/main.rs
(SetpointKnob, TIM1 in encoder mode).
1. Pin assignment
| Encoder leg | Discovery pin | Function | Extra parts |
|---|---|---|---|
| A (CLK) | PE9 (TIM1_CH1) | quadrature channel A | 10 kΩ → 3V, 100 nF → GND |
| B (DT) | PE11 (TIM1_CH2) | quadrature channel B | 10 kΩ → 3V, 100 nF → GND |
| C (common) | GND | rotary common | — |
| SW1 | 3V | push-switch leg | — |
| SW2 | PA0 | push-switch leg (‖ B1) | — |
| mount ×2 | GND | shield / mechanical | optional |
Use 3V, not 5V. The STM32F411 is a 3.3 V part; the pull-ups set the logic high level seen by the pins, and the switch drives PA0 directly. 3V matches the MCU and the existing B1 button exactly — no level shifting.
2. Schematic
STM32F4-Discovery Rotary encoder (EC11, 7-leg)
┌──────────────┐
│ 3V ●───────────┬────────────┬──────────────┐
│ │ │ │ │
│ │ ┌┴┐ ┌┴┐ │
│ │ 10k │ │ 10k │ │ │ (pull-ups
│ │ └┬┘ └┬┘ │ to 3V)
│ │ │ │ │
│ PE9 (CH1) ●───────────┼────────────● A (CLK) │
│ │ │ │ │
│ │ 100n ═╪═ 100n ═╪═ │
│ │ │ │ │
│ PE11 (CH2) ●───────────●────────────┼──● B (DT) │
│ │ │
│ │ ● C (common)──┼──┐
│ │ │ │
│ │ SW1 ●────┘ │
│ PA0 ●──────────────────────────────────● SW2 │ (push-switch, ‖ B1)
│ GND ●──────┬───────────────────────────────────┘
│ │ │ mount legs ●● → GND (shield)
└──────────────┘ │
│ B1 (on-board) also sits 3V ↔ PA0 —
┌─────┴──────┐ the encoder push-switch is in
│ both 100n │ PARALLEL with it.
│ caps → GND │
└────────────┘
3. Breadboard view
RC filter — repeat for each channel (A, B):
3V rail ●━━━┯━━━━━━━━━━━┯━━━━● ← from Discovery 3V
│ │
[10k] [10k]
A node ┼───→ PE9 │
B node │ ┼───→ PE11
[100n] [100n]
│ │
GND rail ●━━━┷━━━━━━━━━━━┷━━━━● ← from Discovery GND
EC11 encoder — straddles the centre trench (┊):
┌─────────────────────────────┐
│ A C B ┊ SW1 SW2 │
└──┬────┬────┬───────┬─────┬──┘
│ │ │ │ └───────→ PA0 (SW2 ‖ on-board B1 button)
│ │ │ └─────────────→ 3V rail (SW1)
│ │ └─────────────────────→ B node (DT, channel B → PE11)
│ └──────────────────────────→ GND rail (C = common)
└───────────────────────────────→ A node (CLK, channel A → PE9)
Power both breadboard rails from the Discovery's 3V and GND pins; tap everything else off those rails.
4. Why the resistors and caps
- 10 kΩ pull-ups (A→3V, B→3V): required. This HAL's QEI driver puts the pins in alternate-function mode without enabling the internal pull-ups, so the channels would float. With the encoder common tied to GND, the lines idle high and each detent pulls them low.
- 100 nF caps (A→GND, B→GND): recommended. Each forms an RC low-pass with its 10 kΩ pull-up, τ = R·C = 10 kΩ · 100 nF = 1 ms — long enough to absorb the ~1–5 ms of mechanical contact bounce, short enough that no hand-turned knob outruns it. Combined with the STM32 inputs' Schmitt-trigger hysteresis, this turns each bounced click into one clean edge. The cap's closure surge also provides wetting current to keep the low-current (~0.3 mA) contacts reliable.
5. Behaviour (firmware)
- TIM1 encoder mode counts quadrature edges (×4). EC11s emit one full cycle
per detent → 4 counter steps per detent (
COUNTS_PER_DETENT). - Each detent moves the setpoint by
SETPOINT_STEP_C(1 °C), clamped to[SETPOINT_MIN_C, SETPOINT_MAX_C]= [25, 100] °C. Power-on default isSETPOINT_DEFAULT_C= 25 °C. - The encoder is sampled every
POLL_MS(20 ms) in the main poll loops (normal and fault), so the setpoint tracks smoothly and the per-second status log prints the live value. - Push-switch: wired in parallel with B1 (3V ↔ PA0). Pressing the knob is electrically identical to the board button and is handled by the existing PA0 polling — no extra code.
6. Alternatives
- Drop the caps: enable TIM1's built-in digital input filter (sample-count debounce) in firmware instead. The RC filter is simpler and also gives wetting current + on-wire noise rejection, so it's preferred for a breadboard build.
- KY-040 module: has onboard pull-ups — power it from 3.3 V (not 5 V) so CLK/DT/SW idle at a level the MCU pins accept; the external 10 kΩ/100 nF here can then be omitted.