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

Yeah, how do you program something to read, understand and write code? Struggling to get my head around that....:unsure:
So am I; I've never been able to program myself to do it.... ;)

But, apparently, some of these things are pretty good at it. The "best" at the moment appears to be Qwen:
 
So am I; I've never been able to program myself to do it.... ;)

But, apparently, some of these things are pretty good at it. The "best" at the moment appears to be Qwen:
Sounds really cool! I was already impressed with the human-like interaction you could have with ChatGpt (and chatgpt was complementing the nice structure of the open source kt firmware btw) Running ai at all and certainly on your own hardware really blows my mind. You might realize your creative coding dreams after all Amberwolf!
 
Finally got my controllers. Removed the two 3pin cables(pas+brake(light?)), and soldered wires for flashing;
IMG_20250628_235336930_HDR.jpg

I'm hoping the stlinkv3 will be usable under linux w/stm8flash for this. I intend to dumb down the firmware
for a trike w/two rear hubs, and likely a "throttle only"-control for these by external mcu(/"main controller").
 
Removed support for pas+displays, and began dropping in the support for bafang displays(all i have)
from my version of bbsfw(Daniel's version does also run on stm8(tsdz2), so will be easy to do for me).
The code for bafang display brings me the support for my own replacement for Daniel's windows-only
"bafang configuration tool", which does support acting as a "virtual display" too making dev'ing faster.

Tbh., i'm surprised of how much there is to optimize in this. As if most, if not everything is "calculated"
during runtime(unnecessarily shifting of many variables in every loop etc.), and how much more could
be done at compiletime/init/level change is ... o_O. Hard to choose from where to begin with that🤯.
 
It works 🤷‍♂️. I don't like this Arduino like "millis", I can't see any advantage in them.
And because of that there's no point in fixing this, or?

If anyone wants to see something funny, go take a look at how GPIO_Init() calls at adc_init() are done.
OR in arguments w/'||' instead of '|' - someone doesn't know C.
Seems to me that this whole thing is working by luck more than anything:rolleyes::bigthumb:.
 
Oh, well i'm nearly done w/my first round of refactoring, and have the display working etc.;


I still stand by what i wrote. This has been written by beginners. The code is literally full of
examples to laugh at. If you want another example, look for summing throttle(really 8bit,
but just from 16bit variable) into 32bit variable where it does "filter" by shifting WHOLE
10bits the ADC can deliver of which two bits were already discarded. Really full of laughs:LOL:
 
Everyone started out as a beginner, including you. You're making yourself pretty unpopular for not having done anything worthwhile for this project so far. 🤷‍♂️

I can't see your fork, so I'm not able to learn from your excellent programming skills ;)

 
Last edited:
Indeed, and there's nothing wrong about that. You compared what i'm doing to arduino, while it
has actually been you, who has complained about stm8 performance, or the lack of it, and been
wasting as much of it to run into issues where you just raise up hands and go for stm32:unsure:.

And about "blaspheme" - i don't believe in self proclaimed god(s).
 
run into issues where you just raise up hands and go for stm32
I didn't run into issues with the Kuntengs, my last Kunteng ran flawlessly, as I didn't follow @Xnyle 's approach with the excessive use of floats. I switched to the Lishui hardware, because they have three phase current shunts and have sufficient computing power to do sensorless FOC. Still without FPU, so everything based on integer arithmetic ;).
Be happy with the Kunteng and show us your code, as befits open source development.
 
Anyone else here using this with throttle only ? I'm thinking the best way forward for me with this
is to remove everything else(as it is the easiest fix for unnecessary/harmful code w/bugs), and add
back trimmed/fixed features not used by most under compiletime options* only. I guess there's a
strong desire here to keep this as generic as it has been written so far, so many improvements will
likely be considered not-for-merging-back i'm afraid, but my fork should still give some ideas for
anyone interested to fix this current mess.

Ordered one controller for spare/use on desk to setup proper debugging env, but still wasn't able
to convince myself to waste money on display for kt, so it's unlikely i will work keeping up code for
those up to date beyond making their use of uart&init procedure compatible with what i use**.

But parts of features like dynamic assist must go - i think there's enough evidence in commit history
that whoever came up with that, didn't even realize shifting out all the throttle, so instead went with
obscure inverse percentage calculations to fix the 0 w/assist level to make it look like it's doing what
was intendedo_O.

*) for example current code for speed calculations does expensive operations on a 32bit variable
which only might get used, if using ext.sensor, but it does that unconditionally in the main()-loop.

**) can't really guarantee there will be enough cycles left for those, as i might look into using some
of the free'd time to possibly adding feedforward checking for current filtering, and stuff like that
which might actually improve "performance"(=reactiveness) if done right/with correct values.
 
Hello everyone.
Is my KTE-SVP-B12 controller compatible with OSEC?
Its very old, i think 13 years old.
IMG_20250706_093753.jpg
 
Hello everyone.
Is my KTE-SVP-B12 controller compatible with OSEC?
Its very old, i think 13 years old.
View attachment 373676
Looks like it might(should?) be.

Fwiw., if you have tools to check, you could compare some connections on pcb to what i have:
C:
/* analog connections:
 * PB0    (ADC_AIN0)    | n/a
 * PB1    (ADC_AIN1)    | n/a
 * PB2    (ADC_AIN2)    | n/a
 * PB3    (ADC_AIN3)    | n/a
 *
 * PB4    (ADC_AIN4)    | throttle
 * PB5    (ADC_AIN5)    | current_phase_B
 * PB6    (ADC_AIN6)    | motor_current
 * PB7    (ADC_AIN7)    | x4
 * PE7    (ADC_AIN8)    | battery_current
 * PE6    (ADC_AIN9)    | battery_voltage
 *
 * Motor PHASE_A: yellow wire
 * Motor PHASE_B: green wire
 * Motor PHASE_C: blue wire
 *
 * external interrupt sensitivity configuration:
 * PA    (brake)        | falling
 * PB            |
 * PC    (speed*)    |
 * PD    (oc,pas*)    | falling
 * PE            |
 *
 * *) unused
 *
 * PIN            | IN/OUT| Function
 * ----------------------------------------------------------
 * PB4    (ADC_AIN4)    | in    | throttle
 * PB5    (ADC_AIN5)    | in    | current_phase_B
 * PB6    (ADC_AIN6)    | in    | ishunt_current
 * PB7    (ADC_AIN7)    | in    | x4
 * PE7    (ADC_AIN8)    | in    | battery_current - filtered ishunt_current
 * PE6    (ADC_AIN9)    | in    | battery_voltage
 *
 * PE0            | in    | Hall_sensor_A
 * PE1            | in    | Hall_sensor_B
 * PE2            | in    | Hall_sensor_C
 *
 * PB2    (TIM1_CH3N)    | out    | PWM_phase_A_low
 * PB1    (TIM1_CH2N)    | out    | PWM_phase_B_low
 * PB0    (TIM1_CH1N)    | out    | PWM_phase_C_low
 * PC3    (TIM1_CH3)    | out    | PWM_phase_A_high
 * PC2    (TIM1_CH2)    | out    | PWM_phase_B_high
 * PC1    (TIM1_CH1)    | out    | PWM_phase_C_high
 *
 * PD5    (UART2_TX)    | out    | uart_tx
 * PD6    (UART2_RX)    | in   | uart_rx
 *
 * PA4            | in     | brake
 * PD0            | in     | pas
 * PC5            | in     | speed
 * PD7            | in     | oc (overcurrent, tli/soft interrupt ?)
 *
 * PC4            | out    | light ?            - blue 2k2
 * PC7            | inout    | something to do w/lights    - yellow no resistor
 * PD2            | inout    | something to do w/lights    - green 2k2
 *
 *     pins unused, which might be still easy to reuse:
 * PE3            | inout    | through-hole. possibly pulled up to 5V w/10k resistor.
 * PD3            | inout    | 2k2 -> through-hole T23
 * PD4            | inout    | 2k2 -> through-hole T24
 * PA1            | in*    | 2k2 -> trough-hole x6 10k pullup to 5V ?
 * PA2            | inout    | 2k2 -> trough-hole x7 10k pullup to 5V ?
 * PE5            | inout    | 2k2 -> trough-hole x8 10k pullup to 5V ?
 *
 * *) was "learn" on old schematics
 *
 *     pins w/o visible traces(some might be easy to lift/use for atleast debugging):
 * PA3
 * PA5
 * PA6
 * PB3
 * PC6
 * PG0
 * PG1
 */
 
Last edited:
Looks like it might(should?) be.

Fwiw., if you have tools to check, you could compare some connections on pcb to what i have:
C:
/* analog connections:
 * PB0    (ADC_AIN0)    | n/a
 * PB1    (ADC_AIN1)    | n/a
 * PB2    (ADC_AIN2)    | n/a
 * PB3    (ADC_AIN3)    | n/a
 *
 * PB4    (ADC_AIN4)    | throttle
 * PB5    (ADC_AIN5)    | current_phase_B
 * PB6    (ADC_AIN6)    | motor_current
 * PB7    (ADC_AIN7)    | x4
 * PE7    (ADC_AIN8)    | battery_current
 * PE6    (ADC_AIN9)    | battery_voltage
 *
 * Motor PHASE_A: yellow wire
 * Motor PHASE_B: green wire
 * Motor PHASE_C: blue wire
 *
 * external interrupt sensitivity configuration:
 * PA    (brake)        | falling
 * PB            |
 * PC    (speed*)    |
 * PD    (oc,pas*)    | falling
 * PE            |
 *
 * *) unused
 *
 * PIN            | IN/OUT| Function
 * ----------------------------------------------------------
 * PB4    (ADC_AIN4)    | in    | throttle
 * PB5    (ADC_AIN5)    | in    | current_phase_B
 * PB6    (ADC_AIN6)    | in    | ishunt_current
 * PB7    (ADC_AIN7)    | in    | x4
 * PE7    (ADC_AIN8)    | in    | battery_current - filtered ishunt_current
 * PE6    (ADC_AIN9)    | in    | battery_voltage
 *
 * PE0            | in    | Hall_sensor_A
 * PE1            | in    | Hall_sensor_B
 * PE2            | in    | Hall_sensor_C
 *
 * PB2    (TIM1_CH3N)    | out    | PWM_phase_A_low
 * PB1    (TIM1_CH2N)    | out    | PWM_phase_B_low
 * PB0    (TIM1_CH1N)    | out    | PWM_phase_C_low
 * PC3    (TIM1_CH3)    | out    | PWM_phase_A_high
 * PC2    (TIM1_CH2)    | out    | PWM_phase_B_high
 * PC1    (TIM1_CH1)    | out    | PWM_phase_C_high
 *
 * PD5    (UART2_TX)    | out    | uart_tx
 * PD6    (UART2_RX)    | in   | uart_rx
 *
 * PA4            | in     | brake
 * PD0            | in     | pas
 * PC5            | in     | speed
 * PD7            | in     | oc (overcurrent, tli/soft interrupt ?)
 *
 * PC4            | out    | light ?            - blue 2k2
 * PC7            | inout    | something to do w/lights    - yellow no resistor
 * PD2            | inout    | something to do w/lights    - green 2k2
 *
 *     pins unused, which might be still easy to reuse:
 * PE3            | inout    | through-hole. possibly pulled up to 5V w/10k resistor.
 * PD3            | inout    | 2k2 -> through-hole T23
 * PD4            | inout    | 2k2 -> through-hole T24
 * PA1            | in*    | 2k2 -> trough-hole x6 10k pullup to 5V ?
 * PA2            | inout    | 2k2 -> trough-hole x7 10k pullup to 5V ?
 * PE5            | inout    | 2k2 -> trough-hole x8 10k pullup to 5V ?
 *
 * *) was "learn" on old schematics
 *
 *     pins w/o visible traces(some might be easy to lift/use for atleast debugging):
 * PA3
 * PA5
 * PA6
 * PB3
 * PC6
 * PG0
 * PG1
 */
I have only multimeter.
 
I have only multimeter.
Ok, that is enough to make sure that J1 has the correct holes to solder into for flashing.
NRST is already visible there(fourth of J1), so it is basically just making sure that 5V is first
and GND is third.

edit: fwiw., this pcb seems to be from 2014, so this has certainly ran on older versions also:
 
Okay so I'm trying to hook up my KT display to an usb uart to dump out the xor values. I've seen the instructions how to calculate and stuff but have been unable to find the wiring instructions other than to bridge red and blue. Any help?
 
Back
Top