From 0bfe9bce9a0593252a6aa7e050ce8f8ca19cfaf3 Mon Sep 17 00:00:00 2001 From: Benjamin Vedder Date: Thu, 8 May 2014 23:44:27 +0200 Subject: [PATCH] Watchdog, a bugfix and current control improvements --- conf_general.h | 4 +-- mcconf/mcconf_outrunner2.h | 54 ++++++++++++++++++++++++++++++++++++ mcconf/mcconf_sten.h | 4 ++- mcpwm.c | 57 ++++++++++++++++++++++++++++++-------- mcpwm.h | 12 ++++++-- 5 files changed, 114 insertions(+), 17 deletions(-) create mode 100644 mcconf/mcconf_outrunner2.h diff --git a/conf_general.h b/conf_general.h index 785de8c2..71d4189e 100644 --- a/conf_general.h +++ b/conf_general.h @@ -39,8 +39,8 @@ /* * Select only one motor configuration */ -#define MCCONF_OUTRUNNER1 -//#define MCCONF_OUTRUNNER2 +//#define MCCONF_OUTRUNNER1 +#define MCCONF_OUTRUNNER2 //#define MCCONF_RCCAR1 //#define MCCONF_STEN diff --git a/mcconf/mcconf_outrunner2.h b/mcconf/mcconf_outrunner2.h new file mode 100644 index 00000000..1114def5 --- /dev/null +++ b/mcconf/mcconf_outrunner2.h @@ -0,0 +1,54 @@ +/* + Copyright 2012-2014 Benjamin Vedder benjamin@vedder.se + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +/* + * mcconf_outrunner1.h + * + * A configuration for my 3kw black outrunner. + * + * Created on: 14 apr 2014 + * Author: benjamin + */ + +#ifndef MCCONF_OUTRUNNER2_H_ +#define MCCONF_OUTRUNNER2_H_ + +/* + * Parameters + */ +#define MCPWM_CURRENT_MAX 60.0 // Current limit in Amperes (Upper) +#define MCPWM_CURRENT_MIN -60.0 // Current limit in Amperes (Lower) +#define MCPWM_IN_CURRENT_MAX 60.0 // Input current limit in Amperes (Upper) +#define MCPWM_IN_CURRENT_MIN -20.0 // Input current limit in Amperes (Lower) + +// Sensorless settings +#define MCPWM_IS_SENSORLESS 1 // Use sensorless commutation +#define MCPWM_MIN_RPM 300 // Auto-commutate below this RPM +#define MCPWM_CYCLE_INT_LIMIT_LOW 150.0 // Flux integrator limit 0 ERPM +#define MCPWM_CYCLE_INT_LIMIT_HIGH 20.0 // Flux integrator limit 50K ERPM + +// Speed PID parameters +#define MCPWM_PID_KP 0.0001 // Proportional gain +#define MCPWM_PID_KI 0.002 // Integral gain +#define MCPWM_PID_KD 0.0 // Derivative gain +#define MCPWM_PID_MIN_RPM 1200.0 // Minimum allowed RPM + +// Current control parameters +#define MCPWM_CURRENT_CONTROL_GAIN 0.0016 // Current controller error gain +#define MCPWM_CURRENT_CONTROL_MIN 1.0 // Minimum allowed current + +#endif /* MCCONF_OUTRUNNER2_H_ */ diff --git a/mcconf/mcconf_sten.h b/mcconf/mcconf_sten.h index d298c6d7..47f5f48c 100644 --- a/mcconf/mcconf_sten.h +++ b/mcconf/mcconf_sten.h @@ -34,8 +34,10 @@ #define MCPWM_IN_CURRENT_MIN -25.0 // Input current limit in Amperes (Lower) #define MCPWM_RPM_MAX 29000.0 // The motor speed limit (Upper) #define MCPWM_RPM_MIN -10.0 // The motor speed limit (Lower) -#define MCPWM_MIN_VOLTAGE 34.0 // Minimum input voltage +#define MCPWM_MIN_VOLTAGE 8.0 // Minimum input voltage #define MCPWM_MAX_VOLTAGE 45.0 // Maximum input voltage +#define MCPWM_CURRENT_CONTROL_NO_REV 1 // Do not reverse the direction in current control mode, brake only +#define MCPWM_CURRENT_STARTUP_BOOST 0.05 // The lowest duty cycle to use in current control mode (has to be > MCPWM_MIN_DUTY_CYCLE) // Sensorless settings #define MCPWM_IS_SENSORLESS 1 // Use sensorless commutation diff --git a/mcpwm.c b/mcpwm.c index 250ab836..26c58de3 100644 --- a/mcpwm.c +++ b/mcpwm.c @@ -507,6 +507,12 @@ void mcpwm_init(void) { // Start the timer thread chThdCreateStatic(timer_thread_wa, sizeof(timer_thread_wa), NORMALPRIO, timer_thread, NULL); + + // WWDG configuration + RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); + WWDG_SetPrescaler(WWDG_Prescaler_1); + WWDG_SetWindowValue(255); + WWDG_Enable(100); } /** @@ -1270,6 +1276,9 @@ void mcpwm_adc_int_handler(void *p, uint32_t flags) { TIM4->CNT = 0; + // Reset the watchdog + WWDG_SetCounter(100); + const float input_voltage = GET_INPUT_VOLTAGE(); volatile int ph1, ph2, ph3; @@ -1428,21 +1437,47 @@ void mcpwm_adc_int_handler(void *p, uint32_t flags) { utils_truncate_number(&step, -ramp_step, ramp_step); } - dutycycle_now_tmp += step; - - if (fabsf(dutycycle_now_tmp) < MCPWM_MIN_DUTY_CYCLE) { - if (dutycycle_now_tmp < 0.0 && current_set > 0.0) { - dutycycle_now_tmp = MCPWM_MIN_DUTY_CYCLE + 0.001; - } else if (dutycycle_now_tmp > 0.0 && current_set < 0.0) { - dutycycle_now_tmp = -(MCPWM_MIN_DUTY_CYCLE + 0.001); + if (!MCPWM_CURRENT_CONTROL_NO_REV || dutycycle_now_tmp > 0.0) { + if (fabsf(dutycycle_now_tmp) < MCPWM_CURRENT_STARTUP_BOOST) { + step_towards(&dutycycle_now_tmp, + current_set > 0.0 ? + MCPWM_CURRENT_STARTUP_BOOST : + -MCPWM_CURRENT_STARTUP_BOOST, ramp_step); + } else { + dutycycle_now_tmp += step; } } + // Upper truncation utils_truncate_number((float*)&dutycycle_now_tmp, -MCPWM_MAX_DUTY_CYCLE, MCPWM_MAX_DUTY_CYCLE); - // The set dutycycle should be in the correct direction in case the output is lower - // than the minimum duty cycle and the mechanism below gets activated. - dutycycle_set = dutycycle_now_tmp > 0 ? MCPWM_MIN_DUTY_CYCLE + 0.001 : -(MCPWM_MIN_DUTY_CYCLE + 0.001); + // Lower truncation + if (MCPWM_CURRENT_CONTROL_NO_REV) { + if (dutycycle_now > -(MCPWM_MIN_DUTY_CYCLE + 0.01)) { + if (dutycycle_now_tmp < 0.0) { + dutycycle_now_tmp = 0.0; + dutycycle_set = 0.0; + } else { + if (dutycycle_now_tmp < MCPWM_MIN_DUTY_CYCLE && current_set > 0.0) { + dutycycle_now_tmp = MCPWM_MIN_DUTY_CYCLE + 0.001; + } + } + } else { + step_towards(&dutycycle_now_tmp, 0.0, ramp_step); + } + } else { + if (fabsf(dutycycle_now_tmp) < MCPWM_MIN_DUTY_CYCLE) { + if (dutycycle_now_tmp < 0.0 && current_set > 0.0) { + dutycycle_now_tmp = MCPWM_MIN_DUTY_CYCLE + 0.001; + } else if (dutycycle_now_tmp > 0.0 && current_set < 0.0) { + dutycycle_now_tmp = -(MCPWM_MIN_DUTY_CYCLE + 0.001); + } + } + + // The set dutycycle should be in the correct direction in case the output is lower + // than the minimum duty cycle and the mechanism below gets activated. + dutycycle_set = dutycycle_now_tmp >= 0.0 ? MCPWM_MIN_DUTY_CYCLE + 0.001 : -(MCPWM_MIN_DUTY_CYCLE + 0.001); + } } else { step_towards((float*)&dutycycle_now_tmp, dutycycle_set, ramp_step); } @@ -1456,7 +1491,7 @@ void mcpwm_adc_int_handler(void *p, uint32_t flags) { direction ? MCPWM_MAX_DUTY_CYCLE : -MCPWM_MAX_DUTY_CYCLE, ramp_step); } else if (current_in > MCPWM_IN_CURRENT_MAX) { step_towards((float*) &dutycycle_now, 0.0, - ramp_step * fabsf(current - MCPWM_CURRENT_MAX) * MCPWM_CURRENT_LIMIT_GAIN); + ramp_step * fabsf(current_in - MCPWM_IN_CURRENT_MAX) * MCPWM_CURRENT_LIMIT_GAIN); } else if (current_in < MCPWM_IN_CURRENT_MIN) { step_towards((float*) &dutycycle_now, direction ? MCPWM_MAX_DUTY_CYCLE : -MCPWM_MAX_DUTY_CYCLE, ramp_step); diff --git a/mcpwm.h b/mcpwm.h index 6aa581a3..620b6c5a 100644 --- a/mcpwm.h +++ b/mcpwm.h @@ -108,18 +108,18 @@ extern volatile int mcpwm_vzero; /* * Parameters */ -#define MCPWM_SWITCH_FREQUENCY_MIN 8000 // The lowest switching frequency in Hz +#define MCPWM_SWITCH_FREQUENCY_MIN 4000 // The lowest switching frequency in Hz #define MCPWM_SWITCH_FREQUENCY_MAX 30000 // The highest switching frequency in Hz #define MCPWM_DEAD_TIME_CYCLES 80 // Dead time #define MCPWM_PWM_MODE PWM_MODE_SYNCHRONOUS // Default PWM mode -#define MCPWM_MIN_DUTY_CYCLE 0.01 // Minimum duty cycle +#define MCPWM_MIN_DUTY_CYCLE 0.02 // Minimum duty cycle #define MCPWM_MAX_DUTY_CYCLE 0.95 // Maximum duty cycle #define MCPWM_AVG_COM_RPM 6 // Number of commutations to average RPM over #define MCPWM_RAMP_STEP 0.02 // Ramping step (1000 times/sec) at maximum duty cycle #define MCPWM_RAMP_STEP_CURRENT_MAX 0.03 // Maximum ramping step (1000 times/sec) for the current control #define MCPWM_CURRENT_LIMIT_GAIN 0.1 // The error gain of the current limiting algorithm #define MCPWM_FAULT_STOP_TIME 3000 // Ignore commands for this duration in msec when faults occur -#define MCPWM_CMD_STOP_TIME 20 // Ignore commands for this duration in msec after a stop has been sent +#define MCPWM_CMD_STOP_TIME 50 // 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 // Speed PID parameters @@ -141,5 +141,11 @@ extern volatile int mcpwm_vzero; #ifndef MCPWM_RPM_MIN #define MCPWM_RPM_MIN -100000.0 // The motor speed limit (Lower) #endif +#ifndef MCPWM_CURRENT_CONTROL_NO_REV +#define MCPWM_CURRENT_CONTROL_NO_REV 0 // Do not reverse the direction in current control mode, brake only +#endif +#ifndef MCPWM_CURRENT_STARTUP_BOOST +#define MCPWM_CURRENT_STARTUP_BOOST 0.05 // The lowest duty cycle to use in current control mode (has to be > MCPWM_MIN_DUTY_CYCLE) +#endif #endif /* MC_PWM_H_ */