change back to HAL_Delay

This commit is contained in:
interfisch 2019-12-06 22:08:17 +01:00
parent 2e28a807ea
commit f302ff8041
2 changed files with 210 additions and 215 deletions

View File

@ -89,7 +89,7 @@
#define START_FRAME 0xAAAA // [-] Start frame definition for serial commands #define START_FRAME 0xAAAA // [-] Start frame definition for serial commands
#define SERIAL_TIMEOUT 160 // [-] Serial timeout duration for the received data. 160 ~= 0.8 sec. Calculation: 0.8 sec / 0.005 sec #define SERIAL_TIMEOUT 160 // [-] Serial timeout duration for the received data. 160 ~= 0.8 sec. Calculation: 0.8 sec / 0.005 sec
#define USART2_BAUD 38400 // UART2 baud rate (long wired cable, soldered next to buzzer) #define USART2_BAUD 38400 // UART2 baud rate (long wired cable, soldered next to buzzer)
#define USART2_WORDLENGTH UART_WORDLENGTH_8B // UART_WORDLENGTH_8B or UART_WORDLENGTH_9B #define USART2_WORDLENGTH UART_WORDLENGTH_8B // UART_WORDLENGTH_8B or UART_WORDLENGTH_9B
#define CONTROL_SERIAL_USART2 // left sensor board cable, disable if ADC or PPM is used! For Arduino control check the hoverSerial.ino #define CONTROL_SERIAL_USART2 // left sensor board cable, disable if ADC or PPM is used! For Arduino control check the hoverSerial.ino
#define FEEDBACK_SERIAL_USART2 // left sensor board cable, disable if ADC or PPM is used! #define FEEDBACK_SERIAL_USART2 // left sensor board cable, disable if ADC or PPM is used!

View File

@ -284,239 +284,234 @@ int main(void) {
int16_t board_temp_adcFilt = adc_buffer.temp; int16_t board_temp_adcFilt = adc_buffer.temp;
int16_t board_temp_deg_c; int16_t board_temp_deg_c;
uint32_t timePrev=0; //for loop timing
while(1) { while(1) {
//HAL_Delay(DELAY_IN_MAIN_LOOP); //delay in ms HAL_Delay(DELAY_IN_MAIN_LOOP); //delay in ms
if ((HAL_GetTick()-timePrev) > DELAY_IN_MAIN_LOOP) { // try with DELAY_IN_MAIN_LOOP = 5 ms and then with DELAY_IN_MAIN_LOOP = 10 ms
#ifdef CONTROL_NUNCHUCK #ifdef CONTROL_NUNCHUCK
Nunchuck_Read(); Nunchuck_Read();
cmd1 = CLAMP((nunchuck_data[0] - 127) * 8, -1000, 1000); // x - axis. Nunchuck joystick readings range 30 - 230 cmd1 = CLAMP((nunchuck_data[0] - 127) * 8, -1000, 1000); // x - axis. Nunchuck joystick readings range 30 - 230
cmd2 = CLAMP((nunchuck_data[1] - 128) * 8, -1000, 1000); // y - axis cmd2 = CLAMP((nunchuck_data[1] - 128) * 8, -1000, 1000); // y - axis
button1 = (uint8_t)nunchuck_data[5] & 1; button1 = (uint8_t)nunchuck_data[5] & 1;
button2 = (uint8_t)(nunchuck_data[5] >> 1) & 1; button2 = (uint8_t)(nunchuck_data[5] >> 1) & 1;
#endif
#ifdef CONTROL_PPM
cmd1 = CLAMP((ppm_captured_value[0] - 500) * 2, -1000, 1000);
cmd2 = CLAMP((ppm_captured_value[1] - 500) * 2, -1000, 1000);
button1 = ppm_captured_value[5] > 500;
float scale = ppm_captured_value[2] / 1000.0f;
#endif
#ifdef CONTROL_ADC
// ADC values range: 0-4095, see ADC-calibration in config.h
#ifdef ADC1_MID_POT
cmd1 = CLAMP((adc_buffer.l_tx2 - ADC1_MID) * 1000 / (ADC1_MAX - ADC1_MID), 0, 1000)
-CLAMP((ADC1_MID - adc_buffer.l_tx2) * 1000 / (ADC1_MID - ADC1_MIN), 0, 1000); // ADC1
#else
cmd1 = CLAMP((adc_buffer.l_tx2 - ADC1_MIN) * 1000 / (ADC1_MAX - ADC1_MIN), 0, 1000); // ADC1
#endif #endif
#ifdef CONTROL_PPM #ifdef ADC2_MID_POT
cmd1 = CLAMP((ppm_captured_value[0] - 500) * 2, -1000, 1000); cmd2 = CLAMP((adc_buffer.l_rx2 - ADC2_MID) * 1000 / (ADC2_MAX - ADC2_MID), 0, 1000)
cmd2 = CLAMP((ppm_captured_value[1] - 500) * 2, -1000, 1000); -CLAMP((ADC2_MID - adc_buffer.l_rx2) * 1000 / (ADC2_MID - ADC2_MIN), 0, 1000); // ADC2
button1 = ppm_captured_value[5] > 500; #else
float scale = ppm_captured_value[2] / 1000.0f; cmd2 = CLAMP((adc_buffer.l_rx2 - ADC2_MIN) * 1000 / (ADC2_MAX - ADC2_MIN), 0, 1000); // ADC2
#endif #endif
#ifdef CONTROL_ADC // use ADCs as button inputs:
// ADC values range: 0-4095, see ADC-calibration in config.h button1 = (uint8_t)(adc_buffer.l_tx2 > 2000); // ADC1
#ifdef ADC1_MID_POT button2 = (uint8_t)(adc_buffer.l_rx2 > 2000); // ADC2
cmd1 = CLAMP((adc_buffer.l_tx2 - ADC1_MID) * 1000 / (ADC1_MAX - ADC1_MID), 0, 1000)
-CLAMP((ADC1_MID - adc_buffer.l_tx2) * 1000 / (ADC1_MID - ADC1_MIN), 0, 1000); // ADC1
#else
cmd1 = CLAMP((adc_buffer.l_tx2 - ADC1_MIN) * 1000 / (ADC1_MAX - ADC1_MIN), 0, 1000); // ADC1
#endif
#ifdef ADC2_MID_POT timeout = 0;
cmd2 = CLAMP((adc_buffer.l_rx2 - ADC2_MID) * 1000 / (ADC2_MAX - ADC2_MID), 0, 1000) #endif
-CLAMP((ADC2_MID - adc_buffer.l_rx2) * 1000 / (ADC2_MID - ADC2_MIN), 0, 1000); // ADC2
#else
cmd2 = CLAMP((adc_buffer.l_rx2 - ADC2_MIN) * 1000 / (ADC2_MAX - ADC2_MIN), 0, 1000); // ADC2
#endif
// use ADCs as button inputs: #if defined CONTROL_SERIAL_USART2 || defined CONTROL_SERIAL_USART3
button1 = (uint8_t)(adc_buffer.l_tx2 > 2000); // ADC1
button2 = (uint8_t)(adc_buffer.l_rx2 > 2000); // ADC2
timeout = 0;
#endif
#if defined CONTROL_SERIAL_USART2 || defined CONTROL_SERIAL_USART3
// Handle received data validity, timeout and fix out-of-sync if necessary
if (command.start == START_FRAME && command.checksum == (uint16_t)(command.start ^ command.speedLeft ^ command.speedRight)) {
if (timeoutFlag) { // Check for previous timeout flag
if (timeoutCnt-- <= 0) // Timeout de-qualification
timeoutFlag = 0; // Timeout flag cleared
} else {
//cmd1 = CLAMP((int16_t)command.steer, -1000, 1000);
cmd1 = CLAMP((int16_t)command.speedLeft, -1000, 1000);
//cmd2 = CLAMP((int16_t)command.speed, -1000, 1000);
cmd2 = CLAMP((int16_t)command.speedRight, -1000, 1000);
command.start = 0xFFFF; // Change the Start Frame for timeout detection in the next cycle
timeoutCnt = 0; // Reset the timeout counter
}
// ####### MOTOR ENABLING: Only if the initial input is very small (for SAFETY) #######
if (enable == 0 && (cmd1 > -50 && cmd1 < 50) && (cmd2 > -50 && cmd2 < 50)){
buzzerPattern = 0;
buzzerFreq = 6; HAL_Delay(100); // make 2 beeps indicating the motor enable
buzzerFreq = 4; HAL_Delay(200);
buzzerFreq = 0;
enable = 1; // enable motors
consoleLog("-- Motors enabled --\r\n");
}
// Handle received data validity, timeout and fix out-of-sync if necessary
if (command.start == START_FRAME && command.checksum == (uint16_t)(command.start ^ command.speedLeft ^ command.speedRight)) {
if (timeoutFlag) { // Check for previous timeout flag
if (timeoutCnt-- <= 0) // Timeout de-qualification
timeoutFlag = 0; // Timeout flag cleared
} else { } else {
if (timeoutCnt++ >= SERIAL_TIMEOUT) { // Timeout qualification //cmd1 = CLAMP((int16_t)command.steer, -1000, 1000);
timeoutFlag = 1; // Timeout detected cmd1 = CLAMP((int16_t)command.speedLeft, -1000, 1000);
timeoutCnt = SERIAL_TIMEOUT; // Limit timout counter value //cmd2 = CLAMP((int16_t)command.speed, -1000, 1000);
} cmd2 = CLAMP((int16_t)command.speedRight, -1000, 1000);
// Check the received Start Frame. If it is NOT OK, most probably we are out-of-sync. command.start = 0xFFFF; // Change the Start Frame for timeout detection in the next cycle
// Try to re-sync by reseting the DMA timeoutCnt = 0; // Reset the timeout counter
if (command.start != START_FRAME && command.start != 0xFFFF) {
HAL_UART_DMAStop(&huart);
HAL_UART_Receive_DMA(&huart, (uint8_t *)&command, sizeof(command));
}
} }
if (timeoutFlag) { // In case of timeout bring the system to a Safe State // ####### MOTOR ENABLING: Only if the initial input is very small (for SAFETY) #######
ctrlModReq = 0; // OPEN_MODE request. This will bring the motor power to 0 in a controlled way if (enable == 0 && (cmd1 > -50 && cmd1 < 50) && (cmd2 > -50 && cmd2 < 50)){
cmd1 = 0; buzzerPattern = 0;
cmd2 = 0; buzzerFreq = 6; HAL_Delay(100); // make 2 beeps indicating the motor enable
} else { buzzerFreq = 4; HAL_Delay(200);
ctrlModReq = ctrlModReqRaw; // Follow the Mode request buzzerFreq = 0;
enable = 1; // enable motors
consoleLog("-- Motors enabled --\r\n");
} }
timeout = 0;
#endif
// ####### LOW-PASS FILTER #######
/*
rateLimiter16(cmd1, RATE, &steerRateFixdt);
rateLimiter16(cmd2, RATE, &speedRateFixdt);
filtLowPass16(steerRateFixdt >> 4, FILTER, &steerFixdt);
filtLowPass16(speedRateFixdt >> 4, FILTER, &speedFixdt);
steer = steerFixdt >> 4; // convert fixed-point to integer
speed = speedFixdt >> 4; // convert fixed-point to integer
*/
rateLimiter16(cmd1, RATE, &speedLeftRateFixdt);
rateLimiter16(cmd2, RATE, &speedRightRateFixdt);
filtLowPass16(speedLeftRateFixdt >> 4, FILTER, &speedLeftFixdt);
filtLowPass16(speedRightRateFixdt >> 4, FILTER, &speedRightFixdt);
speedL = speedLeftFixdt >> 4; // convert fixed-point to integer
speedR = speedRightFixdt >> 4; // convert fixed-point to integer
speed = (speedL+speedR)/2;
// ####### MIXER #######
// speedR = CLAMP((int)(speed * SPEED_COEFFICIENT - steer * STEER_COEFFICIENT), -1000, 1000);
// speedL = CLAMP((int)(speed * SPEED_COEFFICIENT + steer * STEER_COEFFICIENT), -1000, 1000);
//mixerFcn(speedFixdt, steerFixdt, &speedR, &speedL); // This function implements the equations above
// ####### SET OUTPUTS (if the target change is less than +/- 50) #######
if ((speedL > lastSpeedL-50 && speedL < lastSpeedL+50) && (speedR > lastSpeedR-50 && speedR < lastSpeedR+50) && timeout < TIMEOUT) {
#ifdef INVERT_R_DIRECTION
pwmr = speedR;
#else
pwmr = -speedR;
#endif
#ifdef INVERT_L_DIRECTION
pwml = -speedL;
#else
pwml = speedL;
#endif
}
lastSpeedL = speedL;
lastSpeedR = speedR;
// ####### CALC BOARD TEMPERATURE #######
filtLowPass16(adc_buffer.temp, TEMP_FILT_COEF, &board_temp_adcFixdt);
board_temp_adcFilt = board_temp_adcFixdt >> 4; // convert fixed-point to integer
board_temp_deg_c = (TEMP_CAL_HIGH_DEG_C - TEMP_CAL_LOW_DEG_C) * (board_temp_adcFilt - TEMP_CAL_LOW_ADC) / (TEMP_CAL_HIGH_ADC - TEMP_CAL_LOW_ADC) + TEMP_CAL_LOW_DEG_C;
serialSendCounter++; // Increment the counter
if (serialSendCounter > 20) { // Send data every 100 ms = 20 * 5 ms, where 5 ms is approximately the main loop duration
serialSendCounter = 0; // Reset the counter
// ####### DEBUG SERIAL OUT #######
#if defined(DEBUG_SERIAL_USART2) || defined(DEBUG_SERIAL_USART3)
#ifdef CONTROL_ADC
setScopeChannel(0, (int16_t)adc_buffer.l_tx2); // 1: ADC1
setScopeChannel(1, (int16_t)adc_buffer.l_rx2); // 2: ADC2
#endif
setScopeChannel(2, (int16_t)speedR); // 1: output command: [-1000, 1000]
setScopeChannel(3, (int16_t)speedL); // 2: output command: [-1000, 1000]
setScopeChannel(4, (int16_t)adc_buffer.batt1); // 5: for battery voltage calibration
setScopeChannel(5, (int16_t)(batVoltage * BAT_CALIB_REAL_VOLTAGE / BAT_CALIB_ADC)); // 6: for verifying battery voltage calibration
setScopeChannel(6, (int16_t)board_temp_adcFilt); // 7: for board temperature calibration
setScopeChannel(7, (int16_t)board_temp_deg_c); // 8: for verifying board temperature calibration
consoleScope();
// ####### FEEDBACK SERIAL OUT #######
#elif defined(FEEDBACK_SERIAL_USART2) || defined(FEEDBACK_SERIAL_USART3)
if(UART_DMA_CHANNEL->CNDTR == 0) {
Feedback.start = (uint16_t)START_FRAME;
Feedback.cmd1 = (int16_t)cmd1;
Feedback.cmd2 = (int16_t)cmd2;
Feedback.speedR = (int16_t)speedR;
Feedback.speedL = (int16_t)speedL;
Feedback.speedR_meas = (int16_t)rtY_Left.n_mot;
Feedback.speedL_meas = (int16_t)rtY_Right.n_mot;
Feedback.batVoltage = (int16_t)(batVoltage * BAT_CALIB_REAL_VOLTAGE / BAT_CALIB_ADC);
Feedback.boardTemp = (int16_t)board_temp_deg_c;
Feedback.checksum = (uint16_t)(Feedback.start ^ Feedback.cmd1 ^ Feedback.cmd2 ^ Feedback.speedR ^ Feedback.speedL
^ Feedback.speedR_meas ^ Feedback.speedL_meas ^ Feedback.batVoltage ^ Feedback.boardTemp);
UART_DMA_CHANNEL->CCR &= ~DMA_CCR_EN;
UART_DMA_CHANNEL->CNDTR = sizeof(Feedback);
UART_DMA_CHANNEL->CMAR = (uint32_t)&Feedback;
UART_DMA_CHANNEL->CCR |= DMA_CCR_EN;
}
#endif
}
HAL_GPIO_TogglePin(LED_PORT, LED_PIN);
// ####### POWEROFF BY POWER-BUTTON #######
if (HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN)) {
enable = 0; // disable motors
while (HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN)) {} // wait until button is released
if(__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST)) { // do not power off after software reset (from a programmer/debugger)
__HAL_RCC_CLEAR_RESET_FLAGS(); // clear reset flags
} else {
poweroff(); // release power-latch
}
}
// ####### BEEP AND EMERGENCY POWEROFF #######
if ((TEMP_POWEROFF_ENABLE && board_temp_deg_c >= TEMP_POWEROFF && abs(speed) < 20) || (batVoltage < BAT_LOW_DEAD && abs(speed) < 20)) { // poweroff before mainboard burns OR low bat 3
poweroff();
} else if (TEMP_WARNING_ENABLE && board_temp_deg_c >= TEMP_WARNING) { // beep if mainboard gets hot
buzzerFreq = 4;
buzzerPattern = 1;
} else if (batVoltage < BAT_LOW_LVL1 && batVoltage >= BAT_LOW_LVL2 && BAT_LOW_LVL1_ENABLE) { // low bat 1: slow beep
buzzerFreq = 5;
buzzerPattern = 42;
} else if (batVoltage < BAT_LOW_LVL2 && batVoltage >= BAT_LOW_DEAD && BAT_LOW_LVL2_ENABLE) { // low bat 2: fast beep
buzzerFreq = 5;
buzzerPattern = 6;
} else if (errCode_Left || errCode_Right || timeoutFlag) { // beep in case of Motor error or serial timeout - fast beep
buzzerFreq = 12;
buzzerPattern = 1;
} else if (BEEPS_BACKWARD && speed < -50) { // backward beep
buzzerFreq = 5;
buzzerPattern = 1;
} else { // do not beep
buzzerFreq = 0;
buzzerPattern = 0;
}
// ####### INACTIVITY TIMEOUT #######
if (abs(speedL) > 50 || abs(speedR) > 50) {
inactivity_timeout_counter = 0;
} else { } else {
inactivity_timeout_counter ++; if (timeoutCnt++ >= SERIAL_TIMEOUT) { // Timeout qualification
timeoutFlag = 1; // Timeout detected
timeoutCnt = SERIAL_TIMEOUT; // Limit timout counter value
}
// Check the received Start Frame. If it is NOT OK, most probably we are out-of-sync.
// Try to re-sync by reseting the DMA
if (command.start != START_FRAME && command.start != 0xFFFF) {
HAL_UART_DMAStop(&huart);
HAL_UART_Receive_DMA(&huart, (uint8_t *)&command, sizeof(command));
}
} }
if (inactivity_timeout_counter > (INACTIVITY_TIMEOUT * 60 * 1000) / (DELAY_IN_MAIN_LOOP + 1)) { // rest of main loop needs maybe 1ms
poweroff(); if (timeoutFlag) { // In case of timeout bring the system to a Safe State
ctrlModReq = 0; // OPEN_MODE request. This will bring the motor power to 0 in a controlled way
cmd1 = 0;
cmd2 = 0;
} else {
ctrlModReq = ctrlModReqRaw; // Follow the Mode request
}
timeout = 0;
#endif
// ####### LOW-PASS FILTER #######
/*
rateLimiter16(cmd1, RATE, &steerRateFixdt);
rateLimiter16(cmd2, RATE, &speedRateFixdt);
filtLowPass16(steerRateFixdt >> 4, FILTER, &steerFixdt);
filtLowPass16(speedRateFixdt >> 4, FILTER, &speedFixdt);
steer = steerFixdt >> 4; // convert fixed-point to integer
speed = speedFixdt >> 4; // convert fixed-point to integer
*/
rateLimiter16(cmd1, RATE, &speedLeftRateFixdt);
rateLimiter16(cmd2, RATE, &speedRightRateFixdt);
filtLowPass16(speedLeftRateFixdt >> 4, FILTER, &speedLeftFixdt);
filtLowPass16(speedRightRateFixdt >> 4, FILTER, &speedRightFixdt);
speedL = speedLeftFixdt >> 4; // convert fixed-point to integer
speedR = speedRightFixdt >> 4; // convert fixed-point to integer
speed = (speedL+speedR)/2;
// ####### MIXER #######
// speedR = CLAMP((int)(speed * SPEED_COEFFICIENT - steer * STEER_COEFFICIENT), -1000, 1000);
// speedL = CLAMP((int)(speed * SPEED_COEFFICIENT + steer * STEER_COEFFICIENT), -1000, 1000);
//mixerFcn(speedFixdt, steerFixdt, &speedR, &speedL); // This function implements the equations above
// ####### SET OUTPUTS (if the target change is less than +/- 50) #######
if ((speedL > lastSpeedL-50 && speedL < lastSpeedL+50) && (speedR > lastSpeedR-50 && speedR < lastSpeedR+50) && timeout < TIMEOUT) {
#ifdef INVERT_R_DIRECTION
pwmr = speedR;
#else
pwmr = -speedR;
#endif
#ifdef INVERT_L_DIRECTION
pwml = -speedL;
#else
pwml = speedL;
#endif
}
lastSpeedL = speedL;
lastSpeedR = speedR;
// ####### CALC BOARD TEMPERATURE #######
filtLowPass16(adc_buffer.temp, TEMP_FILT_COEF, &board_temp_adcFixdt);
board_temp_adcFilt = board_temp_adcFixdt >> 4; // convert fixed-point to integer
board_temp_deg_c = (TEMP_CAL_HIGH_DEG_C - TEMP_CAL_LOW_DEG_C) * (board_temp_adcFilt - TEMP_CAL_LOW_ADC) / (TEMP_CAL_HIGH_ADC - TEMP_CAL_LOW_ADC) + TEMP_CAL_LOW_DEG_C;
serialSendCounter++; // Increment the counter
if (serialSendCounter > 20) { // Send data every 100 ms = 20 * 5 ms, where 5 ms is approximately the main loop duration
serialSendCounter = 0; // Reset the counter
// ####### DEBUG SERIAL OUT #######
#if defined(DEBUG_SERIAL_USART2) || defined(DEBUG_SERIAL_USART3)
#ifdef CONTROL_ADC
setScopeChannel(0, (int16_t)adc_buffer.l_tx2); // 1: ADC1
setScopeChannel(1, (int16_t)adc_buffer.l_rx2); // 2: ADC2
#endif
setScopeChannel(2, (int16_t)speedR); // 1: output command: [-1000, 1000]
setScopeChannel(3, (int16_t)speedL); // 2: output command: [-1000, 1000]
setScopeChannel(4, (int16_t)adc_buffer.batt1); // 5: for battery voltage calibration
setScopeChannel(5, (int16_t)(batVoltage * BAT_CALIB_REAL_VOLTAGE / BAT_CALIB_ADC)); // 6: for verifying battery voltage calibration
setScopeChannel(6, (int16_t)board_temp_adcFilt); // 7: for board temperature calibration
setScopeChannel(7, (int16_t)board_temp_deg_c); // 8: for verifying board temperature calibration
consoleScope();
// ####### FEEDBACK SERIAL OUT #######
#elif defined(FEEDBACK_SERIAL_USART2) || defined(FEEDBACK_SERIAL_USART3)
if(UART_DMA_CHANNEL->CNDTR == 0) {
Feedback.start = (uint16_t)START_FRAME;
Feedback.cmd1 = (int16_t)cmd1;
Feedback.cmd2 = (int16_t)cmd2;
Feedback.speedR = (int16_t)speedR;
Feedback.speedL = (int16_t)speedL;
Feedback.speedR_meas = (int16_t)rtY_Left.n_mot;
Feedback.speedL_meas = (int16_t)rtY_Right.n_mot;
Feedback.batVoltage = (int16_t)(batVoltage * BAT_CALIB_REAL_VOLTAGE / BAT_CALIB_ADC);
Feedback.boardTemp = (int16_t)board_temp_deg_c;
Feedback.checksum = (uint16_t)(Feedback.start ^ Feedback.cmd1 ^ Feedback.cmd2 ^ Feedback.speedR ^ Feedback.speedL
^ Feedback.speedR_meas ^ Feedback.speedL_meas ^ Feedback.batVoltage ^ Feedback.boardTemp);
UART_DMA_CHANNEL->CCR &= ~DMA_CCR_EN;
UART_DMA_CHANNEL->CNDTR = sizeof(Feedback);
UART_DMA_CHANNEL->CMAR = (uint32_t)&Feedback;
UART_DMA_CHANNEL->CCR |= DMA_CCR_EN;
}
#endif
}
HAL_GPIO_TogglePin(LED_PORT, LED_PIN);
// ####### POWEROFF BY POWER-BUTTON #######
if (HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN)) {
enable = 0; // disable motors
while (HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN)) {} // wait until button is released
if(__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST)) { // do not power off after software reset (from a programmer/debugger)
__HAL_RCC_CLEAR_RESET_FLAGS(); // clear reset flags
} else {
poweroff(); // release power-latch
} }
} }
timePrev = HAL_GetTick();
// ####### BEEP AND EMERGENCY POWEROFF #######
if ((TEMP_POWEROFF_ENABLE && board_temp_deg_c >= TEMP_POWEROFF && abs(speed) < 20) || (batVoltage < BAT_LOW_DEAD && abs(speed) < 20)) { // poweroff before mainboard burns OR low bat 3
poweroff();
} else if (TEMP_WARNING_ENABLE && board_temp_deg_c >= TEMP_WARNING) { // beep if mainboard gets hot
buzzerFreq = 4;
buzzerPattern = 1;
} else if (batVoltage < BAT_LOW_LVL1 && batVoltage >= BAT_LOW_LVL2 && BAT_LOW_LVL1_ENABLE) { // low bat 1: slow beep
buzzerFreq = 5;
buzzerPattern = 42;
} else if (batVoltage < BAT_LOW_LVL2 && batVoltage >= BAT_LOW_DEAD && BAT_LOW_LVL2_ENABLE) { // low bat 2: fast beep
buzzerFreq = 5;
buzzerPattern = 6;
} else if (errCode_Left || errCode_Right || timeoutFlag) { // beep in case of Motor error or serial timeout - fast beep
buzzerFreq = 12;
buzzerPattern = 1;
} else if (BEEPS_BACKWARD && speed < -50) { // backward beep
buzzerFreq = 5;
buzzerPattern = 1;
} else { // do not beep
buzzerFreq = 0;
buzzerPattern = 0;
}
// ####### INACTIVITY TIMEOUT #######
if (abs(speedL) > 50 || abs(speedR) > 50) {
inactivity_timeout_counter = 0;
} else {
inactivity_timeout_counter ++;
}
if (inactivity_timeout_counter > (INACTIVITY_TIMEOUT * 60 * 1000) / (DELAY_IN_MAIN_LOOP + 1)) { // rest of main loop needs maybe 1ms
poweroff();
}
} }
} }