Notes on Bafang CAN Bus

Bafang M200 (M-series) mid-drive motor with CAN bus
Bafang M200 mid-drive motor (model MM G210.250.C) with 36V battery connector (yellow, from left), empty 6-pin electric break connector (purple), 8-pin rear light and wheel speed connector, and 8-pin front light and display connector.

I got my wife this Accolmile Antelope 1S electric bicycle with Bafang components from their latest M-series lineup of mid-drive motors and displays which communicate over a CAN bus. It’s a great city bike and the price includes fast shipping from the warehouse in Poland. Their support was also quick to send a replacement wheel for the original that got dented during transport (despite the thoughtful packaging).

CAN over NodeJS

The M500/M600 motors are particularly popular with MTB riders so the communication protocol has been discussed in this forum thread and documented in this GitHub repository. Importantly, the BESST software for managing the configuration and firmware updates is an Electron app with all logic as plain HTML and JS files (and bundled source maps for all minified code), including the CAN frame specification. I’ve started documenting my research in this GitHub repository.

Connecting to CAN Bus

The display connector at the wheel is the most convenient place to tap into the CAN bus. I purchased two HIGO 5-pin connectors B5-F and S5-F from ETShop in Germany for around €7 each and soldered the CAN high (green), CAN low (white) and ground (black) wires from each for a connection to (a copy of) the CANable Pro 1.0 CAN-to-USB adapter. Be sure to test the wiring with a multimeter because one of the wires carries the full battery voltage!

HIGO S5-F connector wires for Bafang CAN bus

Technically any CAN-to-USB adapter will work (as long as it supports 250kbit transfer rate) and the choice depends more on the software you want to use for interacting with the bus. The CANable adapter runs the slcan firmware which implements the Lawicel SLCAN protocol (a basic ASCII serial) which is supported by various libraries, including SocketCAN.

Bafang HIGO S5 and B5 connectors attached to CANable Pro
HIGO 5-pin B5-F and S5-F connectors attached to CANable Pro 1.0 CAN-to-USB adaptor.
CANbus traffic between Bafang M200 and DP C245 display.
Logging CANbus traffic between Bafang M200 (G210.250.C) motor and DP C245 display.

Update Controller Configuration

I was able to test the setup by increasing the assisted maximum speed to 60km/h from the original 25km/h by sending a CAN message composed of the following components:

  • 0x05 for the message source (0x01 — torque sensor, 0x02 — controller, 0x03 — display or HMI, 0x04 — battery, 0x05 — BESST),
  • 0x02 for the message target (controller),
  • 0x00 for a WRITE operation (0x01 for READ),

which are transformed into a frame ID prefix for the 0x3203 code and subcode for “speed limit, wheel diameter and circumference” registry through this transformer function:

buildHexStringCommand = (source, target, opt, anfn, nfn) => {
    const cmdPrefix = hexAllocToBinaryStr(source.toString(16), 5) + hexAllocToBinaryStr(target.toString(16), 5) + hexAllocToBinaryStr(opt.toString(16), 3);
    let cmdPrefixHex = parseInt(cmdPrefix, 2).toString(16);
    if (cmdPrefixHex.length % 2 !== 0) {
        cmdPrefixHex = '0' + cmdPrefixHex;
    }
    let cmdHexString = cmdPrefixHex + anfn + nfn;
    return hexReverse(cmdHexString);
};

which returns:

05 10 32 03

as the frame ID along with the payload:

70 17 C0 2B B6 08 

where (with little-endian byte order):

  • 0x1770 is 6000 or 60km/h × 100,
  • 0x2BC0 is 700 or 700c wheel diameter (29-inch), and
  • 0x08B6 is 2230 or 2230mm wheel circumference.

Leave a Reply