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

OK, I found one error, I had to set the battery voltage to 36V. The motor runs now sometimes somehow but it produces more noise than mechanical power :-(
I've set the MOTOR_ROTOR_OFFSET_ANGLE to 227 as you suggested and changed to throttle mode but it's not satisfying at the moment.

To be honest, I'm really confused by your naming of the ride modes. Can you please explain, which entry in the config.h has which behaviour. The comments in the config example helped me not really...

Can you please try the High Speed Motor branch to see if this works with your direct drive (you have to pull down X4 to gnd with a 1k resistor)

regards
stancecoke
 
stancecoke said:
To be honest, I'm really confused by your naming of the ride modes. Can you please explain, which entry in the config.h has which behaviour. The comments in the config example helped me not really...
Code:
// choose between throttle and/or pas or torque sensor
#define EBIKE_THROTTLE_TYPE	EBIKE_THROTTLE_TYPE_THROTTLE_PAS
//#define EBIKE_THROTTLE_TYPE	EBIKE_THROTTLE_TYPE_TORQUE_SENSOR
So that should be very clear.

Code:
// next, choose one of the both (only apply to throttle and/or PAS)
//#define EBIKE_THROTTLE_TYPE_THROTTLE_PAS_PWM_DUTY_CYCLE // direct PWM duty_cycle control
#define EBIKE_THROTTLE_TYPE_THROTTLE_PAS_CURRENT_SPEED // control using motor current/torque and/or wheel speed

EBIKE_THROTTLE_TYPE_THROTTLE_PAS_PWM_DUTY_CYCLE will run this piece of code only (I think you should go with this one to make sure your motor is working well and before try to control it using PAS or torque sensor):
Code:
void ebike_throttle_type_throttle_pas (void)
{
#if defined (EBIKE_THROTTLE_TYPE_THROTTLE_PAS_PWM_DUTY_CYCLE)
  uint8_t ui8_temp;
  float f_temp;

  f_temp = (float) (((float) ui8_throttle_value_filtered) * f_get_assist_level ());
  ui8_temp = (uint8_t) (map ((uint32_t) f_temp,
  			 (uint32_t) 0,
  			 (uint32_t) 255,
  			 (uint32_t) 0,
  			 (uint32_t) 255));
  motor_set_pwm_duty_cycle_target (ui8_temp);
EBIKE_THROTTLE_TYPE_THROTTLE_PAS_CURRENT_SPEED is for regular control from Throotle and/or PAS and that includes the current and speed controllers.

Code:
// next, if enabled, output of torque sensor algorithm is the human power (torque * cadence) other way will be the same as the torque signal
// (only apply to torque sensor)
#define EBIKE_THROTTLE_TYPE_TORQUE_SENSOR_HUMAN_POWER
EBIKE_THROTTLE_TYPE_TORQUE_SENSOR_HUMAN_POWER is only for when Torque sensor is selected and enables this piece of code:
Code:
#if defined (EBIKE_THROTTLE_TYPE_TORQUE_SENSOR_HUMAN_POWER)
  // calc humam power on the crank using as input the pedal torque sensor value and pedal cadence
  ui16_temp = (uint16_t) (f_temp * ((float) ((float) ui8_pas1_cadence_rpm / ((float) PAS_MAX_CADENCE_RPM))));


stancecoke said:
Can you please try the High Speed Motor branch to see if this works with your direct drive (you have to pull down X4 to gnd with a 1k resistor)
I am away from home next days, can't help here.

Do you think it runs bad only on startup phase or all over the full speed range?
 
Hm, I'm still not sure what happens in which mode.

EBIKE_THROTTLE_TYPE_THROTTLE_PAS_PWM_DUTY_CYCLE: sets the dutycylce directly by throttle signal, PAS has no function at all?! Why is there "PAS" in the name?!? Are there any mosfet protection mechanisms (e.g. current limiting) active in this mode?

Is regen active in this mode? I guess due to my modded PAS the code want's to regen more or less randomly... perhaps I'll plug off the PAS for next tries...

casainho said:
Do you think it runs bad only on startup phase or all over the full speed range?

It starts somehow, but I can't get to higher speeds, as is make noise an regens in randomly short intervals.

regards
stancecoke
 
stancecoke said:
EBIKE_THROTTLE_TYPE_THROTTLE_PAS_PWM_DUTY_CYCLE: sets the dutycylce directly by throttle signal, PAS has no function at all?! Why is there "PAS" in the name?!? Are there any mosfet protection mechanisms (e.g. current limiting) active in this mode?
PAS has no function at all on that mode. PAS is in the name because that mode applies only if you choose the other option EBIKE_THROTTLE_TYPE_THROTTLE_PAS.

The protection mechanisms on that mode are (they run on PWM interrupt code):
Code:
  // PWM duty_cycle controller:
  // - limit battery overvoltage
  // - limit battery undervoltage
  // - limit battery max current
  // - limit battery max regen current
  // - limit motor max current
  // - limit motor max regen current
  // - limit motor max ERPS
  // - ramp up/down PWM duty_cycle value

You may give a look to ebike_app_state_machine() and maybe comment it -- I think it should be of no problem, but I can't say for sure.

stancecoke said:
Is regen active in this mode? I guess due to my modded PAS the code want's to regen more or less randomly... perhaps I'll plug off the PAS for next tries...
Yes, regen is active on that mode.

stancecoke said:
casainho said:
Do you think it runs bad only on startup phase or all over the full speed range?
It starts somehow, but I can't get to higher speeds, as is make noise an regens in randomly short intervals.
So, running the motor with direct control of PWM from throttle should be the best to test that motor runs well.
You need to make sure brakes are not for some reason working. Maybe commenting all the code inside ebike_app_controller() and just apply dutycylce directly by throttle signal.
 
Hmm, I tested now direct duty cycle mode and disconnected the PAS, but the behaviour is still the same. The start up is quite OK, but after a few meters of riding, the motor starts to make noise and brakes. The only guess I have, is that the FOC runs in the wrong direction. I will disable FOC for testing tomorrow, enough tests for today :)

regards
stancecoke
 
stancecoke said:
The only guess I have, is that the FOC runs in the wrong direction.
Good idea to disable FOC on that situation!
 
Hm, it's really strange. Now with FOC disabled:
With throttle only and the wheel in the air, the motor runs noisy and draws much current. After a few moments, there's no longer a reaction to the throttle and the motor runs until you unplug the battery :shock:

I don't know, if it's a problem with the phase/hall wire combination, but with the highspeed motor branch, everything ist working really fine.

No ideas at the moment...

regards
stancecoke
 
MOTOR_ROTOR_OFFSET_ANGLE you need to ajust again.

Also use the same phase wire colors for the hall sensors. Just like original connections. Follow the phase wires colora based on PCB and follow from ground wire
 
The colours of the phase- and hall wires of the BionX are completely randomly, as I soldered them in by myself. :D
But I can crosscheck, if the stock firmware runs with the combination that I'm using actually.

I've already tried the MOTOR_ROTOR_OFFSET_ANGLE that works fine with the high speed motor branch, but no success :cry:

regards
stancecoke
 
stancecoke said:
I've already tried the MOTOR_ROTOR_OFFSET_ANGLE that works fine with the high speed motor branch, but no success :cry:
I have being changing the code and the value for MOTOR_ROTOR_OFFSET_ANGLE may need to be different now. You can try change on steps of 15 value up to you get something working and then you can refine the value.
 
OK, next hurdle taken: The wiring was OK.
After setting MOTOR_ROTOR_ERPS_START_INTERPOLATION_60_DEGREES to 5, the motor runs quiet now. Obviously the BionX runs at very low erps. I've reactivated the FOC after this success.
But now the motor stops running after a few seconds even with no load, crazy, as before the motor never stopped until you unplugged the battery :shock: .
In my eyes the motor still draws too much current with no load (up to 3 amps).

regards
stancecoke
 
So, if motor runs silently but you think it still asks to much current, I think you now need to ajust FOC_READ_ID_CURRENT_ANGLE_ADJUST.

When motor runs but never stops, does it reacts to brakes, do you see values on LCD changing??
 
I have no brakes and no display connected.
Why the motors stops now and restarts only when the stopped?

regards
stancecoke
 
stancecoke said:
Why the motors stops now and restarts only when the stopped?
If the motor runs at max speed after startup, you need to think on that control on PWM interrupt that increase the duty-cycle... Try to figure out what condition happens so the duty-cycle is automatically increased.
 
??? The motor speed follows the throttle, that's OK. But the motor stops after a few seconds at any throttle position...

regards
stancecoke
 
stancecoke said:
??? The motor speed follows the throttle, that's OK. But the motor stops after a few seconds at any throttle position...
Good!! So it's is working as expected. The user needs needs to pedal / cadence other way torque signal happens even with pedals stopped.

read_torque_sensor_throttle() <-- this is the function where torque signal is read and that logic is implemented. So, without PAS cadence, the system will not work... Please give a look at the code to understand but I can explain any part you need.
 
But I'm in pure throttle mode! The PAS has no function here?!

casainho said:
stancecoke said:
EBIKE_THROTTLE_TYPE_THROTTLE_PAS_PWM_DUTY_CYCLE: sets the dutycylce directly by throttle signal, PAS has no function at all?! Why is there "PAS" in the name?!? Are there any mosfet protection mechanisms (e.g. current limiting) active in this mode?
PAS has no function at all on that mode.


Here my config.h

Code:
*
 /* config.h
 *
 *  Automatically created by Flexible OpenSource firmware - Configuration tool
 *  Author: stancecoke
 *  Author: casainho
 */

#ifndef CONFIG_H_
#define CONFIG_H_

//#define EBIKE_THROTTLE_TYPE EBIKE_THROTTLE_TYPE_TORQUE_SENSOR
#define EBIKE_THROTTLE_TYPE	EBIKE_THROTTLE_TYPE_THROTTLE_PAS
//#define EBIKE_THROTTLE_TYPE_THROTTLE_PAS_CURRENT_SPEED
#define EBIKE_THROTTLE_TYPE_THROTTLE_PAS_PWM_DUTY_CYCLE
#define EBIKE_THROTTLE_TYPE_THROTTLE_PAS_ASSIST_LEVEL_PAS_ONLY
#define PAS_NUMBER_MAGNETS 12
#define PAS_MAX_CADENCE_RPM 80
#define PAS_DIRECTION PAS_DIRECTION_RIGHT
#define ASSIST_LEVEL_0 0.0
#define ASSIST_LEVEL_1 0.2
#define ASSIST_LEVEL_2 0.4
#define ASSIST_LEVEL_3 0.6
#define ASSIST_LEVEL_4 0.8
#define ASSIST_LEVEL_5 1.0
#define BATTERY_LI_ION_CELLS_NUMBER 10
#define ADC_BATTERY_CURRENT_MAX 18
#define ADC_BATTERY_REGEN_CURRENT_MAX 35
#define MOTOR_ROTOR_OFFSET_ANGLE 214
#define FOC_READ_ID_CURRENT_ANGLE_ADJUST 115
#define MOTOR_ROTOR_ERPS_START_INTERPOLATION_60_DEGREES 5
#define ADC_MOTOR_CURRENT_MAX 120
#define ADC_MOTOR_REGEN_CURRENT_MAX 66
#define PWM_DUTY_CYCLE_RAMP_UP_INVERSE_STEP 35
#define PWM_DUTY_CYCLE_RAMP_DOWN_INVERSE_STEP 35

#define EBIKE_REGEN_EBRAKE_LIKE_COAST_BRAKES

#endif /* CONFIG_H_ */

regards
stancecoke
 
stancecoke said:
But I'm in pure throttle mode! The PAS has no function here?!
I am not at computer right now, later I will look at the code.
Maybe this is ebike_app_state_machine() limiting...
Please give a look a the code, it must be something on ebike_app.c, ebike_app_controller().
 
Today riding with other controllers I saw some things which you may find interesting..

Sabvoton controller has user programmable kP value - stock 299 has about 3 second current build up. At 999 its like instant. In user manual they say theres no need to ever change kI.

It is controlling phase current by throttle, which I found also not ideal.
Example: pA set at 350A, bA set at 70A
At high speed 1/4 throttle is the same as full, because max pA is limited by bA. While throttle is still mapped like 0-350A.

So if feel like Adaptto controller is controlling battery Amps or both? < really interesting

Last thing - looks like Adaptto is using only one microcontroller pin for throttle and brake? If you turn both full it does nothing, if you start releasing brake while throttle full its like adding throttle.

It may have some benefits..?
 
stancecoke said:
But now the motor stops running after a few seconds even with no load
stancecoke said:
Why the motors stops now and restarts only when the stopped?
Looking at the code, I think the only possibility is ebike_app_state_machine() that stops the motor after 3 seconds of startup -- and I think that happens because of ui8_wheel_speed that for some reason is 0 -- please look at the code. Try to comment the code on ebike_app_state_machine() to see the result.
 
I tried now the torquesensor mode (with PAS) but still the same :(

I switched back to the high speed motor branch now...

regards
stancecoke


edit:
casainho said:
Try to comment the code on ebike_app_state_machine() to see the result.

which line do you mean?! To be honest, I don't understand that stuff with the "state machine". Do we really need this?! :shock:
 
stancecoke said:
edit:
casainho said:
Try to comment the code on ebike_app_state_machine() to see the result.

which line do you mean?!
The full code.

For how many seconds the motor run before stop?
 
So, after changing MOTOR_ROTOR_ERPS_START_INTERPOLATION_60_DEGREES to 10, I almost don't feel the any vibrations. Then, I wanted to look to FOC working while regen, as Stancecoke told it doesn't work well for regen.

I took a log and saw that "angle_correction" keeps decreasing and even underflows from 0 to 255 while regen, which is really bad -- see green bottom line, that keeps decreasing while "adc_battery_current" < 80 (regen):


Then I went and limited the max and min possible values of "angle_correction" to +- 15 and also avoided decreasing during regen - the output is now what I expected and I can fell it working well on a real ride:


Final code:
Code:
  // make sure we just execute one time per ERPS, so use the flag ui8_flag_foc_read_id_current
  if ((ui8_motor_rotor_angle >= ((uint8_t) FOC_READ_ID_CURRENT_ANGLE_ADJUST)) && (ui8_flag_foc_read_id_current))
  {
    ui8_flag_foc_read_id_current = 0;

    // minimum speed to do FOC
    if (ui16_motor_speed_erps > MOTOR_ROTOR_ERPS_START_INTERPOLATION_60_DEGREES)
    {
      // read here the phase B current: FOC Id current
      ui8_adc_id_current = UI8_ADC_MOTOR_PHASE_B_CURRENT;
      if (ui8_adc_id_current > ADC_PHASE_B_CURRENT_ZERO_AMPS_FOC_MAX)
      {
	// limit max ui8_angle_correction value (127 + 15)
	if ((ui8_angle_correction+1) < 143) { ui8_angle_correction++; }
      }
      else if (ui8_adc_id_current < ADC_PHASE_B_CURRENT_ZERO_AMPS_FOC_MIN)
      {
	// limit min ui8_angle_correction value (127 - 15)
	if ((ui8_angle_correction-1) > 112)
	{
	  // decrease only when not regen!! other way ui8_angle_correction will always decrease... CAN WE IMPROVE THIS??
	  if (UI8_ADC_BATTERY_CURRENT > (ui8_adc_battery_current_offset+2)) { ui8_angle_correction--; }
	}
      }
    }
  }
 
casainho said:
For how many seconds the motor run before stop?

about 6 seconds

I commented out the whole state machine now, but the problem is still the same. :cry:

Do you have a suggestion which parameters we should print out to the BT-Module for debugging?

(I don't know how much patience I have left, as the high speed motor branch works really good for me :wink: )

regards
stancecoke
 
stancecoke said:
casainho said:
For how many seconds the motor run before stop?

about 6 seconds

I commented out the whole state machine now, but the problem is still the same. :cry:

Do you have a suggestion which parameters we should print out to the BT-Module for debugging?
So about 5 seconds:

Code:
void read_torque_sensor_throttle (void)
{

...
    // now count 5 seconds
    case 1:
    if (ui8_rtst_counter++ > 50) // 5 seconds
    {

I guess your issue is with PAS:
Code:
  // if user doesn't pedal, disable throttle signal
  if ((ui8_startup_phase == 0) && (ui8_pas1_cadence_rpm == 0))
  {
    ui8_throttle_value_filtered = 0;

Log this values:
ui8_adc_throttle_value -- is the raw value
ui8_throttle_value_filtered -- is processed value, I think the issue is on processing
just compared that both variables on serial

My most recent code that improves and is easier to read that piece of code is on this branch, I am being improving because of troque sensor: improving_for_direct_drive_motor
 
Back
Top