Skip to content

Documentation

Wheels by brand

What is supported on each brand, and how well it has been confirmed on real hardware.

Every brand's protocol is decoded separately. Below is a straight account of what works and what was reconstructed from the manufacturer's app and still needs confirming on a real wheel.

The rule all of this follows: a command is only ever sent to a wheel once its meaning has been confirmed by a real capture or a real write. Reverse engineering someone else's app produces a hypothesis, nothing more. The exception is the KingSong and older InMotion settings: their commands were built from two independent sources that matched byte for byte, but have not been tried on a real wheel yet. Each of those brands says so below.

If a wheel was renamed and its name gives nothing away, the app recognises Begode, KingSong and LeaperKim from the very first bytes the wheel sends and switches to the right decoder on its own. NOSFET cannot be told from LeaperKim by its bytes, so a renamed NOSFET shows up as LeaperKim.

On the wheel settings screen a value is spelled out in words wherever a word is more accurate than a number: tilt-back that is switched off reads "Off", not "0 km/h"; a King Song threshold that will never fire reads "Off" too; Begode units read "Kilometres" or "Miles"; and the auto power-off timer reads "3 min", not "180". The slider you are dragging is labelled the same way, not just the value the wheel has already reported — pull tilt-back all the way down and you see "Off" before anything is written. The labels follow the interface language: until now some brands printed them only in Russian and others only in English, whichever language your app was set to.

Settings your wheel does not have are not shown on that screen, and a section left with none is hidden altogether. On Android such rows used to be listed as "Not supported".

The screen itself is built from sections, and the sections are collapsed: a P6 decodes into some thirty-five rows, and expanded they turn into thirteen screens of scrolling. The first section — "Control", the one people usually come here for — is open straight away; every other one says in its header how many settings it holds. The search field above the sections expands whatever matched, so tilt-back is three letters away rather than ten screens of scrolling. The "Raw values" switch adds the byte offset and the raw number under each setting; that is protocol material, and it is off by default. All of this is the same on Android and on iPhone.

LeaperKim#

The most complete support.

  • All telemetry, including angles, left and right battery currents and the wheel's own limits.
  • Battery cells, page by page.
  • Wheel settings are written from the app: pedal stiffness and ride mode, tilt-back speed, alarm speed, PWM threshold, screen backlight, pedal angle, transport mode, units, voltage correction, low battery mode, high speed mode, button volume, maximum charge voltage, acceleration and braking assistance, and more.
  • Setting presets.
  • Automatic light, automatic volume.
  • The headlight switches on across the whole brand, the older models included. Sherman, Sherman Max, Sherman S and Abrams understand only the text light command - their firmware carries no binary one at all, and the light button used to do nothing on them. The app now looks at which wheel answered and sends the command that firmware parses.
  • Keeping a parked wheel awake. The setting stays on when you power the wheel off from the app: on Android the power-off button used to clear it silently.
  • The maximum charge voltage is shown in volts only when the base is known: the wheel reported it, or it is known for that model or firmware build (Lynx and Sherman-L: 145). Otherwise only the adjustment is shown, e.g. "+6.2 V". Such wheels used to show a wrong number — 134.2 V instead of the real 151.2 V, with the slider ending at 140 V.
  • Firmware flashing sits in the dashboard menu as its own item, and only on LeaperKim and NOSFET wheels: other brands do not get the item at all. It has been proven on two wheels so far, the LeaperKim Lynx S and the NOSFET Aeon; the other LeaperKim wheels use the same file format, but nobody has tested the bootloader entry on them, and the Sherman L runs a different microcontroller on top of that. I strongly advise against using it: a failed flash turns a wheel into a heavy piece of furniture.
  • Firmware recovery is on Android, in a saved wheel's long-press menu in the garage: "Try to recover the firmware". It is for a wheel that went silent after a failed flash — it is not in the scan and sends no telemetry — but still answers "Test sleep connect". The app connects to the saved address and sends the chosen file blind, with no tilt check. There are two ways: the way the official LeaperKim app recovers a wheel, with no command, and with the programming-mode command sent first. Neither has been proven on a real wheel yet; if the first does not help, switch the wheel off and on and try the second.
  • Event log — its own item in the dashboard menu, on Android and on iPhone. The wheel keeps its own log: events, protection trips, errors. "Read the log" asks the wheel to hand the records over; ordinary telemetry keeps flowing meanwhile, and reading stops by itself once the records run out. "Copy" puts what was read on the clipboard — handy for sending it to us. Custom firmware writes its debug there too, if you flashed any. Reading the log has only been done on a real wheel from Android; on iPhone it is built and proven against a wheel emulator, not against a wheel.

NOSFET#

The same protocol as LeaperKim, so everything is available: telemetry, battery, wheel settings, presets, lights, power off.

The only gap is keeping a parked wheel awake: it is tied to LeaperKim for now. If someone volunteers to test it on a real NOSFET, I will add it.

The event log reads the same way as on LeaperKim — the same dashboard menu item.

Firmware flashing, and firmware recovery on Android, are available on NOSFET too: the brand's firmware is a branch of LeaperKim's, with the same file format and the same bootloader entry command. Flashing from LoEUC has been proven on a real Aeon, with both the factory firmware and a modified one. Nobody has tried the other NOSFET models or firmware recovery yet, so for those everything said above about LeaperKim applies twice over. Each model has its own firmware file, with the model number in its name:

Model File
Apex _main5010xx.bin
Aero _main5020xx.bin
Aeon _main5030xx.bin
Xeno _main5040xx.bin

The firmware screen compares the number in the file with the one the connected wheel reports and warns you if they differ.

InMotion#

V11 and everything newer. V12, V13, V14 and P6 are the best understood.

  • Full telemetry.
  • Battery.
  • The list of faults and warnings the wheel reports about itself.
  • Quick actions: low and high beam, automatic light, power off.
  • The P6 also reports tyre pressure, LTE signal strength and the trip maxima the wheel keeps itself: speed, battery power and motor power.
  • P6 readings refresh twice as often: the app asks the wheel for two sets of readings in turn, as the manufacturer's app does.
  • The wheel's total distance: the app asks for it every couple of seconds, as WheelLog and the manufacturer's app do.
  • On a V11 with main board firmware 1.4 or later the trip distance is now read from the field the wheel actually counts it in; it used to sit at zero.
  • The polling interval is adjustable: polling more often gives smoother readings but loads the connection harder.

For V12 and for the V14 family including the P6, light settings are written: turning the wheel's own automatic light on, its light sensor thresholds, and brightness. V12 and V14 lay these out differently internally, and that is accounted for.

The V11 writes a wider set: speed limit, pedal angle and sensitivity, voice volume, standby timeout, headlight brightness, the acceleration and braking assists, sound, daytime running lights and the wheel's own automatic light. After every write LoEUC asks the wheel to re-read its settings, so what you see on the screen is what the wheel accepted rather than what was requested. The two fan rows are shown but not writable: one of them is a state the wheel reports rather than a setting, and neither has a write command I trust.

The V12S, V11Y and V9 are now decoded with their own layout. The V12S used to be read as a V12, which made its speed, PWM, charge and power wrong. The V13, V11Y, V12S and V9 now have a settings screen: voice volume, sound and automatic light are written, the rest is read-only for now. The V12, V12S, V9, V11Y and the V11 on main board firmware 1.4 or later get a horn on the widget. The V13, V14 and P6 do not: the sources disagree on the bytes.

A caveat: these writes have been verified against the checksum maths and the manufacturer's own code, but not fully confirmed on real hardware. A few settings, such as the high beam switching threshold and the turn signal state, are read-only because I know of no way to write them.

Older InMotion: V5, V8, V10 and Solowheel Glide 3#

Experimental. These speak a different protocol from the V11 and newer, and no wheel of this series has connected to LoEUC yet. The decoding is checked only against real V5F, V8F and V8S recordings published by WheelLog. If you own one, please send a ride recording — that is exactly what is missing.

  • Speed, voltage, current, power, temperature, trip and total distance, pitch.
  • Charge is estimated from voltage: these wheels have no smart battery with per-cell pages.
  • The wheel's model, serial number and firmware.
  • Wheel settings are written from the app, and the wheel is read back after every write: top speed, headlight, decorative light, volume, ride mode, pedal horizon, the handle button and pedal hardness. What is available depends on the model — a V5F, for example, only offers the headlight, top speed and pedal horizon.
  • Quick actions: headlight and horn.

The app unlocks the wheel with the default PIN 000000. If the PIN on your wheel was changed, the wheel will stay silent — entering your own PIN is not available yet.

The settings commands come from WheelLog and were checked against InMotion's own app — the bytes match, but they have not been sent to a real wheel yet. Start with small steps. Below 100 the two sources scale pedal hardness differently; here it follows WheelLog. There is no power off: the manufacturer's app has no such command, and the codes next to it there are the lock. Calibration, lock and transport mode will not be added.

Begode#

Both current models and old ones such as the RS.

Read reliably:

  • battery voltage,
  • cell voltages of both batteries,
  • charge level,
  • speed,
  • PWM,
  • temperature,
  • battery temperature, highest and lowest.

Not every Begode reports PWM and motor temperature: on an EX30, for one, that field goes out empty. The app used to show a flat 0 % PWM for the whole ride on such wheels — an overload gauge reading "no load" right up to the cutout. Those wheels now get PWM estimated from speed and voltage, the way older Begodes have always had it, and no motor temperature at all, since the wheel does not report one.

Not every wheel measures the battery temperature: of three captures, one answers that field with a flat zero. A zero there means "no sensor", not "the battery is at freezing point", so on such a wheel the tile and the battery-overheat alert are simply not offered - better than a number nobody should trust.

Battery current and power on modern Begode wheels carry a sign: plus while the battery drives the motor, minus while braking and downhills return energy. The wheel itself sends that current the other way round - a draw is negative - and the app used to show it as sent: on a ride forwards the battery power and the consumption per kilometre came out negative, and the apparent power went below zero too. The sign is now flipped, consumption counts the energy spent, and apparent power is always positive. Rides recorded before the fix are corrected by the app itself on the first launch of the new version, and so are rides that arrive later from an old archive. The only ones left as they were are those whose data cannot tell the old sign apart: a session parked on the charger, or a ride that was downhill from start to finish. The battery model the app learned for such a wheel was trained on the flipped current, so the correction resets it; it is rebuilt from the next rides or with the "Train on past rides" button.

The wheel does not always measure that current accurately. An X-Way reads about 1.3 times less than the real current; a RACE standing still reads -2.8 A instead of zero, and a ride's consumption went below zero. When the wheel has a smart BMS, the BMS measures the battery current itself, and the app pulls the wheel's reading onto it: quick changes come from the wheel, the average level from the BMS. The correction starts after about half a minute of riding, which is how long the app needs to tell from the data which way that BMS signs its current. While the wheel only stands, the current is shown as the wheel sends it. Past rides are not recalculated: they hold no BMS current.

Wheel model#

Charge from voltage is the pack voltage divided by the number of cells in series, and that number comes from the catalogue — along with capacity and full-charge voltage. The catalogue has one key: the model name. Most wheels report it; Begode does not. It advertises as GotWay_005913, which is a serial number, and answers nothing to a name request.

So the model is picked by hand: dashboard menu → Model. The pick is stored for that wheel and survives a reconnect. If the app recognised the model on its own, the menu shows its name marked "detected from name" and there is nothing to do.

The same goes for a King Song without a smart BMS — the S18 and its relatives. An S22 rebuilds the charge from its BMS pages, which is a measurement; an S18 sends no such pages at all, and King Song states no percentage anywhere in the protocol, so until the model is picked there is nothing to compute the charge from.

Until the model is picked or recognised, charge is not shown. The series-cell count cannot be derived from a single voltage even in principle: a full 36S reads 151.2 V, and so does a 40S at 3.78 V per cell. The app used to guess here from voltage, and on a T4 it guessed wrong — a sag below 90 V moved the divider from 24S to 20S, and charge read 100 % on a half-empty pack for the rest of the ride.

If you set the voltage class by hand before, it keeps working until you pick a model.

Settings#

Begode settings are written from the app: dashboard menu → Wheel settings.

  • Speed tilt-back, and switching it off.
  • Ride mode: soft, medium, hard.
  • Field weakening.
  • Pedal dip in turns and horizontal pedal trim.
  • Side-fall cutoff angle — two rows: as a level (low, medium, high) and in degrees.
  • Buzzer volume.
  • LED strip mode.
  • The first speed alarm, on or off; the second one stays armed either way.
  • Tilt-back on low power reserve, and the threshold it fires at.
  • Units on the wheel's own display.
  • Auto power-off timer — read-only.

The power threshold is shown as the reserve left: "warn me at 30 % reserve" means the wheel starts warning when 30 % of the reserve is left. The wire carries the opposite number, the load level — the vendor apps show one end or the other, which is confusing. The reserve is clearer.

One thing to know about this brand: the wheel confirms nothing it is told. There is no reply, no echo and no checksum in the protocol. It reports only five of its settings back — speed tilt-back, the auto power-off timer, the units, the ride mode and the power-margin threshold — and only those rows carry a current value. The other rows are blank on purpose: filling them with the last value sent would show you your own intent dressed up as the wheel's state.

What is missing and will stay missing: gyroscope calibration. Its bytes are understood, but the command is not exposed on any brand. It uncouples the motor and needs a manual power-off and levelling procedure; sending it blind from a phone is a fall.

What is missing for now: racing mode (in the protocol it is a toggle with no way to ask for a specific state, and the wheel does not report it) and the third speed-alarm position — the two independent readings disagreed on whether it silences the second alarm or all of them. A rider who believes the second alarm is still armed and is wrong gets no warning at all. It will appear once a live wheel settles it.

The commands themselves come from two independent readings — the official Begode app and the Begode branch of EUC World — and only what both agreed on is implemented. Not all of it has been verified on a live wheel; start with a small step and watch what the wheel does.

Custom firmware#

On connect the app asks the wheel for its firmware version and shows it in the settings. Stock Begode, ExtremeBull, Freestyl3r and SmirnoV are recognised.

  • On Freestyl3r and SmirnoV, PWM comes from the wheel itself instead of being estimated from speed and voltage.
  • On SmirnoV the app also reads battery current, pedal mode and the controller settings — PID, compensations, currents, extreme mode. Read-only: these tune the balance, and there is no second source for writing them.
  • On Freestyl3r, PWM tilt-back can be written. WheelLog and EUC World send the same command for it.

I have not had a live wheel with these firmwares; the decoding follows WheelLog.

KingSong#

Built from the manufacturer's app plus one real capture from an S22.

  • Telemetry and ride statistics.
  • PWM.
  • The speed ceiling and the flag the wheel raises while holding it.
  • Watt-hour counters.
  • Battery with cells and temperatures. The decode closes on itself: thirty cells add up to within a fraction of a percent of the voltage the same pack reports as a whole.
  • Headlight control: on, off, automatic.
  • The wheel's model, firmware and serial number.
  • Fan and charging state.
  • The F18 Pro and F22 Pro battery, which these wheels send as one long frame: cells, temperatures, charge, cycles, temperature and humidity sensors.
  • Quick actions: horn and power off.

About the temperatures. King Song sends two sensors, and the app used to show the wrong one: the "Controller temperature" tile carried the cooler, slower of the two. It now carries the one that heats under load — in an S18 Pro+ capture it went from 17 to 24 °C over a minute of riding while the other only reached 21 °C — which is also the one WheelLog shows. The second sensor is the motor: that is what the stock King Song app calls it, and the physics agree. A motor carries more thermal mass than a power stage, so it heats slower — which is exactly the lag the capture shows.

The "Motor temperature" tile is offered by the same rule as on Begode: when the wheel actually sends the number. The brand has no probe for the MOSFETs, the board, the coil, the CPU or the IMU, so those tiles are no longer offered for it. Metrics that a King Song never fills are gone from the picker too: field weakening, and on a wheel without a smart BMS the cells and pack currents. Charging state came back, though — the wheel does report it, and it had been dropped by mistake.

Settings are written from the app: speed alarms 1–3 and tilt-back, pedal mode, headlight, LED strip, strobe, auto power-off and charge limit. The value in each row is what the wheel reported, not what was sent.

The commands come from WheelLog and were checked against the KingSong app. In two places the sources disagree, and there the app's version is used. None of this has been confirmed by a write to a real wheel yet — start with small steps. Calibration and gyro angles are not there and will not be.

The test base is small and I do not own one of these wheels, so some readings may be off.

Ninebot Z#

Z6, Z8 and Z10 support is experimental. Telemetry and battery decoding follow WheelLog's protocol, but the project has no real Ninebot capture yet. Readings and commands have not been confirmed on a real wheel.

Solowheel Xtreme#

The oldest wheel here, from Inventist, from before InMotion. It sends three numbers as short text about once a second.

The app shows speed and voltage. Voltage is confirmed by a real capture, and the speed scale was calibrated from a real ride. The third number is some kind of state whose meaning is unknown, so it is shown as it arrives rather than dressed up in an invented label.

Your brand is not here#

Write to me. Adding support takes two things:

  1. A capture of the conversation with the wheel. The app records it through the service screen and exports it as a file.
  2. A couple of known values from the wheel's own display or the manufacturer's app: voltage, speed, distance. They are what turns a guess into a check.

The longer the capture and the more varied the riding in it, the more fields can be worked out.