Fixed PPM, PWM timeout

- fixed the general timeout handling: there is no need to disable the MOSFETs timer because it will confuse the BLDC_controller, making him consider the timeout as a false MOSFET defective error.
- renamed `timeout` to `timeoutCnt` for consistency and to ease the search
#61
This commit is contained in:
EmanuelFeru 2020-07-01 19:50:32 +02:00
parent 68776699e1
commit 22984a7fd6
5 changed files with 28 additions and 24 deletions

View File

@ -31,7 +31,7 @@
#else #else
#define DELAY_IN_MAIN_LOOP 5 // in ms. default 5. it is independent of all the timing critical stuff. do not touch if you do not know what you are doing. #define DELAY_IN_MAIN_LOOP 5 // in ms. default 5. it is independent of all the timing critical stuff. do not touch if you do not know what you are doing.
#endif #endif
#define TIMEOUT 5 // number of wrong / missing input commands before emergency off #define TIMEOUT 20 // number of wrong / missing input commands before emergency off
#define A2BIT_CONV 50 // A to bit for current conversion on ADC. Example: 1 A = 50, 2 A = 100, etc #define A2BIT_CONV 50 // A to bit for current conversion on ADC. Example: 1 A = 50, 2 A = 100, etc
// ADC conversion time definitions // ADC conversion time definitions

View File

@ -57,8 +57,6 @@ volatile int pwmr = 0;
extern volatile adc_buf_t adc_buffer; extern volatile adc_buf_t adc_buffer;
extern volatile uint32_t timeout;
uint8_t buzzerFreq = 0; uint8_t buzzerFreq = 0;
uint8_t buzzerPattern = 0; uint8_t buzzerPattern = 0;
static uint32_t buzzerTimer = 0; static uint32_t buzzerTimer = 0;
@ -116,13 +114,13 @@ void DMA1_Channel1_IRQHandler(void) {
// Disable PWM when current limit is reached (current chopping) // Disable PWM when current limit is reached (current chopping)
// This is the Level 2 of current protection. The Level 1 should kick in first given by I_MOT_MAX // This is the Level 2 of current protection. The Level 1 should kick in first given by I_MOT_MAX
if(ABS(curL_DC) > curDC_max || timeout > TIMEOUT || enable == 0) { if(ABS(curL_DC) > curDC_max || enable == 0) {
LEFT_TIM->BDTR &= ~TIM_BDTR_MOE; LEFT_TIM->BDTR &= ~TIM_BDTR_MOE;
} else { } else {
LEFT_TIM->BDTR |= TIM_BDTR_MOE; LEFT_TIM->BDTR |= TIM_BDTR_MOE;
} }
if(ABS(curR_DC) > curDC_max || timeout > TIMEOUT || enable == 0) { if(ABS(curR_DC) > curDC_max || enable == 0) {
RIGHT_TIM->BDTR &= ~TIM_BDTR_MOE; RIGHT_TIM->BDTR &= ~TIM_BDTR_MOE;
} else { } else {
RIGHT_TIM->BDTR |= TIM_BDTR_MOE; RIGHT_TIM->BDTR |= TIM_BDTR_MOE;

View File

@ -10,7 +10,7 @@ TIM_HandleTypeDef TimHandle;
TIM_HandleTypeDef TimHandle2; TIM_HandleTypeDef TimHandle2;
uint8_t ppm_count = 0; uint8_t ppm_count = 0;
uint8_t pwm_count = 0; uint8_t pwm_count = 0;
uint32_t timeout = 100; uint32_t timeoutCnt = 0;
uint8_t nunchuk_data[6] = {0}; uint8_t nunchuk_data[6] = {0};
uint8_t i2cBuffer[2]; uint8_t i2cBuffer[2];
@ -40,7 +40,7 @@ void PPM_ISR_Callback(void) {
ppm_count = 0; ppm_count = 0;
} }
else if (ppm_count < PPM_NUM_CHANNELS && IN_RANGE(rc_delay, 900, 2100)){ else if (ppm_count < PPM_NUM_CHANNELS && IN_RANGE(rc_delay, 900, 2100)){
timeout = 0; timeoutCnt = 0;
ppm_captured_value_buffer[ppm_count++] = CLAMP(rc_delay, 1000, 2000) - 1000; ppm_captured_value_buffer[ppm_count++] = CLAMP(rc_delay, 1000, 2000) - 1000;
} else { } else {
ppm_valid = false; ppm_valid = false;
@ -113,7 +113,7 @@ void PWM_ISR_CH1_Callback(void) {
} else { // Falling Edge interrupt -> measure pulse duration } else { // Falling Edge interrupt -> measure pulse duration
uint16_t rc_signal = TIM2->CNT - pwm_CNT_prev_ch1; uint16_t rc_signal = TIM2->CNT - pwm_CNT_prev_ch1;
if (IN_RANGE(rc_signal, 900, 2100)){ if (IN_RANGE(rc_signal, 900, 2100)){
timeout = 0; timeoutCnt = 0;
pwm_timeout_ch1 = 0; pwm_timeout_ch1 = 0;
pwm_captured_ch1_value = CLAMP(rc_signal, 1000, 2000) - 1000; pwm_captured_ch1_value = CLAMP(rc_signal, 1000, 2000) - 1000;
} }
@ -132,7 +132,7 @@ void PWM_ISR_CH2_Callback(void) {
} else { // Falling Edge interrupt -> measure pulse duration } else { // Falling Edge interrupt -> measure pulse duration
uint16_t rc_signal = TIM2->CNT - pwm_CNT_prev_ch2; uint16_t rc_signal = TIM2->CNT - pwm_CNT_prev_ch2;
if (IN_RANGE(rc_signal, 900, 2100)){ if (IN_RANGE(rc_signal, 900, 2100)){
timeout = 0; timeoutCnt = 0;
pwm_timeout_ch2 = 0; pwm_timeout_ch2 = 0;
pwm_captured_ch2_value = CLAMP(rc_signal, 1000, 2000) - 1000; pwm_captured_ch2_value = CLAMP(rc_signal, 1000, 2000) - 1000;
} }
@ -143,7 +143,7 @@ void PWM_ISR_CH2_Callback(void) {
void PWM_SysTick_Callback(void) { void PWM_SysTick_Callback(void) {
pwm_timeout_ch1++; pwm_timeout_ch1++;
pwm_timeout_ch2++; pwm_timeout_ch2++;
// Stop after 500 ms without PPM signal // Stop after 500 ms without PWM signal
if(pwm_timeout_ch1 > 500) { if(pwm_timeout_ch1 > 500) {
pwm_captured_ch1_value = 500; pwm_captured_ch1_value = 500;
pwm_timeout_ch1 = 0; pwm_timeout_ch1 = 0;
@ -228,11 +228,11 @@ void Nunchuk_Read(void) {
HAL_I2C_Master_Transmit(&hi2c2,0xA4,(uint8_t*)i2cBuffer, 1, 10); HAL_I2C_Master_Transmit(&hi2c2,0xA4,(uint8_t*)i2cBuffer, 1, 10);
HAL_Delay(3); HAL_Delay(3);
if (HAL_I2C_Master_Receive(&hi2c2,0xA4,(uint8_t*)nunchuk_data, 6, 10) == HAL_OK) { if (HAL_I2C_Master_Receive(&hi2c2,0xA4,(uint8_t*)nunchuk_data, 6, 10) == HAL_OK) {
timeout = 0; timeoutCnt = 0;
} }
#ifndef TRANSPOTTER #ifndef TRANSPOTTER
if (timeout > 3) { if (timeoutCnt > 3) {
HAL_Delay(50); HAL_Delay(50);
Nunchuk_Init(); Nunchuk_Init();
} }

View File

@ -65,6 +65,7 @@ extern int16_t cmd2; // normalized input value. -1000 to 1000
extern int16_t speedAvg; // Average measured speed extern int16_t speedAvg; // Average measured speed
extern int16_t speedAvgAbs; // Average measured speed in absolute extern int16_t speedAvgAbs; // Average measured speed in absolute
extern volatile uint32_t timeoutCnt; // Timeout counter for the General timeout (PPM, PWM, Nunchuck)
extern uint8_t timeoutFlagADC; // Timeout Flag for for ADC Protection: 0 = OK, 1 = Problem detected (line disconnected or wrong ADC data) extern uint8_t timeoutFlagADC; // Timeout Flag for for ADC Protection: 0 = OK, 1 = Problem detected (line disconnected or wrong ADC data)
extern uint8_t timeoutFlagSerial; // Timeout Flag for Rx Serial command: 0 = OK, 1 = Problem detected (line disconnected or wrong Rx data) extern uint8_t timeoutFlagSerial; // Timeout Flag for Rx Serial command: 0 = OK, 1 = Problem detected (line disconnected or wrong Rx data)
@ -76,7 +77,6 @@ extern uint8_t buzzerPattern; // global variable for the buzzer patter
extern uint8_t enable; // global variable for motor enable extern uint8_t enable; // global variable for motor enable
extern volatile uint32_t timeout; // global variable for timeout
extern int16_t batVoltage; // global variable for battery voltage extern int16_t batVoltage; // global variable for battery voltage
#if defined(SIDEBOARD_SERIAL_USART2) #if defined(SIDEBOARD_SERIAL_USART2)
@ -236,6 +236,12 @@ int main(void) {
} }
#endif #endif
// ####### GENERAL TIMEOUT #######
if (timeoutCnt > TIMEOUT) { // Bring the system to a Safe State
cmd1 = 0;
cmd2 = 0;
}
// ####### LOW-PASS FILTER ####### // ####### LOW-PASS FILTER #######
rateLimiter16(cmd1, RATE, &steerRateFixdt); rateLimiter16(cmd1, RATE, &steerRateFixdt);
rateLimiter16(cmd2, RATE, &speedRateFixdt); rateLimiter16(cmd2, RATE, &speedRateFixdt);
@ -259,7 +265,7 @@ int main(void) {
mixerFcn(speed << 4, steer << 4, &speedR, &speedL); // This function implements the equations above mixerFcn(speed << 4, steer << 4, &speedR, &speedL); // This function implements the equations above
// ####### SET OUTPUTS (if the target change is less than +/- 100) ####### // ####### SET OUTPUTS (if the target change is less than +/- 100) #######
if ((speedL > lastSpeedL-100 && speedL < lastSpeedL+100) && (speedR > lastSpeedR-100 && speedR < lastSpeedR+100) && timeout < TIMEOUT) { if ((speedL > lastSpeedL-100 && speedL < lastSpeedL+100) && (speedR > lastSpeedR-100 && speedR < lastSpeedR+100)) {
#ifdef INVERT_R_DIRECTION #ifdef INVERT_R_DIRECTION
pwmr = speedR; pwmr = speedR;
#else #else
@ -308,10 +314,10 @@ int main(void) {
enable = 0; enable = 0;
} }
} }
timeout = 0; timeoutCnt = 0;
} }
if (timeout > TIMEOUT) { if (timeoutCnt > TIMEOUT) {
pwml = 0; pwml = 0;
pwmr = 0; pwmr = 0;
enable = 0; enable = 0;
@ -345,7 +351,7 @@ int main(void) {
#ifdef SUPPORT_LCD #ifdef SUPPORT_LCD
LCD_SetLocation(&lcd, 0, 0); LCD_WriteString(&lcd, "Nunchuk Control"); LCD_SetLocation(&lcd, 0, 0); LCD_WriteString(&lcd, "Nunchuk Control");
#endif #endif
timeout = 0; timeoutCnt = 0;
HAL_Delay(1000); HAL_Delay(1000);
nunchuk_connected = 1; nunchuk_connected = 1;
} }
@ -452,7 +458,7 @@ int main(void) {
enable = 0; enable = 0;
buzzerFreq = 8; buzzerFreq = 8;
buzzerPattern = 1; buzzerPattern = 1;
} else if (timeoutFlagADC || timeoutFlagSerial) { // beep in case of ADC or Serial timeout - fast beep } else if (timeoutFlagADC || timeoutFlagSerial || timeoutCnt > TIMEOUT) { // beep in case of ADC timeout, Serial timeout or General timeout - fast beep
buzzerFreq = 24; buzzerFreq = 24;
buzzerPattern = 1; buzzerPattern = 1;
} else if (TEMP_WARNING_ENABLE && board_temp_deg_c >= TEMP_WARNING) { // beep if mainboard gets hot } else if (TEMP_WARNING_ENABLE && board_temp_deg_c >= TEMP_WARNING) { // beep if mainboard gets hot
@ -479,7 +485,7 @@ int main(void) {
if (abs(speedL) > 50 || abs(speedR) > 50) { if (abs(speedL) > 50 || abs(speedR) > 50) {
inactivity_timeout_counter = 0; inactivity_timeout_counter = 0;
} else { } else {
inactivity_timeout_counter ++; inactivity_timeout_counter++;
} }
if (inactivity_timeout_counter > (INACTIVITY_TIMEOUT * 60 * 1000) / (DELAY_IN_MAIN_LOOP + 1)) { // rest of main loop needs maybe 1ms if (inactivity_timeout_counter > (INACTIVITY_TIMEOUT * 60 * 1000) / (DELAY_IN_MAIN_LOOP + 1)) { // rest of main loop needs maybe 1ms
poweroff(); poweroff();
@ -490,7 +496,7 @@ int main(void) {
lastSpeedL = speedL; lastSpeedL = speedL;
lastSpeedR = speedR; lastSpeedR = speedR;
main_loop_counter++; main_loop_counter++;
timeout++; timeoutCnt++;
} }
} }

View File

@ -52,7 +52,7 @@ extern uint8_t buzzerPattern; // global variable for the buzzer patter
extern uint8_t enable; // global variable for motor enable extern uint8_t enable; // global variable for motor enable
extern uint8_t nunchuk_data[6]; extern uint8_t nunchuk_data[6];
extern volatile uint32_t timeout; // global variable for timeout extern volatile uint32_t timeoutCnt; // global variable for general timeout counter
extern volatile uint32_t main_loop_counter; extern volatile uint32_t main_loop_counter;
#if defined(CONTROL_PPM_LEFT) || defined(CONTROL_PPM_RIGHT) #if defined(CONTROL_PPM_LEFT) || defined(CONTROL_PPM_RIGHT)
@ -746,7 +746,7 @@ void readCommand(void) {
button1 = !HAL_GPIO_ReadPin(BUTTON1_PORT, BUTTON1_PIN); button1 = !HAL_GPIO_ReadPin(BUTTON1_PORT, BUTTON1_PIN);
button2 = !HAL_GPIO_ReadPin(BUTTON2_PORT, BUTTON2_PIN); button2 = !HAL_GPIO_ReadPin(BUTTON2_PORT, BUTTON2_PIN);
#endif #endif
timeout = 0; timeoutCnt = 0;
#endif #endif
#if defined(CONTROL_SERIAL_USART2) || defined(CONTROL_SERIAL_USART3) #if defined(CONTROL_SERIAL_USART2) || defined(CONTROL_SERIAL_USART3)
@ -776,7 +776,7 @@ void readCommand(void) {
button1 = !HAL_GPIO_ReadPin(BUTTON1_PORT, BUTTON1_PIN); button1 = !HAL_GPIO_ReadPin(BUTTON1_PORT, BUTTON1_PIN);
button2 = !HAL_GPIO_ReadPin(BUTTON2_PORT, BUTTON2_PIN); button2 = !HAL_GPIO_ReadPin(BUTTON2_PORT, BUTTON2_PIN);
#endif #endif
timeout = 0; timeoutCnt = 0;
#endif #endif
#if defined(CONTROL_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART2) #if defined(CONTROL_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART2)
@ -798,7 +798,7 @@ void readCommand(void) {
#endif #endif
#ifdef VARIANT_HOVERCAR #ifdef VARIANT_HOVERCAR
brakePressed = (uint8_t)(cmd1 > 50); brakePressed = (uint8_t)(cmd1 > 50);
#endif #endif
#ifdef VARIANT_TRANSPOTTER #ifdef VARIANT_TRANSPOTTER