Skip to content

Commit d4e058d

Browse files
authored
Merge pull request #393 from simplefoc/dev
v2.3.3
2 parents 88f3346 + af2c7c0 commit d4e058d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+2014
-316
lines changed

README.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,20 @@ Therefore this is an attempt to:
2525
- *Medium-power* BLDC driver (<30Amps): [Arduino <span class="simple">Simple<b>FOC</b>PowerShield</span> ](https://github.com/simplefoc/Arduino-SimpleFOC-PowerShield).
2626
- See also [@byDagor](https://github.com/byDagor)'s *fully-integrated* ESP32 based board: [Dagor Brushless Controller](https://github.com/byDagor/Dagor-Brushless-Controller)
2727

28-
> NEW RELEASE 📢 : <span class="simple">Simple<span class="foc">FOC</span>library</span> v2.3.2
29-
> - Improved [space vector modulation code](https://github.com/simplefoc/Arduino-FOC/pull/309) thanks to [@Candas1](https://github.com/Candas1)
30-
> - Bugfix for stepper motor initialization
31-
> - Bugfix for current sensing when only 2 phase currents available - please re-check your current sense PID tuning
32-
> - Bugfix for teensy3.2 - [#321](https://github.com/simplefoc/Arduino-FOC/pull/321)
33-
> - Added teensy3/4 compile to the github CI using platformio
34-
> - Fix compile issues with recent versions of ESP32 framework
35-
> - Add ADC calibration on STM32 MCUs
36-
> - Bugfix for crash when using ADC2 on ESP32s - [thanks to @mcells](https://github.com/simplefoc/Arduino-FOC/pull/346)
37-
> - Bugfix for renesas PWM on UNO R4 WiFi - [thanks to @facchinm](https://github.com/simplefoc/Arduino-FOC/pull/322)
38-
> - And more bugfixes - see the complete list of 2.3.2 [fixes and PRs](https://github.com/simplefoc/Arduino-FOC/milestone/9?closed=1)
39-
40-
41-
## Arduino *SimpleFOClibrary* v2.3.2
28+
> NEW RELEASE 📢 : <span class="simple">Simple<span class="foc">FOC</span>library</span> v2.3.3
29+
> - Teensy4
30+
> - support for low-side current sensing [#392](https://github.com/simplefoc/Arduino-FOC/pull/392)
31+
> - support for center aligned 6pwm and 3pwm (optional) [#392](https://github.com/simplefoc/Arduino-FOC/pull/392)
32+
> - stm32
33+
> - support for center aligned pwm (even across multiple timers and motors/drivers) [#374](https://github.com/simplefoc/Arduino-FOC/pull/374), [#388](https://github.com/simplefoc/Arduino-FOC/pull/388)
34+
> - support for DMA based low-side current sensing: [#383](https://github.com/simplefoc/Arduino-FOC/pull/383),[#378](https://github.com/simplefoc/Arduino-FOC/pull/378),
35+
> - KV rating calculation fix [#347](https://github.com/simplefoc/Arduino-FOC/pull/347)
36+
> - Much more performant Space Vector PWM calculation [#340](https://github.com/simplefoc/Arduino-FOC/pull/340)
37+
> - And much more:
38+
> - See the complete list of bugfixes and new features of v2.3.3 [fixes and PRs](https://github.com/simplefoc/Arduino-FOC/milestone/10?closed=1)
39+
40+
41+
## Arduino *SimpleFOClibrary* v2.3.3
4242

4343
<p align="">
4444
<a href="https://youtu.be/Y5kLeqTc6Zk">

examples/utils/calibration/find_kv_rating/encoder/find_kv_rating/find_kv_rating.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Commander command = Commander(Serial);
3636
void doTarget(char* cmd) { command.scalar(&target_voltage, cmd); }
3737
void calcKV(char* cmd) {
3838
// calculate the KV
39-
Serial.println(motor.shaft_velocity/motor.target*30.0f/_PI);
39+
Serial.println(motor.shaft_velocity/motor.target/_SQRT3*30.0f/_PI);
4040

4141
}
4242

examples/utils/calibration/find_kv_rating/hall_sensor/find_kv_rating/find_kv_rating.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Commander command = Commander(Serial);
3333
void doTarget(char* cmd) { command.scalar(&target_voltage, cmd); }
3434
void calcKV(char* cmd) {
3535
// calculate the KV
36-
Serial.println(motor.shaft_velocity/motor.target*30.0f/_PI);
36+
Serial.println(motor.shaft_velocity/motor.target/_SQRT3*30.0f/_PI);
3737

3838
}
3939

examples/utils/calibration/find_kv_rating/magnetic_sensor/find_kv_rating/find_kv_rating.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Commander command = Commander(Serial);
3131
void doTarget(char* cmd) { command.scalar(&target_voltage, cmd); }
3232
void calcKV(char* cmd) {
3333
// calculate the KV
34-
Serial.println(motor.shaft_velocity/motor.target*30.0f/_PI);
34+
Serial.println(motor.shaft_velocity/motor.target/_SQRT3*30.0f/_PI);
3535

3636
}
3737

library.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"build": {
3+
"libArchive": false
4+
}
5+
}

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=Simple FOC
2-
version=2.3.2
2+
version=2.3.3
33
author=Simplefoc <[email protected]>
44
maintainer=Simplefoc <[email protected]>
55
sentence=A library demistifying FOC for BLDC motors

src/BLDCMotor.cpp

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ BLDCMotor::BLDCMotor(int pp, float _R, float _KV, float _inductance)
4646
// 1/sqrt(2) - rms value
4747
KV_rating = NOT_SET;
4848
if (_isset(_KV))
49-
KV_rating = _KV*_SQRT2;
49+
KV_rating = _KV;
5050
// save phase inductance
5151
phase_inductance = _inductance;
5252

@@ -111,6 +111,8 @@ void BLDCMotor::init() {
111111
// disable motor driver
112112
void BLDCMotor::disable()
113113
{
114+
// disable the current sense
115+
if(current_sense) current_sense->disable();
114116
// set zero to PWM
115117
driver->setPwm(0, 0, 0);
116118
// disable the driver
@@ -125,6 +127,13 @@ void BLDCMotor::enable()
125127
driver->enable();
126128
// set zero to PWM
127129
driver->setPwm(0, 0, 0);
130+
// enable the current sense
131+
if(current_sense) current_sense->enable();
132+
// reset the pids
133+
PID_velocity.reset();
134+
P_angle.reset();
135+
PID_current_q.reset();
136+
PID_current_d.reset();
128137
// motor status update
129138
enabled = 1;
130139
}
@@ -142,32 +151,36 @@ int BLDCMotor::initFOC() {
142151
// alignment necessary for encoders!
143152
// sensor and motor alignment - can be skipped
144153
// by setting motor.sensor_direction and motor.zero_electric_angle
145-
_delay(500);
146154
if(sensor){
147155
exit_flag *= alignSensor();
148156
// added the shaft_angle update
149157
sensor->update();
150158
shaft_angle = shaftAngle();
151-
}else {
152-
exit_flag = 0; // no FOC without sensor
153-
SIMPLEFOC_DEBUG("MOT: No sensor.");
154-
}
155159

156-
// aligning the current sensor - can be skipped
157-
// checks if driver phases are the same as current sense phases
158-
// and checks the direction of measuremnt.
159-
_delay(500);
160-
if(exit_flag){
161-
if(current_sense){
162-
if (!current_sense->initialized) {
163-
motor_status = FOCMotorStatus::motor_calib_failed;
164-
SIMPLEFOC_DEBUG("MOT: Init FOC error, current sense not initialized");
165-
exit_flag = 0;
166-
}else{
167-
exit_flag *= alignCurrentSense();
160+
// aligning the current sensor - can be skipped
161+
// checks if driver phases are the same as current sense phases
162+
// and checks the direction of measuremnt.
163+
if(exit_flag){
164+
if(current_sense){
165+
if (!current_sense->initialized) {
166+
motor_status = FOCMotorStatus::motor_calib_failed;
167+
SIMPLEFOC_DEBUG("MOT: Init FOC error, current sense not initialized");
168+
exit_flag = 0;
169+
}else{
170+
exit_flag *= alignCurrentSense();
171+
}
168172
}
173+
else { SIMPLEFOC_DEBUG("MOT: No current sense."); }
174+
}
175+
176+
} else {
177+
SIMPLEFOC_DEBUG("MOT: No sensor.");
178+
if ((controller == MotionControlType::angle_openloop || controller == MotionControlType::velocity_openloop)){
179+
exit_flag = 1;
180+
SIMPLEFOC_DEBUG("MOT: Openloop only!");
181+
}else{
182+
exit_flag = 0; // no FOC without sensor
169183
}
170-
else { SIMPLEFOC_DEBUG("MOT: No current sense."); }
171184
}
172185

173186
if(exit_flag){
@@ -212,14 +225,18 @@ int BLDCMotor::alignSensor() {
212225
// stop init if not found index
213226
if(!exit_flag) return exit_flag;
214227

228+
// v2.3.3 fix for R_AVR_7_PCREL against symbol" bug for AVR boards
229+
// TODO figure out why this works
230+
float voltage_align = voltage_sensor_align;
231+
215232
// if unknown natural direction
216233
if(sensor_direction==Direction::UNKNOWN){
217234

218235
// find natural direction
219236
// move one electrical revolution forward
220237
for (int i = 0; i <=500; i++ ) {
221238
float angle = _3PI_2 + _2PI * i / 500.0f;
222-
setPhaseVoltage(voltage_sensor_align, 0, angle);
239+
setPhaseVoltage(voltage_align, 0, angle);
223240
sensor->update();
224241
_delay(2);
225242
}
@@ -229,13 +246,13 @@ int BLDCMotor::alignSensor() {
229246
// move one electrical revolution backwards
230247
for (int i = 500; i >=0; i-- ) {
231248
float angle = _3PI_2 + _2PI * i / 500.0f ;
232-
setPhaseVoltage(voltage_sensor_align, 0, angle);
249+
setPhaseVoltage(voltage_align, 0, angle);
233250
sensor->update();
234251
_delay(2);
235252
}
236253
sensor->update();
237254
float end_angle = sensor->getAngle();
238-
setPhaseVoltage(0, 0, 0);
255+
// setPhaseVoltage(0, 0, 0);
239256
_delay(200);
240257
// determine the direction the sensor moved
241258
float moved = fabs(mid_angle - end_angle);
@@ -250,7 +267,8 @@ int BLDCMotor::alignSensor() {
250267
sensor_direction = Direction::CW;
251268
}
252269
// check pole pair number
253-
if( fabs(moved*pole_pairs - _2PI) > 0.5f ) { // 0.5f is arbitrary number it can be lower or higher!
270+
pp_check_result = !(fabs(moved*pole_pairs - _2PI) > 0.5f); // 0.5f is arbitrary number it can be lower or higher!
271+
if( pp_check_result==false ) {
254272
SIMPLEFOC_DEBUG("MOT: PP check: fail - estimated pp: ", _2PI/moved);
255273
} else {
256274
SIMPLEFOC_DEBUG("MOT: PP check: OK!");
@@ -262,7 +280,7 @@ int BLDCMotor::alignSensor() {
262280
if(!_isset(zero_electric_angle)){
263281
// align the electrical phases of the motor and sensor
264282
// set angle -90(270 = 3PI/2) degrees
265-
setPhaseVoltage(voltage_sensor_align, 0, _3PI_2);
283+
setPhaseVoltage(voltage_align, 0, _3PI_2);
266284
_delay(700);
267285
// read the sensor
268286
sensor->update();
@@ -396,7 +414,7 @@ void BLDCMotor::move(float new_target) {
396414
if(_isset(new_target)) target = new_target;
397415

398416
// calculate the back-emf voltage if KV_rating available U_bemf = vel*(1/KV)
399-
if (_isset(KV_rating)) voltage_bemf = shaft_velocity/KV_rating/_RPM_TO_RADS;
417+
if (_isset(KV_rating)) voltage_bemf = shaft_velocity/(KV_rating*_SQRT3)/_RPM_TO_RADS;
400418
// estimate the motor current if phase reistance available and current_sense not available
401419
if(!current_sense && _isset(phase_resistance)) current.q = (voltage.q - voltage_bemf)/phase_resistance;
402420

src/BLDCMotor.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,7 @@ class BLDCMotor: public FOCMotor
6969
void move(float target = NOT_SET) override;
7070

7171
float Ua, Ub, Uc;//!< Current phase voltages Ua,Ub and Uc set to motor
72-
float Ualpha, Ubeta; //!< Phase voltages U alpha and U beta used for inverse Park and Clarke transform
73-
72+
7473
/**
7574
* Method using FOC to set Uq to the motor at the optimal angle
7675
* Heart of the FOC algorithm

src/StepperMotor.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ StepperMotor::StepperMotor(int pp, float _R, float _KV, float _inductance)
1616
phase_resistance = _R;
1717
// save back emf constant KV = 1/K_bemf
1818
// usually used rms
19-
KV_rating = _KV*_SQRT2;
19+
KV_rating = _KV;
2020
// save phase inductance
2121
phase_inductance = _inductance;
2222

@@ -114,7 +114,15 @@ int StepperMotor::initFOC() {
114114
// added the shaft_angle update
115115
sensor->update();
116116
shaft_angle = sensor->getAngle();
117-
} else { SIMPLEFOC_DEBUG("MOT: No sensor."); }
117+
} else {
118+
SIMPLEFOC_DEBUG("MOT: No sensor.");
119+
if ((controller == MotionControlType::angle_openloop || controller == MotionControlType::velocity_openloop)){
120+
exit_flag = 1;
121+
SIMPLEFOC_DEBUG("MOT: Openloop only!");
122+
}else{
123+
exit_flag = 0; // no FOC without sensor
124+
}
125+
}
118126

119127
if(exit_flag){
120128
SIMPLEFOC_DEBUG("MOT: Ready.");
@@ -133,6 +141,10 @@ int StepperMotor::alignSensor() {
133141
int exit_flag = 1; //success
134142
SIMPLEFOC_DEBUG("MOT: Align sensor.");
135143

144+
// v2.3.3 fix for R_AVR_7_PCREL against symbol" bug for AVR boards
145+
// TODO figure out why this works
146+
float voltage_align = voltage_sensor_align;
147+
136148
// if unknown natural direction
137149
if(sensor_direction == Direction::UNKNOWN){
138150
// check if sensor needs zero search
@@ -144,7 +156,7 @@ int StepperMotor::alignSensor() {
144156
// move one electrical revolution forward
145157
for (int i = 0; i <=500; i++ ) {
146158
float angle = _3PI_2 + _2PI * i / 500.0f;
147-
setPhaseVoltage(voltage_sensor_align, 0, angle);
159+
setPhaseVoltage(voltage_align, 0, angle);
148160
sensor->update();
149161
_delay(2);
150162
}
@@ -154,7 +166,7 @@ int StepperMotor::alignSensor() {
154166
// move one electrical revolution backwards
155167
for (int i = 500; i >=0; i-- ) {
156168
float angle = _3PI_2 + _2PI * i / 500.0f ;
157-
setPhaseVoltage(voltage_sensor_align, 0, angle);
169+
setPhaseVoltage(voltage_align, 0, angle);
158170
sensor->update();
159171
_delay(2);
160172
}
@@ -175,7 +187,8 @@ int StepperMotor::alignSensor() {
175187
}
176188
// check pole pair number
177189
float moved = fabs(mid_angle - end_angle);
178-
if( fabs(moved*pole_pairs - _2PI) > 0.5f ) { // 0.5f is arbitrary number it can be lower or higher!
190+
pp_check_result = !(fabs(moved*pole_pairs - _2PI) > 0.5f); // 0.5f is arbitrary number it can be lower or higher!
191+
if( pp_check_result==false ) {
179192
SIMPLEFOC_DEBUG("MOT: PP check: fail - estimated pp: ", _2PI/moved);
180193
} else {
181194
SIMPLEFOC_DEBUG("MOT: PP check: OK!");
@@ -189,7 +202,7 @@ int StepperMotor::alignSensor() {
189202
if(!_isset(zero_electric_angle)){
190203
// align the electrical phases of the motor and sensor
191204
// set angle -90(270 = 3PI/2) degrees
192-
setPhaseVoltage(voltage_sensor_align, 0, _3PI_2);
205+
setPhaseVoltage(voltage_align, 0, _3PI_2);
193206
_delay(700);
194207
// read the sensor
195208
sensor->update();
@@ -292,7 +305,7 @@ void StepperMotor::move(float new_target) {
292305
if(_isset(new_target) ) target = new_target;
293306

294307
// calculate the back-emf voltage if KV_rating available U_bemf = vel*(1/KV)
295-
if (_isset(KV_rating)) voltage_bemf = shaft_velocity/KV_rating/_RPM_TO_RADS;
308+
if (_isset(KV_rating)) voltage_bemf = shaft_velocity/(KV_rating*_SQRT3)/_RPM_TO_RADS;
296309
// estimate the motor current if phase reistance available and current_sense not available
297310
if(!current_sense && _isset(phase_resistance)) current.q = (voltage.q - voltage_bemf)/phase_resistance;
298311

src/StepperMotor.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ class StepperMotor: public FOCMotor
7373
*/
7474
void move(float target = NOT_SET) override;
7575

76-
float Ualpha,Ubeta; //!< Phase voltages U alpha and U beta used for inverse Park and Clarke transform
77-
7876
/**
7977
* Method using FOC to set Uq to the motor at the optimal angle
8078
* Heart of the FOC algorithm

0 commit comments

Comments
 (0)