Added new BLDC motor control

This commit is contained in:
EmanuelFeru
2019-05-26 15:33:57 +02:00
parent f06ce1fcd3
commit febbfc823c
11 changed files with 2428 additions and 1412 deletions

444
Inc/BLDC_controller.h Normal file
View File

@ -0,0 +1,444 @@
/*
* Academic License - for use in teaching, academic research, and meeting
* course requirements at degree granting institutions only. Not for
* government, commercial, or other organizational use.
*
* File: BLDC_controller.h
*
* Code generated for Simulink model 'BLDC_controller'.
*
* Model version : 1.800
* Simulink Coder version : 8.13 (R2017b) 24-Jul-2017
* C/C++ source code generated on : Sat May 25 21:42:39 2019
*
* Target selection: ert.tlc
* Embedded hardware selection: ARM Compatible->ARM Cortex
* Emulation hardware selection:
* Differs from embedded hardware (MATLAB Host)
* Code generation objectives:
* 1. Execution efficiency
* 2. RAM efficiency
* Validation result: Not run
*/
#ifndef RTW_HEADER_BLDC_controller_h_
#define RTW_HEADER_BLDC_controller_h_
#include "rtwtypes.h"
#include "zero_crossing_types.h"
#ifndef BLDC_controller_COMMON_INCLUDES_
# define BLDC_controller_COMMON_INCLUDES_
#include "rtwtypes.h"
#include "zero_crossing_types.h"
#endif /* BLDC_controller_COMMON_INCLUDES_ */
/* Macros for accessing real-time model data structure */
/* Block signals and states (auto storage) for system '<S12>/F01_03_Direction_Detection' */
typedef struct {
int8_T UnitDelay1_DSTATE; /* '<S22>/UnitDelay1' */
} DW_F01_03_Direction_Detection;
/* Block signals and states (auto storage) for system '<S23>/Edge_counter' */
typedef struct {
uint8_T UnitDelay1_DSTATE; /* '<S38>/UnitDelay1' */
boolean_T Edge_counter_MODE; /* '<S23>/Edge_counter' */
} DW_Edge_counter;
/* Block signals and states (auto storage) for system '<S23>/Moving_Average_Filter' */
typedef struct {
int32_T UnitDelay5_DSTATE; /* '<S28>/UnitDelay5' */
int32_T UnitDelay1_DSTATE; /* '<S28>/UnitDelay1' */
} DW_Moving_Average_Filter;
/* Zero-crossing (trigger) state for system '<S23>/Moving_Average_Filter' */
typedef struct {
ZCSigState Moving_Average_Filter_Trig_ZCE;/* '<S23>/Moving_Average_Filter' */
} ZCE_Moving_Average_Filter;
/* Zero-crossing (trigger) state for system '<S23>/Raw_ Speed_calculation' */
typedef struct {
ZCSigState Raw_Speed_calculation_Trig_ZCE;/* '<S23>/Raw_ Speed_calculation' */
} ZCE_Raw_Speed_calculation;
/* Block signals and states (auto storage) for system '<Root>' */
typedef struct {
DW_Moving_Average_Filter Moving_Average_Filter_n;/* '<S63>/Moving_Average_Filter' */
DW_Edge_counter Edge_counter_l; /* '<S63>/Edge_counter' */
DW_F01_03_Direction_Detection F01_03_Direction_Detection_j;/* '<S52>/F01_03_Direction_Detection' */
DW_Moving_Average_Filter Moving_Average_Filter_l;/* '<S23>/Moving_Average_Filter' */
DW_Edge_counter Edge_counter_f; /* '<S23>/Edge_counter' */
DW_F01_03_Direction_Detection F01_03_Direction_Detection_o;/* '<S12>/F01_03_Direction_Detection' */
int32_T Switch_PhaAdv; /* '<S53>/Switch_PhaAdv' */
int32_T rpm_signed; /* '<S69>/Product2' */
int32_T Switch_PhaAdv_a; /* '<S13>/Switch_PhaAdv' */
int32_T rpm_signed_c; /* '<S29>/Product2' */
int16_T Merge; /* '<S14>/Merge' */
int16_T Merge1; /* '<S14>/Merge1' */
int16_T Merge2; /* '<S14>/Merge2' */
int16_T Merge_j; /* '<S54>/Merge' */
int16_T Merge1_m; /* '<S54>/Merge1' */
int16_T Merge2_d; /* '<S54>/Merge2' */
int16_T z_counterRawPrev_DSTATE; /* '<S23>/z_counterRawPrev' */
int16_T z_counter2_DSTATE; /* '<S23>/z_counter2' */
int16_T UnitDelay1_DSTATE; /* '<S32>/UnitDelay1' */
int16_T z_counterRawPrev_DSTATE_p; /* '<S63>/z_counterRawPrev' */
int16_T z_counter2_DSTATE_h; /* '<S63>/z_counter2' */
int16_T UnitDelay1_DSTATE_k; /* '<S72>/UnitDelay1' */
int8_T UnitDelay1; /* '<S62>/UnitDelay1' */
int8_T Switch2; /* '<S62>/Switch2' */
int8_T UnitDelay1_k; /* '<S22>/UnitDelay1' */
int8_T Switch2_e; /* '<S22>/Switch2' */
int8_T If1_ActiveSubsystem; /* '<S2>/If1' */
int8_T If1_ActiveSubsystem_j; /* '<S3>/If1' */
uint8_T Sum2_i; /* '<S67>/Sum2' */
uint8_T Sum2_l; /* '<S27>/Sum2' */
uint8_T UnitDelay_DSTATE; /* '<S20>/UnitDelay' */
uint8_T UnitDelay1_DSTATE_p; /* '<S20>/UnitDelay1' */
uint8_T UnitDelay2_DSTATE; /* '<S20>/UnitDelay2' */
uint8_T UnitDelay1_DSTATE_g; /* '<S21>/UnitDelay1' */
uint8_T UnitDelay_DSTATE_j; /* '<S60>/UnitDelay' */
uint8_T UnitDelay1_DSTATE_f; /* '<S60>/UnitDelay1' */
uint8_T UnitDelay2_DSTATE_b; /* '<S60>/UnitDelay2' */
uint8_T UnitDelay1_DSTATE_j; /* '<S61>/UnitDelay1' */
boolean_T RelationalOperator4; /* '<S63>/Relational Operator4' */
boolean_T LogicalOperator; /* '<S71>/Logical Operator' */
boolean_T UnitDelay8_DSTATE; /* '<S23>/UnitDelay8' */
boolean_T UnitDelay8_DSTATE_p; /* '<S63>/UnitDelay8' */
boolean_T UnitDelay_DSTATE_k; /* '<S71>/UnitDelay' */
boolean_T UnitDelay_DSTATE_l; /* '<S31>/UnitDelay' */
boolean_T Memory_PreviousInput; /* '<S30>/Memory' */
boolean_T Relay_Mode; /* '<S15>/Relay' */
boolean_T Memory_PreviousInput_i; /* '<S70>/Memory' */
boolean_T Relay_Mode_m; /* '<S55>/Relay' */
} DW;
/* Zero-crossing (trigger) state */
typedef struct {
ZCE_Raw_Speed_calculation Raw_Speed_calculation_k;/* '<S63>/Raw_ Speed_calculation' */
ZCE_Moving_Average_Filter Moving_Average_Filter_n;/* '<S63>/Moving_Average_Filter' */
ZCE_Raw_Speed_calculation Raw_Speed_calculation_m;/* '<S23>/Raw_ Speed_calculation' */
ZCE_Moving_Average_Filter Moving_Average_Filter_l;/* '<S23>/Moving_Average_Filter' */
} PrevZCX;
/* Constant parameters (auto storage) */
typedef struct {
/* Pooled Parameter (Expression: r_trapPhaA_M1)
* Referenced by:
* '<S43>/r_trapPhaA_M1'
* '<S83>/r_trapPhaA_M1'
*/
int16_T pooled8[7];
/* Pooled Parameter (Expression: r_trapPhaB_M1)
* Referenced by:
* '<S43>/r_trapPhaB_M1'
* '<S83>/r_trapPhaB_M1'
*/
int16_T pooled9[7];
/* Pooled Parameter (Expression: r_trapPhaC_M1)
* Referenced by:
* '<S43>/r_trapPhaC_M1'
* '<S83>/r_trapPhaC_M1'
*/
int16_T pooled10[7];
/* Pooled Parameter (Expression: r_sinPhaA_M1)
* Referenced by:
* '<S45>/r_sinPhaA_M1'
* '<S85>/r_sinPhaA_M1'
*/
int16_T pooled11[37];
/* Pooled Parameter (Expression: r_sinPhaB_M1)
* Referenced by:
* '<S45>/r_sinPhaB_M1'
* '<S85>/r_sinPhaB_M1'
*/
int16_T pooled12[37];
/* Pooled Parameter (Expression: r_sinPhaC_M1)
* Referenced by:
* '<S45>/r_sinPhaC_M1'
* '<S85>/r_sinPhaC_M1'
*/
int16_T pooled13[37];
/* Pooled Parameter (Expression: r_sin3PhaA_M1)
* Referenced by:
* '<S44>/r_sin3PhaA_M1'
* '<S84>/r_sin3PhaA_M1'
*/
int16_T pooled14[37];
/* Pooled Parameter (Expression: r_sin3PhaB_M1)
* Referenced by:
* '<S44>/r_sin3PhaB_M1'
* '<S84>/r_sin3PhaB_M1'
*/
int16_T pooled15[37];
/* Pooled Parameter (Expression: r_sin3PhaC_M1)
* Referenced by:
* '<S44>/r_sin3PhaC_M1'
* '<S84>/r_sin3PhaC_M1'
*/
int16_T pooled16[37];
/* Pooled Parameter (Expression: z_commutMap_M1)
* Referenced by:
* '<S15>/z_commutMap_M1'
* '<S55>/z_commutMap_M1'
*/
int16_T pooled17[18];
/* Pooled Parameter (Expression: vec_hallToPos)
* Referenced by:
* '<S21>/vec_hallToPos'
* '<S61>/vec_hallToPos'
*/
uint8_T pooled27[8];
/* Pooled Parameter (Expression: [0 1;1 0;0 1;0 1;1 0;1 0;0 0;0 0])
* Referenced by:
* '<S30>/Logic'
* '<S70>/Logic'
*/
boolean_T pooled31[16];
} ConstP;
/* External inputs (root inport signals with auto storage) */
typedef struct {
uint8_T b_hallALeft; /* '<Root>/b_hallALeft ' */
uint8_T b_hallBLeft; /* '<Root>/b_hallBLeft' */
uint8_T b_hallCLeft; /* '<Root>/b_hallCLeft' */
int32_T r_DCLeft; /* '<Root>/r_DCLeft' */
uint8_T b_hallARight; /* '<Root>/b_hallARight' */
uint8_T b_hallBRight; /* '<Root>/b_hallBRight' */
uint8_T b_hallCRight; /* '<Root>/b_hallCRight' */
int32_T r_DCRight; /* '<Root>/r_DCRight' */
} ExtU;
/* External outputs (root outports fed by signals with auto storage) */
typedef struct {
int32_T DC_phaALeft; /* '<Root>/DC_phaALeft' */
int32_T DC_phaBLeft; /* '<Root>/DC_phaBLeft' */
int32_T DC_phaCLeft; /* '<Root>/DC_phaCLeft' */
int32_T n_motLeft; /* '<Root>/n_motLeft' */
int32_T a_elecAngleLeft; /* '<Root>/a_elecAngleLeft' */
int32_T DC_phaARight; /* '<Root>/DC_phaARight' */
int32_T DC_phaBRight; /* '<Root>/DC_phaBRight' */
int32_T DC_phaCRight; /* '<Root>/DC_phaCRight' */
int32_T n_motRight; /* '<Root>/n_motRight' */
int32_T a_elecAngleRight; /* '<Root>/a_elecAngleRight' */
} ExtY;
/* Parameters (auto storage) */
struct P_ {
int32_T cf_spdCoef; /* Variable: cf_spdCoef
* Referenced by:
* '<S29>/cf_spdCoef'
* '<S69>/cf_spdCoef'
*/
int32_T n_commAcvLo; /* Variable: n_commAcvLo
* Referenced by:
* '<S15>/Relay'
* '<S55>/Relay'
*/
int32_T n_commDeacvHi; /* Variable: n_commDeacvHi
* Referenced by:
* '<S15>/Relay'
* '<S55>/Relay'
*/
int32_T n_thresSpdDeacv; /* Variable: n_thresSpdDeacv
* Referenced by:
* '<S23>/n_thresSpdDeacv'
* '<S63>/n_thresSpdDeacv'
*/
int32_T r_commDCDeacv; /* Variable: r_commDCDeacv
* Referenced by:
* '<S15>/r_commDCDeacv'
* '<S55>/r_commDCDeacv'
*/
int32_T r_phaAdvDC_XA[11]; /* Variable: r_phaAdvDC_XA
* Referenced by:
* '<S13>/r_phaAdvDC_XA'
* '<S53>/r_phaAdvDC_XA'
*/
int16_T a_phaAdv_M1[11]; /* Variable: a_phaAdv_M1
* Referenced by:
* '<S13>/a_phaAdv_M2'
* '<S53>/a_phaAdv_M2'
*/
int16_T z_maxCntRst; /* Variable: z_maxCntRst
* Referenced by:
* '<S23>/z_maxCntRst'
* '<S63>/z_maxCntRst'
* '<S29>/z_maxCntRst'
* '<S69>/z_maxCntRst'
*/
uint8_T z_ctrlTypSel; /* Variable: z_ctrlTypSel
* Referenced by:
* '<S12>/z_ctrlTypSel1'
* '<S52>/z_ctrlTypSel1'
*/
uint8_T z_nrEdgeSpdAcv; /* Variable: z_nrEdgeSpdAcv
* Referenced by:
* '<S23>/z_nrEdgeSpdAcv'
* '<S63>/z_nrEdgeSpdAcv'
*/
boolean_T b_phaAdvEna; /* Variable: b_phaAdvEna
* Referenced by:
* '<S13>/a_elecPeriod1'
* '<S53>/a_elecPeriod1'
*/
};
/* Parameters (auto storage) */
typedef struct P_ P;
/* Block parameters (auto storage) */
extern P rtP;
/* Block signals and states (auto storage) */
extern DW rtDW;
/* External inputs (root inport signals with auto storage) */
extern ExtU rtU;
/* External outputs (root outports fed by signals with auto storage) */
extern ExtY rtY;
/* Constant parameters (auto storage) */
extern const ConstP rtConstP;
/* Model entry point functions */
extern void BLDC_controller_initialize(void);
extern void BLDC_controller_step(void);
/*-
* These blocks were eliminated from the model due to optimizations:
*
* Block '<S23>/Scope2' : Unused code path elimination
* Block '<S13>/Scope' : Unused code path elimination
* Block '<S63>/Scope2' : Unused code path elimination
* Block '<S53>/Scope' : Unused code path elimination
*/
/*-
* The generated code includes comments that allow you to trace directly
* back to the appropriate location in the model. The basic format
* is <system>/block_name, where system is the system number (uniquely
* assigned by Simulink) and block_name is the name of the block.
*
* Note that this particular code originates from a subsystem build,
* and has its own system numbers different from the parent model.
* Refer to the system hierarchy for this subsystem below, and use the
* MATLAB hilite_system command to trace the generated code back
* to the parent model. For example,
*
* hilite_system('BLDCmotorControl_R2017b/BLDC_controller') - opens subsystem BLDCmotorControl_R2017b/BLDC_controller
* hilite_system('BLDCmotorControl_R2017b/BLDC_controller/Kp') - opens and selects block Kp
*
* Here is the system hierarchy for this model
*
* '<Root>' : 'BLDCmotorControl_R2017b'
* '<S1>' : 'BLDCmotorControl_R2017b/BLDC_controller'
* '<S2>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left'
* '<S3>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right'
* '<S4>' : 'BLDCmotorControl_R2017b/BLDC_controller/signal_log1'
* '<S5>' : 'BLDCmotorControl_R2017b/BLDC_controller/signal_log2'
* '<S6>' : 'BLDCmotorControl_R2017b/BLDC_controller/signal_log3'
* '<S7>' : 'BLDCmotorControl_R2017b/BLDC_controller/signal_log4'
* '<S8>' : 'BLDCmotorControl_R2017b/BLDC_controller/signal_log5'
* '<S9>' : 'BLDCmotorControl_R2017b/BLDC_controller/signal_log6'
* '<S10>' : 'BLDCmotorControl_R2017b/BLDC_controller/signal_log7'
* '<S11>' : 'BLDCmotorControl_R2017b/BLDC_controller/signal_log8'
* '<S12>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations'
* '<S13>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F02_Electrical_Angle_Calculation'
* '<S14>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F03_Control_Method_Selection'
* '<S15>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F04_Control_Type_Management'
* '<S16>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/signal_log1'
* '<S17>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/signal_log2'
* '<S18>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/signal_log3'
* '<S19>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/signal_log6'
* '<S20>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_01_Edge_Detector'
* '<S21>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_02_Position_Calculation'
* '<S22>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_03_Direction_Detection'
* '<S23>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation'
* '<S24>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_01_Edge_Detector/signal_log6'
* '<S25>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_02_Position_Calculation/signal_log6'
* '<S26>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_03_Direction_Detection/signal_log6'
* '<S27>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/Edge_counter'
* '<S28>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/Moving_Average_Filter'
* '<S29>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/Raw_ Speed_calculation'
* '<S30>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/S-R Flip-Flop'
* '<S31>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/rising_edge'
* '<S32>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/rst_Delay'
* '<S33>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/signal_log1'
* '<S34>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/signal_log2'
* '<S35>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/signal_log3'
* '<S36>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/signal_log4'
* '<S37>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/signal_log6'
* '<S38>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/Edge_counter/rst_Delay'
* '<S39>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F02_Electrical_Angle_Calculation/Modulo_Calculation'
* '<S40>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F02_Electrical_Angle_Calculation/signal_log1'
* '<S41>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F02_Electrical_Angle_Calculation/signal_log2'
* '<S42>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F02_Electrical_Angle_Calculation/signal_log6'
* '<S43>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F03_Control_Method_Selection/F03_01_Pure_Trapezoidal_Method'
* '<S44>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F03_Control_Method_Selection/F03_02_Sinusoidal3rd_Method'
* '<S45>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F03_Control_Method_Selection/F03_02_Sinusoidal_Method'
* '<S46>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F03_Control_Method_Selection/signal_log1'
* '<S47>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F03_Control_Method_Selection/signal_log2'
* '<S48>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F03_Control_Method_Selection/signal_log6'
* '<S49>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F04_Control_Type_Management/signal_log1'
* '<S50>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F04_Control_Type_Management/signal_log2'
* '<S51>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F04_Control_Type_Management/signal_log6'
* '<S52>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations'
* '<S53>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F02_Electrical_Angle_Calculation'
* '<S54>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F03_Control_Method_Selection'
* '<S55>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F04_Control_Type_Management'
* '<S56>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/signal_log1'
* '<S57>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/signal_log2'
* '<S58>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/signal_log3'
* '<S59>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/signal_log6'
* '<S60>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_01_Edge_Detector'
* '<S61>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_02_Position_Calculation'
* '<S62>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_03_Direction_Detection'
* '<S63>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation'
* '<S64>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_01_Edge_Detector/signal_log6'
* '<S65>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_02_Position_Calculation/signal_log6'
* '<S66>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_03_Direction_Detection/signal_log6'
* '<S67>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/Edge_counter'
* '<S68>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/Moving_Average_Filter'
* '<S69>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/Raw_ Speed_calculation'
* '<S70>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/S-R Flip-Flop'
* '<S71>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/rising_edge'
* '<S72>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/rst_Delay'
* '<S73>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/signal_log1'
* '<S74>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/signal_log2'
* '<S75>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/signal_log3'
* '<S76>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/signal_log4'
* '<S77>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/signal_log6'
* '<S78>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/Edge_counter/rst_Delay'
* '<S79>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F02_Electrical_Angle_Calculation/Modulo_Calculation'
* '<S80>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F02_Electrical_Angle_Calculation/signal_log1'
* '<S81>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F02_Electrical_Angle_Calculation/signal_log2'
* '<S82>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F02_Electrical_Angle_Calculation/signal_log6'
* '<S83>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F03_Control_Method_Selection/F03_01_Pure_Trapezoidal_Method'
* '<S84>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F03_Control_Method_Selection/F03_02_Sinusoidal3rd_Method'
* '<S85>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F03_Control_Method_Selection/F03_02_Sinusoidal_Method'
* '<S86>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F03_Control_Method_Selection/signal_log1'
* '<S87>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F03_Control_Method_Selection/signal_log2'
* '<S88>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F03_Control_Method_Selection/signal_log6'
* '<S89>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F04_Control_Type_Management/signal_log1'
* '<S90>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F04_Control_Type_Management/signal_log2'
* '<S91>' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F04_Control_Type_Management/signal_log6'
*/
#endif /* RTW_HEADER_BLDC_controller_h_ */
/*
* File trailer for generated code.
*
* [EOF]
*/

View File

@ -6,16 +6,16 @@
#define PWM_FREQ 16000 // PWM frequency in Hz
#define DEAD_TIME 32 // PWM deadtime
#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.
#define TIMEOUT 5 // number of wrong / missing input commands before emergency off
#define TIMEOUT 5 // number of wrong / missing input commands before emergency off
// ############################### GENERAL ###############################
// 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_REAL_VOLTAGE 43.0 // input voltage measured by multimeter
#define BAT_CALIB_ADC 1704 // adc-value measured by mainboard (value nr 5 on UART debug output)
#define BAT_NUMBER_OF_CELLS 10 // normal Hoverboard battery: 10s
@ -64,16 +64,35 @@
// ###### 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!). 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 CONTROL_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)
#define CONTROL_ADC // use ADC as input. disable CONTROL_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. use original nunchuck. most clones does not work very well.
//#define CONTROL_NUNCHUCK // use nunchuck as input. disable DEBUG_SERIAL_USART3!
// ############################### MOTOR CONTROL (overwrite) #########################
#define CTRL_TYP_SEL 3 // [-] Control method selection: 0 = Commutation , 1 = Pure Trapezoidal , 2 = Sinusoidal, 3 = Sinusoidal 3rd armonic (default)
#define PHASE_ADV_ENA 1 // [-] Phase advance enable parameter: 0 = disabled, 1 = enabled (default)
#define COMM_DEACV_HI 180 // [rpm] Commutation method deactivation speed high (above this value the control switches from Commutation method to Selected method above)
#define COMM_ACV_LO 100 // [rpm] Commutation method activation speed low
// GENERAL NOTES:
// 1. All the available motor parameters can be found in the BLDC_controller_data.c
// 2. For more details regarding the parameters and the working principle of the controller please consult the Simulink model
// 3. A webview was created, so Matlab/Simulink installation is not needed, unless you want to regenerate the code
// NOTES Phase Advance / Field weakening:
// 1. In BLDC_controller_data.c you can find the Phase advance Map as a function of Duty Cycle: MAP = a_phaAdv_M1, XAXIS = r_phaAdvDC_XA
// 2. The default calibration was experimentaly obtained on the real motor based on the minimum noise and minimum torque ripple
// 3. If you re-calibrate the Phase advance map please take all the safety measures!
// 4. I do not recommend more than 40 deg MAX Phase advance. The motors can spin VERY VERY FAST!!! Please use it with care!!
// ############################### DRIVING BEHAVIOR ###############################
// inputs:
@ -82,23 +101,13 @@
// - adc_buffer.l_tx2 and adc_buffer.l_rx2: unfiltered ADC values (you do not need them). 0 to 4095
// outputs:
// - speedR and speedL: normal driving -1000 to 1000
// - weakr and weakl: field weakening for extra boost at high speed (speedR > 700 and speedL > 700). 0 to ~400
#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 SPEED_COEFFICIENT 1.0 //0.5 // higher value == stronger. 0.0 to ~2.0?
#define STEER_COEFFICIENT 0.5//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 BEEPS_BACKWARD 1 // 0 or 1
//Turbo boost at high speeds while button1 is pressed:
//#define ADDITIONAL_CODE \
if (button1 && speedR > 700) { /* field weakening at high speeds */ \
weakl = cmd1 - 700; /* weak should never exceed 400 or 450 MAX!! */ \
weakr = cmd1 - 700; } \
else { \
weakl = 0; \
weakr = 0; }
#define BEEPS_BACKWARD 0 // 0 or 1
// ###### SIMPLE BOBBYCAR ######
// for better bobbycar code see: https://github.com/larsmm/hoverboard-firmware-hack-bbcar
@ -106,30 +115,10 @@ else { \
// #define SPEED_COEFFICIENT -1
// #define STEER_COEFFICIENT 0
// #define ADDITIONAL_CODE \
if (button1 && speedR < 300) { /* drive backwards */ \
speedR = speedR * -0.2f; \
speedL = speedL * -0.2f; } \
else { \
direction = 1; } \
if (button1 && speedR > 700) { /* field weakening at high speeds */ \
weakl = speedR - 600; /* weak should never exceed 400 or 450 MAX!! */ \
weakr = speedR - 600; } \
else { \
weakl = 0; \
weakr = 0; }
// ###### ARMCHAIR ######
// #define FILTER 0.05
// #define SPEED_COEFFICIENT 0.5
// #define STEER_COEFFICIENT -0.2
// #define ADDITIONAL_CODE if (button1 && scale > 0.8) { /* field weakening at high speeds */ \
weakl = speedL - 600; /* weak should never exceed 400 or 450 MAX!! */ \
weakr = speedR - 600; } \
else {\
weakl = 0;\
weakr = 0;
// #define STEER_COEFFICIENT -0.2
// ############################### VALIDATE SETTINGS ###############################

116
Inc/ert_main.c Normal file
View File

@ -0,0 +1,116 @@
/*
* Academic License - for use in teaching, academic research, and meeting
* course requirements at degree granting institutions only. Not for
* government, commercial, or other organizational use.
*
* File: ert_main.c
*
* Code generated for Simulink model 'BLDC_controller'.
*
* Model version : 1.790
* Simulink Coder version : 8.13 (R2017b) 24-Jul-2017
* C/C++ source code generated on : Wed May 22 23:49:19 2019
*
* Target selection: ert.tlc
* Embedded hardware selection: ARM Compatible->ARM Cortex
* Emulation hardware selection:
* Differs from embedded hardware (MATLAB Host)
* Code generation objectives:
* 1. Execution efficiency
* 2. RAM efficiency
* Validation result: Not run
*/
#include <stddef.h>
#include <stdio.h> /* This ert_main.c example uses printf/fflush */
#include "BLDC_controller.h" /* Model's header file */
#include "rtwtypes.h"
#include "zero_crossing_types.h"
/*
* Associating rt_OneStep with a real-time clock or interrupt service routine
* is what makes the generated code "real-time". The function rt_OneStep is
* always associated with the base rate of the model. Subrates are managed
* by the base rate from inside the generated code. Enabling/disabling
* interrupts and floating point context switches are target specific. This
* example code indicates where these should take place relative to executing
* the generated code step function. Overrun behavior should be tailored to
* your application needs. This example simply sets an error status in the
* real-time model and returns from rt_OneStep.
*/
void rt_OneStep(void);
void rt_OneStep(void)
{
static boolean_T OverrunFlag = false;
/* Disable interrupts here */
/* Check for overrun */
if (OverrunFlag) {
return;
}
OverrunFlag = true;
/* Save FPU context here (if necessary) */
/* Re-enable timer or interrupt here */
/* Set model inputs here */
/* Step the model */
BLDC_controller_step();
/* Get model outputs here */
/* Indicate task complete */
OverrunFlag = false;
/* Disable interrupts here */
/* Restore FPU context here (if necessary) */
/* Enable interrupts here */
}
/*
* The example "main" function illustrates what is required by your
* application code to initialize, execute, and terminate the generated code.
* Attaching rt_OneStep to a real-time clock is target specific. This example
* illustrates how you do this relative to initializing the model.
*/
int_T main(int_T argc, const char *argv[])
{
/* Unused arguments */
(void)(argc);
(void)(argv);
/* Initialize model */
BLDC_controller_initialize();
/* Attach rt_OneStep to a timer or interrupt service routine with
* period 1.0E-5 seconds (the model's base sample time) here. The
* call syntax for rt_OneStep is
*
* rt_OneStep();
*/
printf("Warning: The simulation will run forever. "
"Generated ERT main won't simulate model step behavior. "
"To change this behavior select the 'MAT-file logging' option.\n");
fflush((NULL));
while (1) {
/* Perform other application tasks here */
}
/* The option 'Remove error status field in real-time model data structure'
* is selected, therefore the following code does not need to execute.
*/
#if 0
/* Disable rt_OneStep() here */
#endif
return 0;
}
/*
* File trailer for generated code.
*
* [EOF]
*/

108
Inc/rtwtypes.h Normal file
View File

@ -0,0 +1,108 @@
/*
* Academic License - for use in teaching, academic research, and meeting
* course requirements at degree granting institutions only. Not for
* government, commercial, or other organizational use.
*
* File: rtwtypes.h
*
* Code generated for Simulink model 'BLDC_controller'.
*
* Model version : 1.800
* Simulink Coder version : 8.13 (R2017b) 24-Jul-2017
* C/C++ source code generated on : Sat May 25 21:42:39 2019
*
* Target selection: ert.tlc
* Embedded hardware selection: ARM Compatible->ARM Cortex
* Emulation hardware selection:
* Differs from embedded hardware (MATLAB Host)
* Code generation objectives:
* 1. Execution efficiency
* 2. RAM efficiency
* Validation result: Not run
*/
#ifndef RTWTYPES_H
#define RTWTYPES_H
/* Logical type definitions */
#if (!defined(__cplusplus))
# ifndef false
# define false (0U)
# endif
# ifndef true
# define true (1U)
# endif
#endif
/*=======================================================================*
* Target hardware information
* Device type: MATLAB Host
* Number of bits: char: 8 short: 16 int: 32
* long: 32 long long: 64
* native word size: 64
* Byte ordering: LittleEndian
* Signed integer division rounds to: Zero
* Shift right on a signed integer as arithmetic shift: on
*=======================================================================*/
/*=======================================================================*
* Fixed width word size data types: *
* int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers *
* uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers *
* real32_T, real64_T - 32 and 64 bit floating point numbers *
*=======================================================================*/
typedef signed char int8_T;
typedef unsigned char uint8_T;
typedef short int16_T;
typedef unsigned short uint16_T;
typedef int int32_T;
typedef unsigned int uint32_T;
typedef long long int64_T;
typedef unsigned long long uint64_T;
typedef float real32_T;
typedef double real64_T;
/*===========================================================================*
* Generic type definitions: boolean_T, char_T, byte_T, int_T, uint_T, *
* real_T, time_T, ulong_T, ulonglong_T. *
*===========================================================================*/
typedef double real_T;
typedef double time_T;
typedef unsigned char boolean_T;
typedef int int_T;
typedef unsigned int uint_T;
typedef unsigned long ulong_T;
typedef unsigned long long ulonglong_T;
typedef char char_T;
typedef unsigned char uchar_T;
typedef char_T byte_T;
/*=======================================================================*
* Min and Max: *
* int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers *
* uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers *
*=======================================================================*/
#define MAX_int8_T ((int8_T)(127))
#define MIN_int8_T ((int8_T)(-128))
#define MAX_uint8_T ((uint8_T)(255U))
#define MAX_int16_T ((int16_T)(32767))
#define MIN_int16_T ((int16_T)(-32768))
#define MAX_uint16_T ((uint16_T)(65535U))
#define MAX_int32_T ((int32_T)(2147483647))
#define MIN_int32_T ((int32_T)(-2147483647-1))
#define MAX_uint32_T ((uint32_T)(0xFFFFFFFFU))
#define MAX_int64_T ((int64_T)(9223372036854775807LL))
#define MIN_int64_T ((int64_T)(-9223372036854775807LL-1LL))
#define MAX_uint64_T ((uint64_T)(0xFFFFFFFFFFFFFFFFULL))
/* Block D-Work pointer type */
typedef void * pointer_T;
#endif /* RTWTYPES_H */
/*
* File trailer for generated code.
*
* [EOF]
*/

57
Inc/zero_crossing_types.h Normal file
View File

@ -0,0 +1,57 @@
/*
* Academic License - for use in teaching, academic research, and meeting
* course requirements at degree granting institutions only. Not for
* government, commercial, or other organizational use.
*
* File: zero_crossing_types.h
*
* Code generated for Simulink model 'BLDC_controller'.
*
* Model version : 1.800
* Simulink Coder version : 8.13 (R2017b) 24-Jul-2017
* C/C++ source code generated on : Sat May 25 21:42:39 2019
*
* Target selection: ert.tlc
* Embedded hardware selection: ARM Compatible->ARM Cortex
* Emulation hardware selection:
* Differs from embedded hardware (MATLAB Host)
* Code generation objectives:
* 1. Execution efficiency
* 2. RAM efficiency
* Validation result: Not run
*/
#ifndef ZERO_CROSSING_TYPES_H
#define ZERO_CROSSING_TYPES_H
#include "rtwtypes.h"
/* Trigger directions: falling, either, and rising */
typedef enum {
FALLING_ZERO_CROSSING = -1,
ANY_ZERO_CROSSING = 0,
RISING_ZERO_CROSSING = 1
} ZCDirection;
/* Previous state of a trigger signal */
typedef uint8_T ZCSigState;
/* Initial value of a trigger zero crossing signal */
#define UNINITIALIZED_ZCSIG 0x03U
#define NEG_ZCSIG 0x02U
#define POS_ZCSIG 0x01U
#define ZERO_ZCSIG 0x00U
/* Current state of a trigger signal */
typedef enum {
FALLING_ZCEVENT = -1,
NO_ZCEVENT = 0,
RISING_ZCEVENT = 1
} ZCEventType;
#endif /* ZERO_CROSSING_TYPES_H */
/*
* File trailer for generated code.
*
* [EOF]
*/

1313
Src/BLDC_controller.c Normal file

File diff suppressed because it is too large Load Diff

212
Src/BLDC_controller_data.c Normal file
View File

@ -0,0 +1,212 @@
/*
* Academic License - for use in teaching, academic research, and meeting
* course requirements at degree granting institutions only. Not for
* government, commercial, or other organizational use.
*
* File: BLDC_controller_data.c
*
* Code generated for Simulink model 'BLDC_controller'.
*
* Model version : 1.800
* Simulink Coder version : 8.13 (R2017b) 24-Jul-2017
* C/C++ source code generated on : Sat May 25 21:42:39 2019
*
* Target selection: ert.tlc
* Embedded hardware selection: ARM Compatible->ARM Cortex
* Emulation hardware selection:
* Differs from embedded hardware (MATLAB Host)
* Code generation objectives:
* 1. Execution efficiency
* 2. RAM efficiency
* Validation result: Not run
*/
#include "BLDC_controller.h"
/* Block parameters (auto storage) */
P rtP = {
/* Variable: cf_spdCoef
* Referenced by:
* '<S29>/cf_spdCoef'
* '<S69>/cf_spdCoef'
*/
66667,
/* Variable: n_commAcvLo
* Referenced by:
* '<S15>/Relay'
* '<S55>/Relay'
*/
100,
/* Variable: n_commDeacvHi
* Referenced by:
* '<S15>/Relay'
* '<S55>/Relay'
*/
180,
/* Variable: n_thresSpdDeacv
* Referenced by:
* '<S23>/n_thresSpdDeacv'
* '<S63>/n_thresSpdDeacv'
*/
5,
/* Variable: r_commDCDeacv
* Referenced by:
* '<S15>/r_commDCDeacv'
* '<S55>/r_commDCDeacv'
*/
70,
/* Variable: r_phaAdvDC_XA
* Referenced by:
* '<S13>/r_phaAdvDC_XA'
* '<S53>/r_phaAdvDC_XA'
*/
{ 0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 },
/* Variable: a_phaAdv_M1
* Referenced by:
* '<S13>/a_phaAdv_M2'
* '<S53>/a_phaAdv_M2'
*/
{ 0, 0, 7, 2, 2, 2, 4, 5, 9, 16, 25 },
/* Variable: z_maxCntRst
* Referenced by:
* '<S23>/z_maxCntRst'
* '<S63>/z_maxCntRst'
* '<S29>/z_maxCntRst'
* '<S69>/z_maxCntRst'
*/
2000,
/* Variable: z_ctrlTypSel
* Referenced by:
* '<S12>/z_ctrlTypSel1'
* '<S52>/z_ctrlTypSel1'
*/
3U,
/* Variable: z_nrEdgeSpdAcv
* Referenced by:
* '<S23>/z_nrEdgeSpdAcv'
* '<S63>/z_nrEdgeSpdAcv'
*/
5U,
/* Variable: b_phaAdvEna
* Referenced by:
* '<S13>/a_elecPeriod1'
* '<S53>/a_elecPeriod1'
*/
1
};
/* Constant parameters (auto storage) */
const ConstP rtConstP = {
/* Pooled Parameter (Expression: r_trapPhaA_M1)
* Referenced by:
* '<S43>/r_trapPhaA_M1'
* '<S83>/r_trapPhaA_M1'
*/
{ 1000, 1000, 1000, -1000, -1000, -1000, 1000 },
/* Pooled Parameter (Expression: r_trapPhaB_M1)
* Referenced by:
* '<S43>/r_trapPhaB_M1'
* '<S83>/r_trapPhaB_M1'
*/
{ -1000, -1000, 1000, 1000, 1000, -1000, -1000 },
/* Pooled Parameter (Expression: r_trapPhaC_M1)
* Referenced by:
* '<S43>/r_trapPhaC_M1'
* '<S83>/r_trapPhaC_M1'
*/
{ 1000, -1000, -1000, -1000, 1000, 1000, 1000 },
/* Pooled Parameter (Expression: r_sinPhaA_M1)
* Referenced by:
* '<S45>/r_sinPhaA_M1'
* '<S85>/r_sinPhaA_M1'
*/
{ 500, 643, 766, 866, 940, 985, 1000, 985, 940, 866, 766, 643, 500, 342, 174,
0, -174, -342, -500, -643, -766, -866, -940, -985, -1000, -985, -940, -866,
-766, -643, -500, -342, -174, 0, 174, 342, 500 },
/* Pooled Parameter (Expression: r_sinPhaB_M1)
* Referenced by:
* '<S45>/r_sinPhaB_M1'
* '<S85>/r_sinPhaB_M1'
*/
{ -1000, -985, -940, -866, -766, -643, -500, -342, -174, 0, 174, 342, 500, 643,
766, 866, 940, 985, 1000, 985, 940, 866, 766, 643, 500, 342, 174, 0, -174,
-342, -500, -643, -766, -866, -940, -985, -1000 },
/* Pooled Parameter (Expression: r_sinPhaC_M1)
* Referenced by:
* '<S45>/r_sinPhaC_M1'
* '<S85>/r_sinPhaC_M1'
*/
{ 500, 342, 174, 0, -174, -342, -500, -643, -766, -866, -940, -985, -1000,
-985, -940, -866, -766, -643, -500, -342, -174, 0, 174, 342, 500, 643, 766,
866, 940, 985, 1000, 985, 940, 866, 766, 643, 500 },
/* Pooled Parameter (Expression: r_sin3PhaA_M1)
* Referenced by:
* '<S44>/r_sin3PhaA_M1'
* '<S84>/r_sin3PhaA_M1'
*/
{ 795, 930, 991, 996, 971, 942, 930, 942, 971, 996, 991, 930, 795, 584, 310, 0,
-310, -584, -795, -930, -991, -996, -971, -942, -930, -942, -971, -996, -991,
-930, -795, -584, -310, 0, 310, 584, 795 },
/* Pooled Parameter (Expression: r_sin3PhaB_M1)
* Referenced by:
* '<S44>/r_sin3PhaB_M1'
* '<S84>/r_sin3PhaB_M1'
*/
{ -930, -942, -971, -996, -991, -930, -795, -584, -310, 0, 310, 584, 795, 930,
991, 996, 971, 942, 930, 942, 971, 996, 991, 930, 795, 584, 310, 0, -310,
-584, -795, -930, -991, -996, -971, -942, -930 },
/* Pooled Parameter (Expression: r_sin3PhaC_M1)
* Referenced by:
* '<S44>/r_sin3PhaC_M1'
* '<S84>/r_sin3PhaC_M1'
*/
{ 795, 584, 310, 0, -310, -584, -795, -930, -991, -996, -971, -942, -930, -942,
-971, -996, -991, -930, -795, -584, -310, 0, 310, 584, 795, 930, 991, 996,
971, 942, 930, 942, 971, 996, 991, 930, 795 },
/* Pooled Parameter (Expression: z_commutMap_M1)
* Referenced by:
* '<S15>/z_commutMap_M1'
* '<S55>/z_commutMap_M1'
*/
{ 1000, -1000, 0, 1000, 0, -1000, 0, 1000, -1000, -1000, 1000, 0, -1000, 0,
1000, 0, -1000, 1000 },
/* Pooled Parameter (Expression: vec_hallToPos)
* Referenced by:
* '<S21>/vec_hallToPos'
* '<S61>/vec_hallToPos'
*/
{ 0U, 5U, 3U, 4U, 1U, 0U, 2U, 0U },
/* Pooled Parameter (Expression: [0 1;1 0;0 1;0 1;1 0;1 0;0 0;0 0])
* Referenced by:
* '<S30>/Logic'
* '<S70>/Logic'
*/
{ 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0 }
};
/*
* File trailer for generated code.
*
* [EOF]
*/

View File

@ -1,16 +1,38 @@
/*
* 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 <aerdronix@gmail.com>
*
* 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
#include "BLDC_controller.h" /* Model's header file */
#include "rtwtypes.h"
volatile int posl = 0;
volatile int posr = 0;
volatile int pwml = 0;
volatile int pwmr = 0;
volatile int weakl = 0;
volatile int weakr = 0;
extern volatile int speed;
@ -18,110 +40,13 @@ extern volatile adc_buf_t adc_buffer;
extern volatile uint32_t timeout;
uint32_t buzzerFreq = 0;
uint32_t buzzerPattern = 0;
uint32_t buzzerFreq = 0;
uint32_t buzzerPattern = 0;
uint32_t buzzerTimer = 0;
uint8_t enable = 0;
uint8_t enable = 0;
const int pwm_res = 64000000 / 2 / PWM_FREQ; // = 2000
const uint8_t hall_to_pos[8] = {
0,
0,
2,
1,
4,
5,
3,
0,
};
inline void blockPWM(int pwm, int pos, int *u, int *v, int *w) {
switch(pos) {
case 0:
*u = 0;
*v = pwm;
*w = -pwm;
break;
case 1:
*u = -pwm;
*v = pwm;
*w = 0;
break;
case 2:
*u = -pwm;
*v = 0;
*w = pwm;
break;
case 3:
*u = 0;
*v = -pwm;
*w = pwm;
break;
case 4:
*u = pwm;
*v = -pwm;
*w = 0;
break;
case 5:
*u = pwm;
*v = 0;
*w = -pwm;
break;
default:
*u = 0;
*v = 0;
*w = 0;
}
}
inline void blockPhaseCurrent(int pos, int u, int v, int *q) {
switch(pos) {
case 0:
*q = u - v;
// *u = 0;
// *v = pwm;
// *w = -pwm;
break;
case 1:
*q = u;
// *u = -pwm;
// *v = pwm;
// *w = 0;
break;
case 2:
*q = u;
// *u = -pwm;
// *v = 0;
// *w = pwm;
break;
case 3:
*q = v;
// *u = 0;
// *v = -pwm;
// *w = pwm;
break;
case 4:
*q = v;
// *u = pwm;
// *v = -pwm;
// *w = 0;
break;
case 5:
*q = -(u - v);
// *u = pwm;
// *v = 0;
// *w = -pwm;
break;
default:
*q = 0;
// *u = 0;
// *v = 0;
// *w = 0;
}
}
uint32_t buzzerTimer = 0;
const int pwm_res = 64000000 / 2 / PWM_FREQ; // = 2000
int offsetcount = 0;
int offsetrl1 = 2000;
@ -133,20 +58,11 @@ int offsetdcr = 2000;
float batteryVoltage = BAT_NUMBER_OF_CELLS * 4.0;
int curl = 0;
// int errorl = 0;
// int kp = 5;
// volatile int cmdl = 0;
int last_pos = 0;
int timer = 0;
const int max_time = PWM_FREQ / 10;
volatile int vel = 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() {
DMA1->IFCR = DMA_IFCR_CTCIF1;
// HAL_GPIO_WritePin(LED_PORT, LED_PIN, 1);
@ -180,61 +96,6 @@ void DMA1_Channel1_IRQHandler() {
RIGHT_TIM->BDTR |= TIM_BDTR_MOE;
}
int ul, vl, wl;
int ur, vr, wr;
//determine next position based on hall sensors
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);
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);
uint8_t halll = hall_ul * 1 + hall_vl * 2 + hall_wl * 4;
posl = hall_to_pos[halll];
posl += 2;
posl %= 6;
uint8_t hallr = hall_ur * 1 + hall_vr * 2 + hall_wr * 4;
posr = hall_to_pos[hallr];
posr += 2;
posr %= 6;
blockPhaseCurrent(posl, adc_buffer.rl1 - offsetrl1, adc_buffer.rl2 - offsetrl2, &curl);
//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) {
@ -245,35 +106,64 @@ void DMA1_Channel1_IRQHandler() {
HAL_GPIO_WritePin(BUZZER_PORT, BUZZER_PIN, 0);
}
//update PWM channels based on position
blockPWM(pwml, posl, &ul, &vl, &wl);
blockPWM(pwmr, posr, &ur, &vr, &wr);
// ############################### MOTOR CONTROL ###############################
int ul, vl, wl;
int ur, vr, wr;
int weakul, weakvl, weakwl;
if (pwml > 0) {
blockPWM(weakl, (posl+5) % 6, &weakul, &weakvl, &weakwl);
} else {
blockPWM(-weakl, (posl+1) % 6, &weakul, &weakvl, &weakwl);
// 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);
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);
static boolean_T OverrunFlag = false;
/* Check for overrun */
if (OverrunFlag) {
return;
}
ul += weakul;
vl += weakvl;
wl += weakwl;
OverrunFlag = true;
/* Set motor inputs here */
rtU.b_hallALeft = hall_ul;
rtU.b_hallBLeft = hall_vl;
rtU.b_hallCLeft = hall_wl;
rtU.r_DCLeft = pwml;
int weakur, weakvr, weakwr;
if (pwmr > 0) {
blockPWM(weakr, (posr+5) % 6, &weakur, &weakvr, &weakwr);
} else {
blockPWM(-weakr, (posr+1) % 6, &weakur, &weakvr, &weakwr);
}
ur += weakur;
vr += weakvr;
wr += weakwr;
rtU.b_hallARight = hall_ur;
rtU.b_hallBRight = hall_vr;
rtU.b_hallCRight = hall_wr;
rtU.r_DCRight = pwmr;
/* Step the controller */
BLDC_controller_step();
/* Get motor outputs here */
ul = rtY.DC_phaALeft;
vl = rtY.DC_phaBLeft;
wl = rtY.DC_phaCLeft;
// motSpeedLeft = rtY.n_motLeft;
// motAngleLeft = rtY.a_elecAngleLeft;
ur = rtY.DC_phaARight;
vr = rtY.DC_phaBRight;
wr = rtY.DC_phaCRight;
// motSpeedRight = rtY.n_motRight;
// motAngleRight = rtY.a_elecAngleRight;
/* Indicate task complete */
OverrunFlag = false;
// ###############################################################################
LEFT_TIM->LEFT_TIM_U = CLAMP(ul + pwm_res / 2, 10, pwm_res-10);
LEFT_TIM->LEFT_TIM_V = CLAMP(vl + pwm_res / 2, 10, pwm_res-10);
LEFT_TIM->LEFT_TIM_W = CLAMP(wl + pwm_res / 2, 10, pwm_res-10);
RIGHT_TIM->RIGHT_TIM_U = CLAMP(ur + pwm_res / 2, 10, pwm_res-10);
RIGHT_TIM->RIGHT_TIM_V = CLAMP(vr + pwm_res / 2, 10, pwm_res-10);
RIGHT_TIM->RIGHT_TIM_W = CLAMP(wr + pwm_res / 2, 10, pwm_res-10);
LEFT_TIM->LEFT_TIM_U = CLAMP(ul + pwm_res / 2, 10, pwm_res-10);
LEFT_TIM->LEFT_TIM_V = CLAMP(vl + pwm_res / 2, 10, pwm_res-10);
LEFT_TIM->LEFT_TIM_W = CLAMP(wl + pwm_res / 2, 10, pwm_res-10);
RIGHT_TIM->RIGHT_TIM_U = CLAMP(ur + pwm_res / 2, 10, pwm_res-10);
RIGHT_TIM->RIGHT_TIM_V = CLAMP(vr + pwm_res / 2, 10, pwm_res-10);
RIGHT_TIM->RIGHT_TIM_W = CLAMP(wr + pwm_res / 2, 10, pwm_res-10);
}

View File

@ -23,8 +23,13 @@
#include "defines.h"
#include "setup.h"
#include "config.h"
#include <stdlib.h>
//#include "hd44780.h"
// Matlab includes - from auto-code generation
#include "BLDC_controller.h" /* Model's header file */
#include "rtwtypes.h"
void SystemClock_Config(void);
extern TIM_HandleTypeDef htim_left;
@ -38,7 +43,6 @@ extern UART_HandleTypeDef huart2;
int cmd1; // normalized input values. -1000 to 1000
int cmd2;
int cmd3;
typedef struct{
int16_t steer;
@ -55,8 +59,6 @@ int speed; // global variable for speed. -1000 to 1000
extern volatile int pwml; // global variable for pwm left. -1000 to 1000
extern volatile int pwmr; // global variable for pwm right. -1000 to 1000
extern volatile int weakl; // global variable for field weakening left. -1000 to 1000
extern volatile int weakr; // global variable for field weakening right. -1000 to 1000
extern uint8_t buzzerFreq; // global variable for the buzzer pitch. can be 1, 2, 3, 4, 5, 6, 7...
extern uint8_t buzzerPattern; // global variable for the buzzer pattern. can be 1, 2, 3, 4, 5, 6, 7...
@ -77,7 +79,7 @@ int milli_vel_error_sum = 0;
void poweroff() {
if (abs(speed) < 20) {
// if (abs(speed) < 20) { // wait for the speed to drop, then shut down -> this is commented out for SAFETY reasons
buzzerPattern = 0;
enable = 0;
for (int i = 0; i < 8; i++) {
@ -86,11 +88,12 @@ void poweroff() {
}
HAL_GPIO_WritePin(OFF_PORT, OFF_PIN, 0);
while(1) {}
}
// }
}
int main(void) {
HAL_Init();
__HAL_RCC_AFIO_CLK_ENABLE();
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
@ -127,6 +130,19 @@ int main(void) {
HAL_ADC_Start(&hadc1);
HAL_ADC_Start(&hadc2);
//////////////////////////////////////
/* Set BLDC controller parameters */
rtP.z_ctrlTypSel = CTRL_TYP_SEL;
rtP.b_phaAdvEna = PHASE_ADV_ENA;
rtP.n_commDeacvHi = COMM_DEACV_HI;
rtP.n_commAcvLo = COMM_ACV_LO;
/* Initialize BLDC controller */
BLDC_controller_initialize();
/////////////////////////////////////
for (int i = 8; i >= 0; i--) {
buzzerFreq = i;
HAL_Delay(100);
@ -137,7 +153,6 @@ int main(void) {
int lastSpeedL = 0, lastSpeedR = 0;
int speedL = 0, speedR = 0;
float direction = 1;
#ifdef CONTROL_PPM
PPM_Init();
@ -180,6 +195,7 @@ int main(void) {
enable = 1; // enable motors
while(1) {
HAL_Delay(DELAY_IN_MAIN_LOOP); //delay in ms
@ -201,8 +217,8 @@ int main(void) {
#ifdef CONTROL_ADC
// ADC values range: 0-4095, see ADC-calibration in config.h
cmd1 = CLAMP(adc_buffer.l_tx2 - ADC1_MIN, 0, ADC1_MAX) / (ADC1_MAX / 1000.0f); // ADC1
cmd2 = CLAMP(adc_buffer.l_rx2 - ADC2_MIN, 0, ADC2_MAX) / (ADC2_MAX / 1000.0f); // ADC2
cmd1 = CLAMP(adc_buffer.l_tx2 - ADC1_MIN, 0, ADC1_MAX) / (ADC1_MAX / 1000.0f); // ADC1
cmd2 = CLAMP(adc_buffer.l_rx2 - ADC2_MIN, 0, ADC2_MAX) / (ADC2_MAX / 1000.0f); // ADC2
// use ADCs as button inputs:
button1 = (uint8_t)(adc_buffer.l_tx2 > 2000); // ADC1
@ -218,7 +234,6 @@ int main(void) {
timeout = 0;
#endif
// ####### LOW-PASS FILTER #######
steer = steer * (1.0 - FILTER) + cmd1 * FILTER;
speed = speed * (1.0 - FILTER) + cmd2 * FILTER;
@ -234,7 +249,7 @@ int main(void) {
#endif
// ####### SET OUTPUTS #######
// ####### SET OUTPUTS (if the target change less than +/- 50) #######
if ((speedL < lastSpeedL + 50 && speedL > lastSpeedL - 50) && (speedR < lastSpeedR + 50 && speedR > lastSpeedR - 50) && timeout < TIMEOUT) {
#ifdef INVERT_R_DIRECTION
pwmr = speedR;
@ -256,24 +271,27 @@ int main(void) {
// ####### 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
// 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
setScopeChannel(0, (int)speedR); // 1: output command: [-1000, 1000]
setScopeChannel(1, (int)speedL); // 2: output command: [-1000, 1000]
setScopeChannel(2, (int)rtY.n_motRight); // 3: Real motor speed [rpm]
setScopeChannel(3, (int)rtY.n_motLeft); // 4: Real motor speed [rpm]
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();
}
// ####### POWEROFF BY POWER-BUTTON #######
if (HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN) && weakr == 0 && weakl == 0) {
if (HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN)) {
enable = 0;
while (HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN)) {}
poweroff();

File diff suppressed because it is too large Load Diff

22
platformio.ini Normal file
View File

@ -0,0 +1,22 @@
; PlatformIO Project Configuration File2
; http://docs.platformio.org/page/projectconf.html
[platformio]
include_dir = Inc
[env:genericSTM32F103RC]
platform = ststm32
framework = stm32cube
board = genericSTM32F103RC
debug_tool = stlink
upload_protocol = stlink
build_flags =
-I${PROJECT_DIR}/inc/
-DUSE_HAL_DRIVER
-DSTM32F103xE
-Wl,-T./STM32F103RCTx_FLASH.ld
-Wl,-lc
-Wl,-lm
-g -ggdb ; to generate correctly the 'firmware.elf' for STM STUDIO vizualization
# -Wl,-lnosys