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:
parent
612dce68ea
commit
0243eb347e
93
Inc/config.h
93
Inc/config.h
|
@ -1,65 +1,78 @@
|
|||
#pragma once
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
// ################################################################################
|
||||
// ############################### DO-NOT-TOUCH SETTINGS ###############################
|
||||
|
||||
#define PWM_FREQ 16000 // PWM frequency in Hz
|
||||
#define DEAD_TIME 32 // PWM deadtime
|
||||
|
||||
#define DC_CUR_LIMIT 15 // DC current limit in amps per motor. so 15 means it will draw 30A out of your battery. it does not disable motors, it is a soft current limit.
|
||||
#define DELAY_IN_MAIN_LOOP 2 // 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.
|
||||
#define TIMEOUT 5 // number of wrong / missing input commands before emergency off
|
||||
|
||||
// Battery voltage calibration: connect power source. use multimeter to measure real voltage and write it to BAT_CALIB_REAL_VOLTAGE. enable DEBUG_SERIAL_USART3 and DEBUG_SERIAL_ASCII (and disconnect and disable CONTROL_NUNCHUCK) and watch UART on right sensor board cable. write value nr 5 to BAT_CALIB_ADC. make and flash firmware. you can verify voltage on UART debug value 6 (devide it by 100.0 to get calibrated voltage).
|
||||
#define BAT_CALIB_REAL_VOLTAGE 42.0 // input voltage measured by multimeter
|
||||
#define BAT_CALIB_ADC 1667 // adc-value measured by mainboard (value nr 4 on UART debug output)
|
||||
// ############################### GENERAL ###############################
|
||||
|
||||
#define BAT_NUMBER_OF_CELLS 12 // normal Hoverboard battery: 10s
|
||||
// How to calibrate: connect GND and RX of a 3.3v uart-usb adapter to the right sensor board cable (be careful not to use the red wire of the cable. 15v will destroye verything.). if you are using nunchuck, disable it temporarily. enable DEBUG_SERIAL_USART3 and DEBUG_SERIAL_ASCII use asearial terminal.
|
||||
|
||||
// Battery voltage calibration: connect power source. see <How to calibrate>. write value nr 5 to BAT_CALIB_ADC. make and flash firmware. then you can verify voltage on value 6 (devide it by 100.0 to get calibrated voltage).
|
||||
#define BAT_CALIB_REAL_VOLTAGE 43.0 // input voltage measured by multimeter
|
||||
#define BAT_CALIB_ADC 1704 // adc-value measured by mainboard (value nr 4 on UART debug output)
|
||||
|
||||
#define BAT_NUMBER_OF_CELLS 10 // normal Hoverboard battery: 10s
|
||||
#define BAT_LOW_LVL1_ENABLE 0 // to beep or not to beep, 1 or 0
|
||||
#define BAT_LOW_LVL1 3.6 // gently beeps at this voltage level. [V/cell]
|
||||
#define BAT_LOW_LVL2_ENABLE 1 // to beep or not to beep, 1 or 0
|
||||
#define BAT_LOW_LVL2 3.5 // your battery is almost empty. Charge now! [V/cell]
|
||||
#define BAT_LOW_DEAD 3.37 // undervoltage lockout. [V/cell]
|
||||
#define BAT_LOW_DEAD 3.37 // undervoltage poweroff. (while not driving) [V/cell]
|
||||
|
||||
#define DC_CUR_LIMIT 15 // DC current limit in amps per motor. so 15 means it will draw 30A out of your battery. it does not disable motors, it is a soft current limit.
|
||||
|
||||
// Board overheat detection: the sensor is inside the STM/GD chip. it is very inaccurate without calibration (up to 45°C). so only enable this funcion after calibration! let your board cool down. see <How to calibrate>. get the real temp of the chip by thermo cam or another temp-sensor taped on top of the chip and write it to TEMP_CAL_LOW_DEG_C. write debug value 8 to TEMP_CAL_LOW_ADC. drive around to warm up the board. it should be at least 20°C warmer. repeat it for the HIGH-values. enable warning and/or poweroff and make and flash firmware.
|
||||
#define TEMP_CAL_LOW_ADC 1655 // temperature 1: ADC value
|
||||
#define TEMP_CAL_LOW_DEG_C 35.8 // temperature 1: measured temperature [°C]
|
||||
#define TEMP_CAL_HIGH_ADC 1588 // temperature 2: ADC value
|
||||
#define TEMP_CAL_HIGH_DEG_C 48.9 // temperature 2: measured temperature [°C]
|
||||
#define TEMP_WARNING_ENABLE 0 // to beep or not to beep, 1 or 0, DO NOT ACTIVITE WITHOUT CALIBRATION!
|
||||
#define TEMP_WARNING 60 // annoying fast beeps [°C]
|
||||
#define TEMP_POWEROFF_ENABLE 0 // to poweroff or not to poweroff, 1 or 0, DO NOT ACTIVITE WITHOUT CALIBRATION!
|
||||
#define TEMP_POWEROFF 65 // overheat poweroff. (while not driving) [°C]
|
||||
|
||||
#define INACTIVITY_TIMEOUT 8 // minutes of not driving until poweroff. it is not very precise.
|
||||
|
||||
// ################################################################################
|
||||
//#define DEBUG_I2C_LCD // standard 16x2 or larger text-lcd via i2c-converter on right sensor board cable
|
||||
|
||||
//#define DEBUG_SERIAL_USART3 // right sensor board cable, disable if I2C (nunchuck) is used!
|
||||
// ############################### SERIAL DEBUG ###############################
|
||||
|
||||
#define DEBUG_SERIAL_USART3 // right sensor board cable, disable if I2C (nunchuck or lcd) is used!
|
||||
#define DEBUG_BAUD 115200 // UART baud rate
|
||||
//#define DEBUG_SERIAL_SERVOTERM
|
||||
#define DEBUG_SERIAL_ASCII // "1:345 2:1337 3:0 4:0 5:0 6:0 7:0 8:0\r\n"
|
||||
|
||||
// ############################### INPUT ###############################
|
||||
|
||||
// ###### CONTROL VIA UART (serial) ######
|
||||
//#define CONTROL_SERIAL_USART2 // left sensor board cable, disable if ADC or PPM is used!
|
||||
#define CONTROL_BAUD 19200 // control via usart from eg an Arduino or raspberry
|
||||
// for Arduino, use void loop(void){ Serial.write((uint8_t *) &steer, sizeof(steer)); Serial.write((uint8_t *) &speed, sizeof(speed));delay(20); }
|
||||
|
||||
//#define DEBUG_I2C_LCD // standard 16x2 or larger text-lcd via i2c-converter on right sensor board cable
|
||||
|
||||
#define TIMEOUT 5 // number of wrong / missing commands before emergency off
|
||||
|
||||
// ################################################################################
|
||||
|
||||
// ###### CONTROL VIA RC REMOTE ######
|
||||
// left sensor board cable. Channel 1: steering, Channel 2: speed.
|
||||
//#define CONTROL_PPM // use PPM-Sum as input. disable DEBUG_SERIAL_USART2!
|
||||
//#define PPM_NUM_CHANNELS 6 // total number of PPM channels to receive, even if they are not used.
|
||||
|
||||
// ###### CONTROL VIA TWO POTENTIOMETERS ######
|
||||
// ADC-calibration to cover the full poti-range: connect potis to left sensor board cable (0 to 3.3V) (do NOT use the red 15V wire in the cable!). enable DEBUG_SERIAL_USART3 and DEBUG_SERIAL_ASCII (and disconnect and disable CONTROL_NUNCHUCK) and watch UART on right sensor board cable. value1 == ADC1 and value2 == ADC2. write minimum and maximum poti position-values to ADC?_MIN and ADC?_MAX.
|
||||
//#define CONTROL_ADC // use ADC as input. disable DEBUG_SERIAL_USART2!
|
||||
//#define ADC1_MIN 0 // min ADC1-value while poti at minimum-position (0 - 4095)
|
||||
//#define ADC1_MAX 4095 // max ADC1-value while poti at maximum-position (0 - 4095)
|
||||
//#define ADC2_MIN 0 // min ADC2-value while poti at minimum-position (0 - 4095)
|
||||
//#define ADC2_MAX 4095 // max ADC2-value while poti at maximum-position (0 - 4095)
|
||||
// ADC-calibration to cover the full poti-range: connect potis to left sensor board cable (0 to 3.3V) (do NOT use the red 15V wire in the cable!). see <How to calibrate>. turn the potis to minimum position, write value 1 to ADC1_MIN and value 2 to ADC2_MIN. turn to maximum position and repeat it for ADC?_MAX. make, flash and test it.
|
||||
#define CONTROL_ADC // use ADC as input. disable DEBUG_SERIAL_USART2!
|
||||
#define ADC1_MIN 0 // min ADC1-value while poti at minimum-position (0 - 4095)
|
||||
#define ADC1_MAX 4095 // max ADC1-value while poti at maximum-position (0 - 4095)
|
||||
#define ADC2_MIN 0 // min ADC2-value while poti at minimum-position (0 - 4095)
|
||||
#define ADC2_MAX 4095 // max ADC2-value while poti at maximum-position (0 - 4095)
|
||||
|
||||
// ###### CONTROL VIA NINTENDO NUNCHUCK ######
|
||||
// left sensor board cable. keep cable short, use shielded cable, use ferrits, stabalize voltage in nunchuck, use the right one of the 2 types of nunchucks, add i2c pullups.
|
||||
// left sensor board cable. keep cable short, use shielded cable, use ferrits, stabalize voltage in nunchuck, use the right one of the 2 types of nunchucks, add i2c pullups. use original nunchuck. most clones does not work very well.
|
||||
//#define CONTROL_NUNCHUCK // use nunchuck as input. disable DEBUG_SERIAL_USART3!
|
||||
|
||||
// ################################################################################
|
||||
|
||||
// ###### DRIVING BEHAVIOR ######
|
||||
// ############################### DRIVING BEHAVIOR ###############################
|
||||
|
||||
// inputs:
|
||||
// - cmd1 and cmd2: analog normalized input values. -1000 to 1000
|
||||
|
@ -72,8 +85,9 @@
|
|||
#define FILTER 0.1 // lower value == softer filter. do not use values <0.01, you will get float precision issues.
|
||||
#define SPEED_COEFFICIENT 0.5 // higher value == stronger. 0.0 to ~2.0?
|
||||
#define STEER_COEFFICIENT 0.5 // higher value == stronger. if you do not want any steering, set it to 0.0; 0.0 to 1.0
|
||||
//#define INVERT_R_DIRECTION
|
||||
//#define INVERT_L_DIRECTION
|
||||
#define INVERT_R_DIRECTION
|
||||
#define INVERT_L_DIRECTION
|
||||
#define BEEPS_BACKWARD 1 // 0 or 1
|
||||
|
||||
//Turbo boost at high speeds while button1 is pressed:
|
||||
//#define ADDITIONAL_CODE \
|
||||
|
@ -84,7 +98,8 @@ else { \
|
|||
weakl = 0; \
|
||||
weakr = 0; }
|
||||
|
||||
// ###### BOBBYCAR ######
|
||||
// ###### SIMPLE BOBBYCAR ######
|
||||
// for better bobbycar code see: https://github.com/larsmm/hoverboard-firmware-hack-bbcar
|
||||
// #define FILTER 0.1
|
||||
// #define SPEED_COEFFICIENT -1
|
||||
// #define STEER_COEFFICIENT 0
|
||||
|
@ -114,22 +129,22 @@ else {\
|
|||
weakl = 0;\
|
||||
weakr = 0;
|
||||
|
||||
#define BEEPS_BACKWARD 1 // 0 or 1
|
||||
// ############################### VALIDATE SETTINGS ###############################
|
||||
|
||||
// ################################################################################
|
||||
|
||||
// validate settings (do not touch this):
|
||||
|
||||
#if defined DEBUG_SERIAL_USART2 && defined CONTROL_ADC
|
||||
#error CONTROL_ADC and DEBUG_SERIAL_USART2 not allowed. use DEBUG_SERIAL_USART3 instead.
|
||||
#if defined CONTROL_SERIAL_USART2 && defined CONTROL_ADC
|
||||
#error CONTROL_ADC and CONTROL_SERIAL_USART2 not allowed. it is on the same cable.
|
||||
#endif
|
||||
|
||||
#if defined DEBUG_SERIAL_USART2 && defined CONTROL_PPM
|
||||
#error CONTROL_PPM and DEBUG_SERIAL_USART2 not allowed. use DEBUG_SERIAL_USART3 instead.
|
||||
#if defined CONTROL_SERIAL_USART2 && defined CONTROL_PPM
|
||||
#error CONTROL_PPM and CONTROL_SERIAL_USART2 not allowed. it is on the same cable.
|
||||
#endif
|
||||
|
||||
#if defined DEBUG_SERIAL_USART3 && defined CONTROL_NUNCHUCK
|
||||
#error CONTROL_NUNCHUCK and DEBUG_SERIAL_USART3 not allowed. use DEBUG_SERIAL_USART2 instead.
|
||||
#error CONTROL_NUNCHUCK and DEBUG_SERIAL_USART3 not allowed. it is on the same cable.
|
||||
#endif
|
||||
|
||||
#if defined DEBUG_SERIAL_USART3 && defined DEBUG_I2C_LCD
|
||||
#error DEBUG_I2C_LCD and DEBUG_SERIAL_USART3 not allowed. it is on the same cable.
|
||||
#endif
|
||||
|
||||
#if defined CONTROL_PPM && defined CONTROL_ADC && defined CONTROL_NUNCHUCK || defined CONTROL_PPM && defined CONTROL_ADC || defined CONTROL_ADC && defined CONTROL_NUNCHUCK || defined CONTROL_PPM && defined CONTROL_NUNCHUCK
|
||||
|
|
|
@ -155,6 +155,6 @@ typedef struct {
|
|||
uint16_t dcl;
|
||||
uint16_t batt1;
|
||||
uint16_t l_tx2;
|
||||
uint16_t bat1;
|
||||
uint16_t temp;
|
||||
uint16_t l_rx2;
|
||||
} adc_buf_t;
|
||||
|
|
15
README.md
15
README.md
|
@ -8,6 +8,8 @@ The firmware you can find here allows you to use your Hoverboard Hardware (like
|
|||
If you want an overview of what you can do with this firmware, here is a ~40min video of a talk about this project:
|
||||
https://media.ccc.de/v/gpn18-95-howto-moving-objects
|
||||
|
||||
There is a bobbycar-optimized firmware based on this one with driving modes, acceleration ramps and some other features: https://github.com/larsmm/hoverboard-firmware-hack-bbcar
|
||||
|
||||
---
|
||||
|
||||
#### Hardware
|
||||
|
@ -22,17 +24,26 @@ http://vocke.tv/lib/exe/fetch.php?media=20150722_hoverboard_sch.pdf
|
|||
---
|
||||
|
||||
#### Flashing
|
||||
To build the firmware, just type "make". Make sure you have specified your gcc-arm-none-eabi binary location in the Makefile ("PREFIX = ..."). Right to the STM32, there is a debugging header with GND, 3V3, SWDIO and SWCLK. Connect GND, SWDIO and SWCLK to your SWD programmer, like the ST-Link found on many STM devboards.
|
||||
To build the firmware, just type "make". Make sure you have specified your gcc-arm-none-eabi binary (verion 7 works, there is a version that does not!) location in the Makefile ("PREFIX = ..."). Right to the STM32, there is a debugging header with GND, 3V3, SWDIO and SWCLK. Connect GND, SWDIO and SWCLK to your SWD programmer, like the ST-Link found on many STM devboards.
|
||||
|
||||
Make sure you hold the powerbutton or connect a jumper to the power button pins while flashing the firmware, as the STM might release the power latch and switches itself off during flashing. Battery > 36V have to be connected while flashing.
|
||||
|
||||
To flash the STM32, use the ST-Flash utility (https://github.com/texane/stlink).
|
||||
|
||||
If you never flashed your mainboard before, the STM is probably locked. To unlock the flash, use the following OpenOCD command:
|
||||
|
||||
```
|
||||
openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg -c init -c "reset halt" -c "stm32f1x unlock 0"
|
||||
```
|
||||
|
||||
If that does not work:
|
||||
```
|
||||
openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg -c init -c "reset halt" -c "mww 0x40022004 0x45670123" -c "mww 0x40022004 0xCDEF89AB" -c "mww 0x40022008 0x45670123" -c "mww 0x40022008 0xCDEF89AB" -c "mww 0x40022010 0x220" -c "mww 0x40022010 0x260" -c "sleep 100" -c "mww 0x40022010 0x230" -c "mwh 0x1ffff800 0x5AA5" -c "sleep 1000" -c "mww 0x40022010 0x2220" -c "sleep 100" -c "mdw 0x40022010" -c "mdw 0x4002201c" -c "mdw 0x1ffff800" -c targets -c "halt" -c "stm32f1x unlock 0"
|
||||
```
|
||||
```
|
||||
openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg -c init -c "reset halt" -c "mww 0x40022004 0x45670123" -c "mww 0x40022004 0xCDEF89AB" -c "mww 0x40022008 0x45670123" -c "mww 0x40022008 0xCDEF89AB" -c targets -c "halt" -c "stm32f1x unlock 0"
|
||||
```
|
||||
Or use the Windows ST-Link utility.
|
||||
|
||||
Then you can simply flash the firmware:
|
||||
```
|
||||
st-flash --reset write build/hover.bin 0x8000000
|
||||
|
|
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);
|
||||
|
||||
|
|
2055
build/hover.hex
2055
build/hover.hex
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue