You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Proper low cost FOC supporting boards are very hard to find these days and even may not exist. The reason may be that the hobby community has not yet dug into it properly. Therefore this is the attempt to demistify the Field Oriented Control (FOC) algorithm and make a robust but simple implementation for usage with Arduino hadrware.
7
9
8
10
### This project aims to close the gap in the areas:
@@ -19,16 +21,16 @@ Proper low cost FOC supporting boards are very hard to find these days and even
To explore better the encoder algorithm we provide an example `encoder_example.ino`.
157
+
To explore better the encoder algorithm an example is provided`encoder_example.ino`.
151
158
152
159
## Motor setup
153
160
To intialise the motor you need to input the `pwm` pins, number of `pole pairs` and optionally driver `enable` pin.
@@ -190,7 +197,6 @@ First parameter you can change is the variable you want to control. You set it b
190
197
// ControlType::angle
191
198
motor.controller = ControlType::angle;
192
199
```
193
-
194
200
### Voltage control loop
195
201
This control loop allows you to run the BLDC motor as it is simple DC motor using Park transformation. This mode is enabled by:
196
202
```cpp
@@ -270,6 +276,35 @@ Additionally you can configure the `velocity_limit` value of the controller. Thi
270
276
271
277
Finally, each application is a bit different and the chances are you will have to tune the controller values a bit to reach desired behaviour.
272
278
279
+
280
+
### Ultra slow velocity control loop
281
+
This control loop allows you to spin your BLDC motor with desired velocity as well as the [velocity loop](#velocity-control-loop) but it is intended for very smooth operation in very low velocityes (< 0.1 rad/s). This mode is enabled by:
You can test this algorithm by running the example `velocity_ultrasloaw_control_serial.ino` .
290
+
This type of the velocity control is nothing more but motor angle control. It works particularly well for the purposes of very slow movements because regular velocity calculation techniques are not vel suited for this application and regular [velocity control loop](#velocity-control-loop) would not work well.
291
+
The behavior is achieved by integrating the user set target velocity $\textsf{v}_d$ to get the necessary angle $\textsf{a}_d$. And then controlling the motor angle $\textsf{a}$ with high-gain PI controller. This controller reads the motor angle $\textsf{a}$ and sets the $\textsf{u}_q$ voltage to the motor in a such maner that it closely follows the target angle $\textsf{a}_d$, to achieve the velocity profile $\textsf{v}_d$, set by the user.
292
+
#### PI controller parameters
293
+
To change the parameters of your PI controller to reach desired behaiour you can change `motor.PI_velocity` structure:
294
+
```cpp
295
+
// velocity PI controller parameters
296
+
// default K=120.0 Ti = 100.0
297
+
motor.PI_velocity_ultra_slow.K = 120;
298
+
motor.PI_velocity_ultra_slow.Ti = 100;
299
+
motor.PI_velocity_ultra_slow.u_limit = 12;
300
+
```
301
+
The parameters of the PI controller are proportional gain `K`, integral time constant `Ti` and voltage limit `u_limit` which is by default set to the `power_supply_voltage`.
302
+
- The `u_limit` parameter is intended if some reason you wish to limit the voltage that can be sent to your motor.
303
+
- In general by raising the proportional constant `K` your motor controller will be more reactive, but too much will make it unstable.
304
+
- The same goes for integral time constant `Ti` the smaller it is the faster motors reaction to disturbance will be, but too small value will make it unstable. By defaualt the integral time constant `Ti` is set `100s`. Which means that it is extreamply slow, meaning that it is not effecting the behvior of the controlle, making it basically a P controller.
305
+
306
+
From the PI controller parameters you can see that the values are much higher than in the [velocity control loop](#velocity-control-loop). The reason is because the angle control loop is not the main loop and we need it to follow the profile as good as possible as fast as possible. Therefore we need much higher gain than before.
307
+
273
308
## FOC routine
274
309
### Intialisation - `setup()`
275
310
After the motor and encoder are intialised and the driver and control loops are configured you intialise the FOC algorithm.
@@ -310,7 +345,7 @@ It receives one parameter `BLDCMotor::move(float target)` which is current user
310
345
- If the user runs the [voltage loop](#voltage-control-loop), `move` funciton will interpret the `target` parameter as voltage $\textbf{u}_q$.
311
346
312
347
313
-
> At this point because we are goriented to simplicity we did not implement synchornious version of this code. Uing timer interrupt. The main reason for the moment is that Arduino UNO doesn't have enough timers to run it.
348
+
> At this point because we are oriented to simplicity we did not implement synchornious version of this code. Uing timer interrupt. The main reason for the moment is that Arduino UNO doesn't have enough timers to run it.
314
349
> *But in future we are planning to include this functionality.*
315
350
316
351
## Examples
@@ -397,8 +432,15 @@ class Encoder{
397
432
398
433
399
434
# Future Work Roadmap
400
-
-[ ] Encoder index proper implementation
401
-
-[ ] Timer interrupt execution rather than in the `loop()`
435
+
#### Library maintenance
402
436
-[ ] Proper introduction of the **Arudino FOC Shield V1.2**
403
437
-[ ] Make the library accesible in the Arduino Library Manager
404
-
-[ ] Publish a video utilising the library and the samples
438
+
-[ ] Publish a video utilising the library and the samples
439
+
-[ ] Make minimal version of the arduino code - all in one arduino file
440
+
441
+
#### Code developement
442
+
-[ ] Encoder index proper implementation
443
+
-[ ] Enable more dirver types
444
+
-[ ] Timer interrupt execution rather than in the `loop()`
445
+
-[ ] Make support for magnetic encoder AS5048 and similar
0 commit comments