Skip to content

Commit 47e1a7b

Browse files
authored
Merge pull request #151 from simplefoc/dev
release v2.2.1
2 parents ed90016 + ecd1c25 commit 47e1a7b

File tree

52 files changed

+1516
-213
lines changed

Some content is hidden

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

52 files changed

+1516
-213
lines changed

.github/workflows/ccpp.yml

+9-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ jobs:
1212
- arduino:sam:arduino_due_x # arduino due
1313
- arduino:samd:nano_33_iot # samd21
1414
- adafruit:samd:adafruit_metro_m4 # samd51
15-
- esp32:esp32:esp32doit-devkit-v1 # esm32
15+
- esp32:esp32:esp32 # esp32
16+
- esp32:esp32:esp32s2 # esp32s2
1617
- STM32:stm32:GenF1:pnum=BLUEPILL_F103C8 # stm32 bluepill
1718
- STM32:stm32:Nucleo_64:pnum=NUCLEO_F411RE # stm32 nucleo
1819
- arduino:mbed_rp2040:pico # rpi pico
@@ -36,15 +37,19 @@ jobs:
3637
platform-url: https://adafruit.github.io/arduino-board-index/package_adafruit_index.json
3738
sketch-names: single_full_control_example.ino
3839

39-
- arduino-boards-fqbn: esp32:esp32:esp32doit-devkit-v1 # esp32
40-
platform-url: https://dl.espressif.com/dl/package_esp32_index.json
40+
- arduino-boards-fqbn: esp32:esp32:esp32s2 # esp32s2
41+
platform-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json
42+
sketch-names: bldc_driver_3pwm_standalone.ino, stepper_driver_2pwm_standalone.ino, stepper_driver_4pwm_standalone
43+
44+
- arduino-boards-fqbn: esp32:esp32:esp32 # esp32
45+
platform-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json
4146
sketch-names: esp32_position_control.ino, esp32_i2c_dual_bus_example.ino, esp32_current_control_low_side.ino, esp32_spi_alt_example.ino
4247

4348
- arduino-boards-fqbn: STM32:stm32:GenF1:pnum=BLUEPILL_F103C8 # bluepill - hs examples
4449
platform-url: https://github.com/stm32duino/BoardManagerFiles/raw/master/STM32/package_stm_index.json
4550
sketch-names: bluepill_position_control.ino, stm32_i2c_dual_bus_example.ino, stm32_spi_alt_example.ino
4651

47-
- arduino-boards-fqbn: STM32:stm32:Nucleo_64:pnum=NUCLEO_F411RE # one full example
52+
- arduino-boards-fqbn: STM32:stm32:Nucleo_64:pnum=NUCLEO_F411RE # nucleo one full example
4853
platform-url: https://github.com/stm32duino/BoardManagerFiles/raw/master/STM32/package_stm_index.json
4954
sketch-names: single_full_control_example.ino, stm32_spi_alt_example.ino
5055

README.md

+19-21
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
![Library Compile](https://github.com/simplefoc/Arduino-FOC/workflows/Library%20Compile/badge.svg)
55
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
66
[![arduino-library-badge](https://www.ardu-badge.com/badge/Simple%20FOC.svg?)](https://www.ardu-badge.com/badge/Simple%20FOC.svg)
7+
[![status](https://joss.theoj.org/papers/4382445f249e064e9f0a7f6c1bb06b1d/status.svg)](https://joss.theoj.org/papers/4382445f249e064e9f0a7f6c1bb06b1d)
78

89
We live in very exciting times 😃! BLDC motors are entering the hobby community more and more and many great projects have already emerged leveraging their far superior dynamics and power capabilities. BLDC motors have numerous advantages over regular DC motors but they have one big disadvantage, the complexity of control. Even though it has become relatively easy to design and manufacture PCBs and create our own hardware solutions for driving BLDC motors the proper low-cost solutions are yet to come. One of the reasons for this is the apparent complexity of writing the BLDC driving algorithms, Field oriented control (FOC) being an example of one of the most efficient ones.
910
The solutions that can be found on-line are almost exclusively very specific for certain hardware configuration and the microcontroller architecture used.
@@ -17,33 +18,30 @@ Therefore this is an attempt to:
1718
- See also [@byDagor](https://github.com/byDagor)'s *fully-integrated* ESP32 based board: [Dagor Brushless Controller](https://github.com/byDagor/Dagor-Brushless-Controller)
1819

1920

21+
2022
<blockquote class="info">
21-
<p class="heading">NEW RELEASE 📢: <span class="simple">Simple<span class="foc">FOC</span>library</span> v2.2 - <a href="https://github.com/simplefoc/Arduino-FOC/releases/tag/v2.2">see release</a></p>
23+
<p class="heading">NEW RELEASE 📢: <span class="simple">Simple<span class="foc">FOC</span>library</span> v2.2.1 <a href="https://github.com/simplefoc/Arduino-FOC/releases/tag/v2.2.1">see release</a></p>
2224
<ul>
23-
<li>Sensor floating point error bugfix (initial solution) #83, #37</li>
24-
<li>Sensor class restructuring - <b>slight API change</b> - <a href="https://docs.simplefoc.com/sensors">docs</a></li>
25-
<li>Restructured the generic code and simplified adding new mcus: <b>IMPORTANT: an additional compiler flag needed for PlatformIO</b> see <a href="https://github.com/simplefoc/Arduino-FOC/issues/99">issue</a> and <a href="https://docs.simplefoc.com/library_platformio">PlatformIO docs</a></li>
26-
<li>Removed initial jump #110, #111</li>
27-
<li>Double to float transformation of the code - performance increase by <a href="https://github.com/sDessens">@sDessens</a> (#100), <a href="https://github.com/KaSroka">@KaSroka</a> (#100) </li>
28-
<li> <a href="https://docs.simplefoc.com/docs_chinese"><b>Docs webiste translated to Chinese!</b></a> 🎉: Awesome work 😃 by <a href="https://github.com/MINQING1101">@MINQING1101</a>, <a href="https://github.com/Deng-ge-open-source">@Deng-ge-open-source</a> and <a href="https://github.com/mingggggggg">@mingggggggg</a></li>
29-
<li>New MCU support - <a href="https://docs.simplefoc.com/microcontrollers">docs</a>
25+
<li>Sensor class init bugfix <a href="https://github.com/simplefoc/Arduino-FOC/issues/121">#121</a></li>
26+
<li>Voltage/current limit handling bugs <a href="https://github.com/simplefoc/Arduino-FOC/issues/118">#118</a></li>
27+
<li>Added the new motion control interface to the commander <a href="https://docs.simplefoc.com/commander_target">see docs</a>
3028
<ul>
31-
<li>Support for arduino leonardo #108 </li>
32-
<li>Initial support for portenta h7 board in collaboration with <img src="https://docs.simplefoc.com/extras/Images/arduino.png" height="15px"><a href="https://www.arduino.cc/">Arduino</a></li>
33-
<li>Initial support for esp8266</li>
29+
<li>New target setting - possible to set the position, velocity and torque target at once</li>
30+
<li>Separated the motion control interface from full motor callback - only motion control and torque control type, enable disable and target setting</li>
3431
</ul>
35-
</li>
36-
<li>Low side current sensing initial support - <a href="https://docs.simplefoc.com/current_sense">docs</a>
32+
</li>
33+
<li>New MCU support <a href="https://docs.simplefoc.com/microcontrollers">see docs</a>
3734
<ul>
38-
<li>Initial support for stm32 B_G431B_ESC1 by <a href="https://github.com/sDessens">@sDessens</a>: PR #73</li>
39-
<li>Initial support for samd21 by <a href="https://github.com/maxlem">@maxlem</a>: PR #79</li>
40-
<li>Initial support for esp32 by <a href="https://github.com/maxlem">@byDagor</a></li>
41-
</ul>
42-
</li>
43-
</ul>
35+
<li>NRF52 series mcus support by <a href="https://github.com/Polyphe">@Polyphe</a></li>
36+
<li><b>esp32 arduino package transfer to v2.0.1+</b> - helpful <a href="https://github.com/simplefoc/Arduino-FOC/pull/92/149">PR#149</a> by <a href="https://github.com/samguns">samguns</a></li>
37+
<li>Initial support for esp32s2 and esp32s3 - separation of the esp32 mcpwm and led implementation</li>
38+
</ul>
39+
</li>
40+
<li>Generic sensor class - to implement a new sensor only implement one function <a href="https://docs.simplefoc.com/generic_sensor">see docs</a></li>
41+
</ul>
4442
</blockquote>
4543

46-
## Arduino *SimpleFOClibrary* v2.1
44+
## Arduino *SimpleFOClibrary* v2.2
4745

4846
<p align="">
4947
<a href="https://youtu.be/Y5kLeqTc6Zk">
@@ -73,7 +71,7 @@ This video demonstrates the *Simple**FOC**library* basic usage, electronic conne
7371

7472
<p align=""> <img src="https://docs.simplefoc.com/extras/Images/uno_l6234.jpg" height="170px"> <img src="https://docs.simplefoc.com/extras/Images/hmbgc_v22.jpg" height="170px"> <img src="https://docs.simplefoc.com/extras/Images/foc_shield_v13.jpg" height="170px"></p>
7573

76-
## Arduino *SimpleFOCShield* v2.0.3
74+
## Arduino *SimpleFOCShield* v2.0.4
7775
<p align="">
7876
<a href="https://youtu.be/G5pbo0C6ujE">
7977
<img src="https://docs.simplefoc.com/extras/Images/foc_shield_video.jpg" height="320px">

examples/hardware_specific_examples/SimpleFOCShield/version_v2/single_full_control_example/single_full_control_example.ino

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ InlineCurrentSense current_sense = InlineCurrentSense(0.01, 50.0, A0, A2);
1717

1818
// commander communication instance
1919
Commander command = Commander(Serial);
20-
void doTarget(char* cmd){ command.scalar(&motor.target, cmd); }
20+
void doMotion(char* cmd){ command.motion(&motor, cmd); }
2121
// void doMotor(char* cmd){ command.motor(&motor, cmd); }
2222

2323
void setup() {
@@ -74,7 +74,7 @@ void setup() {
7474
motor.target = 2;
7575

7676
// subscribe motor to the commander
77-
command.add('T', doTarget, "target");
77+
command.add('T', doMotion, "motion control");
7878
// command.add('M', doMotor, "motor");
7979

8080
// Run user commands to configure and the motor (find the full command list in docs.simplefoc.com)

examples/motion_control/open_loop_motor_control/open_loop_position_example/open_loop_position_example.ino

+13
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,29 @@ float target_position = 0;
1818
// instantiate the commander
1919
Commander command = Commander(Serial);
2020
void doTarget(char* cmd) { command.scalar(&target_position, cmd); }
21+
void doLimit(char* cmd) { command.scalar(&motor.voltage_limit, cmd); }
22+
void doVelocity(char* cmd) { command.scalar(&motor.velocity_limit, cmd); }
2123

2224
void setup() {
2325

2426
// driver config
2527
// power supply voltage [V]
2628
driver.voltage_power_supply = 12;
29+
// limit the maximal dc voltage the driver can set
30+
// as a protection measure for the low-resistance motors
31+
// this value is fixed on startup
32+
driver.voltage_limit = 6;
2733
driver.init();
2834
// link the motor and the driver
2935
motor.linkDriver(&driver);
3036

3137
// limiting motor movements
38+
// limit the voltage to be set to the motor
39+
// start very low for high resistance motors
40+
// currnet = resistance*voltage, so try to be well under 1Amp
3241
motor.voltage_limit = 3; // [V]
42+
// limit/set the velocity of the transition in between
43+
// target angles
3344
motor.velocity_limit = 5; // [rad/s] cca 50rpm
3445
// open loop control config
3546
motor.controller = MotionControlType::angle_openloop;
@@ -39,6 +50,8 @@ void setup() {
3950

4051
// add target command T
4152
command.add('T', doTarget, "target angle");
53+
command.add('L', doLimit, "voltage limit");
54+
command.add('V', doLimit, "movement velocity");
4255

4356
Serial.begin(115200);
4457
Serial.println("Motor ready!");

examples/motion_control/open_loop_motor_control/open_loop_velocity_example/open_loop_velocity_example.ino

+9-1
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,26 @@ float target_velocity = 0;
1919
// instantiate the commander
2020
Commander command = Commander(Serial);
2121
void doTarget(char* cmd) { command.scalar(&target_velocity, cmd); }
22+
void doLimit(char* cmd) { command.scalar(&motor.voltage_limit, cmd); }
2223

2324
void setup() {
2425

2526
// driver config
2627
// power supply voltage [V]
2728
driver.voltage_power_supply = 12;
29+
// limit the maximal dc voltage the driver can set
30+
// as a protection measure for the low-resistance motors
31+
// this value is fixed on startup
32+
driver.voltage_limit = 6;
2833
driver.init();
2934
// link the motor and the driver
3035
motor.linkDriver(&driver);
3136

3237
// limiting motor movements
38+
// limit the voltage to be set to the motor
39+
// start very low for high resistance motors
40+
// currnet = resistance*voltage, so try to be well under 1Amp
3341
motor.voltage_limit = 3; // [V]
34-
motor.velocity_limit = 5; // [rad/s] cca 50rpm
3542

3643
// open loop control config
3744
motor.controller = MotionControlType::velocity_openloop;
@@ -41,6 +48,7 @@ void setup() {
4148

4249
// add target command T
4350
command.add('T', doTarget, "target velocity");
51+
command.add('L', doLimit, "voltage limit");
4452

4553
Serial.begin(115200);
4654
Serial.println("Motor ready!");

examples/utils/calibration/find_pole_pair_number/encoder/find_pole_pairs_number/find_pole_pairs_number.ino

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ void setup() {
7373
while(motor_angle <= pp_search_angle){
7474
motor_angle += 0.01f;
7575
motor.move(motor_angle);
76+
_delay(1);
7677
}
7778
_delay(1000);
7879
// read the encoder value for 180

examples/utils/calibration/find_pole_pair_number/magnetic_sensor/find_pole_pairs_number/find_pole_pairs_number.ino

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ void setup() {
7373
motor_angle += 0.01f;
7474
sensor.update(); // keep track of the overflow
7575
motor.move(motor_angle);
76+
_delay(1);
7677
}
7778
_delay(1000);
7879
// read the sensor value for 180
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* An example code for the generic current sensing implementation
3+
*/
4+
#include <SimpleFOC.h>
5+
6+
7+
// user defined function for reading the phase currents
8+
// returning the value per phase in amps
9+
PhaseCurrent_s readCurrentSense(){
10+
PhaseCurrent_s c;
11+
// dummy example only reading analog pins
12+
c.a = analogRead(A0);
13+
c.b = analogRead(A1);
14+
c.c = analogRead(A2); // if no 3rd current sense set it to 0
15+
return(c);
16+
}
17+
18+
// user defined function for intialising the current sense
19+
// it is optional and if provided it will be called in current_sense.init()
20+
void initCurrentSense(){
21+
pinMode(A0,INPUT);
22+
pinMode(A1,INPUT);
23+
pinMode(A2,INPUT);
24+
}
25+
26+
27+
// GenericCurrentSense class constructor
28+
// it receives the user defined callback for reading the current sense
29+
// and optionally the user defined callback for current sense initialisation
30+
GenericCurrentSense current_sense = GenericCurrentSense(readCurrentSense, initCurrentSense);
31+
32+
33+
void setup() {
34+
// if callbacks are not provided in the constructor
35+
// they can be assigned directly:
36+
//current_sense.readCallback = readCurrentSense;
37+
//current_sense.initCallback = initCurrentSense;
38+
39+
// initialise the current sensing
40+
current_sense.init();
41+
42+
43+
Serial.begin(115200);
44+
Serial.println("Current sense ready.");
45+
}
46+
47+
void loop() {
48+
49+
PhaseCurrent_s currents = current_sense.getPhaseCurrents();
50+
float current_magnitude = current_sense.getDCCurrent();
51+
52+
Serial.print(currents.a); // milli Amps
53+
Serial.print("\t");
54+
Serial.print(currents.b); // milli Amps
55+
Serial.print("\t");
56+
Serial.print(currents.c); // milli Amps
57+
Serial.print("\t");
58+
Serial.println(current_magnitude); // milli Amps
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* Generic sensor example code
3+
*
4+
* This is a code intended to demonstrate how to implement the generic sensor class
5+
*
6+
*/
7+
8+
#include <SimpleFOC.h>
9+
10+
// sensor reading function example
11+
// for the magnetic sensor with analog communication
12+
// returning an angle in radians in between 0 and 2PI
13+
float readSensor(){
14+
return analogRead(A0)*_2PI/1024.0;
15+
}
16+
17+
// sensor intialising function
18+
void initSensor(){
19+
pinMode(A0,INPUT);
20+
}
21+
22+
// generic sensor class contructor
23+
// - read sensor callback
24+
// - init sensor callback (optional)
25+
GenericSensor sensor = GenericSensor(readSensor, initSensor);
26+
27+
void setup() {
28+
// monitoring port
29+
Serial.begin(115200);
30+
31+
// if callbacks are not provided in the constructor
32+
// they can be assigned directly:
33+
//sensor.readCallback = readSensor;
34+
//sensor.initCallback = initSensor;
35+
36+
sensor.init();
37+
38+
Serial.println("Sensor ready");
39+
_delay(1000);
40+
}
41+
42+
void loop() {
43+
// iterative function updating the sensor internal variables
44+
// it is usually called in motor.loopFOC()
45+
sensor.update();
46+
47+
// display the angle and the angular velocity to the terminal
48+
Serial.print(sensor.getAngle());
49+
Serial.print("\t");
50+
Serial.println(sensor.getVelocity());
51+
}

examples/utils/sensor_test/magnetic_sensors/magnetic_sensor_i2c/magnetic_sensor_i2c_dual_bus_examples/esp32_i2c_dual_bus_example/esp32_i2c_dual_bus_example.ino

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ void setup() {
1818

1919
// Normally SimpleFOC will call begin for i2c but with esp32 begin() is the only way to set pins!
2020
// It seems safe to call begin multiple times
21-
Wire1.begin(19, 23, 400000);
21+
Wire1.begin(19, 23, (uint32_t)400000);
2222

2323
sensor0.init();
2424
sensor1.init(&Wire1);

keywords.txt

+5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ LowsideCurrentSense KEYWORD1
2222
CurrentSense KEYWORD1
2323
Commander KEYWORD1
2424
StepDirListener KEYWORD1
25+
GenericCurrentSense KEYWORD1
26+
GenericSensor KEYWORD1
2527

2628

2729
initFOC KEYWORD2
@@ -102,6 +104,8 @@ lpf KEYWORD2
102104
motor KEYWORD2
103105
handlePWM KEYWORD2
104106
enableInterrupt KEYWORD2
107+
readCallback KEYWORD2
108+
initCallback KEYWORD2
105109

106110

107111

@@ -118,6 +122,7 @@ pullup KEYWORD2
118122
quadrature KEYWORD2
119123
foc_modulation KEYWORD2
120124
target KEYWORD2
125+
motion KEYWORD2
121126
pwm_frequency KEYWORD2
122127
dead_zone KEYWORD2
123128
gain_a KEYWORD2

library.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=Simple FOC
2-
version=2.2
2+
version=2.2.1
33
author=Simplefoc <[email protected]>
44
maintainer=Simplefoc <[email protected]>
55
sentence=A library demistifying FOC for BLDC motors

0 commit comments

Comments
 (0)