static
Meet TIM - GearSense's Throttle Injection Module".
Meet TIM — GearSense's Throttle Injection Module
GearSense needs a way to take control of a bike's throttle signal — smoothly, safely, and in a way that the rider can override at any moment. That job belongs to TIM, the Throttle Injection Module.
TIM sits physically inline between the bike's thumb throttle and the motor controller (ESC). When GearSense is active, TIM substitutes a computed signal for the rider's own throttle input. When the rider wants control back, they take it — instantly, unconditionally.
The relay topology
The heart of TIM is a single relay, K1, wired as a changeover switch between two signal sources:
PHYSICAL THROTTLE ──── K1 NC ─┐
├─ COM ──── ESC throttle input
MCP4725 DAC out ────── K1 NO ─┘
K1 de-energised (default / fail-safe): the rider's physical throttle feeds straight through NC → COM → ESC. TIM is electrically invisible. The bike rides exactly as stock.
K1 energised (TIM active): the DAC drives NO → COM → ESC. The rider's physical throttle is electrically disconnected from the ESC. GearSense has full control of the throttle signal.
This is a hard, hardware-level switch — not a software blend. TIM must actively hold the relay to stay in control. Any power failure, watchdog trip, or firmware crash drops K1 immediately, returning the bike to stock throttle behaviour. The fail-safe state requires no microcontroller involvement to reach or hold.
THROTTLE_SENSE — the rider's hand is always visible
While K1 is energised and the DAC has control, GearSense still has a live ADC tap on the physical throttle signal via a dedicated sense network on pin 8 of the TIM ↔ GearSense connector. This tap runs ahead of the relay — so it's always live, regardless of K1's state.
PHYSICAL THROTTLE SIGNAL
│
├───────────────────── K1 NC (→ ESC when de-energised)
│
└── sense network ──→ GearSense ADC / THROTTLE_SENSE
The network uses an R5 = 5.6kΩ / R6 = 10kΩ divider to scale the throttle's voltage range down to safe ESP32 ADC levels. An optional BAT54S dual Schottky clamp protects the line — it runs through the external harness and could pick up noise. ADC1 is used specifically because ADC2 is unreliable while BLE is active on the ESP32-S3.
This tap is what makes rider intent detection possible while TIM is in control, and it's what closes the previously-open FMEA-07 item: GearSense was formerly blind to what the rider was doing with the throttle grip while the DAC was driving — THROTTLE_SENSE fixes that.
The override state machine — "rider's touch always wins"
TIM operates in two states:
- AUTO — K1 energised, DAC controls the throttle line, assist control law running
- OVERRIDE — K1 de-energised immediately, physical throttle passes straight to the ESC
The rule is deliberately asymmetric:
Entry to OVERRIDE is fast and generous. Any deliberate throttle movement outside the idle envelope triggers it, debounced by just two consecutive filtered samples — roughly 2–8ms worst case. False positives (TIM yields when it didn't need to) are harmless. False negatives (TIM keeps driving when the rider wants out) are the actual hazard. The rule is: any deliberate throttle input is authoritative, full stop — TIM does not try to infer whether the rider wants more or less than it's already delivering.
Return to AUTO is slow and conservative. THROTTLE_SENSE must remain continuously inside the idle envelope for 0.5–1.0 seconds before TIM resumes. And critically, the DAC is written to V_idle before K1 re-energises — so the ESC never sees a stale or mid-computation DAC value when TIM takes back control. No jolt, no unexpected surge.
Auto-calibration — one TIM, any bike
Throttle conventions vary between bikes. Most eBikes use a rising convention (~0.8V idle, rising to ~4.2V full throttle). GearSense's own Cargo and Tofino bikes use an inverted convention (~3.4V idle, falling to ~0.76V full throttle) — meaning LOW voltage = MORE power. Hardcoding these constants into firmware would make each TIM unit bike-specific.
Instead, TIM includes a guided auto-calibration routine:
- Prompted: confirm throttle fully released — sample idle voltage V_a
- Prompted: briefly open the throttle partway — sample partial-open voltage V_b
- Polarity is self-determined: V_b > V_a = standard/rising; V_b < V_a = inverted. No brand or model knowledge needed.
- Capture the full-open endpoint
- Store
(V_idle, V_full, direction)in flash — not firmware constants
The result is a TIM that can be installed on any compatible eBike without a firmware rebuild. A bad calibration can only ever degrade TIM's active control behaviour — and only while the rider's hand is off the throttle. It cannot affect the hardware fail-safe path, which is hard-wired to the physical throttle through K1's NC contact regardless of any software state.
The TIM ↔ GearSense connector
TIM and the GearSense head unit are physically separate boards, connected by a fixed 8-pin JST-GH connector (1.25mm pitch, 22 AWG silicone wire). The GearSense-facing pinout is the same on every TIM variant — only the bike-facing side changes between installations.
| # | Wire | Direction | Purpose |
|---|---|---|---|
| 1 | GND | shared | Common reference |
| 2 | SDA | GearSense ↔ level shifter | I2C data |
| 3 | SCL | GearSense ↔ level shifter | I2C clock |
| 4 | RELAY_EN | GearSense → TIM | Energise relay command |
| 5 | RELAY_STATE | TIM → GearSense | Relay/coil readback — firmware confirms the command landed |
| 6 | 5V (charge) | TIM → GearSense | Docked charging via OR-diode at GearSense's VBUS |
| 7 | 3.3V logic ref | GearSense → level shifter | Powers the I2C level shifter's low side only |
| 8 | THROTTLE_SENSE | TIM → GearSense | Filtered/divided tap of the physical throttle signal, always live ahead of K1 |
What's built and what's next
TIM's relay, DAC, THROTTLE_SENSE network and connector are hardware-done. The override state machine and auto-calibration are firmware tasks in progress. Sitting above all of that — and the reason TIM exists — is the assist control law: the baseline-hold controller that infers rider effort from cadence deviation and computes a target throttle voltage for the DAC to output. That layer is designed in INTENT_SENSING_DESIGN.md and is the next firmware phase.
Two eBikes will carry TIM installations: the Energy One Cargo (Lishui LSW899-45-21M controller) and the Tofino (LSW899-76E). Both share the same controller family but have different gear clusters, making them complementary test beds for the gear-sensing and assist algorithms. A third GearSense variant — running without TIM on a standard pushbike — is being developed separately for Roman.
TGM card (Rev A): footprint assignment and J101 keying
Notes from the footprint-assignment session for the TGM_Rev_A sheet. Source is the BOM in docs/TGM_CARD_SPEC.md §5, read through §6. The last ~31 lines (§6 runtime onward) were not read. Footprint names are from memory of the stock KiCad library, so confirm each in the chooser (KiCad 10 sometimes renames things).
Decision: all-SMD, so JLCPCB can assemble it functional
Paul prefers JLC to place parts rather than hand-solder them, so the through-hole trimpots and the switch move to SMD.
| Ref | Footprint |
|---|---|
| R101–R106 | Resistor_SMD:R_1206_3216Metric |
| C101–C105 | Capacitor_SMD:C_1206_3216Metric |
| D101 (BAT54S) | Package_TO_SOT_SMD:SOT-23 |
| U101 (MCP6002) | Package_SO:SOIC-8_3.9x4.9mm_P1.27mm |
| RV101, RV102 | Potentiometer_SMD:Potentiometer_Bourns_3224W_Vertical (Bourns 3224W 10k, top-adjust) |
| SW101 | SMD DPDT slide switch. The spec's candidate is C&K JS202011SCQN. The stock footprint is for the JCQN variant, so check the datasheet land pattern. |
| J101 | Full 2×8 2.54 mm header footprint, through-hole, pin 16 not fitted |
| TP101–TP104 | TestPoint:TestPoint_Pad_D1.5mm (1.5 mm is my choice; the spec only says "test pads") |
R101 and R102 stay 1206 so the value can be changed after the float test.
Still to verify
- JLC stock for the 3224W and for SW101. The spec says to check both. Stock decides the part, and the part decides the land pattern, so don't lock those footprints until it is checked.
- Whether the carrier's J6 socket supports a plugged pin 16. The carrier spec lists this as an open item.
- C103 and the other values against parts on hand. 1206 is assumed throughout, as the spec says.
- That the three earlier ERC fixes were done.
J101 pin 16: why a blank, and how to make it
The spec (§3, line 59) says pin 16 is removed so the card cannot be inserted rotated 180°. It does not say what a flip would do. From the §3 pin table, a 180° rotation puts pin n on pin 17−n:
- Pin 15 (V_DROK, 5 V) lands on pin 2 (GND): a dead short.
- Pin 10 (3V3) lands on pin 7 (RELAY_EN_IN): drives the relay-enable line.
- Pin 1 (DAC_RAW) lands on pin 16, whatever the carrier puts there.
Every other pin is used and none survives a flip. A plain header with pin 16 simply unused would still fit backwards, and nothing electrical protects against it. The keying therefore has to be mechanical.
Options considered
- Spec design (kept): remove pin 16 and plug the matching hole in the carrier socket. One snip, one plug, cheap.
- Shrouded (notched) header: the standard solution, with polarity from the plastic. It costs a bigger part and a change to the carrier socket. JLC stock and the carrier footprint would need checking. Not chosen, but still open if Paul wants it.
- Plain header, silkscreen only: rejected. A wrong insertion shorts 5 V to GND inside an enclosure on a bike.
Removing pin 16
- Paul can clip it with his own snips. It is a small job.
- Best done before soldering: pull the whole pin out of the plastic. A stub left in the housing can still touch the mating socket.
- If JLC fits the header, snip pin 16 afterwards, then clean up the joint and pull the stub. Alternatively leave J101 unfitted and fit it by hand. Both are fine.
- Check the pin is fully out and the hole is clear, so it lines up with the plugged hole in the carrier socket.
- In KiCad, keep the full 2×8 footprint, leave the pin 16 pad empty, and keep the No Connect marker on it (the ERC fix).
The carrier socket drawing was not checked. The plugged-hole key is assumed from the spec.
How to assign in KiCad
Tools → Assign Footprints. Select a group in the left pane (for example all the R_ parts), double-click the footprint in the right pane, then rerun ERC.
Next step
Check JLC stock for the 3224W and SW101. If the C&K switch isn't stocked, find a drop-in SMD slide switch.
Relay fault detection and the Rev A / Rev B plan
Decision (2026-10-14): Rev A stays as designed, with cards on headers and the existing HK4100F dual-relay module on its current card. Rev A is a proof of concept. The brake lever is wired straight to the ESC and cuts power unconditionally, so a stuck relay is an annoyance, not a runaway hazard. The extra safety work belongs in Rev B.
Why the relay needs a better part for Rev B
- The HK4100F relays are single-pole and cannot detect a welded contact. K2 only detects a dead coil or driver, which is what RELAY_STATE reports.
- A plain DPDT (such as the Fujitsu A5W-K already sourced) is only a partial detector. Contact springs can flex, so the second pole may read "released" while the first is welded.
- A forced-guided (mirror-contact) relay under IEC 61810-3 is built so a welded NO contact physically stops the NC contact closing. A mirror contact then gives firmware a trustworthy signal. This is recorded as FMEA-11 and is a Rev B requirement.
- In the meantime, comparing THROTTLE_SENSE with the DAC command (NC: sense equals throttle; NO: sense equals DAC) catches most of the welded-K1 gap in software.
Rev B candidate: Omron G7SA
- JLCPCB's G7SA stock is all 24 V coil (2A2B C397126, 3A1B C968857, 4A2B, 5A1B). The 12, 18, 21 and 48 V variants show 0 stock. None suits the 5 V rail.
- JLCPCB will not ship relays separately; parts stay in your library for PCBA orders only. A through-hole relay would be hand-fitted or consigned.
- Look for a 5 VDC coil G7SA (2A2B or 3A1B) at Mouser or Digi-Key. Mouser could not be reached, so stock and price are unverified. Panasonic SF-W is the alternative.
- Check on the datasheet: coil current at 5 V, minimum applicable load (the throttle signal is 0-5 V at microamps, so gold-clad or low-level contacts matter), pole mapping and footprint.
Rev B architecture direction
- Carrier rule 1 stands: the rider's fail-safe throttle path never crosses a slot. The forced-guided relay is therefore soldered to the carrier, not put on a plug-in card. A plug-in relay card would put a connector in the fail-safe path, and a missing card would leave the ESC input open.
- Migrate cards onto the carrier where practical, as bare-chip circuitry (MCP4725 plus decoupling and the TGM guard, BSS138 I2C level shifter). JLC can place these. Fold in whichever cards have stopped changing after the Rev A float test.
- Keep a card or header only for things that genuinely vary, such as the bike interface.
- Keep the logic-level contract (RELAY_EN, RELAY_STATE, plus a contact-OK readback) so firmware does not care which relay is fitted.
Open items
- The carrier spec lists U5 (HK4100F module) as a header card carrying K1 and K2, which sits awkwardly with rule 1. For Rev A, accepted because of the brake cutout. Trace how U5's contacts are wired and note it.
- Find out how the Lishui controller treats an open throttle input. It matters for any missing-module case.
- Source a 5 V G7SA and confirm coil current and minimum load.
- Rev A to-do remains: JLC stock for the Bourns 3224W and SW101, and the TGM float test.