mirror of https://github.com/rusefi/bldc.git
Deadband fix, configurable temperature limit
This commit is contained in:
parent
d9c5ed7ac3
commit
33c81db930
|
@ -182,16 +182,7 @@ static msg_t output_thread(void *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
float out_val = app_nunchuk_get_decoded_chuk();
|
float out_val = app_nunchuk_get_decoded_chuk();
|
||||||
|
utils_deadband(&out_val, hysteres, 1.0);
|
||||||
out_val /= (1.0 - hysteres);
|
|
||||||
|
|
||||||
if (out_val > hysteres) {
|
|
||||||
out_val -= hysteres;
|
|
||||||
} else if (out_val < -hysteres) {
|
|
||||||
out_val += hysteres;
|
|
||||||
} else {
|
|
||||||
out_val = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If c is pressed and no throttle is used, maintain the current speed with PID control
|
// If c is pressed and no throttle is used, maintain the current speed with PID control
|
||||||
static bool was_pid = false;
|
static bool was_pid = false;
|
||||||
|
|
|
@ -123,15 +123,7 @@ static msg_t ppm_thread(void *arg) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
servo_val /= (1.0 - hysteres);
|
utils_deadband(&servo_val, hysteres, 1.0);
|
||||||
|
|
||||||
if (servo_val > hysteres) {
|
|
||||||
servo_val -= hysteres;
|
|
||||||
} else if (servo_val < -hysteres) {
|
|
||||||
servo_val += hysteres;
|
|
||||||
} else {
|
|
||||||
servo_val = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
float current = 0;
|
float current = 0;
|
||||||
bool current_mode = false;
|
bool current_mode = false;
|
||||||
|
|
|
@ -182,6 +182,10 @@ void commands_process_packet(unsigned char *data, unsigned char len) {
|
||||||
mcconf.l_max_vin = (float)buffer_get_int32(data, &ind) / 1000.0;
|
mcconf.l_max_vin = (float)buffer_get_int32(data, &ind) / 1000.0;
|
||||||
mcconf.l_slow_abs_current = data[ind++];
|
mcconf.l_slow_abs_current = data[ind++];
|
||||||
mcconf.l_rpm_lim_neg_torque = data[ind++];
|
mcconf.l_rpm_lim_neg_torque = data[ind++];
|
||||||
|
mcconf.l_temp_fet_start = (float)buffer_get_int32(data, &ind) / 1000.0;
|
||||||
|
mcconf.l_temp_fet_end = (float)buffer_get_int32(data, &ind) / 1000.0;
|
||||||
|
mcconf.l_temp_motor_start = (float)buffer_get_int32(data, &ind) / 1000.0;
|
||||||
|
mcconf.l_temp_motor_end = (float)buffer_get_int32(data, &ind) / 1000.0;
|
||||||
|
|
||||||
mcconf.lo_current_max = mcconf.l_current_max;
|
mcconf.lo_current_max = mcconf.l_current_max;
|
||||||
mcconf.lo_current_min = mcconf.l_current_min;
|
mcconf.lo_current_min = mcconf.l_current_min;
|
||||||
|
@ -236,6 +240,10 @@ void commands_process_packet(unsigned char *data, unsigned char len) {
|
||||||
buffer_append_int32(send_buffer, (int32_t)(mcconf.l_max_vin * 1000.0), &ind);
|
buffer_append_int32(send_buffer, (int32_t)(mcconf.l_max_vin * 1000.0), &ind);
|
||||||
send_buffer[ind++] = mcconf.l_slow_abs_current;
|
send_buffer[ind++] = mcconf.l_slow_abs_current;
|
||||||
send_buffer[ind++] = mcconf.l_rpm_lim_neg_torque;
|
send_buffer[ind++] = mcconf.l_rpm_lim_neg_torque;
|
||||||
|
buffer_append_int32(send_buffer, (int32_t)(mcconf.l_temp_fet_start * 1000.0), &ind);
|
||||||
|
buffer_append_int32(send_buffer, (int32_t)(mcconf.l_temp_fet_end * 1000.0), &ind);
|
||||||
|
buffer_append_int32(send_buffer, (int32_t)(mcconf.l_temp_motor_start * 1000.0), &ind);
|
||||||
|
buffer_append_int32(send_buffer, (int32_t)(mcconf.l_temp_motor_end * 1000.0), &ind);
|
||||||
|
|
||||||
send_buffer[ind++] = mcconf.sl_is_sensorless;
|
send_buffer[ind++] = mcconf.sl_is_sensorless;
|
||||||
buffer_append_int32(send_buffer, (int32_t)(mcconf.sl_min_erpm * 1000.0), &ind);
|
buffer_append_int32(send_buffer, (int32_t)(mcconf.sl_min_erpm * 1000.0), &ind);
|
||||||
|
|
|
@ -84,6 +84,18 @@
|
||||||
#ifndef MCPWM_FAULT_STOP_TIME
|
#ifndef MCPWM_FAULT_STOP_TIME
|
||||||
#define MCPWM_FAULT_STOP_TIME 3000 // Ignore commands for this duration in msec when faults occur
|
#define MCPWM_FAULT_STOP_TIME 3000 // Ignore commands for this duration in msec when faults occur
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef MCPWM_LIM_TEMP_FET_START
|
||||||
|
#define MCPWM_LIM_TEMP_FET_START 80.0 // MOSFET temperature where current limiting should begin
|
||||||
|
#endif
|
||||||
|
#ifndef MCPWM_LIM_TEMP_FET_END
|
||||||
|
#define MCPWM_LIM_TEMP_FET_END 100.0 // MOSFET temperature where everything should be shut off
|
||||||
|
#endif
|
||||||
|
#ifndef MCPWM_LIM_TEMP_MOTOR_START
|
||||||
|
#define MCPWM_LIM_TEMP_MOTOR_START 80.0 // MOTOR temperature where current limiting should begin
|
||||||
|
#endif
|
||||||
|
#ifndef MCPWM_LIM_TEMP_MOTOR_END
|
||||||
|
#define MCPWM_LIM_TEMP_MOTOR_END 100.0 // MOTOR temperature where everything should be shut off
|
||||||
|
#endif
|
||||||
|
|
||||||
// EEPROM settings
|
// EEPROM settings
|
||||||
#define EEPROM_BASE_MCCONF 1000
|
#define EEPROM_BASE_MCCONF 1000
|
||||||
|
@ -106,6 +118,8 @@ void conf_general_init(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FLASH_Unlock();
|
FLASH_Unlock();
|
||||||
|
FLASH_ClearFlag(FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR |
|
||||||
|
FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
|
||||||
EE_Init();
|
EE_Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +184,9 @@ bool conf_general_store_app_configuration(app_configuration *conf) {
|
||||||
uint8_t *conf_addr = (uint8_t*)conf;
|
uint8_t *conf_addr = (uint8_t*)conf;
|
||||||
uint16_t var;
|
uint16_t var;
|
||||||
|
|
||||||
|
FLASH_ClearFlag(FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR |
|
||||||
|
FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
|
||||||
|
|
||||||
for (unsigned int i = 0;i < (sizeof(app_configuration) / 2);i++) {
|
for (unsigned int i = 0;i < (sizeof(app_configuration) / 2);i++) {
|
||||||
var = (conf_addr[2 * i] << 8) & 0xFF00;
|
var = (conf_addr[2 * i] << 8) & 0xFF00;
|
||||||
var |= conf_addr[2 * i + 1] & 0xFF;
|
var |= conf_addr[2 * i + 1] & 0xFF;
|
||||||
|
@ -223,6 +240,10 @@ void conf_general_read_mc_configuration(mc_configuration *conf) {
|
||||||
conf->l_max_vin = MCPWM_MAX_VOLTAGE;
|
conf->l_max_vin = MCPWM_MAX_VOLTAGE;
|
||||||
conf->l_slow_abs_current = MCPWM_SLOW_ABS_OVERCURRENT;
|
conf->l_slow_abs_current = MCPWM_SLOW_ABS_OVERCURRENT;
|
||||||
conf->l_rpm_lim_neg_torque = MCPWM_RPM_LIMIT_NEG_TORQUE;
|
conf->l_rpm_lim_neg_torque = MCPWM_RPM_LIMIT_NEG_TORQUE;
|
||||||
|
conf->l_temp_fet_start = MCPWM_LIM_TEMP_FET_START;
|
||||||
|
conf->l_temp_fet_end = MCPWM_LIM_TEMP_FET_END;
|
||||||
|
conf->l_temp_motor_start = MCPWM_LIM_TEMP_MOTOR_START;
|
||||||
|
conf->l_temp_motor_end = MCPWM_LIM_TEMP_MOTOR_END;
|
||||||
|
|
||||||
conf->lo_current_max = conf->l_current_max;
|
conf->lo_current_max = conf->l_current_max;
|
||||||
conf->lo_current_min = conf->l_current_min;
|
conf->lo_current_min = conf->l_current_min;
|
||||||
|
@ -270,6 +291,9 @@ bool conf_general_store_mc_configuration(mc_configuration *conf) {
|
||||||
uint8_t *conf_addr = (uint8_t*)conf;
|
uint8_t *conf_addr = (uint8_t*)conf;
|
||||||
uint16_t var;
|
uint16_t var;
|
||||||
|
|
||||||
|
FLASH_ClearFlag(FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR |
|
||||||
|
FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
|
||||||
|
|
||||||
for (unsigned int i = 0;i < (sizeof(mc_configuration) / 2);i++) {
|
for (unsigned int i = 0;i < (sizeof(mc_configuration) / 2);i++) {
|
||||||
var = (conf_addr[2 * i] << 8) & 0xFF00;
|
var = (conf_addr[2 * i] << 8) & 0xFF00;
|
||||||
var |= conf_addr[2 * i + 1] & 0xFF;
|
var |= conf_addr[2 * i + 1] & 0xFF;
|
||||||
|
|
|
@ -38,8 +38,8 @@
|
||||||
*/
|
*/
|
||||||
//#define HW_VERSION_BW
|
//#define HW_VERSION_BW
|
||||||
//#define HW_VERSION_40
|
//#define HW_VERSION_40
|
||||||
#define HW_VERSION_45
|
//#define HW_VERSION_45
|
||||||
//#define HW_VERSION_46
|
#define HW_VERSION_46
|
||||||
//#define HW_VERSION_R2
|
//#define HW_VERSION_R2
|
||||||
//#define HW_VERSION_VICTOR_R1A
|
//#define HW_VERSION_VICTOR_R1A
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,10 @@ typedef struct {
|
||||||
float l_max_vin;
|
float l_max_vin;
|
||||||
bool l_slow_abs_current;
|
bool l_slow_abs_current;
|
||||||
bool l_rpm_lim_neg_torque;
|
bool l_rpm_lim_neg_torque;
|
||||||
|
float l_temp_fet_start;
|
||||||
|
float l_temp_fet_end;
|
||||||
|
float l_temp_motor_start;
|
||||||
|
float l_temp_motor_end;
|
||||||
// Overridden limits (Computed during runtime)
|
// Overridden limits (Computed during runtime)
|
||||||
float lo_current_max;
|
float lo_current_max;
|
||||||
float lo_current_min;
|
float lo_current_min;
|
||||||
|
|
6
mcpwm.c
6
mcpwm.c
|
@ -528,10 +528,10 @@ static void do_dc_cal(void) {
|
||||||
static void update_override_limits(volatile mc_configuration *conf) {
|
static void update_override_limits(volatile mc_configuration *conf) {
|
||||||
float temp = NTC_TEMP(ADC_IND_TEMP_MOS1);
|
float temp = NTC_TEMP(ADC_IND_TEMP_MOS1);
|
||||||
|
|
||||||
if (temp < MCPWM_OVERTEMP_LIM_START) {
|
if (temp < conf->l_temp_fet_start) {
|
||||||
conf->lo_current_min = conf->l_current_min;
|
conf->lo_current_min = conf->l_current_min;
|
||||||
conf->lo_current_max = conf->l_current_max;
|
conf->lo_current_max = conf->l_current_max;
|
||||||
} else if (temp > MCPWM_OVERTEMP_LIM_END) {
|
} else if (temp > conf->l_temp_fet_end) {
|
||||||
conf->lo_current_min = 0.0;
|
conf->lo_current_min = 0.0;
|
||||||
conf->lo_current_max = 0.0;
|
conf->lo_current_max = 0.0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -540,7 +540,7 @@ static void update_override_limits(volatile mc_configuration *conf) {
|
||||||
maxc = fabsf(conf->l_current_min);
|
maxc = fabsf(conf->l_current_min);
|
||||||
}
|
}
|
||||||
|
|
||||||
maxc = utils_map(temp, MCPWM_OVERTEMP_LIM_START, MCPWM_OVERTEMP_LIM_END, maxc, conf->cc_min_current);
|
maxc = utils_map(temp, conf->l_temp_fet_start, temp > conf->l_temp_fet_end, maxc, conf->cc_min_current);
|
||||||
|
|
||||||
if (fabsf(conf->l_current_max) > maxc) {
|
if (fabsf(conf->l_current_max) > maxc) {
|
||||||
conf->lo_current_max = SIGN(conf->l_current_max) * maxc;
|
conf->lo_current_max = SIGN(conf->l_current_max) * maxc;
|
||||||
|
|
2
mcpwm.h
2
mcpwm.h
|
@ -100,8 +100,6 @@ extern volatile int mcpwm_vzero;
|
||||||
#define MCPWM_CURRENT_LIMIT_GAIN 2.0 // The error gain of the current limiting algorithm
|
#define MCPWM_CURRENT_LIMIT_GAIN 2.0 // The error gain of the current limiting algorithm
|
||||||
#define MCPWM_CMD_STOP_TIME 0 // Ignore commands for this duration in msec after a stop has been sent
|
#define MCPWM_CMD_STOP_TIME 0 // Ignore commands for this duration in msec after a stop has been sent
|
||||||
#define MCPWM_DETECT_STOP_TIME 500 // Ignore commands for this duration in msec after a detect command
|
#define MCPWM_DETECT_STOP_TIME 500 // Ignore commands for this duration in msec after a detect command
|
||||||
#define MCPWM_OVERTEMP_LIM_START 90.0 // Temperature where current limiting should begin
|
|
||||||
#define MCPWM_OVERTEMP_LIM_END 110.0 // Temperature where everything should be shut off
|
|
||||||
|
|
||||||
// Speed PID parameters
|
// Speed PID parameters
|
||||||
#define MCPWM_PID_TIME_K 0.001 // Pid controller sample time in seconds
|
#define MCPWM_PID_TIME_K 0.001 // Pid controller sample time in seconds
|
||||||
|
|
18
utils.c
18
utils.c
|
@ -80,6 +80,24 @@ float utils_map(float x, float in_min, float in_max, float out_min, float out_ma
|
||||||
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Truncate absolute values less than tres to zero. The value
|
||||||
|
* tres will be mapped to 0 and the value max to max.
|
||||||
|
*/
|
||||||
|
void utils_deadband(float *value, float tres, float max) {
|
||||||
|
if (fabsf(*value) < tres) {
|
||||||
|
*value = 0.0;
|
||||||
|
} else {
|
||||||
|
float k = max / (max - tres);
|
||||||
|
if (*value > 0.0) {
|
||||||
|
*value = k * *value + max * (1.0 - k);
|
||||||
|
} else {
|
||||||
|
*value = -(k * -*value + max * (1.0 - k));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A system locking function with a counter. For every lock, a corresponding unlock must
|
* A system locking function with a counter. For every lock, a corresponding unlock must
|
||||||
* exist to unlock the system. That means, if lock is called five times, unlock has to
|
* exist to unlock the system. That means, if lock is called five times, unlock has to
|
||||||
|
|
1
utils.h
1
utils.h
|
@ -30,6 +30,7 @@ float utils_calc_ratio(float low, float high, float val);
|
||||||
void utils_norm_angle(float *angle);
|
void utils_norm_angle(float *angle);
|
||||||
int utils_truncate_number(float *number, float min, float max);
|
int utils_truncate_number(float *number, float min, float max);
|
||||||
float utils_map(float x, float in_min, float in_max, float out_min, float out_max);
|
float utils_map(float x, float in_min, float in_max, float out_min, float out_max);
|
||||||
|
void utils_deadband(float *value, float tres, float max);
|
||||||
void utils_sys_lock_cnt(void);
|
void utils_sys_lock_cnt(void);
|
||||||
void utils_sys_unlock_cnt(void);
|
void utils_sys_unlock_cnt(void);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue