Watchdog, a bugfix and current control improvements

This commit is contained in:
Benjamin Vedder 2014-05-08 23:44:27 +02:00
parent 1539184579
commit 0bfe9bce9a
5 changed files with 114 additions and 17 deletions

View File

@ -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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
/*
* 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_ */

View File

@ -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

57
mcpwm.c
View File

@ -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);

12
mcpwm.h
View File

@ -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_ */