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

Hello, I had problem with this Java tool. In my computer it doesn't work.
OSEC Parameter Configurator always show me this
>>> Loading file main.hex in PROGRAM MEMORY image in computer
(API) ERROR : No such file or directory

The result of compilation via Eclipse is the same like OSEC Parameter Configurator


I have installed Java Runtime Environment, SDCC, ST Visual Development and Github repository.
Flashing via STVP work well but I don't have main.hex file.


I have flashing TSDZ2 already so this is not my first time but this Java tool make my crazy. :confused:



@edit ok problem solved. I installed everything on another computer and it work.
 

Attachments

  • sdsd.png
    sdsd.png
    21.6 KB · Views: 871
sdobbie said:
So what lines of code do I look at to fix the regen so I can get some proper current from it like I did with the vesc controller?
There is nothing to fix. The Kunteng firmware optimizes the dutycycle, if the PI control can't keep the desired regen current any longer due to decreasing speed (if you enable that function and use the right (hardcoded :shock:) motor constant), to get maximum possible regen current at low speeds. This has low brake effekt, but maximum energy yield.
https://github.com/stancecoke/BMSBattery_S_controllers_firmware/blob/18fdd5ce9479425b2fba97a2997f7b2d5f4d27f5/ACAsetPoint.c#L198

The VESC simply shorts the 3 phases for maximum brake effekt, if the desired current can't be achieved any longer:
https://github.com/vedderb/bldc/blob/be439a2a55ae5b1ba8cce8ad6b0da2d80466e9df/mcpwm.c#L967
But this strategy has worse energy yield.

You are invited to show us the regen current graphs during breaking from e.g. 30kph to zero with a desired regencurrent of 10 battery-amps from the Kunteng contoller and from the VESC to have a neutral comparison!
(I'm really interested it this comparison, as I never used a VESC so far!)

regards
stancecoke
 
I am developing a small vesc just now so could get some graphs at some point but won't be for a while sadly. The vesc was able to push the battery voltage up by 1v during hard regen and the motor made a loud screaming sound which drew attention. It decelerated so hard that the back wheel would lock up occasionally but I am only able to get a maximum of 0.1v increase from the kt controller and it makes a rough whirring sound. My battery is a 12s 14ah lipo. Also worth noting that as I increase regen throttle on the kt I get less current back into the battery but more stopping power. I tested this on a long downhill with me pedalling and as I apply a small amount of regen throttle the battery voltage goes up by 0.1v and increasing the throttle makes the voltage drop back to the pack resting voltage and the bike decelates harder.

I will look into the motor constant option as that may be the issue. Where do I set the constant?
 
sdobbie said:
Where do I set the constant?
In the code linked above:

Code:
ui32_dutycycle = ui16_virtual_erps_speed * 2;

The "2" is the constant for the BionX IGH3.

If you don't set the option, the regen current drops to about 1 amp, when the PI-Control can't keep the wanted current.
This picture with wanted regen current = 6 amps:

index.php


You have to look at the duty cyle at the point just before the regen current drops. Here calculate dutycycle/eprs, this is the constant you need.

If you set the correct constant and activate the option, you get this result:

index.php


You can see the switching point from PI control to erps depended dutycycle in the plot as a short peak.

Be aware: you need more than 25kph for reaching 6 amps with my setup! I don't know, if the VESC could produce more at the same speed, but I don't know how that should work physically...

I guess we had all this information somewhere above already :)

regards
stancecoke

https://www.pedelecforum.de/forum/index.php?threads/erfahrungen-zur-rekust%C3%A4rke-von-verschiedenen-motor-controller-kombinationen.55235/post-1019468
 
So far I have tried values between 1 and 8 for the constant but it made no difference to the stopping power or regeneration characteristics.
 
sdobbie said:
but it made no difference
have you activated the option "Bypass PI Control regen @..." ?!

68747470733a2f2f692e696d6775722e636f6d2f735361343738512e706e67


If yes, there is something wrong with Xnyles code.
You could try the branch "Gazelle", there this feature works definitely.

Don't use random numbers for the constant, there is no current limitation active in this moment of regenerataion, so you can burn your mosfets easily, if you choose a wrong value!!! :shock:

regards
stancecoke
 
Hello. Can you tell me why the motor error 145 occurs ? This means that the motor does not start arbitrarily from the gas handle and this is no good when driving actively. This happens more often if I turn the throttle slowly. I attached a photo.
Screenshot_20210831-094116_BluOsec.jpg
 
miklelv said:
Can you tell me why the motor error 145 occurs ?
this is not an error but a status.

See the wiki:
https://github.com/stancecoke/BMSBattery_S_controllers_firmware/wiki/08-Control-State-and-Troubleshooting

"145" in decimal means "10010001" in binary. So the status is

1 you are in torquesimulation and pedaling slower than ramp end

16 throttle / torquesensor currently overrides torque simulatiom / cadence

128 phase current limiting
So your system limits the phase current, that's normal (and neccessary) at starting from standstill. As recommented many times already, you should set the max phase current at least two times higher than the max battery current...
See the wiki again:
https://github.com/stancecoke/BMSBattery_S_controllers_firmware/wiki/04-The-Java-Tool

regards
stancecoke
 
Stancecoke, thanks ! The battery current and the phase current were 5 \ 15 amps, there was really little phase current, with the parameters 5\35, the motor now always starts.
 
I have never used the bypass pi control regen option because it is extremely buggy. As shown in the video, this option turns my regen throttle into some sort of unstable throttle which just spins the wheel and stops sharply. My problem isn't poor regen at low speed anyway, it's poor regen at all speeds [youtube]https://youtu.be/JnvG23jqcNU[/youtube]
 
sdobbie said:
My problem isn't poor regen at low speed anyway, it's poor regen at all speeds
Hm, I don't understand your video. A scooter with the wheel in the air. In this setup you can't get regen and pulling the "brake throttle" at standstill makes no sense also. I never tried this, therefore it might behave strange, but you will never have that situation in "real life"...

As written before. If you set the regen current target to a value that is higher, than the motor can deliver at the recent speed, the PI control will drive the duty cycle to zero and the achieved regen current is very poor.
If you don't know the right motor constant for optimizesd regen and you don't enable the PI bypass option and you use high regen current targets, you will not get satisfying results.

Just follow my suggestion to determine the motor constant, then you will get much better results (and will understand your system much better ;)).

regards
stancecoke

p.s. I saw on your youtube channel that you're driving a BMW i3 :) :thumb: I have one, too. A very early car from 2014 but I'm still excited about it 8)
 
Yeah, the I3 has had a lot of issues to start with but has been good overall. I was pulling the brake throttle to show that it was causing the motor to take off at ridiculous speed which shouldn't happen. I think it is going to take more effort to get the kt controller to work properly than it will take to design my own vesc based unit so I think I am going to leave it here as its far more hassle than it should be. Not saying that to be offensive but the software on this controller just isn't normal. I have never seen anything like it.
 
sdobbie said:
Not saying that to be offensive but the software on this controller just isn't normal. I have never seen anything like it.

no problem, remember, this is just a hobby project and it works flawlessly for almost all users.
Scooter motors seem to be very tricky, that's the experience from the Lishui-Project, where we have real four quadrant vector control. We have ported the EBiCS-firmware to be usable for the cheap Xiaomi M365 FOC-Controllers.

https://github.com/Koxx3/SmartESC_STM32_v3

68747470733a2f2f7777772e706564656c6563666f72756d2e64652f666f72756d2f696e6465782e7068703f6174746163686d656e74732f313631313933363736313036362d706e672e3336343137322f


regards
stancecoke
 
Cool, will check it out. I still need an affordable and stable alternative to vesc with regen so I can do cheap electric bikes for my friends so that looks like a good option.
 
stancecoke said:
you could try to replace all the lines 206-324 by just this two lines:

Code:
uint32_current_target =ui16_sum_throttle + ui16_current_cal_b; 
ui32_dutycycle = PI_control(ui16_BatteryCurrent, uint32_current_target,uint_PWM_Enable);

This just takes the throttle signal for controlling the current. You can do a test ride with throttle and check if the problem is gone.
If yes, it's worth to do the optimizations. If not, there is another cause for your problems...

I do not have a Kunteng controller any longer, so I can't do tests for this project any more. The Lishui controllers are much more interesting ;)
So of course be aware, that this suggested code modification is not tested at all and there is a risk to burn your system...


regards
stancecoke

Hell yeah, It does work with throttle and these two lines only! Only thing I noticed was the startup was a bit slower I think, but that does not bother me. What to do next to get the PAS working also?
 
Valopallo said:
What to do next to get the PAS working also?

untested suggestion, replace lines 205 - 291 from the recent Master with:

Code:
	uint32_current_target = ui16_current_cal_b; // reset target to zero
	controll_state_temp = 0;
	ui8_temp = ui8_assist_percent_actual;
	if ((ui16_aca_flags & DYNAMIC_ASSIST_LEVEL) == DYNAMIC_ASSIST_LEVEL) {
				ui8_temp += ui8_assist_dynamic_percent_addon;
			}
	

	uint32_current_target = (ui8_temp * ui16_battery_current_max_value* 10)>>10; // replace division by right shift: (xxx*10)>>10 is nearly  xxx/100
	uint32_current_target = map(ui16_time_ticks_between_pas_interrupt_smoothed, ui16_s_ramp_end, ui16_s_ramp_start, uint32_current_target, 0);

	uint32_current_target += ui16_current_cal_b;
	if(ui16_time_ticks_between_pas_interrupt_smoothed>ui16_s_ramp_end)controll_state_temp += 1;
	else controll_state_temp += 2;
	
	uint32_temp = ui16_sum_throttle + ui16_current_cal_b; //check throttle override
	if(uint32_temp>uint32_current_target){
		uint32_current_target = uint32_temp;
		controll_state_temp += 16;
		}

regards
stancecoke
 
Hello again ! After increasing the battery current, the motor started always starts. But now, when the speed is set, the bike begins to twitch, as if it itself reduces and adds speed. The state of the motor changes from 17 to 34 and then 35. What can this be related to ? How can I completely disable PAS \ Assist so that it does not interfere with the operation of the gas handle ? I attached the logs.
View attachment 0909-1349-BluOsec.log.csv
 
hello, please ignore if my suggestion is simplistic. I just found this thread looking for a controller upgrade.

is it possible one of your wires is loose on the throttle? I experienced a similar condition when one throttle wire became unseated in the connector.

I didn't see throttle in the log. is it possible one of the other settings in the controller ignores the throttle? I'm not sure how to disable PAS. like I said, I just opened the thread.
 
miklelv said:
the bike begins to twitch

The log doesn't look that bad...
It seems you have only used the throttle and didn't pedal at all. pasCounter stays at 64000 all the time. But this contradicts the state 34. And state 35 is not possible at all.

You should decrease gain i and gain p massively and see what happens. The PI-Control oszilates all the time, see the shape of the setPonit (duty cycle) curve.

regards
stancecoke

Chart.PNG
 
By reducing P and I, I get a delay in the reaction to the throttle stick, which significantly worsens the acceleration dynamics. I want to learn how to build graphs. Can you draw a perfect curve graph that I should follow for an example ?
Thank you for analyzing the logs, stancecoke !
 
stancecoke said:
Valopallo said:
What to do next to get the PAS working also?

untested suggestion, replace lines 205 - 291 from the recent Master with:

Code:
	uint32_current_target = ui16_current_cal_b; // reset target to zero
	controll_state_temp = 0;
	ui8_temp = ui8_assist_percent_actual;
	if ((ui16_aca_flags & DYNAMIC_ASSIST_LEVEL) == DYNAMIC_ASSIST_LEVEL) {
				ui8_temp += ui8_assist_dynamic_percent_addon;
			}
	

	uint32_current_target = (ui8_temp * ui16_battery_current_max_value* 10)>>10; // replace division by right shift: (xxx*10)>>10 is nearly  xxx/100
	uint32_current_target = map(ui16_time_ticks_between_pas_interrupt_smoothed, ui16_s_ramp_end, ui16_s_ramp_start, uint32_current_target, 0);

	uint32_current_target += ui16_current_cal_b;
	if(ui16_time_ticks_between_pas_interrupt_smoothed>ui16_s_ramp_end)controll_state_temp += 1;
	else controll_state_temp += 2;
	
	uint32_temp = ui16_sum_throttle + ui16_current_cal_b; //check throttle override
	if(uint32_temp>uint32_current_target){
		uint32_current_target = uint32_temp;
		controll_state_temp += 16;
		}

regards
stancecoke

Tested and the problem came back but now the max speed is 35km/h so a bit slower. The motor seems a bit more responsive at startup and acceleration though. Another problem is with the PAS levels. Levels 1-4(80%) works fine but when I toggle level 5 (100%) the motor starts to brake. Also when throttle has been used and the bike is stopped there seems to be motor tension to both ways and that is so hard it actually makes the spokes sing a rattling sound when the wheel is turned slowly. The tension releases when the brake is pressed for a moment.
 
Valopallo said:
Tested and the problem came back

OK, so we have to skip all the condition checks first.

Replace lines 205 -324 with

Code:
	uint32_current_target = ui16_current_cal_b; // reset target to zero
	controll_state_temp = 0;
	ui8_temp = ui8_assist_percent_actual;
	if ((ui16_aca_flags & DYNAMIC_ASSIST_LEVEL) == DYNAMIC_ASSIST_LEVEL) {
				ui8_temp += ui8_assist_dynamic_percent_addon;
			}
	

	uint32_current_target = (ui8_temp * ui16_battery_current_max_value* 10)>>10; // replace division by right shift: (xxx*10)>>10 is nearly  xxx/100
	uint32_current_target = map(ui16_time_ticks_between_pas_interrupt_smoothed, ui16_s_ramp_end, ui16_s_ramp_start, uint32_current_target, 0);

	uint32_current_target += ui16_current_cal_b;
	if (ui16_time_ticks_for_pas_calculation > timeout || !PAS_is_active) uint32_current_target = ui16_current_cal_b;
	if(ui16_time_ticks_between_pas_interrupt_smoothed>ui16_s_ramp_end)controll_state_temp += 1;
	else controll_state_temp += 2;
	
	uint32_temp = ui16_sum_throttle + ui16_current_cal_b; //check throttle override
	if(uint32_temp>uint32_current_target){
		uint32_current_target = uint32_temp;
		controll_state_temp += 16;
		}
	if (ui8_walk_assist) uint32_current_target = 10 + ui16_current_cal_b;
	//send current target to PI-controller
	ui32_dutycycle = PI_control(ui16_BatteryCurrent, uint32_current_target,uint_PWM_Enable);

With this there is no speedlimit- , no undervoltage-, no .... check active.
To be honest, I'm not very motivated to add all of this step by step to see when the processor reaches it's limit. I recommend to use the Gazelle branch without the BlueOsec app.... (Or try to do the steps in the Master-code by yourself, it's not that difficult...)

regards
stancecoke
 
miklelv said:
Can you draw a perfect curve graph that I should follow for an example ?
Sorry, but this is just a simple Excel X-Y graph, you can find tons of tutorials in the internet, how to create them.
Much smarter is doing the graphs by python. You can get graphs with zoom an pan function with just a few lines of code like this

Code:
import matplotlib.pyplot as plt
import numpy as np
import tkinter as tk
from tkinter import filedialog

root = tk.Tk()
root.withdraw()

file_path = filedialog.askopenfilename() 
na=np.genfromtxt(file_path,delimiter=';')
f = open(file_path, 'r')

titels = f.readline().split(';')
na=na.astype(float)

x=na[1:,9:10]
y=na[1:,28:29]
z=na[1:,51:52]
w=na[1:,62:63]
v=na[1:,76:77]
fig, axs = plt.subplots(3,sharex='all')

fig.suptitle('BluOSEC log plotter')

axs[0].plot(x, label=titels[9])
axs[0].plot(y, label=titels[28])
axs[0].legend(loc="upper right")
axs[1].plot(w, label=titels[62])
axs[1].plot(v,color='g', label=titels[76])
axs[1].legend(loc="upper right")
axs[2].plot(z,color='r', label=titels[51])
axs[2].legend(loc="upper right")

plt.show()
BluOSEC_plotter.PNG

regards
stancecoke
 
Back
Top