diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index b4830d82..5ee6e772 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -10,6 +10,8 @@ jobs: arduino-boards-fqbn: - arduino:avr:uno # arudino uno - arduino:sam:arduino_due_x # arduino due + - arduino:avr:mega # arduino mega2650 + - arduino:avr:leonardo # arduino leonardo - arduino:samd:nano_33_iot # samd21 - adafruit:samd:adafruit_metro_m4 # samd51 - esp32:esp32:esp32doit-devkit-v1 # esp32 @@ -29,6 +31,12 @@ jobs: - arduino-boards-fqbn: arduino:sam:arduino_due_x # arduino due - one full example sketch-names: single_full_control_example.ino + - arduino-boards-fqbn: arduino:avr:leonardo # arduino leonardo - one full example + sketch-names: open_loop_position_example.ino + + - arduino-boards-fqbn: arduino:avr:mega # arduino mega2660 - one full example + sketch-names: single_full_control_example.ino + - arduino-boards-fqbn: arduino:samd:nano_33_iot # samd21 sketch-names: nano33IoT_velocity_control.ino, smartstepper_control.ino @@ -54,6 +62,9 @@ jobs: - arduino-boards-fqbn: STMicroelectronics:stm32:Disco:pnum=B_G431B_ESC1 # B-G431-ESC1 platform-url: https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json sketch-names: B_G431B_ESC1.ino + build-properties: + B_G431B_ESC1: + -DHAL_OPAMP_MODULE_ENABLED - arduino-boards-fqbn: STMicroelectronics:stm32:GenF4:pnum=GENERIC_F405RGTX # stm32f405 - odrive platform-url: https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json @@ -63,7 +74,6 @@ jobs: platform-url: https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json sketch-names: single_full_control_example.ino, stm32_spi_alt_example.ino, sdouble_full_control_example.ino - # Do not cancel all jobs / architectures if one job fails fail-fast: false @@ -78,3 +88,4 @@ jobs: platform-url: ${{ matrix.platform-url }} sketch-names: ${{ matrix.sketch-names }} sketches-exclude: ${{ matrix.sketches-exclude }} + build-properties: ${{ toJson(matrix.build-properties) }} diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 00000000..ec37686e --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,48 @@ +cff-version: 1.0.0 +message: "If you use this software, please cite it as below." +authors: +- family-names: "Skuric" + given-names: "Antun" + orcid: "https://orcid.org/0000-0002-3323-4482" +- family-names: "Bank" + given-names: "Hasan Sinan" + orcid: "https://orcid.org/0000-0002-0626-2664" +- family-names: "Unger" + given-names: "Richard" +- family-names: "Williams" + given-names: "Owen" +- family-names: "González-Reyes" + given-names: "David" + orcid: "https://orcid.org/0000-0002-1535-3007" +title: "SimpleFOC: A Field Oriented Control (FOC) Library for Controlling Brushless Direct Current (BLDC) and Stepper Motors" +version: 2.2.2 +doi: 10.21105/joss.04232 +date-released: 2022-06-26 +url: "https://github.com/simplefoc/Arduino-FOC" + +preferred-citation: + type: article + authors: + - family-names: "Skuric" + given-names: "Antun" + orcid: "https://orcid.org/0000-0002-3323-4482" + - family-names: "Bank" + given-names: "Hasan Sinan" + orcid: "https://orcid.org/0000-0002-0626-2664" + - family-names: "Unger" + given-names: "Richard" + - family-names: "Williams" + given-names: "Owen" + - family-names: "González-Reyes" + given-names: "David" + orcid: "https://orcid.org/0000-0002-1535-3007" + doi: "10.21105/joss.04232" + journal: "Journal of Open Source Software" + url: "https://doi.org/10.21105/joss.04232" + month: 6 + start: 4232 # First page number + end: 4232 # Last page number + title: "SimpleFOC: A Field Oriented Control (FOC) Library for Controlling Brushless Direct Current (BLDC) and Stepper Motors" + volume: 7 + issue: 74 + year: 2022 diff --git a/README.md b/README.md index 25c728a5..e49ef384 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,12 @@ Therefore this is an attempt to: - *Medium-power* BLDC driver (<30Amps): [Arduino SimpleFOCPowerShield ](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) - +
+ SimpleFOC: A Field Oriented Control (FOC) Library for Controlling Brushless Direct Current (BLDC) and Stepper Motors.
+ A. Skuric, HS. Bank, R. Unger, O. Williams, D. González-Reyes
+Journal of Open Source Software, 7(74), 4232, https://doi.org/10.21105/joss.04232
+
NEW RELEASE 📢: SimpleFOClibrary v2.2.2 see release
@@ -215,6 +220,34 @@ Here are some of the *Simple**FOC**library* and *Simple**FOC**Shield* applicatio +## Citing the *SimpleFOC* + +We are very happy that *Simple**FOC**library* has been used as a component of several research project and has made its way to several scientific papers. We are hoping that this trend is going to continue as the project matures and becomes more robust! +A short resume paper about *Simple**FOC*** has been published in the Journal of Open Source Software: ++ SimpleFOC: A Field Oriented Control (FOC) Library for Controlling Brushless Direct Current (BLDC) and Stepper Motors.
+ +If you are interested in citing *Simple**FOC**library* or some other component of *Simple**FOC**project* in your research, we suggest you to cite our paper: + +```bib +@article{simplefoc2022, + doi = {10.21105/joss.04232}, + url = {https://doi.org/10.21105/joss.04232}, + year = {2022}, + publisher = {The Open Journal}, + volume = {7}, + number = {74}, + pages = {4232}, + author = {Antun Skuric and Hasan Sinan Bank and Richard Unger and Owen Williams and David González-Reyes}, + title = {SimpleFOC: A Field Oriented Control (FOC) Library for Controlling Brushless Direct Current (BLDC) and Stepper Motors}, + journal = {Journal of Open Source Software} +} + +``` + ## Arduino FOC repo structure Branch | Description | Status diff --git a/examples/motion_control/velocity_motion_control/magnetic_sensor/velocity_control/velocity_control.ino b/examples/motion_control/velocity_motion_control/magnetic_sensor/velocity_control/velocity_control.ino index a57fe634..98e09425 100644 --- a/examples/motion_control/velocity_motion_control/magnetic_sensor/velocity_control/velocity_control.ino +++ b/examples/motion_control/velocity_motion_control/magnetic_sensor/velocity_control/velocity_control.ino @@ -77,7 +77,7 @@ void setup() { motor.initFOC(); // add target command T - command.add('T', doTarget, "target voltage"); + command.add('T', doTarget, "target velocity"); Serial.println(F("Motor ready.")); Serial.println(F("Set the target velocity using serial terminal:")); @@ -103,4 +103,4 @@ void loop() { // user communication command.run(); -} \ No newline at end of file +} diff --git a/examples/utils/sensor_test/hall_sensors/hall_sensor_example/hall_sensor_example.ino b/examples/utils/sensor_test/hall_sensors/hall_sensor_example/hall_sensor_example.ino index ef2e504c..c4777baa 100644 --- a/examples/utils/sensor_test/hall_sensors/hall_sensor_example/hall_sensor_example.ino +++ b/examples/utils/sensor_test/hall_sensors/hall_sensor_example/hall_sensor_example.ino @@ -11,7 +11,7 @@ // HallSensor(int hallA, int hallB , int cpr, int index) // - hallA, hallB, hallC - HallSensor A, B and C pins // - pp - pole pairs -HallSensor sensor = HallSensor(2, 3, 4, 11); +HallSensor sensor = HallSensor(2, 3, 4, 14); // Interrupt routine intialisation // channel A and B callbacks @@ -44,4 +44,5 @@ void loop() { Serial.print(sensor.getAngle()); Serial.print("\t"); Serial.println(sensor.getVelocity()); + delay(100); } diff --git a/src/BLDCMotor.h b/src/BLDCMotor.h index 65bacb8d..4c87be67 100644 --- a/src/BLDCMotor.h +++ b/src/BLDCMotor.h @@ -70,10 +70,7 @@ class BLDCMotor: public FOCMotor 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 - - private: - // FOC methods - /** + /** * Method using FOC to set Uq to the motor at the optimal angle * Heart of the FOC algorithm * @@ -82,6 +79,10 @@ class BLDCMotor: public FOCMotor * @param angle_el current electrical angle of the motor */ void setPhaseVoltage(float Uq, float Ud, float angle_el); + + private: + // FOC methods + /** Sensor alignment to electrical 0 angle of the motor */ int alignSensor(); /** Current sense and motor phase alignment */ diff --git a/src/common/base_classes/Sensor.cpp b/src/common/base_classes/Sensor.cpp index 23a51d9b..f3b19053 100644 --- a/src/common/base_classes/Sensor.cpp +++ b/src/common/base_classes/Sensor.cpp @@ -2,7 +2,7 @@ #include "../foc_utils.h" #include "../time_utils.h" -// TODO add an init method to make the startup smoother by initializing internal variables to current values rather than 0 + void Sensor::update() { float val = getSensorAngle(); @@ -18,17 +18,17 @@ void Sensor::update() { float Sensor::getVelocity() { // calculate sample time float Ts = (angle_prev_ts - vel_angle_prev_ts)*1e-6; - // quick fix for strange cases (micros overflow) - if(Ts <= 0) Ts = 1e-3f; - // velocity calculation - float vel = ( (float)(full_rotations - vel_full_rotations)*_2PI + (angle_prev - vel_angle_prev) ) / Ts; - // save variables for future pass + if (Ts
+ A. Skuric, HS. Bank, R. Unger, O. Williams, D. González-Reyes
+Journal of Open Source Software, 7(74), 4232, https://doi.org/10.21105/joss.04232 +getHandle()->Instance == TIM8) - return ADC_EXTERNALTRIGINJECCONV_T8_TRGO; + return ADC_EXTERNALTRIGCONV_T8_TRGO; #endif else return _TRGO_NOT_AVAILABLE; diff --git a/src/drivers/hardware_specific/atmega2560_mcu.cpp b/src/drivers/hardware_specific/atmega2560_mcu.cpp index cf71a949..8ee1a727 100644 --- a/src/drivers/hardware_specific/atmega2560_mcu.cpp +++ b/src/drivers/hardware_specific/atmega2560_mcu.cpp @@ -86,7 +86,7 @@ void* _configure4PWM(long pwm_frequency,const int pin1A, const int pin1B, const _pinHighFrequency(pin2A); _pinHighFrequency(pin2B); GenericDriverParams* params = new GenericDriverParams { - .pins = { pin1A, pin2A, pin2A, pin2B }, + .pins = { pin1A, pin1B, pin2A, pin2B }, .pwm_frequency = pwm_frequency }; return params; @@ -146,8 +146,8 @@ void* _configure6PWM(long pwm_frequency, float dead_zone, const int pinA_h, cons ret_flag += _configureComplementaryPair(pinC_h, pinC_l); if (ret_flag!=0) return SIMPLEFOC_DRIVER_INIT_FAILED; GenericDriverParams* params = new GenericDriverParams { - .pins = { pinA_h,, pinA_l, pinB_h, pinB_l, pinC_h, pinC_l }, - .pwm_frequency = pwm_frequency + .pins = { pinA_h, pinA_l, pinB_h, pinB_l, pinC_h, pinC_l }, + .pwm_frequency = pwm_frequency, .dead_zone = dead_zone }; return params; diff --git a/src/drivers/hardware_specific/atmega328_mcu.cpp b/src/drivers/hardware_specific/atmega328_mcu.cpp index 33e4d497..49318c52 100644 --- a/src/drivers/hardware_specific/atmega328_mcu.cpp +++ b/src/drivers/hardware_specific/atmega328_mcu.cpp @@ -81,7 +81,7 @@ void* _configure4PWM(long pwm_frequency,const int pin1A, const int pin1B, const _pinHighFrequency(pin2A); _pinHighFrequency(pin2B); GenericDriverParams* params = new GenericDriverParams { - .pins = { pin1A, pin2A, pin2A, pin2B }, + .pins = { pin1A, pin1B, pin2A, pin2B }, .pwm_frequency = pwm_frequency }; return params; @@ -170,4 +170,4 @@ void _writeDutyCycle6PWM(float dc_a, float dc_b, float dc_c, void* params){ _setPwmPair(((GenericDriverParams*)params)->pins[4], ((GenericDriverParams*)params)->pins[5], dc_c*255.0, ((GenericDriverParams*)params)->dead_zone*255.0); } -#endif \ No newline at end of file +#endif diff --git a/src/drivers/hardware_specific/atmega32u4_mcu.cpp b/src/drivers/hardware_specific/atmega32u4_mcu.cpp index 22b6c656..9001fd90 100644 --- a/src/drivers/hardware_specific/atmega32u4_mcu.cpp +++ b/src/drivers/hardware_specific/atmega32u4_mcu.cpp @@ -89,7 +89,7 @@ void* _configure4PWM(long pwm_frequency,const int pin1A, const int pin1B, const _pinHighFrequency(pin2A); _pinHighFrequency(pin2B); GenericDriverParams* params = new GenericDriverParams { - .pins = { pin1A, pin2A, pin2A, pin2B }, + .pins = { pin1A, pin1B, pin2A, pin2B }, .pwm_frequency = pwm_frequency }; return params; @@ -158,8 +158,8 @@ void* _configure6PWM(long pwm_frequency, float dead_zone, const int pinA_h, cons ret_flag += _configureComplementaryPair(pinC_h, pinC_l); if (ret_flag!=0) return SIMPLEFOC_DRIVER_INIT_FAILED; GenericDriverParams* params = new GenericDriverParams { - .pins = { pinA_h,, pinA_l, pinB_h, pinB_l, pinC_h, pinC_l }, - .pwm_frequency = pwm_frequency + .pins = { pinA_h, pinA_l, pinB_h, pinB_l, pinC_h, pinC_l }, + .pwm_frequency = pwm_frequency, .dead_zone = dead_zone }; return params; diff --git a/src/drivers/hardware_specific/esp8266_mcu.cpp b/src/drivers/hardware_specific/esp8266_mcu.cpp index df8ae380..5bdfd5d2 100644 --- a/src/drivers/hardware_specific/esp8266_mcu.cpp +++ b/src/drivers/hardware_specific/esp8266_mcu.cpp @@ -54,7 +54,7 @@ void* _configure4PWM(long pwm_frequency,const int pinA, const int pinB, const in _setHighFrequency(pwm_frequency, pinC); _setHighFrequency(pwm_frequency, pinD); GenericDriverParams* params = new GenericDriverParams { - .pins = { pin1A, pin2A, pin2A, pin2B }, + .pins = { pin1A, pin1B, pin2A, pin2B }, .pwm_frequency = pwm_frequency }; return params;