Skip to content

Commit

Permalink
Merge pull request #393 from simplefoc/dev
Browse files Browse the repository at this point in the history
v2.3.3
  • Loading branch information
askuric authored Apr 19, 2024
2 parents 88f3346 + af2c7c0 commit d4e058d
Show file tree
Hide file tree
Showing 46 changed files with 2,014 additions and 316 deletions.
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,20 @@ Therefore this is an attempt to:
- *Medium-power* BLDC driver (<30Amps): [Arduino <span class="simple">Simple<b>FOC</b>PowerShield</span> ](https://github.com/simplefoc/Arduino-SimpleFOC-PowerShield).
- See also [@byDagor](https://github.com/byDagor)'s *fully-integrated* ESP32 based board: [Dagor Brushless Controller](https://github.com/byDagor/Dagor-Brushless-Controller)

> NEW RELEASE 📢 : <span class="simple">Simple<span class="foc">FOC</span>library</span> v2.3.2
> - Improved [space vector modulation code](https://github.com/simplefoc/Arduino-FOC/pull/309) thanks to [@Candas1](https://github.com/Candas1)
> - Bugfix for stepper motor initialization
> - Bugfix for current sensing when only 2 phase currents available - please re-check your current sense PID tuning
> - Bugfix for teensy3.2 - [#321](https://github.com/simplefoc/Arduino-FOC/pull/321)
> - Added teensy3/4 compile to the github CI using platformio
> - Fix compile issues with recent versions of ESP32 framework
> - Add ADC calibration on STM32 MCUs
> - Bugfix for crash when using ADC2 on ESP32s - [thanks to @mcells](https://github.com/simplefoc/Arduino-FOC/pull/346)
> - Bugfix for renesas PWM on UNO R4 WiFi - [thanks to @facchinm](https://github.com/simplefoc/Arduino-FOC/pull/322)
> - And more bugfixes - see the complete list of 2.3.2 [fixes and PRs](https://github.com/simplefoc/Arduino-FOC/milestone/9?closed=1)

## Arduino *SimpleFOClibrary* v2.3.2
> NEW RELEASE 📢 : <span class="simple">Simple<span class="foc">FOC</span>library</span> v2.3.3
> - Teensy4
> - support for low-side current sensing [#392](https://github.com/simplefoc/Arduino-FOC/pull/392)
> - support for center aligned 6pwm and 3pwm (optional) [#392](https://github.com/simplefoc/Arduino-FOC/pull/392)
> - stm32
> - 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)
> - 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),
> - KV rating calculation fix [#347](https://github.com/simplefoc/Arduino-FOC/pull/347)
> - Much more performant Space Vector PWM calculation [#340](https://github.com/simplefoc/Arduino-FOC/pull/340)
> - And much more:
> - 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)

## Arduino *SimpleFOClibrary* v2.3.3

<p align="">
<a href="https://youtu.be/Y5kLeqTc6Zk">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_voltage, cmd); }
void calcKV(char* cmd) {
// calculate the KV
Serial.println(motor.shaft_velocity/motor.target*30.0f/_PI);
Serial.println(motor.shaft_velocity/motor.target/_SQRT3*30.0f/_PI);

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_voltage, cmd); }
void calcKV(char* cmd) {
// calculate the KV
Serial.println(motor.shaft_velocity/motor.target*30.0f/_PI);
Serial.println(motor.shaft_velocity/motor.target/_SQRT3*30.0f/_PI);

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_voltage, cmd); }
void calcKV(char* cmd) {
// calculate the KV
Serial.println(motor.shaft_velocity/motor.target*30.0f/_PI);
Serial.println(motor.shaft_velocity/motor.target/_SQRT3*30.0f/_PI);

}

Expand Down
5 changes: 5 additions & 0 deletions library.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"build": {
"libArchive": false
}
}
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=Simple FOC
version=2.3.2
version=2.3.3
author=Simplefoc <[email protected]>
maintainer=Simplefoc <[email protected]>
sentence=A library demistifying FOC for BLDC motors
Expand Down
68 changes: 43 additions & 25 deletions src/BLDCMotor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ BLDCMotor::BLDCMotor(int pp, float _R, float _KV, float _inductance)
// 1/sqrt(2) - rms value
KV_rating = NOT_SET;
if (_isset(_KV))
KV_rating = _KV*_SQRT2;
KV_rating = _KV;
// save phase inductance
phase_inductance = _inductance;

Expand Down Expand Up @@ -111,6 +111,8 @@ void BLDCMotor::init() {
// disable motor driver
void BLDCMotor::disable()
{
// disable the current sense
if(current_sense) current_sense->disable();
// set zero to PWM
driver->setPwm(0, 0, 0);
// disable the driver
Expand All @@ -125,6 +127,13 @@ void BLDCMotor::enable()
driver->enable();
// set zero to PWM
driver->setPwm(0, 0, 0);
// enable the current sense
if(current_sense) current_sense->enable();
// reset the pids
PID_velocity.reset();
P_angle.reset();
PID_current_q.reset();
PID_current_d.reset();
// motor status update
enabled = 1;
}
Expand All @@ -142,32 +151,36 @@ int BLDCMotor::initFOC() {
// alignment necessary for encoders!
// sensor and motor alignment - can be skipped
// by setting motor.sensor_direction and motor.zero_electric_angle
_delay(500);
if(sensor){
exit_flag *= alignSensor();
// added the shaft_angle update
sensor->update();
shaft_angle = shaftAngle();
}else {
exit_flag = 0; // no FOC without sensor
SIMPLEFOC_DEBUG("MOT: No sensor.");
}

// aligning the current sensor - can be skipped
// checks if driver phases are the same as current sense phases
// and checks the direction of measuremnt.
_delay(500);
if(exit_flag){
if(current_sense){
if (!current_sense->initialized) {
motor_status = FOCMotorStatus::motor_calib_failed;
SIMPLEFOC_DEBUG("MOT: Init FOC error, current sense not initialized");
exit_flag = 0;
}else{
exit_flag *= alignCurrentSense();
// aligning the current sensor - can be skipped
// checks if driver phases are the same as current sense phases
// and checks the direction of measuremnt.
if(exit_flag){
if(current_sense){
if (!current_sense->initialized) {
motor_status = FOCMotorStatus::motor_calib_failed;
SIMPLEFOC_DEBUG("MOT: Init FOC error, current sense not initialized");
exit_flag = 0;
}else{
exit_flag *= alignCurrentSense();
}
}
else { SIMPLEFOC_DEBUG("MOT: No current sense."); }
}

} else {
SIMPLEFOC_DEBUG("MOT: No sensor.");
if ((controller == MotionControlType::angle_openloop || controller == MotionControlType::velocity_openloop)){
exit_flag = 1;
SIMPLEFOC_DEBUG("MOT: Openloop only!");
}else{
exit_flag = 0; // no FOC without sensor
}
else { SIMPLEFOC_DEBUG("MOT: No current sense."); }
}

if(exit_flag){
Expand Down Expand Up @@ -212,14 +225,18 @@ int BLDCMotor::alignSensor() {
// stop init if not found index
if(!exit_flag) return exit_flag;

// v2.3.3 fix for R_AVR_7_PCREL against symbol" bug for AVR boards
// TODO figure out why this works
float voltage_align = voltage_sensor_align;

// if unknown natural direction
if(sensor_direction==Direction::UNKNOWN){

// find natural direction
// move one electrical revolution forward
for (int i = 0; i <=500; i++ ) {
float angle = _3PI_2 + _2PI * i / 500.0f;
setPhaseVoltage(voltage_sensor_align, 0, angle);
setPhaseVoltage(voltage_align, 0, angle);
sensor->update();
_delay(2);
}
Expand All @@ -229,13 +246,13 @@ int BLDCMotor::alignSensor() {
// move one electrical revolution backwards
for (int i = 500; i >=0; i-- ) {
float angle = _3PI_2 + _2PI * i / 500.0f ;
setPhaseVoltage(voltage_sensor_align, 0, angle);
setPhaseVoltage(voltage_align, 0, angle);
sensor->update();
_delay(2);
}
sensor->update();
float end_angle = sensor->getAngle();
setPhaseVoltage(0, 0, 0);
// setPhaseVoltage(0, 0, 0);
_delay(200);
// determine the direction the sensor moved
float moved = fabs(mid_angle - end_angle);
Expand All @@ -250,7 +267,8 @@ int BLDCMotor::alignSensor() {
sensor_direction = Direction::CW;
}
// check pole pair number
if( fabs(moved*pole_pairs - _2PI) > 0.5f ) { // 0.5f is arbitrary number it can be lower or higher!
pp_check_result = !(fabs(moved*pole_pairs - _2PI) > 0.5f); // 0.5f is arbitrary number it can be lower or higher!
if( pp_check_result==false ) {
SIMPLEFOC_DEBUG("MOT: PP check: fail - estimated pp: ", _2PI/moved);
} else {
SIMPLEFOC_DEBUG("MOT: PP check: OK!");
Expand All @@ -262,7 +280,7 @@ int BLDCMotor::alignSensor() {
if(!_isset(zero_electric_angle)){
// align the electrical phases of the motor and sensor
// set angle -90(270 = 3PI/2) degrees
setPhaseVoltage(voltage_sensor_align, 0, _3PI_2);
setPhaseVoltage(voltage_align, 0, _3PI_2);
_delay(700);
// read the sensor
sensor->update();
Expand Down Expand Up @@ -396,7 +414,7 @@ void BLDCMotor::move(float new_target) {
if(_isset(new_target)) target = new_target;

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

Expand Down
3 changes: 1 addition & 2 deletions src/BLDCMotor.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ class BLDCMotor: public FOCMotor
void move(float target = NOT_SET) override;

float Ua, Ub, Uc;//!< Current phase voltages Ua,Ub and Uc set to motor
float Ualpha, Ubeta; //!< Phase voltages U alpha and U beta used for inverse Park and Clarke transform


/**
* Method using FOC to set Uq to the motor at the optimal angle
* Heart of the FOC algorithm
Expand Down
27 changes: 20 additions & 7 deletions src/StepperMotor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ StepperMotor::StepperMotor(int pp, float _R, float _KV, float _inductance)
phase_resistance = _R;
// save back emf constant KV = 1/K_bemf
// usually used rms
KV_rating = _KV*_SQRT2;
KV_rating = _KV;
// save phase inductance
phase_inductance = _inductance;

Expand Down Expand Up @@ -114,7 +114,15 @@ int StepperMotor::initFOC() {
// added the shaft_angle update
sensor->update();
shaft_angle = sensor->getAngle();
} else { SIMPLEFOC_DEBUG("MOT: No sensor."); }
} else {
SIMPLEFOC_DEBUG("MOT: No sensor.");
if ((controller == MotionControlType::angle_openloop || controller == MotionControlType::velocity_openloop)){
exit_flag = 1;
SIMPLEFOC_DEBUG("MOT: Openloop only!");
}else{
exit_flag = 0; // no FOC without sensor
}
}

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

// v2.3.3 fix for R_AVR_7_PCREL against symbol" bug for AVR boards
// TODO figure out why this works
float voltage_align = voltage_sensor_align;

// if unknown natural direction
if(sensor_direction == Direction::UNKNOWN){
// check if sensor needs zero search
Expand All @@ -144,7 +156,7 @@ int StepperMotor::alignSensor() {
// move one electrical revolution forward
for (int i = 0; i <=500; i++ ) {
float angle = _3PI_2 + _2PI * i / 500.0f;
setPhaseVoltage(voltage_sensor_align, 0, angle);
setPhaseVoltage(voltage_align, 0, angle);
sensor->update();
_delay(2);
}
Expand All @@ -154,7 +166,7 @@ int StepperMotor::alignSensor() {
// move one electrical revolution backwards
for (int i = 500; i >=0; i-- ) {
float angle = _3PI_2 + _2PI * i / 500.0f ;
setPhaseVoltage(voltage_sensor_align, 0, angle);
setPhaseVoltage(voltage_align, 0, angle);
sensor->update();
_delay(2);
}
Expand All @@ -175,7 +187,8 @@ int StepperMotor::alignSensor() {
}
// check pole pair number
float moved = fabs(mid_angle - end_angle);
if( fabs(moved*pole_pairs - _2PI) > 0.5f ) { // 0.5f is arbitrary number it can be lower or higher!
pp_check_result = !(fabs(moved*pole_pairs - _2PI) > 0.5f); // 0.5f is arbitrary number it can be lower or higher!
if( pp_check_result==false ) {
SIMPLEFOC_DEBUG("MOT: PP check: fail - estimated pp: ", _2PI/moved);
} else {
SIMPLEFOC_DEBUG("MOT: PP check: OK!");
Expand All @@ -189,7 +202,7 @@ int StepperMotor::alignSensor() {
if(!_isset(zero_electric_angle)){
// align the electrical phases of the motor and sensor
// set angle -90(270 = 3PI/2) degrees
setPhaseVoltage(voltage_sensor_align, 0, _3PI_2);
setPhaseVoltage(voltage_align, 0, _3PI_2);
_delay(700);
// read the sensor
sensor->update();
Expand Down Expand Up @@ -292,7 +305,7 @@ void StepperMotor::move(float new_target) {
if(_isset(new_target) ) target = new_target;

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

Expand Down
2 changes: 0 additions & 2 deletions src/StepperMotor.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ class StepperMotor: public FOCMotor
*/
void move(float target = NOT_SET) override;

float Ualpha,Ubeta; //!< Phase voltages U alpha and U beta used for inverse Park and Clarke transform

/**
* Method using FOC to set Uq to the motor at the optimal angle
* Heart of the FOC algorithm
Expand Down
Loading

0 comments on commit d4e058d

Please sign in to comment.