mirror of
https://github.com/lucysrausch/hoverboard-firmware-hack.git
synced 2025-08-01 08:34:27 +02:00
added board temperature calibration, warning and poweroff (rene-dev and me); rearranged config.h; fixed backwards beep overflow; removed duplicate battery-adc-code (rene-dev); improved battery voltage measurement precision; put poweroff procedure to a separate function; poweroff button now only work if field weakening is 0 (otherwise everything will explode)
This commit is contained in:
38
Src/bldc.c
38
Src/bldc.c
@@ -18,8 +18,8 @@ extern volatile adc_buf_t adc_buffer;
|
||||
|
||||
extern volatile uint32_t timeout;
|
||||
|
||||
uint8_t buzzerFreq = 0;
|
||||
uint8_t buzzerPattern = 0;
|
||||
uint32_t buzzerFreq = 0;
|
||||
uint32_t buzzerPattern = 0;
|
||||
|
||||
uint8_t enable = 0;
|
||||
|
||||
@@ -121,7 +121,7 @@ inline void blockPhaseCurrent(int pos, int u, int v, int *q) {
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t buzzerTimer = 0;
|
||||
uint32_t buzzerTimer = 0;
|
||||
|
||||
int offsetcount = 0;
|
||||
int offsetrl1 = 2000;
|
||||
@@ -161,8 +161,8 @@ void DMA1_Channel1_IRQHandler() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (buzzerTimer % 100 == 0) { // because you get float rounding errors if it would run every time
|
||||
batteryVoltage = batteryVoltage * 0.999 + ((float)adc_buffer.batt1 * ((float)BAT_CALIB_REAL_VOLTAGE / (float)BAT_CALIB_ADC)) * 0.001;
|
||||
if (buzzerTimer % 1000 == 0) { // because you get float rounding errors if it would run every time
|
||||
batteryVoltage = batteryVoltage * 0.99 + ((float)adc_buffer.batt1 * ((float)BAT_CALIB_REAL_VOLTAGE / (float)BAT_CALIB_ADC)) * 0.01;
|
||||
}
|
||||
|
||||
//disable PWM when current limit is reached (current chopping)
|
||||
@@ -207,6 +207,34 @@ void DMA1_Channel1_IRQHandler() {
|
||||
//setScopeChannel(2, (adc_buffer.rl1 - offsetrl1) / 8);
|
||||
//setScopeChannel(3, (adc_buffer.rl2 - offsetrl2) / 8);
|
||||
|
||||
|
||||
// uint8_t buzz(uint16_t *notes, uint32_t len){
|
||||
// static uint32_t counter = 0;
|
||||
// static uint32_t timer = 0;
|
||||
// if(len == 0){
|
||||
// return(0);
|
||||
// }
|
||||
|
||||
// struct {
|
||||
// uint16_t freq : 4;
|
||||
// uint16_t volume : 4;
|
||||
// uint16_t time : 8;
|
||||
// } note = notes[counter];
|
||||
|
||||
// if(timer / 500 == note.time){
|
||||
// timer = 0;
|
||||
// counter++;
|
||||
// }
|
||||
|
||||
// if(counter == len){
|
||||
// counter = 0;
|
||||
// }
|
||||
|
||||
// timer++;
|
||||
// return(note.freq);
|
||||
// }
|
||||
|
||||
|
||||
//create square wave for buzzer
|
||||
buzzerTimer++;
|
||||
if (buzzerFreq != 0 && (buzzerTimer / 5000) % (buzzerPattern + 1) == 0) {
|
||||
|
103
Src/main.c
103
Src/main.c
@@ -40,7 +40,6 @@ int cmd1; // normalized input values. -1000 to 1000
|
||||
int cmd2;
|
||||
int cmd3;
|
||||
|
||||
|
||||
typedef struct{
|
||||
int16_t steer;
|
||||
int16_t speed;
|
||||
@@ -76,6 +75,21 @@ extern volatile uint16_t ppm_captured_value[PPM_NUM_CHANNELS+1];
|
||||
|
||||
int milli_vel_error_sum = 0;
|
||||
|
||||
|
||||
void poweroff() {
|
||||
if (abs(speed) < 20) {
|
||||
buzzerPattern = 0;
|
||||
enable = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
buzzerFreq = i;
|
||||
HAL_Delay(100);
|
||||
}
|
||||
HAL_GPIO_WritePin(OFF_PORT, OFF_PIN, 0);
|
||||
while(1) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(void) {
|
||||
HAL_Init();
|
||||
__HAL_RCC_AFIO_CLK_ENABLE();
|
||||
@@ -161,6 +175,9 @@ int main(void) {
|
||||
LCD_WriteString(&lcd, "Initializing...");
|
||||
#endif
|
||||
|
||||
float board_temp_adc_filtered = (float)adc_buffer.temp;
|
||||
float board_temp_deg_c;
|
||||
|
||||
enable = 1; // enable motors
|
||||
|
||||
while(1) {
|
||||
@@ -212,22 +229,6 @@ int main(void) {
|
||||
speedL = CLAMP(speed * SPEED_COEFFICIENT + steer * STEER_COEFFICIENT, -1000, 1000);
|
||||
|
||||
|
||||
// ####### DEBUG SERIAL OUT #######
|
||||
if (inactivity_timeout_counter % 10 == 0) {
|
||||
#ifdef CONTROL_ADC
|
||||
setScopeChannel(0, (int)adc_buffer.l_tx2); // 1: ADC1
|
||||
setScopeChannel(1, (int)adc_buffer.l_rx2); // 2: ADC2
|
||||
#endif
|
||||
setScopeChannel(2, (int)speedR); // 3:
|
||||
setScopeChannel(3, (int)speedL); // 4:
|
||||
setScopeChannel(4, (int)adc_buffer.batt1); // 5: for battery voltage calibration
|
||||
setScopeChannel(5, (int)(batteryVoltage * 100.0f)); // 6: for verifying battery voltage calibration
|
||||
// setScopeChannel(6, (int)); // 7:
|
||||
// setScopeChannel(7, (int)); // 8:
|
||||
consoleScope();
|
||||
}
|
||||
|
||||
|
||||
#ifdef ADDITIONAL_CODE
|
||||
ADDITIONAL_CODE;
|
||||
#endif
|
||||
@@ -251,24 +252,39 @@ int main(void) {
|
||||
lastSpeedR = speedR;
|
||||
|
||||
|
||||
// ####### POWEROFF BY POWER-BUTTON #######
|
||||
if (HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN)) {
|
||||
enable = 0;
|
||||
while (HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN)) {}
|
||||
buzzerFreq = 0;
|
||||
buzzerPattern = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
buzzerFreq = i;
|
||||
HAL_Delay(100);
|
||||
}
|
||||
HAL_GPIO_WritePin(OFF_PORT, OFF_PIN, 0);
|
||||
while(1) {}
|
||||
if (inactivity_timeout_counter % 25 == 0) {
|
||||
// ####### CALC BOARD TEMPERATURE #######
|
||||
board_temp_adc_filtered = board_temp_adc_filtered * 0.99 + (float)adc_buffer.temp * 0.01;
|
||||
board_temp_deg_c = ((float)TEMP_CAL_HIGH_DEG_C - (float)TEMP_CAL_LOW_DEG_C) / ((float)TEMP_CAL_HIGH_ADC - (float)TEMP_CAL_LOW_ADC) * (board_temp_adc_filtered - (float)TEMP_CAL_LOW_ADC) + (float)TEMP_CAL_LOW_DEG_C;
|
||||
|
||||
// ####### DEBUG SERIAL OUT #######
|
||||
#ifdef CONTROL_ADC
|
||||
setScopeChannel(0, (int)adc_buffer.l_tx2); // 1: ADC1
|
||||
setScopeChannel(1, (int)adc_buffer.l_rx2); // 2: ADC2
|
||||
#endif
|
||||
setScopeChannel(2, (int)speedR); // 3: output speed: 0-1000
|
||||
setScopeChannel(3, (int)speedL); // 4: output speed: 0-1000
|
||||
setScopeChannel(4, (int)adc_buffer.batt1); // 5: for battery voltage calibration
|
||||
setScopeChannel(5, (int)(batteryVoltage * 100.0f)); // 6: for verifying battery voltage calibration
|
||||
setScopeChannel(6, (int)board_temp_adc_filtered); // 7: for board temperature calibration
|
||||
setScopeChannel(7, (int)board_temp_deg_c); // 8: for verifying board temperature calibration
|
||||
consoleScope();
|
||||
}
|
||||
|
||||
|
||||
// ####### BATTERY VOLTAGE #######
|
||||
if (BEEPS_BACKWARD && speed < -50) { // backward beep
|
||||
buzzerFreq = 5;
|
||||
// ####### POWEROFF BY POWER-BUTTON #######
|
||||
if (HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN) && weakr == 0 && weakl == 0) {
|
||||
enable = 0;
|
||||
while (HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN)) {}
|
||||
poweroff();
|
||||
}
|
||||
|
||||
|
||||
// ####### BEEP AND EMERGENCY POWEROFF #######
|
||||
if ((TEMP_POWEROFF_ENABLE && board_temp_deg_c >= TEMP_POWEROFF && abs(speed) < 20) || (batteryVoltage < ((float)BAT_LOW_DEAD * (float)BAT_NUMBER_OF_CELLS) && 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 (batteryVoltage < ((float)BAT_LOW_LVL1 * (float)BAT_NUMBER_OF_CELLS) && batteryVoltage > ((float)BAT_LOW_LVL2 * (float)BAT_NUMBER_OF_CELLS) && BAT_LOW_LVL1_ENABLE) { // low bat 1: slow beep
|
||||
buzzerFreq = 5;
|
||||
@@ -276,15 +292,9 @@ int main(void) {
|
||||
} else if (batteryVoltage < ((float)BAT_LOW_LVL2 * (float)BAT_NUMBER_OF_CELLS) && batteryVoltage > ((float)BAT_LOW_DEAD * (float)BAT_NUMBER_OF_CELLS) && BAT_LOW_LVL2_ENABLE) { // low bat 2: fast beep
|
||||
buzzerFreq = 5;
|
||||
buzzerPattern = 6;
|
||||
} else if (batteryVoltage < ((float)BAT_LOW_DEAD * (float)BAT_NUMBER_OF_CELLS) && abs(speed) < 20) { // low bat 3: power off
|
||||
buzzerPattern = 0;
|
||||
enable = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
buzzerFreq = i;
|
||||
HAL_Delay(100);
|
||||
}
|
||||
HAL_GPIO_WritePin(OFF_PORT, OFF_PIN, 0);
|
||||
while(1) {}
|
||||
} else if (BEEPS_BACKWARD && speed < -50) { // backward beep
|
||||
buzzerFreq = 5;
|
||||
buzzerPattern = 1;
|
||||
} else { // do not beep
|
||||
buzzerFreq = 0;
|
||||
buzzerPattern = 0;
|
||||
@@ -298,14 +308,7 @@ int main(void) {
|
||||
inactivity_timeout_counter ++;
|
||||
}
|
||||
if (inactivity_timeout_counter > (INACTIVITY_TIMEOUT * 60 * 1000) / (DELAY_IN_MAIN_LOOP + 1)) { // rest of main loop needs maybe 1ms
|
||||
buzzerPattern = 0;
|
||||
enable = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
buzzerFreq = i;
|
||||
HAL_Delay(100);
|
||||
}
|
||||
HAL_GPIO_WritePin(OFF_PORT, OFF_PIN, 0);
|
||||
while(1) {}
|
||||
poweroff();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -338,7 +341,7 @@ void SystemClock_Config(void) {
|
||||
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
|
||||
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
|
||||
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV8;
|
||||
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV8; // 8 MHz
|
||||
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
|
||||
|
||||
/**Configure the Systick interrupt time
|
||||
|
27
Src/setup.c
27
Src/setup.c
@@ -551,29 +551,32 @@ void MX_ADC1_Init(void) {
|
||||
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_7CYCLES_5;
|
||||
|
||||
sConfig.Channel = ADC_CHANNEL_14;
|
||||
sConfig.Channel = ADC_CHANNEL_14; // pc4 left b
|
||||
sConfig.Rank = 1;
|
||||
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
|
||||
|
||||
sConfig.Channel = ADC_CHANNEL_0;
|
||||
sConfig.Channel = ADC_CHANNEL_0; // pa0 right a
|
||||
sConfig.Rank = 2;
|
||||
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
|
||||
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_13CYCLES_5;
|
||||
|
||||
sConfig.Channel = ADC_CHANNEL_11;
|
||||
sConfig.Channel = ADC_CHANNEL_11; // pc1 left cur
|
||||
sConfig.Rank = 3;
|
||||
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
|
||||
|
||||
sConfig.Channel = ADC_CHANNEL_12;
|
||||
sConfig.Channel = ADC_CHANNEL_12; // pc2 vbat
|
||||
sConfig.Rank = 4;
|
||||
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
|
||||
|
||||
sConfig.Channel = ADC_CHANNEL_12;
|
||||
//temperature requires at least 17.1uS sampling time
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
|
||||
|
||||
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; // internal temp
|
||||
sConfig.Rank = 5;
|
||||
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
|
||||
|
||||
hadc1.Instance->CR2 |= ADC_CR2_DMA;
|
||||
hadc1.Instance->CR2 |= ADC_CR2_DMA | ADC_CR2_TSVREFE;
|
||||
|
||||
__HAL_ADC_ENABLE(&hadc1);
|
||||
|
||||
@@ -611,25 +614,27 @@ void MX_ADC2_Init(void) {
|
||||
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_7CYCLES_5;
|
||||
|
||||
sConfig.Channel = ADC_CHANNEL_15;
|
||||
sConfig.Channel = ADC_CHANNEL_15; // pc5 left c
|
||||
sConfig.Rank = 1;
|
||||
HAL_ADC_ConfigChannel(&hadc2, &sConfig);
|
||||
|
||||
sConfig.Channel = ADC_CHANNEL_13;
|
||||
sConfig.Channel = ADC_CHANNEL_13; // pc3 right b
|
||||
sConfig.Rank = 2;
|
||||
HAL_ADC_ConfigChannel(&hadc2, &sConfig);
|
||||
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_13CYCLES_5;
|
||||
|
||||
sConfig.Channel = ADC_CHANNEL_10;
|
||||
sConfig.Channel = ADC_CHANNEL_10; // pc0 right cur
|
||||
sConfig.Rank = 3;
|
||||
HAL_ADC_ConfigChannel(&hadc2, &sConfig);
|
||||
|
||||
sConfig.Channel = ADC_CHANNEL_2;
|
||||
sConfig.Channel = ADC_CHANNEL_2; // pa2 uart-l-tx
|
||||
sConfig.Rank = 4;
|
||||
HAL_ADC_ConfigChannel(&hadc2, &sConfig);
|
||||
|
||||
sConfig.Channel = ADC_CHANNEL_3;
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
|
||||
|
||||
sConfig.Channel = ADC_CHANNEL_3; // pa3 uart-l-rx
|
||||
sConfig.Rank = 5;
|
||||
HAL_ADC_ConfigChannel(&hadc2, &sConfig);
|
||||
|
||||
|
Reference in New Issue
Block a user