Skip to content

Commit 640d850

Browse files
committed
FEAT d components added
1 parent 0e537c8 commit 640d850

File tree

8 files changed

+65
-70
lines changed

8 files changed

+65
-70
lines changed

keywords.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ angleOpenloop KEYWORD2
6262
velocityOpenloop KEYWORD2
6363

6464
voltage_q KEYWORD2
65+
voltage_d KEYWORD2
6566
shaft_angle_sp KEYWORD2
6667
shaft_velocity_sp KEYWORD2
6768
shaft_angle KEYWORD2

src/BLDCMotor.cpp

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ void BLDCMotor::linkDriver(BLDCDriver* _driver) {
3333
void BLDCMotor::init() {
3434
if(monitor_port) monitor_port->println("MOT: Initialise variables.");
3535
// sanity check for the voltage limit configuration
36-
if(voltage_limit > driver->voltage_power_supply) voltage_limit = driver->voltage_power_supply;
36+
if(voltage_limit > driver->voltage_limit) voltage_limit = driver->voltage_limit;
3737
// constrain voltage for sensor alignment
3838
if(voltage_sensor_align > voltage_limit) voltage_sensor_align = voltage_limit;
3939
// update the controller limits
@@ -98,13 +98,13 @@ int BLDCMotor::alignSensor() {
9898
float start_angle = shaftAngle();
9999
for (int i = 0; i <=5; i++ ) {
100100
float angle = _3PI_2 + _2PI * i / 6.0;
101-
setPhaseVoltage(voltage_sensor_align, angle);
101+
setPhaseVoltage(voltage_sensor_align, 0, angle);
102102
_delay(200);
103103
}
104104
float mid_angle = shaftAngle();
105105
for (int i = 5; i >=0; i-- ) {
106106
float angle = _3PI_2 + _2PI * i / 6.0;
107-
setPhaseVoltage(voltage_sensor_align, angle);
107+
setPhaseVoltage(voltage_sensor_align, 0, angle);
108108
_delay(200);
109109
}
110110
if (mid_angle < start_angle) {
@@ -119,7 +119,7 @@ int BLDCMotor::alignSensor() {
119119
// set sensor to zero
120120
sensor->initRelativeZero();
121121
_delay(500);
122-
setPhaseVoltage(0,0);
122+
setPhaseVoltage(0, 0, 0);
123123
_delay(200);
124124

125125
// find the index if available
@@ -151,7 +151,7 @@ int BLDCMotor::absoluteZeroAlign() {
151151
}
152152
voltage_q = 0;
153153
// disable motor
154-
setPhaseVoltage(0,0);
154+
setPhaseVoltage(0, 0, 0);
155155

156156
// align absolute zero if it has been found
157157
if(!sensor->needsAbsoluteZeroSearch()){
@@ -170,7 +170,7 @@ void BLDCMotor::loopFOC() {
170170
// shaft angle
171171
shaft_angle = shaftAngle();
172172
// set the phase voltage - FOC heart function :)
173-
setPhaseVoltage(voltage_q, _electricalAngle(shaft_angle,pole_pairs));
173+
setPhaseVoltage(voltage_q, voltage_d, _electricalAngle(shaft_angle,pole_pairs));
174174
}
175175

176176
// Iterative function running outer loop of the FOC algorithm
@@ -217,16 +217,17 @@ void BLDCMotor::move(float new_target) {
217217
}
218218

219219

220-
// Method using FOC to set Uq to the motor at the optimal angle
220+
// Method using FOC to set Uq and Ud to the motor at the optimal angle
221221
// Function implementing Space Vector PWM and Sine PWM algorithms
222222
//
223223
// Function using sine approximation
224224
// regular sin + cos ~300us (no memory usaage)
225225
// approx _sin + _cos ~110us (400Byte ~ 20% of memory)
226-
void BLDCMotor::setPhaseVoltage(float Uq, float angle_el) {
226+
void BLDCMotor::setPhaseVoltage(float Uq, float Ud, float angle_el) {
227227

228228
const bool centered = true;
229229
int sector;
230+
float _ca,_sa;
230231

231232
switch (foc_modulation)
232233
{
@@ -243,9 +244,9 @@ void BLDCMotor::setPhaseVoltage(float Uq, float angle_el) {
243244
Uc = Uq + trap_120_map[sector][2] * Uq;
244245

245246
if (centered) {
246-
Ua += (voltage_power_supply)/2 -Uq;
247-
Ub += (voltage_power_supply)/2 -Uq;
248-
Uc += (voltage_power_supply)/2 -Uq;
247+
Ua += (driver->voltage_limit)/2 -Uq;
248+
Ub += (driver->voltage_limit)/2 -Uq;
249+
Uc += (driver->voltage_limit)/2 -Uq;
249250
}
250251
break;
251252

@@ -263,9 +264,9 @@ void BLDCMotor::setPhaseVoltage(float Uq, float angle_el) {
263264

264265
//center
265266
if (centered) {
266-
Ua += (voltage_power_supply)/2 -Uq;
267-
Ub += (voltage_power_supply)/2 -Uq;
268-
Uc += (voltage_power_supply)/2 -Uq;
267+
Ua += (driver->voltage_limit)/2 -Uq;
268+
Ub += (driver->voltage_limit)/2 -Uq;
269+
Uc += (driver->voltage_limit)/2 -Uq;
269270
}
270271

271272
break;
@@ -277,20 +278,22 @@ void BLDCMotor::setPhaseVoltage(float Uq, float angle_el) {
277278
// angle normalization in between 0 and 2pi
278279
// only necessary if using _sin and _cos - approximation functions
279280
angle_el = _normalizeAngle(angle_el + zero_electric_angle);
281+
_ca = _cos(angle_el);
282+
_sa = _sin(angle_el);
280283
// Inverse park transform
281-
Ualpha = -_sin(angle_el) * Uq; // -sin(angle) * Uq;
282-
Ubeta = _cos(angle_el) * Uq; // cos(angle) * Uq;
284+
Ualpha = _ca * Ud - _sa * Uq; // -sin(angle) * Uq;
285+
Ubeta = _sa * Ud + _ca * Uq; // cos(angle) * Uq;
283286

284287
// Clarke transform
285-
Ua = Ualpha + driver->voltage_power_supply/2;
286-
Ub = -0.5 * Ualpha + _SQRT3_2 * Ubeta + driver->voltage_power_supply/2;
287-
Uc = -0.5 * Ualpha - _SQRT3_2 * Ubeta + driver->voltage_power_supply/2;
288+
Ua = Ualpha + driver->voltage_limit/2;
289+
Ub = -0.5 * Ualpha + _SQRT3_2 * Ubeta + driver->voltage_limit/2;
290+
Uc = -0.5 * Ualpha - _SQRT3_2 * Ubeta + driver->voltage_limit/2;
288291

289292
if (!centered) {
290293
float Umin = min(Ua, min(Ub, Uc));
291-
Ua -=Umin;
292-
Ub -=Umin;
293-
Uc -=Umin;
294+
Ua -= Umin;
295+
Ub -= Umin;
296+
Uc -= Umin;
294297
}
295298

296299
break;
@@ -311,12 +314,12 @@ void BLDCMotor::setPhaseVoltage(float Uq, float angle_el) {
311314
// find the sector we are in currently
312315
sector = floor(angle_el / _PI_3) + 1;
313316
// calculate the duty cycles
314-
float T1 = _SQRT3*_sin(sector*_PI_3 - angle_el) * Uq/driver->voltage_power_supply;
315-
float T2 = _SQRT3*_sin(angle_el - (sector-1.0)*_PI_3) * Uq/driver->voltage_power_supply;
317+
float T1 = _SQRT3*_sin(sector*_PI_3 - angle_el) * Uq/driver->voltage_limit;
318+
float T2 = _SQRT3*_sin(angle_el - (sector-1.0)*_PI_3) * Uq/driver->voltage_limit;
316319
// two versions possible
317320
float T0 = 0; // pulled to 0 - better for low power supply voltage
318321
if (centered) {
319-
T0 = 1 - T1 - T2; //centered around driver->voltage_power_supply/2
322+
T0 = 1 - T1 - T2; //centered around driver->voltage_limit/2
320323
}
321324

322325
// calculate the duty cycles(times)
@@ -360,9 +363,9 @@ void BLDCMotor::setPhaseVoltage(float Uq, float angle_el) {
360363
}
361364

362365
// calculate the phase voltages and center
363-
Ua = Ta*driver->voltage_power_supply;
364-
Ub = Tb*driver->voltage_power_supply;
365-
Uc = Tc*driver->voltage_power_supply;
366+
Ua = Ta*driver->voltage_limit;
367+
Ub = Tb*driver->voltage_limit;
368+
Uc = Tc*driver->voltage_limit;
366369
break;
367370

368371
}
@@ -386,7 +389,7 @@ void BLDCMotor::velocityOpenloop(float target_velocity){
386389
shaft_angle += target_velocity*Ts;
387390

388391
// set the maximal allowed voltage (voltage_limit) with the necessary angle
389-
setPhaseVoltage(voltage_limit, _electricalAngle(shaft_angle, pole_pairs));
392+
setPhaseVoltage(voltage_limit, 0, _electricalAngle(shaft_angle, pole_pairs));
390393

391394
// save timestamp for next call
392395
open_loop_timestamp = now_us;
@@ -409,7 +412,7 @@ void BLDCMotor::angleOpenloop(float target_angle){
409412
shaft_angle = target_angle;
410413

411414
// set the maximal allowed voltage (voltage_limit) with the necessary angle
412-
setPhaseVoltage(voltage_limit, _electricalAngle(shaft_angle, pole_pairs));
415+
setPhaseVoltage(voltage_limit, 0, _electricalAngle(shaft_angle, pole_pairs));
413416

414417
// save timestamp for next call
415418
open_loop_timestamp = now_us;

src/BLDCMotor.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,10 @@ class BLDCMotor: public FOCMotor
7676
* Heart of the FOC algorithm
7777
*
7878
* @param Uq Current voltage in q axis to set to the motor
79+
* @param Ud Current voltage in d axis to set to the motor
7980
* @param angle_el current electrical angle of the motor
8081
*/
81-
void setPhaseVoltage(float Uq, float angle_el);
82+
void setPhaseVoltage(float Uq, float Ud, float angle_el);
8283
/** Sensor alignment to electrical 0 angle of the motor */
8384
int alignSensor();
8485
/** Motor and sensor alignment to the sensors absolute 0 angle */

src/StepperMotor.cpp

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ void StepperMotor::init() {
2424
if(monitor_port) monitor_port->println("MOT: Init variables.");
2525

2626
// sanity check for the voltage limit configuration
27-
if(voltage_limit > voltage_power_supply) voltage_limit = voltage_power_supply;
27+
if(voltage_limit > driver->voltage_limit) voltage_limit = driver->voltage_limit;
2828
// constrain voltage for sensor alignment
2929
if(voltage_sensor_align > voltage_limit) voltage_sensor_align = voltage_limit;
3030

@@ -91,13 +91,13 @@ int StepperMotor::alignSensor() {
9191
float start_angle = shaftAngle();
9292
for (int i = 0; i <=5; i++ ) {
9393
float angle = _3PI_2 + _2PI * i / 6.0;
94-
setPhaseVoltage(voltage_sensor_align, angle);
94+
setPhaseVoltage(voltage_sensor_align, 0, angle);
9595
_delay(200);
9696
}
9797
float mid_angle = shaftAngle();
9898
for (int i = 5; i >=0; i-- ) {
9999
float angle = _3PI_2 + _2PI * i / 6.0;
100-
setPhaseVoltage(voltage_sensor_align, angle);
100+
setPhaseVoltage(voltage_sensor_align, 0, angle);
101101
_delay(200);
102102
}
103103
if (mid_angle < start_angle) {
@@ -112,7 +112,7 @@ int StepperMotor::alignSensor() {
112112
// set sensor to zero
113113
sensor->initRelativeZero();
114114
_delay(500);
115-
setPhaseVoltage(0,0);
115+
setPhaseVoltage(0, 0, 0);
116116
_delay(200);
117117

118118
// find the index if available
@@ -143,8 +143,9 @@ int StepperMotor::absoluteZeroAlign() {
143143
voltage_q = PID_velocity(velocity_index_search - shaftVelocity());
144144
}
145145
voltage_q = 0;
146+
voltage_d = 0;
146147
// disable motor
147-
setPhaseVoltage(0,0);
148+
setPhaseVoltage(0, 0, 0);
148149

149150
// align absolute zero if it has been found
150151
if(!sensor->needsAbsoluteZeroSearch()){
@@ -163,7 +164,7 @@ void StepperMotor::loopFOC() {
163164
// shaft angle
164165
shaft_angle = shaftAngle();
165166
// set the phase voltage - FOC heart function :)
166-
setPhaseVoltage(voltage_q, _electricalAngle(shaft_angle, pole_pairs));
167+
setPhaseVoltage(voltage_q, voltage_d, _electricalAngle(shaft_angle, pole_pairs));
167168
}
168169

169170
// Iterative function running outer loop of the FOC algorithm
@@ -210,36 +211,25 @@ void StepperMotor::move(float new_target) {
210211
}
211212

212213

213-
// Method using FOC to set Uq to the motor at the optimal angle
214-
// Function implementingSine PWM algorithms
214+
// Method using FOC to set Uq and Ud to the motor at the optimal angle
215+
// Function implementing Sine PWM algorithms
215216
// - space vector not implemented yet
216217
//
217218
// Function using sine approximation
218219
// regular sin + cos ~300us (no memory usaage)
219220
// approx _sin + _cos ~110us (400Byte ~ 20% of memory)
220-
void StepperMotor::setPhaseVoltage(float Uq, float angle_el) {
221+
void StepperMotor::setPhaseVoltage(float Uq, float Ud, float angle_el) {
221222
// Sinusoidal PWM modulation
222223
// Inverse Park transformation
223224

224225
// angle normalization in between 0 and 2pi
225226
// only necessary if using _sin and _cos - approximation functions
226-
angle_el = _normalizeAngle(angle_el + zero_electric_angle);
227+
angle_el = _normalizeAngle(angle_el + zero_electric_angle);
228+
float _ca = _cos(angle_el);
229+
float _sa = _sin(angle_el);
227230
// Inverse park transform
228-
Ualpha = -(_sin(angle_el)) * Uq; // -sin(angle) * Uq;
229-
Ubeta = (_cos(angle_el)) * Uq; // cos(angle) * Uq;
230-
// if (angle_el < _PI_2) {
231-
// Ualpha = 0;
232-
// Ubeta = Uq;
233-
// }else if (angle_el < _PI) {
234-
// Ualpha =- Uq;
235-
// Ubeta = 0;
236-
// }else if (angle_el < _3PI_2) {
237-
// Ualpha = 0;
238-
// Ubeta = -Uq;
239-
// }else{
240-
// Ualpha = Uq;
241-
// Ubeta = 0;
242-
// }
231+
Ualpha = _ca * Ud - _sa * Uq; // -sin(angle) * Uq;
232+
Ubeta = _sa * Ud + _ca * Uq; // cos(angle) * Uq;
243233

244234
// set the voltages in hardware
245235
driver->setPwm(Ualpha, Ubeta);
@@ -258,7 +248,7 @@ void StepperMotor::velocityOpenloop(float target_velocity){
258248
shaft_angle += target_velocity*Ts;
259249

260250
// set the maximal allowed voltage (voltage_limit) with the necessary angle
261-
setPhaseVoltage(voltage_limit, _electricalAngle(shaft_angle,pole_pairs));
251+
setPhaseVoltage(voltage_limit, 0, _electricalAngle(shaft_angle,pole_pairs));
262252

263253
// save timestamp for next call
264254
open_loop_timestamp = now_us;
@@ -281,7 +271,7 @@ void StepperMotor::angleOpenloop(float target_angle){
281271
shaft_angle = target_angle;
282272

283273
// set the maximal allowed voltage (voltage_limit) with the necessary angle
284-
setPhaseVoltage(voltage_limit, _electricalAngle(shaft_angle,pole_pairs));
274+
setPhaseVoltage(voltage_limit, 0, _electricalAngle(shaft_angle,pole_pairs));
285275

286276
// save timestamp for next call
287277
open_loop_timestamp = now_us;

src/StepperMotor.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,10 @@ class StepperMotor: public FOCMotor
8484
* Heart of the FOC algorithm
8585
*
8686
* @param Uq Current voltage in q axis to set to the motor
87+
* @param Ud Current voltage in d axis to set to the motor
8788
* @param angle_el current electrical angle of the motor
8889
*/
89-
void setPhaseVoltage(float Uq, float angle_el);
90+
void setPhaseVoltage(float Uq, float Ud , float angle_el);
9091

9192
/** Sensor alignment to electrical 0 angle of the motor */
9293
int alignSensor();

src/common/base_classes/FOCMotor.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,10 @@
55
*/
66
FOCMotor::FOCMotor()
77
{
8-
// Power supply voltage
9-
voltage_power_supply = DEF_POWER_SUPPLY;
10-
118
// maximum angular velocity to be used for positioning
129
velocity_limit = DEF_VEL_LIM;
1310
// maximum voltage to be set to the motor
14-
voltage_limit = voltage_power_supply;
11+
voltage_limit = DEF_POWER_SUPPLY;
1512

1613
// index search velocity
1714
velocity_index_search = DEF_INDEX_SEARCH_TARGET_VELOCITY;
@@ -26,6 +23,8 @@ FOCMotor::FOCMotor()
2623

2724
// default target value
2825
target = 0;
26+
voltage_d = 0;
27+
voltage_q = 0;
2928

3029
//monitor_port
3130
monitor_port = nullptr;

src/common/base_classes/FOCMotor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@ class FOCMotor
103103
float shaft_velocity_sp;//!< current target velocity
104104
float shaft_angle_sp;//!< current target angle
105105
float voltage_q;//!< current voltage u_q set
106+
float voltage_d;//!< current voltage u_d set
106107

107108
// motor configuration parameters
108-
float voltage_power_supply;//!< Power supply voltage
109109
float voltage_sensor_align;//!< sensor and motor align voltage parameter
110110
float velocity_index_search;//!< target velocity for index search
111111
int pole_pairs;//!< Motor pole pairs number

src/drivers/hardware_specific/esp32_mcu.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -283,12 +283,12 @@ void _writeDutyCycle6PWM(float dc_a, float dc_b, float dc_c, float dead_zone, i
283283
if(esp32_bldc_6pwm_motor_slots[i].pinAH == pinA_h){ // if motor slot found
284284
// se the PWM on the slot timers
285285
// transform duty cycle from [0,1] to [0,100.0]
286-
mcpwm_set_duty(esp32_bldc_6pwm_motor_slots[i].mcpwm_unit, MCPWM_TIMER_0, MCPWM_OPR_A, dc_a*100);
287-
mcpwm_set_duty(esp32_bldc_6pwm_motor_slots[i].mcpwm_unit, MCPWM_TIMER_0, MCPWM_OPR_B, dc_a*100);
288-
mcpwm_set_duty(esp32_bldc_6pwm_motor_slots[i].mcpwm_unit, MCPWM_TIMER_1, MCPWM_OPR_A, dc_b*100);
289-
mcpwm_set_duty(esp32_bldc_6pwm_motor_slots[i].mcpwm_unit, MCPWM_TIMER_1, MCPWM_OPR_B, dc_b*100);
290-
mcpwm_set_duty(esp32_bldc_6pwm_motor_slots[i].mcpwm_unit, MCPWM_TIMER_2, MCPWM_OPR_A, dc_c*100);
291-
mcpwm_set_duty(esp32_bldc_6pwm_motor_slots[i].mcpwm_unit, MCPWM_TIMER_2, MCPWM_OPR_B, dc_c*100);
286+
mcpwm_set_duty(esp32_bldc_6pwm_motor_slots[i].mcpwm_unit, MCPWM_TIMER_0, MCPWM_OPR_A, dc_a*100.0);
287+
mcpwm_set_duty(esp32_bldc_6pwm_motor_slots[i].mcpwm_unit, MCPWM_TIMER_0, MCPWM_OPR_B, dc_a*100.0);
288+
mcpwm_set_duty(esp32_bldc_6pwm_motor_slots[i].mcpwm_unit, MCPWM_TIMER_1, MCPWM_OPR_A, dc_b*100.0);
289+
mcpwm_set_duty(esp32_bldc_6pwm_motor_slots[i].mcpwm_unit, MCPWM_TIMER_1, MCPWM_OPR_B, dc_b*100.0);
290+
mcpwm_set_duty(esp32_bldc_6pwm_motor_slots[i].mcpwm_unit, MCPWM_TIMER_2, MCPWM_OPR_A, dc_c*100.0);
291+
mcpwm_set_duty(esp32_bldc_6pwm_motor_slots[i].mcpwm_unit, MCPWM_TIMER_2, MCPWM_OPR_B, dc_c*100.0);
292292
break;
293293
}
294294
}

0 commit comments

Comments
 (0)