• Hello ES! We could use some help to get us past the finish line on building the new knowledgebase for the forum.
    Can you donate? Please see our fundraising page. Thank you!

BAFANG M215 (BBS01 CAN bus), M315 (BBS02 CAN bus), M510, M560, M820, CR-A101 FOC Open Source EBiCS Firmware for GD32F303 processors

This is related to exact this one single torque sensor?!
Yes, exactly. 😊
Is the cadence shown correctly, if the motor stops?
I won’t be able to test this on the bike today, but I just ran a test on the bench — with enough load so that the cadence would at least show up on the display.
I did a simple experiment: I tried to spin the wheel evenly at about 10 km/h and watched the cadence readings — they stayed around 80 rpm. Given my drivetrain, the readings matched pretty closely with what the drivetrain calculator showed.
What I found a bit strange is that after stopping, the cadence doesn’t drop to zero right away — it keeps showing the last value for a while. If you pedal backward during that time, the cadence is still calculated.
 

Attachments

  • Cadence.png
    Cadence.png
    26.3 KB · Views: 9
You can check the cadence sensor signals with two voltmeters and see if there is something weird

 
If you pedal backward during that time, the cadence is still calculated.
Yes, the cadence is simply calculated from the duration between two PAS pulses on the PAS2 input line. This is independend from the turning direction of the pedals.
https://github.com/EBiCS/BAFANG_GD3...820576866e05f1c1d3aea24a42f5/src/main.c#L1167

The calculation is triggered by the falling edge on pin PC11 (PAS2)
https://github.com/EBiCS/BAFANG_GD3...2820576866e05f1c1d3aea24a42f5/src/main.c#L624

The last reading keeps valid, until the torque timeout counter resets it.
https://github.com/EBiCS/BAFANG_GD3...820576866e05f1c1d3aea24a42f5/src/main.c#L1228

It's likely that the PAS1 and PAS2 wires are swapped on your sensor, causing the motor to shut off after 4 PAS pulses because it detects backward pedaling...
We could verify that by sending the value of the Backwards_counter to the calories field. Or you can simply test if it works, if you swap the PAS1 and PAS2 wires on the connector.
https://github.com/EBiCS/BAFANG_GD3...820576866e05f1c1d3aea24a42f5/src/main.c#L1791
 
Last edited:
I've added that feature to the v0.0084 now. The new calibration is executed, if the cadence is zero, the PWM is switched off and the idle value is more than 40mV off the first calibration at startup. Maybe the calibration is triggered, if you rest your leg on the pedal at a red traffic light, you have to try it, I have no M560 on my test bike at the moment. You can check the recent torque value in the calories field
https://github.com/EBiCS/BAFANG_GD3...0/latest_beta/EBiCS_for_M560_BL38_v0.0084.bin
I cheked this 0.0084 but it works erroneously there is no consitent assist and i had problem with installing with besst tool - dosent read s/n. I turned back to 0.008 versions.
 
I cheked this 0.0084 but it works erroneously
Yes, I've deleted the v0.0084 yesterday already and replaced it with the v0.0085. The recalibration is only triggered, if the idle voltage is off four seconds after the last PAS pulse now. But even this might be no suitable criteria for the recalibration. I can't test this feature, as there are no hills around me, that would heat the motor significantly. 🤷‍♂️
 
Or you can simply test if it works, if you swap the PAS1 and PAS2 wires on the connector.
Well, they either really mixed up the pinout or changed it on purpose. I swapped the wires, and everything started working.
As for the v.0.0085 test - I’m also in a flat area, so I don’t have a chance to really heat up the motor. But I noticed something interesting about the calibration algorithm. When I’m waiting at a traffic light or just waiting for my wife, I usually hold the brake and press my foot against the stationary pedal. I think it’s clear how the torque sensor gets calibrated in that situation :D

A couple of words about the motor: it’s an M560 with an M510 controller (I think it’s the most suitable for EBiCS). It’s a fun motor - it’s set to 50 A battery current and 120 A phase current, of course. The HFL1426 overrunning clutch has been replaced with a spacer because it was operating at the limit of its capabilities even in the stock M560 configuration.
All this power is handled great by EBiCS. The downside is a few false triggers of the torque sensor on roots and rocks, but they don’t affect safety. The throttle handle is a bit trickier, but adjusting the exponent settings has improved usability. I’m thinking of taking this motor to the mountains for a week at the end of August. 😊
 
it’s set to 50 A battery current and 120 A phase current
I think we have not documented the ADC limits for the battery- and the motor current yet. The ADC resolution is 12bit, 4096 steps.
The motor current has to be measured in positive and negative direction, therefore the Bafang hardware has an offset of about 2048. So the maximum motor current, the ADC can handle is (4096-2048)*calibration factor. The factor for the motor current is 70mA/step. So the maximum readable current is 2048*70/1000 = 143A.
For the battery current, the offset is about 1360 and the calibration factor is 28, so the maximum battery current that can be read is 76A.

regards
stancecoke
 
Last edited:
I have a question about the throttle grip. I measured the voltage range of my throttle handle with a multimeter — it’s 0.8–4.2 V. However, as we discussed earlier, the M510/M560 controller uses a voltage divider, because you can’t apply more than 3.3 V to the processor input. I came across information saying that stock firmware performs an inverse conversion of the values for convenience — so it’s easier to enter the actual throttle handle values. How is this implemented in EBiCS?
 
How is this implemented in EBiCS?
EBiCS uses the raw ADC values internally. The voltage settings for Throttle offset and Throttle max in the Canable tool are converted to ADC counts in the Parser, assuming, that the voltage divider maps the 0-5V range to the 0-3.3V range exactly. This will not be 100% correct, we would have to send the live ADC data to the debug output to fine tune the conversion formula. But it will not have a big impact on the throttle behaviour.
https://github.com/EBiCS/BAFANG_GD3...820576866e05f1c1d3aea24a42f5/src/parser.c#L20
 
EBiCS uses the raw ADC values internally. The voltage settings for Throttle offset and Throttle max in the Canable tool are converted to ADC counts in the Parser, assuming, that the voltage divider maps the 0-5V range to the 0-3.3V range exactly. This will not be 100% correct, we would have to send the live ADC data to the debug output to fine tune the conversion formula. But it will not have a big impact on the throttle behaviour.
So, it doesn’t really matter what maximum voltage I specify?
 
So, it doesn’t really matter what maximum voltage I specify?
?! No, of course the throttle_max value is part of the setpoint calculation:
C:
mapped_throttle= map_exp(adc_value[1], MP.throttle_offset, MP.throttle_max, 0, phase_current_max_scaled);


Edit: with putting the example in the online debugger, I found, that I ignore the voltage divider in the parser at the moment. :(
I fixed that already, but have not compiled a new bin file. As workaround, if you want to set 0.8V as offset, you have to write 0.5V (=0.8*3.3/5.0) in the canable tool.

 
Last edited:
I rode at least 6 h in mountains with steep uphill and used all modes and looked at torques (at calories field) the baseline values was constant about 740, no apparent drift max readings about 1200-1300. I think that i need turn down boost option because of prolonged motor action after finished uphill - the thing i described before
 
No, as the M560 uses the Bootloader 38, but I've just added the v0.0085 for the M560 to the repo:

But as @Avatarkhorn already stated, the recalibration is triggered too often, the way I've implemented it.
When I’m waiting at a traffic light or just waiting for my wife, I usually hold the brake and press my foot against the stationary pedal. I think it’s clear how the torque sensor gets calibrated in that situation :D

But if you found, that the idle readings stays at about 740 even after a hard uphill session, there is no issue with a thermal drift of the idle reading...
 
Last edited:
Therefore, I asked you to write down the values in the calories field in the various situations ;)
Unfortunately, the relationship between the torque sensor readings and the motor's spontaneous rotation is still unclear. But I have a question: even if the torque readings are above the threshold, why does the motor rotate at zero cadence? I checked, cadence is measured by the cranks, not the sprocket. I'm not turning the cranks, but the motor accelerates.
 
There are two possible reasons:
1. The throttle reading. Even if no throttle is connected at all, the floating input pin may catch some noise and trigger the assistance. Safest way would be to attach the pin permanently to GND or to set the throttle offset and throttle max to above 5V.

2. Even if you think you don't move the pedals, a very little movement may reset the PAS timeout. You can try to rotate the pedals backwards for one revolution and see, if the motor stops. The backwards counter will be filled and the assistance will only start after several forward pulses again.
 
There are two possible reasons:
1. The throttle reading. Even if no throttle is connected at all, the floating input pin may catch some noise and trigger the assistance. Safest way would be to attach the pin permanently to GND or to set the throttle offset and throttle max to above 5V.

2. Even if you think you don't move the pedals, a very little movement may reset the PAS timeout. You can try to rotate the pedals backwards for one revolution and see, if the motor stops. The backwards counter will be filled and the assistance will only start after several forward pulses again.
This is not throttle because turning the pedals backwards stops the motor.
 
I'm trying to compile version V0.008 from GitHub. I installed GD Embedded Builder (it worked on a different PC), imported the project, and set #define BOOTLOADER 38 in config.h. The build runs without errors, but when I try to flash the resulting bin file, the process freezes on step 2. What am I doing wrong?
 
the process freezes
Besides the config.h you have to edit the linker script also to set the right start address offset for the bootloader:

And of course, you have to add the 32byte header to the bin file by running the relating python script from the documentation folder.
 
Back
Top