Hardcut — ESP32 ignition-cut rev limiter & launch control — design
A bolt-on ESP32-S3 box for a 1995 Geo Tracker 1.6 16v MPFI (G16B), 3L30 3-speed automatic, adding a two-step launch limiter and a configurable main rev limiter by intercepting the two low-current logic wires between the ECM and the igniter. It suppresses individual ignition events by shunting the ECM’s spark command (IGt) to ground, while keeping every run of skipped events short enough that the ECM never notices — which is what keeps fuel flowing, and therefore what produces the exhaust bangs. The tap is a parallel open-drain pull to ground: nothing in the harness is cut, and an unpowered or hung box is electrically identical to a stock car.
Related: esp32, kb-agent-api, pipeline, index, cluzter.
ESP32 platform knowledge lives in esp32
The timing-budget findings below — core pinning does not isolate an ISR from WiFi, flash write/erase stalls task code for milliseconds, and the
ESP_INTR_FLAG_LEVEL3 | ESP_INTR_FLAG_IRAM/out_w1ts/ no-printf ISR rules — are generalised there for any timing-critical ESP32 work, together with the S3-vs-C3 choice, flashing and power gotchas from lightaim and the RuView CSI node.
This note is a wire-data source for cluzter
The signal table below carries real JIS/Suzuki-coded wires measured or traced on this car —
Bl/G(IGf → ECM B5),Br/W(igniter IG → coil primary −),B/W(igniter +B), plus Orange (IGt), Green/White (brake switch) and Yellow (VSS → ECM A7). cluzter is the wiring-diagram editor for the same vehicle and treats this as ground truth. Note the trap it is built around:Bis black andBlis blue, one character apart — see cluzter-wiring-gotchas.
Problem
The factory G16B ECM limits revs by fuel cut at 6,720 r/min, restoring at 6,680 — 40 r/min of hysteresis, no ignition involvement, and no launch control of any kind. There is no way to hold a chosen RPM against the torque converter for a brake-torque launch, no way to lower the ceiling for a tired engine, and no bangs, because fuel cut is the one mechanism that guarantees nothing combustible reaches the exhaust.
The naive approach backfires on this car. The OBD1 ECM monitors ignition and cuts fuel when spark is lost — "If spark is bad, all ECU's Cut Fuel injection!" A sustained spark cut therefore yields a stumble, no fuel, no bang, a probable DTC 41, and a real risk of a silent limp-home (rich, heavily retarded, ~3000 r/min ceiling, glowing exhaust) that this ECM enters without lighting the CEL about half the time.
The way through is that the ECM’s detector is a consecutive-miss counter, reset by any real ignition event. Keep every run of cuts below its threshold and the ECM stays satisfied while the engine still loses most of its combustion events.
Goal
- Two-step launch limiter for brake-torque launches, with bangs
- Configurable main limiter, below the factory 6,720
- Hard (clustered) and soft (evenly-spread) cut patterns, switchable
- WiFi web config: RPM targets, mode, hysteresis, live RPM telemetry
- No harness cuts; removable without trace; stock behaviour when unpowered
Non-goals
- No fuel-side control in v1. We never touch injector drives. Spark-only, because fuel is what makes the bang. (A half-cut lever is noted under future levers, deliberately out of scope here.)
- No coil primary switching. Opening a charging primary destroys igniters. Ruled out permanently.
- No 100% spark cut. Not merely unnecessary — actively worse (see the bang mechanism below) and the only case that would need IGf forgery.
- No WiFi while armed. Not a preference; see the timing section.
- No ECM reflash, no PROM work, no standalone ECU. The Mitsubishi/Suzuki processor is proprietary and unrecoverable if blown.
- No CAS interception. Cutting the crank signal kills spark and fuel — no bangs, and it risks the ECM’s start logic.
- No OBD2 / 1996+ support. 1996+ ECMs expose no IGf pin and drop code 41 entirely. The 8-valve igniter is 3-wire with no IGf at all, so an 8v port would be a different design, not a wiring variant.
- No galvanic isolation. Impossible by construction: a shunt FET’s source is ECM ground, so you cannot sink into a floating node.
- No traction control, no flat-shift, no anti-lag, no boost control. Naturally aspirated automatic.
Key decisions
| Decision | Choice | Why |
|---|---|---|
| What to cut | IGt (ECM A4 → igniter), spark only | The only low-current node that stops combustion without touching the coil primary or the fuel side |
| How to cut | Shunt to ground in parallel, 22 Ω + BSS806N | Target is not a logic threshold but below V_BE(on), so aim ≤0.8 V at the node. 47 Ω only achieves that against a weak driver; 22 Ω works across the plausible range |
| Keeping fuel alive | Cap consecutive cuts at 5 | The ECM’s miss counter resets on any real event. 5 is inside the bang sweet spot and safe against the threshold whether it is the FSM’s 8 or kick-fix’s 6 |
| IGf forgery | Hardware fitted, firmware path default-off | Made unnecessary by the run cap, but the FET and resistor cost nothing and re-spinning a board later would |
| Bang pattern (launch) | Clustered: cut N, fire 1 (N = 5) | Bang energy comes from consecutive cuts terminated by a fired event that ignites the accumulated charge. Even spreading is the wrong tool here |
| Smooth pattern (main/soft) | Evenly-spread accumulator, ratio ramped across a band | Matches MaxxECU/Emtron/Haltech practice; deliberately minimises run length, which is what makes it smooth |
| Decision timing | Decide at falling edge N, apply to event N+1 | Gives 4–5 ms of slack, so ISR jitter is irrelevant, and structurally cannot truncate a dwell |
| RPM source | IGt falling edges, 2 per crank revolution | Already tapped; the falling edge is the spark command, so this measures real events |
| Stationary interlock | VSS pulse presence + a dedicated brake microswitch | VSS is read-only from the existing wire. The brake signal comes from our own switch, not the stock circuit — see the install decision below |
| Install method | Tap individual wires; no ECU passthrough | A full 22+26-way passthrough would add ~96 contact points to reach 4 circuits, and still could not supply the brake signal (this ECM has no brake pin). An igniter-connector 4-way passthrough is the option worth building if unplug-to-stock reversibility is wanted, since both driven signals live there. Rejected for this project, not in general — a separate all-pins diagnostic harness is planned, where reading every wire is the point and the connector is temporary rather than permanent. If that gets built, this box can migrate onto it as shared infrastructure |
| Hold cap | 5 s, then forced cooldown | The FSM’s own stall-test caution: "Do not run engine at stall more than 5 seconds continuously" |
| MCU | ESP32-S3, radio off whenever armed | S3 over C3 (C3 is single-core, no MCPWM). Core pinning does not isolate the ISR from WiFi, so the radio must be off |
| Retard mode | Deferred to a later phase | Needs µs edge placement (1 crank° = 28 µs at 6000 rpm); fights ISR jitter |
The falling edge is the spark — never assert the shunt while IGt is high
Toyota Course 852, describing the identical architecture: “When IGT signal voltage drops to 0 volts, the transistor in the igniter turns off.” Pulling IGt low mid-dwell therefore does not suppress a spark — it fires the plug at a random advance angle. This is the one bug in this project that can destroy the engine.
SUPERSEDED — this is now enforced in hardware, not software
This document originally said “no hardware can prevent this; the ISR must read the IGt input and refuse to assert unless it is already low.” That is no longer the design. 2026-08-08-hardcut-plan adds a 74HC74 D flip-flop clocked on IGt’s falling edge: the ESP32 writes only the flip-flop’s
Dinput, andQ— which drives the shunt FET — can change only coincident with the falling edge. The MCU may assert at any time, early, late or wrongly, and the gate still cannot move mid-dwell.The bug becomes physically unreachable rather than merely tested-for, and firmware timing stops being safety-relevant. Build to the plan, not to this callout. See Task 8: Breadboard the front end, flip-flop and shunt.
Why 100% cut is the wrong setting for bangs
Each skipped event pumps a full ~398 cc charge into a manifold+downpipe volume of roughly 3 L. Cut every event and the volume fills, but there is no fired event left to ignite it — one report on resumption, then silence. Runs of 3–5 give 40–66% fill and are each terminated by a real spark whose flame front lights the charge, so the reports repeat. The lever for louder is clustering, not a higher ratio.
Why not intercept the tachometer wire instead
On the 8-valve cars the fail-safe signal genuinely is the coil primary, on a brown wire through the noise suppressor to ECM A1 — so tach and IGf are the same node. On our 16-valve they are separate: IGf is a dedicated igniter output on Bl/G to ECM B5, while the coil primary is Br/W. Tapping the tach wire would give RPM but no IGf, and loading that node risks tripping the fuel cut we are trying to avoid.
Signal source
Everything needed is at one 4-pin connector on the igniter, bolted to the ignition coil on the firewall — external and separately replaceable on a 1995 car. On 1996+ the igniter moved inside the distributor, which is why this design is year-locked.
ECM A4 ──── Or ──────┬──────────────────────► igniter IGt
│ (Darlington base, ~1.4 V threshold, ~11 mA)
[2k2]─┬─BAT54S─┬──► 74LVC1G17Q ──► GPIO read
│ 470pF │
[R_sh 22R] │
[PTC 100mA] │ shunt low = next dwell suppressed = no spark
Q1 BSS806N ──────┴──── GND (ECM signal ground, B14)
100k gate pulldown = the fail-safe
ECM B5 ◄─── Bl/G ────┬────────────────────── igniter IGf (5 V pull-up INSIDE the ECM)
[2k2]─┬─BAT54S─┬──► 74LVC1G17Q ──► GPIO read
│ 100pF │ (no filter cap — the edge matters)
Q2 BSS806N ──────┴──── GND
fitted but idle — forgery only if the run cap proves insufficient
igniter +B ← B/W (power)
igniter IG → Br/W (coil primary −) ── NEVER TOUCHED
| Signal | Where | Electrical nature | Measured / spec |
|---|---|---|---|
| IGt | igniter pin IGt, Orange | ECM-driven, current-mode into Darlington base | 0 → 3.5 V; ~11 mA to fire (150 Ω to +12 V on the bench) |
| IGf | igniter pin IGf, Blue/Green | Open-collector, active-low, ECM-side pull-up | ~5 V at the wire with igniter unplugged |
| Brake | our own microswitch on the pedal bracket | Dry contact to ground, pulled up to 3V3 by us | Nothing is tapped. Positioned to make well into the pedal stroke, so it reports car held, not pedal touched. Stock circuit tap remains the documented fallback |
| VSS | ECM A7, Yellow | Reed switch + magnet in speedometer head, dry contact to ground; the ECM supplies the pull-up | 0–1 V ↔ 4–5 V with ECM connected; 0 Ω ↔ ∞ with it unplugged. 4 pulses per speedo-cable revolution, ≈1.14 Hz per mph |
Ignition events are 2 per crank revolution (4 distributor shutters ÷ 2). Spark-to-spark is 10 ms at 3000 r/min, 5 ms at 6000, 4.29 ms at 7000. Dwell is ECM-controlled, not fixed.
Hardware
| Ref | Part | Role / note |
|---|---|---|
| Q1, Q2 | Infineon BSS806N | SOT-23, 30 mΩ, V_GS(th) 0.55 V. Not BSS138 — its 3.5 Ω eats the 0.8 V budget; not 2N7002 — V_GS(th) too high for 3.3 V |
| R_sh | 22 Ω ¼ W, footprint accepts 10 Ω | IGt shunt; final value set by the measurement gate |
| gate network | 100 Ω series, 100 kΩ pull-down | The pull-down is the fail-safe. Same approach as Speeduino |
| PTC | 100 mA polyfuse | Prototype-only ECM protection while R_sh is unproven |
| U4–U7 | Diodes 74LVC1G17Q | Schmitt, inputs rated 5.5 V independent of V_CC, 0.6 V hysteresis = 17% of the IGt swing |
| clamps | 2.2 kΩ series + BAT54S | 2.2 kΩ holds fault current to 16 mA on a 40 V transient. Placed at connector entry, not at the MCU |
| supply | LM74700-Q1 ideal diode → SMBJ33A → LM5164-Q1 buck (6–100 V) → AP2112K-3.3 | Reverse battery, load dump, cold crank. Not MP1584 (28 V abs max). Not an LDO-only chain (4.5 W at 500 mA) |
| bulk | 470 µF low-ESR + 100 µF + 100 nF | ESP32 peaks ~500 mA on WiFi TX; brownout detector trips at 2.43 V |
| brake in | microswitch + 10 kΩ pull-up to 3V3 + 100 nF | Dry contact to ground, so no divider, no clamp, no 12 V exposure. Software debounce 20–50 ms, sampled in the telemetry task, never the ISR. Choose a switch with a positive-action lever and mount it to make late in the pedal stroke |
| VSS in | 10 kΩ series + 100 nF + BAT54S, no added pull-up | The ECM already pulls this up and already wets the reed contact. A second pull-up is redundant and risks lifting the low level toward a code 24 |
| U9 | ESP32-S3-WROOM-1 | Dual core, MCPWM available |
| U10 | TPL5010 | External watchdog, independent of firmware |
Grounding. One signal-ground wire to ECM pin B14, run in the same loom as the IGt/IGf taps, so ECM ground movement is common-mode and our thresholds move with the ECM’s. Power ground returns separately to battery negative; the two grounds meet at exactly one point, the buck output capacitor. Enclosure bonded to chassis only. Twisted pair per signal, shield grounded at the box end only. Mount under the dash if the loom reaches — the ECM end of these wires is already in the cabin.
Calibration defaults
Every value is user-configurable over WiFi; these are the shipped defaults, each anchored to a factory figure or to documented aftermarket practice.
| Setting | Default | Anchored to |
|---|---|---|
| Launch limit | 2,500 r/min, then set by measurement | Derived, not specified — see the stall callout. Above stall the converter slips and the brakes lose, so a higher setting is fiction |
| Launch hysteresis | 80 r/min | Hysteresis matters proportionally: 150 at 6300 is 2.4%, but 120 at 2700 would be 4.4% — coarse at the one RPM the driver is watching |
| Launch cluster | cut 5, fire 1 | 3–5 consecutive cuts is the bang knee; 5 stays under the ECM’s miss threshold |
| Main limit | 6,300 r/min | Under the factory 6,720, and above the 16v power peak of 95 bhp @ 5,600 — nothing lost by capping here |
| Main hysteresis | 150 r/min | Mid-range of published practice (ProEFI 50, Link/ME 200, HPA 100–200). The factory’s 40 is what makes the stock cut feel like a brick wall |
| Soft-cut band | 250 r/min | Ratio ramps 0 → max across the band below the limit; MaxxECU recommends 200–400 |
| Max consecutive cuts | 5 | Hard ceiling in all modes. Never raised by any web request. Also caps the spread pattern’s ratio at ~83%, which is ample authority |
| Hold cap | 5 s | The 3L30’s own limit: "Do not hold engine at WOT for more than 5 seconds" |
| Cooldown before re-arm | 60 s | The 3L30 time-lag test demands "one minute intervals between tests", and a launch is more severe than that test |
| Configurable ceiling | 6,600 r/min | Firmware-clamped so no web request can set a limit above the factory cut |
Why the launch limit should stay under ~3,000
EGR opens above 3,200 r/min with the vehicle stopped. A stationary hold above that dilutes the intake charge with exhaust gas precisely when we want a rich, ignitable mixture — so a higher launch setting fights itself, quite apart from being beyond the converter’s stall.
The 3L30's stall speed is not documented — measure it, don't assume it
The often-quoted 2,300–2,600 r/min figure belongs to the 4-speed A/T and must not be applied here. No stall speed, stall procedure or cool-down exists for the 3-speed 3L30 anywhere in the manuals. What the factory does give is the converter itself: 245 mm, 3-element, max stall ratio 2.40:1, capacity factor K = 260. From
N_stall = K·√T, at 90–98 lb-ft that yields ≈2,470–2,570 r/min — a derivation, not a specification. So the shipped 2,500 default is a placeholder: commissioning measures the real stall speed on the car (5 s maximum, 60 s cool-down) and the launch limit is then set just above it.
Brake-torquing is pure fluid shear, and the owner's manual says so
Lock-up is guaranteed disengaged while the brake is pressed —
"if the brake pedal is depressed... the lock-up solenoid circuit opens and no voltage is applied."Every joule of a brake-torque hold therefore goes into shearing fluid inside the converter, which is exactly why the 5 s limit exists. The Tracker owner’s manual is blunter still:"Damage to your transmission caused by shifting out of PARK (P) or NEUTRAL (N) with the engine racing isn't covered by your warranty."The time limits are the whole mitigation; treat them as hard.
Architecture
hardcut/
├── firmware/
│ ├── src/
│ │ ├── main.cpp boot, wiring, task pinning
│ │ ├── ign.cpp ISR: edge capture, period, gate decision ← IRAM, LEVEL3
│ │ ├── pattern.cpp clustered & evenly-spread patterns, run cap
│ │ ├── limiter.cpp control law: modes, ratio vs overshoot, hysteresis
│ │ ├── arming.cpp brake + VSS + RPM interlocks, 5 s cap
│ │ ├── config.cpp NVS persistence, firmware-clamped bounds
│ │ └── web.cpp AP, JSON API, inline HTML page ← disabled while armed
│ └── platformio.ini
├── bench/
│ └── emulator.cpp 2nd ESP32: fakes ECM IGt + igniter IGf
└── hardware/
└── schematic.md front ends, output stage, 12 V supply, BOM
ign.cpp is the only timing-critical unit and owns the gate. Everything else advises it by setting a target and a mode; nothing else may write a GPIO. It writes GPIO.out_w1ts/out_w1tc directly — gpio_set_level() is not IRAM-safe — and contains no printf, no float, and no flash-resident constants.
pattern.cpp — cut patterns and the run cap
Two generators over one interface. Clustered emits N cuts then one forced pass. Spread distributes cuts as evenly as the ratio allows. Both are wrapped by a single hard rule: a run of 5 cuts forces the next event to pass, whatever the generator asked for. That rule is the fuel supply’s guarantee and lives in exactly one place.
limiter.cpp / arming.cpp
limiter.cpp converts period to RPM, selects the active limit, and computes the requested ratio from overshoot. arming.cpp owns every reason to refuse — brake plus no VSS pulses plus RPM in window, the 5 s cap and cooldown, and disarming on any loss of confidence.
Timing budget
Baseline GPIO ISR latency is ~4 µs; WiFi activity adds 50–100 µs, and core pinning does not prevent this because bus arbitration is not partitioned by core. Against a 4.29 ms inter-event gap at 7000 rpm even 100 µs is 2%, so jitter is not the threat.
Flash operations are the threat. Cache is disabled during write/erase, stalling task code for milliseconds — long enough to drop events and corrupt the period estimate. Therefore: ISR allocated ESP_INTR_FLAG_LEVEL3 | ESP_INTR_FLAG_IRAM, radio off whenever armed, no NVS/LittleFS write and no OTA while armed, logs buffered in a DRAM ring and flushed only when disarmed.
Failure handling
- Gate asserted while IGt is high → impossible by construction. The 74HC74 only transfers
DtoQon IGt’s falling edge, so the gate physically cannot move mid-dwell whatever the firmware does. The ISR still re-reads IGt and refuses as a belt-and-braces second line, but the hardware is the guarantee. See the superseded-callout above; this is the only failure that can destroy the engine. - Unpowered / booting / brownout / watchdog reset / hung firmware → 100 kΩ gate pull-downs hold both FETs off, which is a stock car. Not an error path, the default state.
- Run cap → a 6th consecutive cut is unreachable, not merely unlikely. Enforced after the generator, so no mode, ratio or config value can defeat it.
- IGt pulses stop → engine off or tap lost; disarm, gate open.
- Implausible period (>2× or <0.5× the last, or below plausible idle) → discard the sample, do not cut.
- 5 s hold exceeded → release and refuse to re-arm until a cooldown elapses, regardless of driver input.
- VSS reed failed open → no edge for >2 s means speed zero, so a dead reed reads as stationary, not as “still moving”. At ≈1.14 Hz per mph a 2 s timeout corresponds to under about 0.5 mph, which is the intended threshold. Bounce is rejected by minimum-interval (≈60% of the period at top speed), never a fixed blanking window.
- We never drive VSS, brake or any other ECM input — all three are read-only, high-impedance taps. The only nodes this box ever drives are IGt and (if ever enabled) IGf.
- Brake alone never arms anything. The stop-light switch closes in the first millimetre of pedal travel, so it proves intent, not that the car is held. VSS stationarity is the load-bearing interlock; the brake is the driver’s request. Do not later “simplify” arming to brake-only — it would look equivalent and would not be.
- Supply below ~10 V → the ECM itself dies here, so degrade to gate-open rather than pretending to work.
- Must never crash the car’s ignition. Every failure mode resolves to “stock Tracker”.
The single easiest bug to ship here
Writing the gate GPIO from the web/config path, or from a timer not synchronised to IGt. It will work on the bench and on most events, then land inside a dwell window at some random RPM and fire the coil at an uncommanded angle. Only
ign.cpptouches that pin, only while IGt is low.
Prior art
- korn101/ArduinoLaunchControl intercepts the Toyota IGT line for exactly this purpose — the right interception point, and instructive for its defects: the cut is decided in
loop()behind a 20 ms delay (four ignition events at 6000 rpm, asynchronous to ignition phase), switched by a relay, with RPM from 1 msmillis()deltas against a 5 ms event period. Decide-at-N / apply-at-N+1 with a FET fixes all three. - IGf forgery is established practice in the Megasquirt community for Toyota conversions — typically an NPN and a resistor generating IGf from IGt, structurally our idle Q2. Reassuring that the fallback is proven.
- Speeduino and rusEFI both use series-R + diode-clamp + hex Schmitt input protection and 100 kΩ gate pull-downs; the front end here is deliberately the same topology.
- Relays are consistently reported as too slow for per-event ignition cutting. We use a MOSFET.
Bench rig
A second ESP32 emulates the ECM and the igniter: it generates IGt at a swept RPM and returns IGf after a configurable delay, optionally omitting IGf to imitate a fault. Every mode, interlock and failure path is proven here before the box goes near the car.
Testing / verification
- Car, identity check — 30 seconds, before anything else. Count the cavities on the ECM couplers: this design assumes the OBD1 16-valve 22-pin “A” + 26-pin “B” ECU. Also read the VIN’s 8th digit and confirm it is the 16-valve code. Every pin number in this document rests on a Vitara manual, corroborated pin-for-pin by a Tracker source but not from a Tracker factory section — these two checks validate or invalidate the whole basis at once. A different cavity count means stop and re-research.
- Emulator, pass-through — IGt out matches IGt in for every event across 500–7000 r/min; zero blocked events when disarmed.
- Emulator, the assertion trap — command the firmware to assert the shunt while IGt is high and verify it refuses. Hardware cannot enforce this, so it gets its own test.
- Emulator, gate integrity — assert across a long sweep that the gate pin never changes while IGt is high. Must fail loudly if the ISR is restructured.
- Emulator, run cap — sweep every mode, ratio and cluster setting; assert no run of blocked events ever exceeds 5. This is the test that protects the fuel supply.
- Emulator, RPM accuracy — within 1 % of commanded across the sweep; no reading survives an injected implausible period.
- Emulator, patterns and interlocks — clustered gives exact N-cut/1-pass groups; spread hits the requested ratio; no cut without brake + stationary; hold releases at 5 s; cooldown blocks re-arming.
- Car, measurement gate — the go/no-go, before anything is built. Key on, engine off, nothing unplugged: measure IGt high level (V1), add a known 220 Ω IGt-to-ground, measure again (V2), compute
R_out = (V1 − V2) / (V2 / 220). ChooseR_sh ≤ R_out / 6. If R_out < 60 Ω the parallel shunt is abandoned in favour of the series interrupt — at that impedance the shunt current is limited only by R_sh and would destroy the ECM driver. Also capture the real IGt→IGf delay and IGf pulse width while here. Best done as a continuity check from the igniter connector’sIGtterminal to ECMA4, andIGftoB5— that single measurement proves the pinout on this car rather than inheriting it from a Vitara manual, and confirms both ends at once. - Car, main limiter — at temperature, in neutral, brief excursion to a limit well under 6,720. Confirm it holds, then read DTCs live at the 6-pin DLC (jumper 2↔4) and confirm no code 41.
- Car, stall measurement — before enabling the launch limiter, measure the actual stall speed: brake fully applied, “D”, full throttle, read rpm when it stabilises, release immediately. 5 s maximum, 60 s at idle before repeating. Set the launch limit just above the measured figure.
- Car, two-step — brake-torque to the launch limit; confirm bangs, release, and that the 5 s cap and 60 s cooldown both fire. Check ATF colour and smell afterwards.
Risks
| Risk | Mitigation |
|---|---|
| Every pin number is Vitara-sourced | No Tracker/Sidekick factory electrical section for the 16-valve exists in the KB. A4/B5/A7 are corroborated by a Tracker-specific ECU pin list that matches the Vitara table pin-for-pin, but the cavity count and VIN check in test 0 are what actually confirm it. Cheap, so do them first |
| Adding a pull-up to VSS lifts its low level and sets code 24 → limp-home | No added pull-up; read high-impedance and rely on the ECM’s own. Verify the low level with a meter once tapped |
| ECM output too stiff for a shunt (R_out < 60 Ω) | The one outcome that invalidates the approach. Resolved by the two-minute measurement in test 7 before any board is built; fallback is a series interrupt, which the igniter’s internal pull-down makes safe for the coil |
| Shunt fails to pull below V_BE and the cut silently does nothing | Why R_sh is 22 Ω rather than 47 Ω, with a 10 Ω footprint in reserve; verified on the emulator and then on the car before relying on it |
| Shunt current stresses the ECM driver | The 8v ECU’s igniter driver is an M5262L, a 2 A peripheral driver, so 15–35 mA is orders of magnitude inside rating (16v part not identified, assumed comparable). IGt also rests at 0 V with ignition ON, so we only contend during the ~3 ms dwell command. Prototype carries a 100 mA polyfuse |
| Run cap does not satisfy the ECM (counter needs more than one good event to reset) | Cap of 5 is conservative against a threshold documented as 8 and reported as 6. If fuel still cuts, enable the fitted Q2 forgery path — hardware is already there |
| Brake-torquing cooks the 3L30 | 5 s hard cap and 60 s cooldown, both from the 3L30’s own procedures. Lock-up is open with the brake down, so this is all converter shear — there is no mechanical path for the heat to avoid. ATF check after every session; normal operating range is 88–93 °C and there is no fluid-temperature sensor on this transmission, so inspection is the only feedback |
| Launch limit set from the wrong transmission’s spec | Fixed: the 2,300–2,600 figure is 4-speed-only. Commissioning measures actual stall on the car; the 2,500 default is explicitly a placeholder |
| Muffler packing destroyed | The most likely casualty by far — a straight-through drum is fibreglass around a perforated tube, and pressure pulses shred and eject it permanently. Treat it as a consumable |
| O2 sensor fouling / thermal shock | Degrades closed-loop fuelling without necessarily setting a code on OBD1. Inspect and expect to replace |
| Cast-iron manifold cracking | Documented for repeated late-combustion thermal cycling. Inspect runner junctions periodically; bounded by the 5 s cap |
| Exhaust valve bounce | Materially lower here than the forums suggest: the classic failure is a bounced valve letting a hydraulic lifter pump up and hold it open, and the G16B is shim-over-bucket with solid lifters. A bounced valve simply recloses. No documented case of a small NA four losing a valve to a two-step |
| Silent limp-home with no CEL | Run cap is the primary defence; read DTCs live at the DLC after every session rather than trusting the lamp |
| Millisecond ISR stall from a flash write drops events | Radio off and no NVS/OTA while armed; logs buffered in DRAM. Enforced structurally, not by discipline |
| Engine-bay EMI corrupting a 3.5 V logic tap | 0.6 V Schmitt hysteresis, clamps at connector entry, twisted/shielded pairs, signal ground referenced to ECM B14 so ground movement is common-mode |
| Decel fuel cut removes the fuel we need | Bangs require an open throttle. Closed-throttle above 3000 r/min triggers the factory decel cut and there is nothing to ignite — a limitation, not a fault |
Future levers (not v1)
- IGf forgery enabled — unlocks runs longer than 5 and a true 100% cut. Only worth it if the run cap disappoints; note the forged pulse may need a width window, since real IGf holds a roughly constant high duration while the low portion varies with RPM.
- Spark retard mode — delay the IGt pulse rather than blocking it. Keeps real spark and real IGf, zero DTC risk, smooth street limiter. Needs ~28 µs placement accuracy; revisit once ISR jitter is measured on the bench.
- Half-cut via one injector group — B11 (injectors 1&4) and B24 (2&3) are separate drivers, so half the fuel could be dropped to tune bang intensity. Adds inductive-load switching risk.
- Igniter-connector passthrough — a 4-way printed adapter carrying IGt, IGf, +B and IG, giving unplug-to-stock reversibility. Shell can be printed (ASA or nylon, never PLA — under-bonnet temperatures pass its glass transition and a crept latch is a connector that backs out); terminals cannot, and would need harvesting from a donor harness.
- Orphaned rear-diff VR sensor as a road-speed source — the ABS speed sensor is already unplugged and cut, so it is electrically free to reuse. Not worth it while the reed switch works (a VR front end is an entirely different circuit), but it is the fallback if the speedo-head reed corrodes, which the KB calls its most common failure.
- Jot the tap points into pipeline as harness entries once verified on the car.
- Telegram fault reporting via the existing bot, if the box ever needs to report off-car.