TSDZ8 OSF (open source firmware)

Hello, I'm from Germany and I flashed my TSDZ8 motor and 860c display with the following firmware:

osf_tsdz8_860c_v00_01_19.hex

860c_v13-v20.1c.5-1-860c-bootloader.bin

Can someone explain to me how to correctly set up or calibrate the torque sensor?

With my settings, I'm getting too high human wattage readings.

I also can't get the thumb throttle to work.

Thanks in advance.

Translated via Google Translate
Compared to other TSDZ8 motors, it looks like:
- torque ADC offset is quite hight (other users reported a value arounds 160/190)
- torque ADC max is quite low (other users reported a value around 450).
Still I do not have a lot of feedback from users about their values. So it could be that your values are correct.

In torque ADC step, you entered 93. I expect this is the result of the calculation done by 860C.
In fact I think that this calculation is not valid anymore for OSF TSDZ8. I expect it is based on the raw values provided by the torque sensor and filled in 860C. In OSF for TSDZ8, the raw values from torque sensor are remapped in order that the range between offset and max is 160 (what is the expected range of TSDZ2 motor).
To get more realistic value for human power, try reducing the torque ADC step. Sorry but at this stage, I can't say which value to use (probably between 30 and 65). Note: I expect that when you change this value, you would also have to change the different values of assistance for the modes where human power is used in the calculation if you want to keep the same feeling.
 
Okay, thank you very much for the quick reply. I'll change the settings as described.

Now I have the problem with my thumb throttle.

I've tried two different thumb throttle levers on the TSDZ8 without success.

Both thumb throttles work on my Bafang 750.

How can I find the problem?

Best regards
 
...
Stále nemám veľa spätnej väzby od používateľov o ich hodnotách. Takže je možné, že vaše hodnoty sú správne.
...
I think that now that the OSF firmware is working quite well, it is time to pay attention to the differences between the TSDZ2 and the TSDZ8 (I mean that the javaconfigurator and the FW of the 860C display are designed for the TSDZ2).

With completely correct settings, with the same human force on the pedals, I achieve the motor performance as with the TSDZ2. Even though I have more than twice the motor power available.

I quote from the 860C display manual, the Power assist menu:
menu Power assist:
Value in %/2, maximum 254.
For example, applying 100 Watts to the pedals,
then:
with assistance level of 254, the motor
delivers 508 Watts, (254x2=508%).

If I want to achieve double the motor performance, I have to apply double the human force to the pedals.
Or, with the same force, adjust the values of the Torque sensor menu:
Torque sensor ADC step (for TSDZ2_default_67).

Actually now I am forced to use the wrong display of human power.

In addition to this I would like to remind you of the following limitations in the 860C display menu:
Bike menu:
Max power limit (max_1000)
Motor menu:
Motor power max (max_1000)
 
Last edited:
@mstrens After pulling the latest changes from your repo, my motor is doing nothing. When i flash OSF_TSDZ8_V00_01_20.hex everything is fine, when i flash the fresh compiled version (Without any code changes) it is not working. Am i missing something like Flags or similar to get it running?
 
@mstrens After pulling the latest changes from your repo, my motor is doing nothing. When i flash OSF_TSDZ8_V00_01_20.hex everything is fine, when i flash the fresh compiled version (Without any code changes) it is not working. Am i missing something like Flags or similar to get it running?
I do not fully understand you post.
Do you mean that :
- you are working on the VLCD5 version
- when you use the hex file I provide (resulting of a compilation on my pc), the motor works
- when you generate your own hex file (compiling your self) it does not work.

If it is so,
- did you downloaded totally my github repository?
- did you use modus to regenerate some files in the config/GeneratedSource.

Please note that in the last version, it is not possible anymore to use modus and to let it generate some source file for the initialisation of the MCU. This is because I made some changes manually on a file that had been generated by modus (in order to use the same setup for VADC as in an infineon example).
 
I do not fully understand you post.
Do you mean that :
- you are working on the VLCD5 version
- when you use the hex file I provide (resulting of a compilation on my pc), the motor works
- when you generate your own hex file (compiling your self) it does not work.

If it is so,
- did you downloaded totally my github repository?
- did you use modus to regenerate some files in the config/GeneratedSource.

Please note that in the last version, it is not possible anymore to use modus and to let it generate some source file for the initialisation of the MCU. This is because I made some changes manually on a file that had been generated by modus (in order to use the same setup for VADC as in an infineon example).
Sorry for the missing information.
I forked the GitHub - mstrens/OSF project.
I set it up as described in the readme.
I was able to sucessfully build the hex.
But when flashing the hex the motor is dead.
Just for comparison i then flashed the OSF_TSDZ8_V00_01_20.hex to check whether my config is ok. And with this hex the motor works.

So if i understand you correctly, the github project is currently not usable because of your modus changes?

EDIT: Ok... i just checked out this commit: v00_01_19 many changes imported from 860C version · mstrens/OSF@3ed87bf
And i was able to compile a working hex.
So is there any way to compile the latest version on my machine?
 
Last edited:
Sorry for the missing information.
I forked the GitHub - mstrens/OSF project.
I set it up as described in the readme.
I was able to sucessfully build the hex.
But when flashing the hex the motor is dead.
Just for comparison i then flashed the OSF_TSDZ8_V00_01_20.hex to check whether my config is ok. And with this hex the motor works.

So if i understand you correctly, the github project is currently not usable because of your modus changes?
Normally, if you just download from github and compile, it should works.

It is only if you use modus program to regenerate some files that have been generated that there should be an issue.

At this stage, I do not see why it does not works when your compile yourself.

Here is what I get when I compile on my pc. Do you get different values?
----------------------------------------------------
| Section Name | Address | Size |
----------------------------------------------------
| .text | 0x10001000 | 34748 |
| .VENEER_Code | 0x2000000c | 312 |
| Stack | 0x20000144 | 1028 |
| .data | 0x20000548 | 480 |
| .ram_code | 0x20000728 | 4712 |
| .bss | 0x20001990 | 9240 |
| .no_init | 0x20003ffc | 4 |
----------------------------------------------------

Total Internal Flash (Available) 65536
Total Internal Flash (Utilized) 40252
 
Normally, if you just download from github and compile, it should works.

It is only if you use modus program to regenerate some files that have been generated that there should be an issue.

At this stage, I do not see why it does not works when your compile yourself.

Here is what I get when I compile on my pc. Do you get different values?

Yes the ".text" differs:
Code:
   ----------------------------------------------------
  | Section Name         |  Address      |  Size       |
   ----------------------------------------------------
  | .text                |  0x10001000   |  35700      |
  | .VENEER_Code         |  0x2000000c   |  312        |
  | Stack                |  0x20000144   |  1028       |
  | .data                |  0x20000548   |  480        |
  | .ram_code            |  0x20000728   |  4712       |
  | .bss                 |  0x20001990   |  9280       |
  | .no_init             |  0x20003ffc   |  4          |
   ----------------------------------------------------

  Total Internal Flash (Available)          65536
  Total Internal Flash (Utilized)           41204

Do you know why ther is a diff?
 
I do not know.
I just noticed that I had 2 files (e.g. config.h) on my pc that were not synchronized with github. I do not know why.

I resynchronized now my pc with github.
Can you try to compile again and see if you get the same figures as me.

Note: I now recompiled (and get the same figures as said in previous post) but did not updated the file in folder files to flash (this requires a manual copy and rename)
 
I do not know.
I just noticed that I had 2 files (e.g. config.h) on my pc that were not synchronized with github. I do not know why.

I resynchronized now my pc with github.
Can you try to compile again and see if you get the same figures as me.

Note: I now recompiled (and get the same figures as said in previous post) but did not updated the file in folder files to flash (this requires a manual copy and rename)
Yep that did the trick!
Output is the same and the generated hex works.
Thanks for your quick support! :)
 
I think that now that the OSF firmware is working quite well, it is time to pay attention to the differences between the TSDZ2 and the TSDZ8 (I mean that the javaconfigurator and the FW of the 860C display are designed for the TSDZ2).

With completely correct settings, with the same human force on the pedals, I achieve the motor performance as with the TSDZ2. Even though I have more than twice the motor power available.

I quote from the 860C display manual, the Power assist menu:
menu Power assist:
Value in %/2, maximum 254.
For example, applying 100 Watts to the pedals,
then:
with assistance level of 254, the motor
delivers 508 Watts, (254x2=508%).

If I want to achieve double the motor performance, I have to apply double the human force to the pedals.
Or, with the same force, adjust the values of the Torque sensor menu:
Torque sensor ADC step (for TSDZ2_default_67).

Actually now I am forced to use the wrong display of human power.

In addition to this I would like to remind you of the following limitations in the 860C display menu:
Bike menu:
Max power limit (max_1000)
Motor menu:
Motor power max (max_1000)
860c display let you enter a value up to about 255 for the assist level in power assist mode (I expect it but did not check it).
When I look in the OSF code in power assist mode, I think that the current assigned to the motor is
Code:
uint8_t ui8_power_assist_multiplier_x50 = ui8_riding_mode_parameter;
uint32_t ui32_pedal_torque_x100 = (uint32_t)(ui16_adc_pedal_torque_delta * ui8_pedal_torque_per_10_bit_ADC_step_x100);
uint32_t ui32_power_assist_x100 = (((uint32_t)(ui8_pedal_cadence_RPM * ui8_power_assist_multiplier_x50))
            * ui32_pedal_torque_x100) >> 9; // see note below
uint32_t ui32_battery_current_target_x100 = (ui32_power_assist_x100 * 1000) / ui16_battery_voltage_filtered_x1000;
uint8_t ui8_power_assist_multiplier_x50 is max 255
ui16_adc_pedal_torque_delta is max 160 (OSF TSDZ8 remap the ADC value to this max value)
ui8_pedal_torque_per_10_bit_ADC_step_x100 is probably in range 30/60 (take 50)
ui8_pedal_cadence_RPM is about in range 50/100
ui16_battery_voltage_filteredX1000 is about 48000
So if I calculate, I get a current of cadence * multiplier * torque / 512 * step * 1000 / voltage / 100 =
75 * 255 *160 / 512 *50*1000/48000 = 62 Amp.

62A * 48V = 2976W wich is more than enough.
So it seems me that setting the assist level on 255 should allow to get the max power of the motor.
 
Hey,

i am currently working on an alternative approach to get rid of the jerking issues.
Feel free to test my beta version, Based on the latest mstrens version (OSF_TSDZ8_V00_01_20).
Keep in mind that you will need to flash the config.hex along with the firmware.
I think this is a good starting point. For me, this is the smoothest firmware so far. But there is a lot of room for improvement. I hope someone can test it to confirm that it not only works on my bike ;)
Use on you own risk!

You can download it here: Dropbox

If someone can confirm that it works as expected, i can improve it further and create a pull-request for mstrens.

So far i only tested Torque-Mode with these settings:
Screenshot 2025-06-06 211033.png
Screenshot 2025-06-06 211049.png

Thanks!
 
Last edited:
...
So it seems me that setting the assist level on 255 should allow to get the max power of the motor.
If so, I'll quote from my private message to @prozyc:

May 14, 2025:
OK. I think the manuals are not up to date. I think the values are 255=100% of the allowed power, because otherwise I wouldn't be able to reach 700-800W of power.

P.S.:
Last value =254, first value =0, total 255 values.
 
Last edited:
Hey,

i am currently working on an alternative approach to get rid of the jerking issues.
Feel free to test my beta version, Based on the latest mstrens version (OSF_TSDZ8_V00_01_20).
Keep in mind that you will need to flash the config.hex along with the firmware.
I think this is a good starting point. For me, this is the smoothest firmware so far. But there is a lot of room for improvement. I hope someone can test it to confirm that it not only works on my bike ;)
Use on you own risk!

You can download it here: Dropbox

If someone can confirm that it works as expected, i can improve it further and create a pull-request for mstrens.

Thanks!
Could you explain (in text) the logic that you apply?
 
Could you explain (in text) the logic that you apply?
Sure, it's basically multisampling. I started with a linear weighting, then added a little logic that weights high changes of torque more than small changes. This way the torque value keeps relatively stable when pedaling normal, but is also able to increase or decrease fast in case of a fast increase or decrease of torque. As mentioned, it needs improvement, but it already works pretty nice in my opinion.

Oh, and currently i am using an array of 30 values which should give me a averaging time of max 30*25ms=750ms...
 
Last edited:
Sure, it's basically multisampling. I started with a linear weighting, then added a little logic that weights high changes of torque more than small changes. This way the torque value keeps relatively stable when pedaling normal, but is also able to increase or decrease fast in case of a fast increase or decrease of torque. As mentioned, it needs improvement, but it already works pretty nice in my opinion.
Is your multisampling based on the torque sensor value over at least one full rotation?
On my motor, I noticed that the torque sensor values offset (at no weight) varies from about 160 up to 170 depending on the position of the pedal. Another user reported even a much bigger difference between lowest and highest values (at no load).
The difference still exist when some weight is applied on the pedal (checked with the pedal at 180 ° but horizontal).
The difference become even bigger when a human is pedaling due to the way he press on the pedal.

That is the reason why I decided to take into account the max value over one pedal rotation. This is not too complex and seems to give good result and it allows very fast reactions when the user press more.
 
Is your multisampling based on the torque sensor value over at least one full rotation?
On my motor, I noticed that the torque sensor values offset (at no weight) varies from about 160 up to 170 depending on the position of the pedal. Another user reported even a much bigger difference between lowest and highest values (at no load).
The difference still exist when some weight is applied on the pedal (checked with the pedal at 180 ° but horizontal).
The difference become even bigger when a human is pedaling due to the way he press on the pedal.

That is the reason why I decided to take into account the max value over one pedal rotation. This is not too complex and seems to give good result and it allows very fast reactions when the user press more.
no i am just using the values without further checks.
my sensor also varies over the rotation. from around 140 to 150.
but to be honest, i think you can pretty much ignore these changes in a real world scenario, because a change of around 10 is nearly no torque at al ;) but it is indeed very important to prevent the value from changing too fast which as we know then produces jerking.
Maybe you want to try my version...

I've tried your approach and it was the best so far... but to be honest it did not feel natural, especially the hard cuts that appear when the power is getting reduced again.
 
no i am just using the values without further checks.
my sensor also varies over the rotation. from around 140 to 150.
but to be honest, i think you can pretty much ignore these changes in a real world scenario, because a change of around 10 is nearly no torque at al ;) but it is indeed very important to prevent the value from changing too fast which as we know then produces jerking.
Maybe you want to try my version...

I've tried your approach and it was the best so far... but to be honest it did not feel natural, especially the hard cuts that appear when the power is getting reduced again.
For a motor having a difference of about 30 (between min and max offsets) , I expect that the difference will give quite bad feeling when the weight on the pedal is quite low (then 30 becomes relatively big compared to "torque delta").
In my approach, it is also possible to change some parameters if you do not like hard cuts. You can try:
- to decrease deceleration
- to change the 2 parameters I added related to the cadence (min threshold cadence, rate of cadence change).
 
To smooth the torque sensor, there is also the solution of mspider that is explained here

His code is here (in get_pedal_torque() and new_torque_sample() )

mbrusa said me that he plan to use it too in the future.

I did not tested it. I took the option of using the max instead of the average per rotation in order to have faster reaction.
Still his solution can also react fast as he uses the actual torque when the difference exceeds a threshold compared to the previous value at the same pedal position.
 
To smooth the torque sensor, there is also the solution of mspider that is explained here

His code is here (in get_pedal_torque() and new_torque_sample() )

mbrusa said me that he plan to use it too in the future.

I did not tested it. I took the option of using the max instead of the average per rotation in order to have faster reaction.
Still his solution can also react fast as he uses the actual torque when the difference exceeds a threshold compared to the previous value at the same pedal position.
note: I expect a small bug in the mspider code because at high cadence, there could be several pas transitions between 2 execution of get_pedal_torque(). This could be greatly avoided if the number of transitions per rotation is reduced to 20 instead of 80 (counting only one of the 4 types of transition)
 
Look, i really appreciate discussing this problem here, but sometimes things are going quicker using trial and error.
Yesterday i spent 2 hours on the road with the bike doing coding -> flashing -> trying -> repeat.
After that i had a already pretty good working algorithm, ready to be tested by others just to confirm my feeling.
That firmware was working better than any other firmware so far, at least on my motor...
So i still hope someone is willing to flash my version just to see the outcome. Maybe people dont like it, thats ok. :) But in case it is also working for others it might be worth it continuing here...
So again, if someone is interested, details here: TSDZ8 OSF (open source firmware)

PS: If someone is interested in the Code, it is here: GitHub - Katana1234/OSF
I didn't want to share it yet because it is still a bunch of dirty uncommented lines that need cleanup. But maybe it helps to get a little more trust here ;)
 
Last edited:
Back
Top
OSZAR »