KT motor controllers -- Flexible OpenSource firmware for BMSBattery S/Kunteng KT motor controllers (0.25kW up to 5kW)

stancecoke said:
casainho said:
I did a refactor/update to motor code FOC angle.

Hm, it's good to have the formerly confusing angle definitons in a logical range now. But when I look at the FOC algorithm, it's the same as before, except looking at the rising vs. the falling edge?!
Well, I just implemented like that, following the BEMF value I measured on my Q85 motor. At 180 degrees happens that I need to read like that... It was strange to see the phase B current inverted comparing to the phase B voltage we are applying... But that may means because sensor is 'placed inverted'... I guess is just a question of reference.

Also, I don't know if there is any a different advantage to read at 0 degrees over reading at 180 degrees. With current code, I think would be hard to read at 0 degrees.
 
Another good thing is that now I think we can tell how to find the correct hall sensor wiring combinations using a multimeter: user should measure a specific sequence while rotating the wheel - the sequence that firmware expects to happen. Then, the motor phases are just 6 different possibilities for trying.
 
geofft said:
honya96 said:
For problem 2) I would suggest a check box if using direct or gear motor and then for gear motor it can be set that motor "never" spins (regen slightly to a stop) without throttle input. This way no one gets this problem with gear motor (most people)

Sounds good to me - I think being able to disable regen functions (for gearmotors) would be a good option...
I didn't forget this. I am trying to solve other things I think have higher priority.

I also think this is an important thing to implement.
 
Firmware for the LCD3
After seeing the LCD internals used on TSDZ2 motor, I found it uses a microcontroller with LCD driver included but a chinese version that we don't a compiler nor example working code.
The LCD from TSDZ2, although big as LCD3, don't show motor usage power that for me is a must. Also is 10 dollars more expensive.

LCD3 uses the same STM8S105 microcontroller, with easy access programming header. Also uses a LCD driver IC that we have datasheet, easy to translate to EN and simple operation as LCD used tecnhologic is basic.

Without our own firmware we could show more information in LCD (numeric only) by cycling modes as also more options like C commamds!!. Also improving things like showing power usage only on 10 watts step, removing the delay/filter and moving the filter to the controller.

In fact, I think TSDZ2 motor users would be better with LCD3 for reading the motor power usage.

I want to make long travels and I need to keep an eye to used power, to makr sure I will arrive on my destin with a bit of remaming power on the battery.
 
guys, my controller is working now. I have dropped the idle wattage from 3W to 1.5W, not bad. But I only have one issue:

The battery indicator at the lcd is always showing full. I am powering it up with a power supply (not with a battery). I start it with 40V (simulating a 36v battery fully charge) and I keep dropping the voltage down to 32 or so and it always remains full. Changing P5 to 0 doesnt seem to fix it.

Do you know if this is normal with the original firmware? When I drop the voltage below 30V, then the battery indicator goes all the way to empty and starts flashing, and disables the motor output. So it seems like reading correctly the voltage.

I think it must be the algorithm or something. I am sure you must know better how is this programmed in the firmware. Is the screen just reading the voltage from the blue/red display wire? Or is there something more fancy through the RX and TX lines?

I have removed the first power resistor, as my switch regulator is safe up to 60V. And I have removed the lm317 and connected right there the switch regulator.

2ec42ae.jpg


25alypw.jpg


I attach here the Eagle project files as well of the board.
 

Attachments

  • mp4560.zip
    781.7 KB · Views: 36
casainho said:
geofft said:
geofft said:
Did a road test with the fully charged battery which threw up a couple of issues with throttle operation:-

1) Full throttle is only giving about 50% power from the motor. Noticed this previously but thought maybe due to almost flat battery - this seems not to be the case.

2) If throttle gently operated at standstill bike pushes forward as expected, when throttle released bike stops but motor 'growls' as if small amount of drive remains, then often gives an '06' error after a few seconds.
1. Please update the firmware from master branch. ONLY choose config.h values taking as reference config-example.h, do not use the firmware configuration tool (at least until we update it).

For instance, assist level should now be higher than 1, something like 2 at least to have max throttle value:
Code:
#define ASSIST_LEVEL_0 0.0
#define ASSIST_LEVEL_1 0.25
#define ASSIST_LEVEL_2 0.5
#define ASSIST_LEVEL_3 1.0
#define ASSIST_LEVEL_4 2.0
#define ASSIST_LEVEL_5 4.0

2. May be because of the throttle THROTTLE_FILTER_COEFFICIENT, if is to high will give a delay... please tell which value are you using to THROTTLE_FILTER_COEFFICIENT.

1) I've now updated to the latest firmware but the full throttle issue remains. To give it some numbers, full pas is pulling around an indicated 650w but full throttle won't go higher than about 320w. Changing assist level seems to have no effect on the full throttle issue.

2) My THROTTLE_FILTER_COEFFICIENT was set to 3, reducing this to 1 effected a cure to this issue. Also related to this, noticed motor startup was very rough. 'MOTOR_ROTOR_ERPS_START_INTERPOLATION_60_DEGREES' (config.h) was set to 30, reducing this to 0 made the startup much smoother.
 
geofft said:
casainho said:
geofft said:
geofft said:
Did a road test with the fully charged battery which threw up a couple of issues with throttle operation:-

1) Full throttle is only giving about 50% power from the motor. Noticed this previously but thought maybe due to almost flat battery - this seems not to be the case.

2) If throttle gently operated at standstill bike pushes forward as expected, when throttle released bike stops but motor 'growls' as if small amount of drive remains, then often gives an '06' error after a few seconds.
1. Please update the firmware from master branch. ONLY choose config.h values taking as reference config-example.h, do not use the firmware configuration tool (at least until we update it).

For instance, assist level should now be higher than 1, something like 2 at least to have max throttle value:
Code:
#define ASSIST_LEVEL_0 0.0
#define ASSIST_LEVEL_1 0.25
#define ASSIST_LEVEL_2 0.5
#define ASSIST_LEVEL_3 1.0
#define ASSIST_LEVEL_4 2.0
#define ASSIST_LEVEL_5 4.0

2. May be because of the throttle THROTTLE_FILTER_COEFFICIENT, if is to high will give a delay... please tell which value are you using to THROTTLE_FILTER_COEFFICIENT.

1) I've now updated to the latest firmware but the full throttle issue remains. To give it some numbers, full pas is pulling around an indicated 650w but full throttle won't go higher than about 320w. Changing assist level seems to have no effect on the full throttle issue.

2) My THROTTLE_FILTER_COEFFICIENT was set to 3, reducing this to 1 effected a cure this issue. Also related to this, noticed motor startup was very rough. 'MOTOR_ROTOR_ERPS_START_INTERPOLATION_60_DEGREES' (config.h) was set to 30, reducing this to 0 made the startup much smoother.
1. ok, I guess you are using the option that assist level only scale PAS and not throttle. Can you please remove that option and test?

2. Ok, I will set as default on config-example.h the value 1.
I just found start motor is really bad, I can hold with my hand the motor and it can't start - no torque. I went to the previous firmware commit and the difference is huge!! Let's see if I put this working as expected.
 
lqbweb said:
Do you know if this is normal with the original firmware? When I drop the voltage below 30V, then the battery indicator goes all the way to empty and starts flashing, and disables the motor output. So it seems like reading correctly the voltage.
I must say I just used original firmware maybe 1h in total so I can't help here.

I can say at our firmware, it never disables the motor output but instead don't ask current to battery when it goes to limit low voltage.
 
lqbweb said:
guys, my controller is working now. I have dropped the idle wattage from 3W to 1.5W, not bad. But I only have one issue:

The battery indicator at the lcd is always showing full. I am powering it up with a power supply (not with a battery). I start it with 40V (simulating a 36v battery fully charge) and I keep dropping the voltage down to 32 or so and it always remains full. Changing P5 to 0 doesnt seem to fix it.

Do you know if this is normal with the original firmware? When I drop the voltage below 30V, then the battery indicator goes all the way to empty and starts flashing, and disables the motor output. So it seems like reading correctly the voltage.

I think it must be the algorithm or something. I am sure you must know better how is this programmed in the firmware. Is the screen just reading the voltage from the blue/red display wire? Or is there something more fancy through the RX and TX lines?

I have removed the first power resistor, as my switch regulator is safe up to 60V. And I have removed the lm317 and connected right there the switch regulator.

2ec42ae.jpg


25alypw.jpg


I attach here the Eagle project files as well of the board.

Can't really help with your battery monitor issue. I found using 12s with the stock firmware (KT36/48SVPR, PSWPower) there was no P5 setting that gave a useful battery monitor, it wanted either 10s or 13s, and had no provision for 12s. Would have thought you'd be ok at 36v though, strange.

Your LM317 replacement looks like a great solution, will be taking a close look at that... :wink:
 
geofft said:
lqbweb said:
guys, my controller is working now. I have dropped the idle wattage from 3W to 1.5W, not bad. But I only have one issue:

The battery indicator at the lcd is always showing full. I am powering it up with a power supply (not with a battery). I start it with 40V (simulating a 36v battery fully charge) and I keep dropping the voltage down to 32 or so and it always remains full. Changing P5 to 0 doesnt seem to fix it.

Do you know if this is normal with the original firmware? When I drop the voltage below 30V, then the battery indicator goes all the way to empty and starts flashing, and disables the motor output. So it seems like reading correctly the voltage.

I think it must be the algorithm or something. I am sure you must know better how is this programmed in the firmware. Is the screen just reading the voltage from the blue/red display wire? Or is there something more fancy through the RX and TX lines?

I have removed the first power resistor, as my switch regulator is safe up to 60V. And I have removed the lm317 and connected right there the switch regulator.

2ec42ae.jpg


25alypw.jpg


I attach here the Eagle project files as well of the board.

Can't really help with your battery monitor issue. I found using 12s with the stock firmware (KT36/48SVPR, PSWPower) there was no P5 setting that gave a useful battery monitor, it wanted either 10s or 13s, and had no provision for 12s. Would have thought you'd be ok at 36v though, strange.

Your LM317 replacement looks like a great solution, will be taking a close look at that... :wink:

thanks for the support.

Do you know how the battery is monitored down at hardware level? From the schematics I see the pin 24 with an analog input from the battery, is it just reading the raw voltage directly from the battery there, and then sent already converted to digital via the TX RX pins to the display ?

Thanks!
 
Do you know how the battery is monitored down at hardware level? From the schematics I see the pin 24 with an analog input from the battery, is it just reading the raw voltage directly from the battery there, and then sent already converted to digital via the TX RX pins to the display ?
Yes. See ebike_app.c and the SOC piece of code.
 
Do you know how the battery is monitored down at hardware level? From the schematics I see the pin 24 with an analog input from the battery, is it just reading the raw voltage directly from the battery there, and then sent already converted to digital via the TX RX pins to the display ?

Looking at the schematic, the raw supply voltage is fed onto the top of a potential divider network (R61,R66) which reduces it down to 8% of it's full value. This, as you say, is fed to pin 24 of the STM8.
After that these guys can tell you much more than I can.... :?
 
Updated master branch:

MOTOR_ROTOR_OFFSET_ANGLE is the value that can be fine tuned for each motor although I suspect this value will be near 0.
I fine tuned by rotating the wheel on the air and got a value where I got lowest current for max speed.
#define MOTOR_ROTOR_OFFSET_ANGLE 0

I also found that initial angle at startup must be +30 degrees to have the highest torque, and in main.h:
#define STARTUP_ADVANCE_ANGLE 21 // 21 --> 30 degrees is needed so the motor has best torque at startup

In the end, FOC is done on ui8_motor_rotor_angle >= MOTOR_ROTOR_ANGLE_30, which I was expecting should be at 180 degrees... I am to tired to understand why in 30 and not in 180....
 
I thought the LCDs received the full battery supply voltage and had their own microcontroller for evaluating charge level.
 
1N4001 said:
I thought the LCDs received the full battery supply voltage and had their own microcontroller for evaluating charge level.

Initially I thought that too, but I saw in the communication protocol instructions for the battery, so no. The display takes VIN because it acts as a switch, on power on the red wire of the lcd goes into the blue wire and the board is powered.

The dumping of the battery is also done by the firmware with P5, so it must happen in the controller itself.
 
ey guys, is there anyway to do a backup of the original firmware before flashing yours? I did not see it in your documentation.

Also, from what I see in the last posts, this firmware seems to be more efficient than the original (quieter, etc) but still not getting all the max power of the original firmware, is that right? What is your opinion in terms of efficiency and max power with the latest changes.
 
1N4001 said:
I thought the LCDs received the full battery supply voltage and had their own microcontroller for evaluating charge level.

The Lishui controllers do it in this way, but the Kuntengs not...

lqbweb said:
ey guys, is there anyway to do a backup of the original firmware before flashing yours? I did not see it in your documentation
No, there's no way back to the stock firmware, as the processor is read protected at delivery.

casainho said:
In the end, FOC is done on ui8_motor_rotor_angle >= MOTOR_ROTOR_ANGLE_30, which I was expecting should be at 180 degrees... I am to tired to understand why in 30 and not in 180....
I hope you slept well :). Can you draw a sketch with rotor angle, BEMF Voltage, PWM voltage and the resulting current? I think this will help a lot for understanding!

Federmodell_Polradwinkel_Synchronmaschine.svg


regards
stancecoke
 
stancecoke said:
I hope you slept well :). Can you draw a sketch with rotor angle, BEMF Voltage, PWM voltage and the resulting current? I think this will help a lot for understanding!
Can't do it today.

But I think I was expecting 180 degrees. It can also be done at 0 degrees and I am doing at 30 degrees, 90 - 60 = 30, maybe I am not using the right hall sensor transition as reference... but I verified with oscilloscope the phase B current signal and did a good number of tests to verify that motor was rotating with lowest current possible for the same load on bike training roller. I also verified the 30 degrees for highest torque at startup.
 
1. ok, I guess you are using the option that assist level only scale PAS and not throttle. Can you please remove that option and test?

Just tried this with EBIKE_THROTTLE_TYPE_PAS_ASSIST_LEVEL_PAS_ONLY (config.h) commented out and everything works as it should. Throttle is scaled with pas as you'd expect and full throttle power is available in the higher assist levels. So it seems only the 'always full throttle' option has the restricted throttle issue.

This is with the previous fw download (i.e. yesterday), haven't tried the latest one just yet, will do so later.

I too hope you slept well, please don't burn yourself out with this stuff... :wink:
 
geofft said:
1. ok, I guess you are using the option that assist level only scale PAS and not throttle. Can you please remove that option and test?

Just tried this with EBIKE_THROTTLE_TYPE_PAS_ASSIST_LEVEL_PAS_ONLY (config.h) commented out and everything works as it should. Throttle is scaled with pas as you'd expect and full throttle power is available in the higher assist levels. So it seems only the 'always full throttle' option has the restricted throttle issue.

This is with the previous fw download (i.e. yesterday), haven't tried the latest one just yet, will do so later.

I too hope you slept well, please don't burn yourself out with this stuff... :wink:
Ok, the issue was because I changed on previous commits the throttle max value, that now is not defined. It is not a problem when you scale it with assist level, but in your specific case it is an issue.
Maybe is a good idea to put a coefficient for scaling throttle and PAS, before the assist level scale?? -- this way someone could even use torque sensor as just a startup switch or something.
The issue is that torque sensor max voltage value is different from throttle value, and maybe different from throttles. The min value is now automatically calibrated but max can't be, anyway, if typically we scale the value, there should be no problem.
 
lqbweb said:
Also, from what I see in the last posts, this firmware seems to be more efficient than the original (quieter, etc) but still not getting all the max power of the original firmware, is that right? What is your opinion in terms of efficiency and max power with the latest changes.

A few small issues are being sorted at the moment but in general terms the new fw produces as much power as stock and runs more smoothly. The only area where stock has been beating it is acceleration under pas (where the stock fw is very strong) but even here I notice later fw versions are improving in this respect.

Efficiency (and therefore range) has been roughly equivalent to stock to date, but the work the guys are currently doing with FOC, etc, may produce further gains here. In short, it's not quite a finished product just yet, but it's beginning to get pretty close... :)
 
Ok, the issue was because I changed on previous commits the throttle max value, that now is not defined. It is not a problem when you scale it with assist level, but in your specific case it is an issue.

I don't think I'm unique in liking my throttle working this way, I think you'll find that most people who use throttles prefer it to be fully available in all pas assist levels.

The issue is that torque sensor max voltage value is different from throttle value, and maybe different from throttles. The min value is now automatically calibrated but max can't be, anyway, if typically we scale the value, there should be no problem.

I don't see that having to set something like 'throttle voltage max' would cause any great problem to most users... :)
 
geofft said:
The issue is that torque sensor max voltage value is different from throttle value, and maybe different from throttles. The min value is now automatically calibrated but max can't be, anyway, if typically we scale the value, there should be no problem.

I don't see that having to set something like 'throttle voltage max' would cause any great problem to most users... :)
Done, it is now on master. I recovered the old tested code.

I also moved battery cells values for SOC from main.h to config.h, this way the user can save his config.h with the configurations for each ebike:

Code:
// Considering the follow voltage values for each li-ion battery cell
// State of charge 		| voltage
#define LI_ION_CELL_VOLTS_MAX 		4.25 // this value is used to protect battery from overcharge on regeneration mode, mainly for direct drive motors
#define LI_ION_CELL_VOLTS_100 		4.06 // this value is used to help finding the battery SOC
#define LI_ION_CELL_VOLTS_80 		3.93 // this value is used to help finding the battery SOC
#define LI_ION_CELL_VOLTS_60 		3.78 // this value is used to help finding the battery SOC
#define LI_ION_CELL_VOLTS_40 		3.60 // this value is used to help finding the battery SOC
#define LI_ION_CELL_VOLTS_20 		3.38 // this value is used to help finding the battery SOC
#define LI_ION_CELL_VOLTS_10 		3.25 // this value is used to help finding the battery SOC
#define LI_ION_CELL_VOLTS_0 		3.00 // this value is used to help finding the battery SOC and is the minimum value after which the firmware don't ask more current to battery, to run the motor
 
casainho said:
geofft said:
The issue is that torque sensor max voltage value is different from throttle value, and maybe different from throttles. The min value is now automatically calibrated but max can't be, anyway, if typically we scale the value, there should be no problem.

I don't see that having to set something like 'throttle voltage max' would cause any great problem to most users... :)
Done, it is now on master. I recovered the old tested code.

Ah, thanks for doing that, I was already starting to miss my 'Mad Max' throttle.. :D

I also moved battery cells values for SOC from main.h to config.h, this way the user can save his config.h with the configurations for each ebike:

Code:
// Considering the follow voltage values for each li-ion battery cell
// State of charge 		| voltage
#define LI_ION_CELL_VOLTS_MAX 		4.25 // this value is used to protect battery from overcharge on regeneration mode, mainly for direct drive motors
#define LI_ION_CELL_VOLTS_100 		4.06 // this value is used to help finding the battery SOC
#define LI_ION_CELL_VOLTS_80 		3.93 // this value is used to help finding the battery SOC
#define LI_ION_CELL_VOLTS_60 		3.78 // this value is used to help finding the battery SOC
#define LI_ION_CELL_VOLTS_40 		3.60 // this value is used to help finding the battery SOC
#define LI_ION_CELL_VOLTS_20 		3.38 // this value is used to help finding the battery SOC
#define LI_ION_CELL_VOLTS_10 		3.25 // this value is used to help finding the battery SOC
#define LI_ION_CELL_VOLTS_0 		3.00 // this value is used to help finding the battery SOC and is the minimum value after which the firmware don't ask more current to battery, to run the motor
Just a thought....we've found from previous tests and issues that there seems to be an -0.06v offset between the actual battery cell voltage and that seen by the firmware. That's not much, but it's enough to play havoc with the battery monitor.

Maybe an idea to put the 'correct' voltages in that table but build in a hidden -0.06v offset before they are presented to the code. That way the 'correct' voltages would maybe work for most users, and they would also be presented with voltages that make sense in the accepted 'SOC vs voltage' graph of lipo chemistry.

Anyway, will give your latest fw a try tomorrow, many thanks for your efforts.
 
geofft said:
Just an thought....we've found from previous tests and issues that there seems to be an -0.06v offset between the actual battery cell voltage and that seen by the firmware. That's not much, but it's enough to play havoc with the battery monitor.

Maybe an idea to put the 'correct' voltages in that table but build in a hidden -0.06v offset before they are presented to the code. That way the 'correct' voltages would maybe work for most users, and they would also be presented with voltages that make sense in the accepted 'SOC vs voltage' graph of lipo chemistry.

Code:
  // calc battery pack state of charge (SOC)
  ui16_battery_volts = ((uint16_t) ebike_app_get_ADC_battery_voltage_filtered ()) * ((uint16_t) ADC_BATTERY_VOLTAGE_K);
  if (ui16_battery_volts > ((uint16_t) BATTERY_PACK_VOLTS_80)) { ui8_battery_soc = 16; } // 4 bars | full
  else if (ui16_battery_volts > ((uint16_t) BATTERY_PACK_VOLTS_60)) { ui8_battery_soc = 12; } // 3 bars
  else if (ui16_battery_volts > ((uint16_t) BATTERY_PACK_VOLTS_40)) { ui8_battery_soc = 8; } // 2 bars
  else if (ui16_battery_volts > ((uint16_t) BATTERY_PACK_VOLTS_20)) { ui8_battery_soc = 4; } // 1 bar
  else if (ui16_battery_volts > ((uint16_t) BATTERY_PACK_VOLTS_10)) { ui8_battery_soc = 3; } // empty
  else { ui8_battery_soc = 1; } // flashing

Please find and test a value for ADC_BATTERY_VOLTAGE_K, that is defined on main.h, that will give the exact voltage. Then I will update ADC_BATTERY_VOLTAGE_K.

See that you are talking in a difference of about 0.06v while each ADC unit represents 0.2652 volts...
 
Back
Top