Where I live, electric bikes have to be limited to actively support only up to a speed of 25 km/h. For a Tenways Ago X, which uses Bafang technology, this limit is set in the controller and can be overridden via a command on the CAN bus of the bike.
This article documents the steps I took to modify that limit to my liking. Neither do I recommend you do the same, nor is it advisable to ride a bike that is in conflict with local regulations should that be the case where you live, silly as you might find them to be.
The most accessible point of contact to attach to the bike's CAN bus is the display. To get in between the controller and the display, a Y cable is needed. As a basis, purchase an extension cable with the needed kind of connector.
After assembly, check each contact with a multimeter for continuity to ensure that no pins are swapped as that might be catastrophic.
Looking into the male connector.
+-----+ / 2 \ | 1 3 | | 5 4 | +-------+
V+ (supply voltage for the display)
CAN L
BAT+
CAN H
GND
I terminate such cables with banana plugs because I have a stock of CAN debugging cables that I can use with them. You might want to terminate directly to Sub-D.
As a precaution, take the battery out of the bike before working on the cabling. Also, better to not have the battery fully charged to the brim. I usually aim for a ~30% charge. Makes mistakes a little less exciting.
Then, put the Y cable in between the display and the bike.
Put the battery in and turn the bike on.
Measure the following leads against GND.
GND (black wire / black banana)
BAT+ (brown wire / red banana) expect > 36 V
V+ (orange wire / open end) for me this is ~3.3 V
Connect the adapter to the PC and configure it for 250 kbit/s.
$ ip link set can0 up type can bitrate 250000
Then, connect the adapter to the bike and listen for frames to check basic functionality.
$ candump can0
Here are some handy commands.
# to observe a specific frame you can pass a filter with a particular ID # the `f`s are a mask $ candump can0,03106300:ffffffff # to observe exchange between controller (2) and BESST (5) $ candump can0,02000000:ff000000,05000000:ff000000
The maximum speed setting is sent out in a regular frame with a period of four
seconds. The message code is 3203. The following command can be used to
observe all frames with that code.
$ candump can0,00003203:0000ffff
Such a frame might look like this.
C4 09 D0 01 1A 09
To decode the data, split it into three 16 bit words in little-endian order.
c4 09 -> 9c4 -> 2500 = 25 km/h d0 01 -> 1d 0 -> 29 0 = 29.0 inches wheel diameter 1a 09 -> 091a -> 2330 = 2330 mm wheel circumference
To explicitly query the data, use the following command to issue a query frame.
$ cansend can0 05113203#
To configure the setting use the following command. The part after the hash is the data.
Do not blindly use these values, there's settings inside that are specific to your bike model!
$ cansend can0 05103203#c409d0011a09
The write operation will be acknowledged by a frame without data on
ID 022a3203.
If for any absurd reason you wanted to configure the max speed to 30 km/h, you'd be using the following frame.
$ cansend can0 05103203#b80bd0011a09
After this, turn off bike and take out the battery.
Then, disconnect the Y cable and restore the proper connection to the display.
Finally, put the battery pack, turn on the bike and go for a test ride.