Five firmware versions in three days.
GearSense learns to see gears.

Three rides, five firmware versions, one breakthrough visualisation, and a magnet that spent an entire commute in my pocket. This weekend GearSense stopped being a pretty display and started being a system that can actually identify gears from real ride data.

5
firmware versions shipped this weekend
4
real commute rides logged
7
gear steps visible in unassisted data
1
magnet found in pocket after a ride

Three rides, three lessons

Each of the weekend's rides taught something different. Not always the thing it was supposed to teach.

May 30 Ride 1

Mark II confirmed working on a real bike. BLE logging live. 13.2 minutes of data, 10,466 PAS pulses, 18,172 wheel pulses. The dominant gear cluster locked onto ratio 12.00 with a standard deviation of 0.254 — the tightest signal GearSense has ever produced. The hardware upgrade was worth it.

May 31 AM Ride 2

Moved the magnet closer to fix double-triggers. Made it worse. The intuition was reasonable — closer magnet, cleaner pulse. The result was the opposite. Lesson: the hardware isn't the problem. The algorithm needs to handle the sensor reality as-is, not the other way around.

May 31 PM Rides 3 & 4

The magnet-in-pocket ride, then the breakthrough. Ride 3 produced nothing useful — the wheel magnet spent the commute in my jacket pocket instead of on the bike. Ride 4 was deliberate: four minutes unassisted, riding first through seventh gear. That section produced the staircase.

On the magnet Every maker has had the equivalent. You prep the hardware, ride across town, and come home with a pocket full of "why is there no wheel data." The "failed" ride turned out to be exactly the dataset the noise calibration protocol needs — a clean zero-magnet baseline. There are no accidents.

The interactive data explorer

The breakthrough didn't come from the firmware. It came from being able to see the data properly for the first time.

After the weekend's rides, a small web-based data explorer was built to visualise the logged CSV files in real time: a PAS cadence vs wheel speed scatter plot, and an instantaneous gear ratio plotted against time. Drag to pan, scroll to zoom. Nothing sophisticated — just enough to ask questions of the data.

Instantaneous gear vs time — full ride, assisted vs unassisted sections
Full ride view — assisted section (tan, 0–16 min) vs unassisted (green, 16–20 min). The circled sections are where stable gear readings accumulate.

The key number the whole thing centres on:

Core signal
instantaneous_gear = wheel_hz ÷ crank_hz
At any given moment, this is the gear ratio. Stable during steady pedalling. Jumps cleanly at a gear change. Everything GearSense builds on top of this one division.

When the unassisted section of Ride 4 was plotted — four minutes of first-through-seventh — the result was a staircase. Seven steps, one per gear, unmistakable. The scatter plot showed the same thing as seven distinct diagonal lines. Each gear: a constant ratio, with wheel speed and cadence varying together along it.

Zoomed unassisted section — staircase gear pattern visible
Unassisted section zoomed — each stable cluster (circled) is a distinct gear. The staircase ascending from ratio 0.6 to 1.5 is the gear map.

Seeing that staircase was the moment the algorithm stopped being a concept and became an engineering problem. We know what we're looking for. We know what it looks like. Now we build the thing that finds it reliably.

The two-regime discovery

The data explorer revealed something that wasn't obvious from first principles: the signal structure is fundamentally different depending on whether the motor is assisting.

Without assist

Each gear produces a diagonal line on the scatter plot. Wheel speed and cadence both vary freely, but their ratio is constant. Clean, separable, algorithm-friendly. This is the signal to learn from.

With motor assist

The BAFANG controller governs wheel speed. Speed is held roughly constant; cadence varies by gear. The gear information is still encoded — just differently. Harder to cluster cleanly.

The implication is direct: learning rides should be done without assist. Unassisted = clean physics = clean gear signal. The algorithm doesn't need to handle both regimes during calibration. It only needs to handle the one where the signal is unambiguous.

Once calibration is complete and the gear map is locked, the system can apply it in both regimes during normal riding. But learning happens unassisted.

GearSense Mark II showing CALIBRATING screen
Mark II on the handlebar — CALIBRATING state, waiting for a clean gear signal

How the algorithm evolved

The naive approach — cluster everything, find peaks — doesn't survive contact with reality. Transitions between gears end up in the map. Double-triggers from the wheel magnet create phantom sub-ratios. Noise clusters pollute the result. What came out of this weekend is a three-layer approach that handles all of it.

GearSense Mark II LEARNING screen — 0 gears, Keep riding
LEARNING state — the screen already knows what the rider needs to do. "No assist — free riding only." The two-regime insight, built into the UI.
Tonight's test v0.5.0 goes on the bike for the first time tonight. Flat-section clustering running live. The next post will have the result.

Looking ahead — rider profiling

The two-regime discovery came partly from thinking about how riding style changes — not just motor on vs off, but how a rider's own mechanics shift over time and circumstance. That question made it worth asking: what would GearSense actually see if the rider changed?

In RUNNING state — normal riding, after calibration — the firmware now accumulates cadence and speed statistics silently in the background. Ride after ride, it builds a profile of how this particular rider pedals on this particular bike. Effort distribution across the gears. Preferred cadence range. How that shifts on hills versus flats. The system already had all the data; it just needed to start keeping it.

This wasn't in the original design. It emerged from the hardware being on the bike and running. That's usually how the interesting features arrive.

What comes next

v0.5.0 on the bike tonight. If flat-section clustering works, the next milestone is rider confirmation and the full learning flow end-to-end.

  1. v0.5.0 field test — flat-section clustering live on the cargo bike
  2. Rider confirmation screen — gear map proposal + accept/reject UI
  3. Noise fingerprint filter validation (calibration ride — no magnet, then with magnet)
  4. Rider profiling baseline collection continues
  5. Full learning flow end-to-end: unassisted ride → cluster → confirm → save