Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
febbfc8
Added new BLDC motor control
EFeru May 26, 2019
a732c60
deleted
EFeru May 26, 2019
fc267cd
Added Matlab model for BLDC control
EFeru May 26, 2019
959027b
added Serial Port settings
EFeru May 26, 2019
b3cc517
update
EFeru May 26, 2019
cdcafba
Update .gitignore
EFeru May 26, 2019
ac0e680
First release commit, dynamic tests done!
EFeru May 28, 2019
09e8d3f
README.md updated from https://stackedit.io/
EFeru May 28, 2019
8758369
README.md updated from https://stackedit.io/
EFeru May 28, 2019
301418b
README.md updated from https://stackedit.io/
EFeru May 28, 2019
5a4e426
Update README.md
EFeru May 28, 2019
2c4d44f
Saved README.md with Dillinger.io
EFeru May 28, 2019
e937fb3
Saved README.md with Dillinger.io
EFeru May 28, 2019
396807b
Saved README.md with Dillinger.io
EFeru May 28, 2019
7f9bbec
Saved README.md with Dillinger.io
EFeru May 28, 2019
ade9a15
Update hoverboard_wheel.JPG
EFeru May 28, 2019
f279ff4
Merge branch 'master' of https://github.com/EmanuelFeru/hoverboard-fi…
EFeru May 28, 2019
3dd416b
Saved README.md with Dillinger.io
EFeru May 28, 2019
d5e2d46
Saved README.md with Dillinger.io
EFeru May 28, 2019
09edcf3
Saved README.md with Dillinger.io
EFeru May 28, 2019
5d64ec0
Saved README.md with Dillinger.io
EFeru May 28, 2019
ffe361a
Saved README.md with Dillinger.io
EFeru May 28, 2019
a144a86
Saved README.md with Dillinger.io
EFeru May 28, 2019
90d7a3c
Saved README.md with Dillinger.io
EFeru May 28, 2019
79abd9d
Update Makefile
p-h-a-i-l May 28, 2019
8adb223
► added firmware.bin
EFeru May 29, 2019
0a6064d
Merge pull request #1 from p-h-a-i-l/patch-1
EFeru May 29, 2019
8619ee3
Saved README.md with Dillinger.io
EFeru May 29, 2019
19e4115
Saved README.md with Dillinger.io
EFeru May 29, 2019
fe4bd76
► Improved controller: faster and better overall
EFeru Jun 5, 2019
b90a250
► New BLDC control
EFeru Jun 6, 2019
61aa161
► updated the 3rd harmonic to peak exactly at 1000
EFeru Jun 6, 2019
3c850ed
Added .travis.yml file
EFeru Jun 7, 2019
ffb6a52
added scr_dir
EFeru Jun 7, 2019
aee1a95
Update README.md
EFeru Jun 7, 2019
116f75d
Added wheel speed calculation in km/h
EFeru Jun 8, 2019
9fdbba1
Made z_maxCntRst as calibratable
EFeru Jun 10, 2019
43b4f4a
► Warning fixes
EFeru Jun 10, 2019
2ca1a19
Removed #define static static inline
EFeru Jun 10, 2019
b828eff
Updated generated firmware
EFeru Jun 10, 2019
bf97251
► Added speed threshold to enable Phase Advance
EFeru Jun 11, 2019
0d908b8
deleted slprj
EFeru Jun 11, 2019
6095748
Added temporary Matlab folder to ignore file
EFeru Jun 11, 2019
8ebf9dc
► Added protection on start-up
EFeru Jun 18, 2019
285f65b
Added some back-up files
EFeru Jun 18, 2019
102eae5
Moved cmd bypasses before the motor enabling
EFeru Jun 18, 2019
193160d
Updated build
EFeru Jun 18, 2019
fa0596c
ADD STM hoverboard pinout and pdf
EFeru Jun 19, 2019
9cf4988
cleanup
EFeru Jun 26, 2019
536aba7
clean-up temporary files
EFeru Jun 26, 2019
c998268
Update README.md
EFeru Jun 26, 2019
8d21a73
Added current measurements figures
EFeru Jun 27, 2019
4f13488
Add: Condition on motor control calculation
EFeru Jul 1, 2019
5bf21fc
Added link for the YST board schematic
EFeru Jul 10, 2019
3266374
Update .gitignore
EFeru Sep 14, 2019
1accd16
Update README.md
EFeru Oct 20, 2019
e5d6ec5
Update README.md
EFeru Jun 22, 2020
98e03b4
Update README.md
EFeru Jul 19, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
build/*
!build/hover.hex
.pio/
.pioenvs/
.vscode/
01_Matlab/slprj/
55 changes: 55 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
notifications:
email: true

sudo: false

matrix:
fast_finish: true
include:

- name: make (gcc-arm-none-eabi-7)
script: make
language: c
addons:
apt:
packages:
- libc6-i386
install:
- pushd .
- cd ~
- mkdir arm-gcc-toolchain
- wget -O $HOME/arm-gcc-toolchain/gcc.tar.bz2 https://developer.arm.com/-/media/Files/downloads/gnu-rm/7-2018q2/gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2?revision=bc2c96c0-14b5-4bb4-9f18-bceb4050fee7?product=GNU%20Arm%20Embedded%20Toolchain,64-bit,,Linux,7-2018-q2-update
- cd arm-gcc-toolchain
- tar -jxf gcc.tar.bz2 --strip=1
- popd
- export PATH=$HOME/arm-gcc-toolchain/bin:$PATH
before_script: arm-none-eabi-gcc --version

- name: make (gcc-arm-none-eabi-5)
script: make
language: c
addons:
apt:
packages:
- libc6-i386
install:
- pushd .
- cd ~
- mkdir arm-gcc-toolchain
- wget -O $HOME/arm-gcc-toolchain/gcc.tar.bz2 https://developer.arm.com/-/media/Files/downloads/gnu-rm/5_4-2016q3/gcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2?revision=111dee36-f88b-4672-8ac6-48cf41b4d375?product=GNU%20Arm%20Embedded%20Toolchain,32-bit,,Linux,5-2016-q3-update
- cd arm-gcc-toolchain
- tar -jxf gcc.tar.bz2 --strip=1
- popd
- export PATH=$HOME/arm-gcc-toolchain/bin:$PATH
before_script: arm-none-eabi-gcc --version

- name: pio genericSTM32F103RC
script: platformio run -e genericSTM32F103RC
language: python
python:
- "2.7"
install:
- pip install -U platformio
- platformio update
cache:
- directories: "~/.platformio"
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added 01_Matlab/02_Figures/control_methods.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
258 changes: 258 additions & 0 deletions 01_Matlab/99_RecycleBin/bldc_motor_derating.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
/*
* This file has been re-implemented with 4 new selectable motor control methods.
* Recommended control method: 3 = Sinusoidal 3rd order. This control method offers superior performanace
* compared to previous method. The new method features:
* ► reduced noise and vibrations
* ► smooth torque output
* ► improved motor efficiency -> lower energy consumption
*
* Copyright (C) 2019 Emanuel FERU <[email protected]>
*
* 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/>.
*/

#include "stm32f1xx_hal.h"
#include "defines.h"
#include "setup.h"
#include "config.h"

// Matlab includes and defines - from auto-code generation
// ###############################################################################
#include "BLDC_controller.h" /* Model's header file */
#include "rtwtypes.h"

extern RT_MODEL *const rtM_Left;
extern RT_MODEL *const rtM_Right;

extern DW rtDW_Left; /* Observable states */
extern ExtU rtU_Left; /* External inputs */
extern ExtY rtY_Left; /* External outputs */

extern DW rtDW_Right; /* Observable states */
extern ExtU rtU_Right; /* External inputs */
extern ExtY rtY_Right; /* External outputs */
// ###############################################################################


volatile int pwml = 0;
volatile int pwmr = 0;

int pwm_limiter = 1024;

extern volatile adc_buf_t adc_buffer;

extern volatile uint32_t timeout;

uint8_t buzzerFreq = 0;
uint8_t buzzerPattern = 0;
static uint32_t buzzerTimer = 0;

uint8_t enable = 0;

static const uint16_t pwm_res = 64000000 / 2 / PWM_FREQ; // = 2000
static float pwml_lim = 0;
static float curl_filt = 0;
float CUR;

static int offsetcount = 0;
static int offsetrl1 = 2000;
static int offsetrl2 = 2000;
static int offsetrr1 = 2000;
static int offsetrr2 = 2000;
static int offsetdcl = 2000;
static int offsetdcr = 2000;

float batteryVoltage = BAT_NUMBER_OF_CELLS * 4.0;

//scan 8 channels with 2ADCs @ 20 clk cycles per sample
//meaning ~80 ADC clock cycles @ 8MHz until new DMA interrupt =~ 100KHz
//=640 cpu cycles
void DMA1_Channel1_IRQHandler(void) {

DMA1->IFCR = DMA_IFCR_CTCIF1;
// HAL_GPIO_WritePin(LED_PORT, LED_PIN, 1);
// HAL_GPIO_TogglePin(LED_PORT, LED_PIN);

if(offsetcount < 1000) { // calibrate ADC offsets
offsetcount++;
offsetrl1 = (adc_buffer.rl1 + offsetrl1) / 2;
offsetrl2 = (adc_buffer.rl2 + offsetrl2) / 2;
offsetrr1 = (adc_buffer.rr1 + offsetrr1) / 2;
offsetrr2 = (adc_buffer.rr2 + offsetrr2) / 2;
offsetdcl = (adc_buffer.dcl + offsetdcl) / 2;
offsetdcr = (adc_buffer.dcr + offsetdcr) / 2;
return;
}

if (buzzerTimer % 1000 == 0) { // because you get float rounding errors if it would run every time
batteryVoltage = batteryVoltage * 0.99f + ((float)adc_buffer.batt1 * ((float)BAT_CALIB_REAL_VOLTAGE / (float)BAT_CALIB_ADC)) * 0.01f;
}

// //disable PWM when current limit is reached (current chopping)
// if(ABS((adc_buffer.dcl - offsetdcl) * MOTOR_AMP_CONV_DC_AMP) > DC_CUR_LIMIT || timeout > TIMEOUT || enable == 0) {
// LEFT_TIM->BDTR &= ~TIM_BDTR_MOE;
// //HAL_GPIO_WritePin(LED_PORT, LED_PIN, 1);
// } else {
// LEFT_TIM->BDTR |= TIM_BDTR_MOE;
// //HAL_GPIO_WritePin(LED_PORT, LED_PIN, 0);
// }

// if(ABS((adc_buffer.dcr - offsetdcr) * MOTOR_AMP_CONV_DC_AMP) > DC_CUR_LIMIT || timeout > TIMEOUT || enable == 0) {
// RIGHT_TIM->BDTR &= ~TIM_BDTR_MOE;
// } else {
// RIGHT_TIM->BDTR |= TIM_BDTR_MOE;
// }

//disable PWM when current limit is reached (current chopping)
if(timeout > TIMEOUT || enable == 0) {
LEFT_TIM->BDTR &= ~TIM_BDTR_MOE;
//HAL_GPIO_WritePin(LED_PORT, LED_PIN, 1);
} else {
LEFT_TIM->BDTR |= TIM_BDTR_MOE;
//HAL_GPIO_WritePin(LED_PORT, LED_PIN, 0);
}

if(timeout > TIMEOUT || enable == 0) {
RIGHT_TIM->BDTR &= ~TIM_BDTR_MOE;
} else {
RIGHT_TIM->BDTR |= TIM_BDTR_MOE;
}

// pwml_lim = pwml_lim + 0.001f * (ABS((adc_buffer.dcr - offsetdcr) * MOTOR_AMP_CONV_DC_AMP) - DC_CUR_LIMIT);
// pwml_lim = CLAMP(pwml_lim, 0, ABS(pwmr));
// pwmr = (int) (pwmr - SIGN(pwmr) * pwml_lim);

// if (ABS((adc_buffer.dcl - offsetdcl) * MOTOR_AMP_CONV_DC_AMP) > DC_CUR_LIMIT)
// pwml_lim = pwml_lim + 0.00001f;
// else
// pwml_lim = pwml_lim - 0.00001f; (pwml_lim * (1.0f - FILTER) + cmd2 * FILTER)

float CUR_FILTER = 0.1f; // 0.00001f;
curl_filt = ((100.0f - CUR_FILTER) * curl_filt + CUR_FILTER * ABS((adc_buffer.dcl - offsetdcl) * MOTOR_AMP_CONV_DC_AMP)) / 100;
// curl_filt = ABS((adc_buffer.dcl - offsetdcl) * MOTOR_AMP_CONV_DC_AMP);
// pwml_lim = pwml_lim + 1 * (curl_filt - DC_CUR_LIMIT);
pwml_lim = 2 * (curl_filt - DC_CUR_LIMIT);
pwml_lim = CLAMP(pwml_lim, 0, ABS(pwml));
pwml = (int) (pwml - SIGN(pwml) * pwml_lim);

// if(curl_filt > DC_CUR_LIMIT) {
// pwml_lim+=0.1f;
// HAL_GPIO_WritePin(LED_PORT, LED_PIN, 1); // Derating active
// } else {
// pwml_lim-=0.1f;
// HAL_GPIO_WritePin(LED_PORT, LED_PIN, 0); // Derating deactive
// }
// pwml_lim = CLAMP(pwml_lim/1000, 0, ABS(pwml));
// pwml = (int) (pwml - SIGN(pwml) * pwml_lim);


// DC_CUR = MAX(ABS((adc_buffer.dcl - offsetdcl) * MOTOR_AMP_CONV_DC_AMP), ABS((adc_buffer.dcr - offsetdcr) * MOTOR_AMP_CONV_DC_AMP));

// CUR = curl_filt;
CUR = (adc_buffer.rl1 - offsetrl1) * MOTOR_AMP_CONV_DC_AMP;
// if(ABS((adc_buffer.dcl - offsetdcl) * MOTOR_AMP_CONV_DC_AMP) > DC_CUR_LIMIT) {
// pwm_limiter--;
// HAL_GPIO_WritePin(LED_PORT, LED_PIN, 1); // Derating active
// } else {
// pwm_limiter++;
// HAL_GPIO_WritePin(LED_PORT, LED_PIN, 0); // Derating deactive
// }
// pwm_limiter = CLAMP(pwm_limiter, 0, 1024);
// pwml = (pwm_limiter*pwml) >> 10;
// pwmr = CLAMP(pwmr, -pwm_lim, pwm_lim);

//create square wave for buzzer
buzzerTimer++;
if (buzzerFreq != 0 && (buzzerTimer / 5000) % (buzzerPattern + 1) == 0) {
if (buzzerTimer % buzzerFreq == 0) {
HAL_GPIO_TogglePin(BUZZER_PORT, BUZZER_PIN);
}
} else {
HAL_GPIO_WritePin(BUZZER_PORT, BUZZER_PIN, 0);
}

// ############################### MOTOR CONTROL ###############################

static boolean_T OverrunFlag = false;
/* Check for overrun */
if (OverrunFlag) {
return;
}
OverrunFlag = true;

int ul, vl, wl;
int ur, vr, wr;
// ========================= LEFT MOTOR ============================
// Get hall sensors values
uint8_t hall_ul = !(LEFT_HALL_U_PORT->IDR & LEFT_HALL_U_PIN);
uint8_t hall_vl = !(LEFT_HALL_V_PORT->IDR & LEFT_HALL_V_PIN);
uint8_t hall_wl = !(LEFT_HALL_W_PORT->IDR & LEFT_HALL_W_PIN);

/* Set motor inputs here */
rtU_Left.b_hallA = hall_ul;
rtU_Left.b_hallB = hall_vl;
rtU_Left.b_hallC = hall_wl;
rtU_Left.r_DC = pwml;

/* Step the controller */
BLDC_controller_step(rtM_Left);

/* Get motor outputs here */
ul = rtY_Left.DC_phaA;
vl = rtY_Left.DC_phaB;
wl = rtY_Left.DC_phaC;
// motSpeedLeft = rtY_Left.n_mot;
// motAngleLeft = rtY_Left.a_elecAngle;

/* Apply commands */
LEFT_TIM->LEFT_TIM_U = (uint16_t)CLAMP(ul + pwm_res / 2, 10, pwm_res-10);
LEFT_TIM->LEFT_TIM_V = (uint16_t)CLAMP(vl + pwm_res / 2, 10, pwm_res-10);
LEFT_TIM->LEFT_TIM_W = (uint16_t)CLAMP(wl + pwm_res / 2, 10, pwm_res-10);
// =================================================================


// ========================= RIGHT MOTOR ===========================
// Get hall sensors values
uint8_t hall_ur = !(RIGHT_HALL_U_PORT->IDR & RIGHT_HALL_U_PIN);
uint8_t hall_vr = !(RIGHT_HALL_V_PORT->IDR & RIGHT_HALL_V_PIN);
uint8_t hall_wr = !(RIGHT_HALL_W_PORT->IDR & RIGHT_HALL_W_PIN);

/* Set motor inputs here */
rtU_Right.b_hallA = hall_ur;
rtU_Right.b_hallB = hall_vr;
rtU_Right.b_hallC = hall_wr;
rtU_Right.r_DC = pwmr;

/* Step the controller */
BLDC_controller_step(rtM_Right);

/* Get motor outputs here */
ur = rtY_Right.DC_phaA;
vr = rtY_Right.DC_phaB;
wr = rtY_Right.DC_phaC;
// motSpeedRight = rtY_Right.n_mot;
// motAngleRight = rtY_Right.a_elecAngle;

/* Apply commands */
RIGHT_TIM->RIGHT_TIM_U = (uint16_t)CLAMP(ur + pwm_res / 2, 10, pwm_res-10);
RIGHT_TIM->RIGHT_TIM_V = (uint16_t)CLAMP(vr + pwm_res / 2, 10, pwm_res-10);
RIGHT_TIM->RIGHT_TIM_W = (uint16_t)CLAMP(wr + pwm_res / 2, 10, pwm_res-10);
// =================================================================

/* Indicate task complete */
OverrunFlag = false;

// ###############################################################################

}
Loading