Skip to content

Commit 241e8c0

Browse files
committed
LinearHall improvements and move to main repository
Changes compared to the original pull request in the drivers repository simplefoc/Arduino-FOC-drivers#12 1. Added a version of init which turns the motor one revolution to find the center values of the sensors. 2. Moved the calls to analogRead into a weakly bound function ReadLinearHalls so it can be overridden with custom ADC code on platforms with poor analogRead performance. 3. Commented out the pinMode calls in init, which makes it possible to pass in ADC channel numbers for custom ReadLinearHalls to use without having to remap them every update. 4. Changed to use the much faster _atan2 function that was added to foc_utils recently. 5. Added examples.
1 parent 1bad770 commit 241e8c0

File tree

6 files changed

+477
-0
lines changed

6 files changed

+477
-0
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/**
2+
*
3+
* Position/angle motion control example
4+
* Steps:
5+
* 1) Configure the motor and hall sensor
6+
* 2) Run the code
7+
* 3) Set the target angle (in radians) from serial terminal
8+
*/
9+
#include <SimpleFOC.h>
10+
11+
// BLDC motor & driver instance
12+
BLDCMotor motor = BLDCMotor(11);
13+
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6, 8);
14+
// Stepper motor & driver instance
15+
//StepperMotor motor = StepperMotor(50);
16+
//StepperDriver4PWM driver = StepperDriver4PWM(9, 5, 10, 6, 8);
17+
18+
// hall sensor instance
19+
LinearHall sensor = LinearHall(A0, A1, 11);
20+
21+
// angle set point variable
22+
float target_angle = 0;
23+
// instantiate the commander
24+
Commander command = Commander(Serial);
25+
void doTarget(char* cmd) { command.scalar(&target_angle, cmd); }
26+
27+
void setup() {
28+
29+
// driver config
30+
// power supply voltage [V]
31+
driver.voltage_power_supply = 12;
32+
driver.init();
33+
// link the motor and the driver
34+
motor.linkDriver(&driver);
35+
36+
37+
// aligning voltage [V]
38+
motor.voltage_sensor_align = 3;
39+
// index search velocity [rad/s]
40+
motor.velocity_index_search = 3;
41+
42+
// set motion control loop to be used
43+
motor.controller = MotionControlType::angle;
44+
45+
// contoller configuration
46+
// default parameters in defaults.h
47+
48+
// velocity PI controller parameters
49+
motor.PID_velocity.P = 0.2f;
50+
motor.PID_velocity.I = 2;
51+
motor.PID_velocity.D = 0;
52+
// default voltage_power_supply
53+
motor.voltage_limit = 6;
54+
// jerk control using voltage voltage ramp
55+
// default value is 300 volts per sec ~ 0.3V per millisecond
56+
motor.PID_velocity.output_ramp = 1000;
57+
58+
// velocity low pass filtering time constant
59+
motor.LPF_velocity.Tf = 0.01f;
60+
61+
// angle P controller
62+
motor.P_angle.P = 20;
63+
// maximal velocity of the position control
64+
motor.velocity_limit = 4;
65+
66+
67+
// use monitoring with serial
68+
Serial.begin(115200);
69+
// comment out if not needed
70+
motor.useMonitoring(Serial);
71+
72+
// initialize motor
73+
motor.init();
74+
// initialize sensor hardware. This moves the motor to find the min/max sensor readings and
75+
// averages them to get the center values. The motor can't move until motor.init is called, and
76+
// motor.initFOC can't do its calibration until the sensor is intialized, so this must be done inbetween.
77+
// You can then take the values printed to the serial monitor and pass them to sensor.init to
78+
// avoid having to move the motor every time. In that case it doesn't matter whether sensor.init
79+
// is called before or after motor.init.
80+
sensor.init(&motor);
81+
Serial.print("LinearHall centerA: ");
82+
Serial.print(sensor.centerA);
83+
Serial.print(", centerB: ");
84+
Serial.println(sensor.centerB);
85+
// link the motor to the sensor
86+
motor.linkSensor(&sensor);
87+
// align sensor and start FOC
88+
motor.initFOC();
89+
90+
// add target command T
91+
command.add('T', doTarget, "target angle");
92+
93+
Serial.println(F("Motor ready."));
94+
Serial.println(F("Set the target angle using serial terminal:"));
95+
_delay(1000);
96+
}
97+
98+
void loop() {
99+
// main FOC algorithm function
100+
// the faster you run this function the better
101+
// Arduino UNO loop ~1kHz
102+
// Bluepill loop ~10kHz
103+
motor.loopFOC();
104+
105+
// Motion control function
106+
// velocity, position or voltage (defined in motor.controller)
107+
// this function can be run at much lower frequency than loopFOC() function
108+
// You can also use motor.move() and set the motor.target in the code
109+
motor.move(target_angle);
110+
111+
// function intended to be used with serial plotter to monitor motor variables
112+
// significantly slowing the execution down!!!!
113+
// motor.monitor();
114+
115+
// user communication
116+
command.run();
117+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/**
2+
*
3+
* Torque control example using voltage control loop.
4+
*
5+
* Most of the low-end BLDC driver boards doesn't have current measurement therefore SimpleFOC offers
6+
* you a way to control motor torque by setting the voltage to the motor instead of the current.
7+
*
8+
* This makes the BLDC motor effectively a DC motor, and you can use it in a same way.
9+
*/
10+
#include <SimpleFOC.h>
11+
12+
13+
// BLDC motor & driver instance
14+
BLDCMotor motor = BLDCMotor(11);
15+
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6, 8);
16+
// Stepper motor & driver instance
17+
//StepperMotor motor = StepperMotor(50);
18+
//StepperDriver4PWM driver = StepperDriver4PWM(9, 5, 10, 6, 8);
19+
20+
// hall sensor instance
21+
LinearHall sensor = LinearHall(A0, A1, 11);
22+
23+
24+
// voltage set point variable
25+
float target_voltage = 2;
26+
// instantiate the commander
27+
Commander command = Commander(Serial);
28+
void doTarget(char* cmd) { command.scalar(&target_voltage, cmd); }
29+
30+
void setup() {
31+
32+
// driver config
33+
// power supply voltage [V]
34+
driver.voltage_power_supply = 12;
35+
driver.init();
36+
// link driver
37+
motor.linkDriver(&driver);
38+
39+
// aligning voltage
40+
motor.voltage_sensor_align = 3;
41+
42+
// choose FOC modulation (optional)
43+
motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
44+
45+
// set motion control loop to be used
46+
motor.controller = MotionControlType::torque;
47+
48+
// use monitoring with serial
49+
Serial.begin(115200);
50+
// comment out if not needed
51+
motor.useMonitoring(Serial);
52+
53+
// initialize motor
54+
motor.init();
55+
// initialize sensor hardware. This moves the motor to find the min/max sensor readings and
56+
// averages them to get the center values. The motor can't move until motor.init is called, and
57+
// motor.initFOC can't do its calibration until the sensor is intialized, so this must be done inbetween.
58+
// You can then take the values printed to the serial monitor and pass them to sensor.init to
59+
// avoid having to move the motor every time. In that case it doesn't matter whether sensor.init
60+
// is called before or after motor.init.
61+
sensor.init(&motor);
62+
Serial.print("LinearHall centerA: ");
63+
Serial.print(sensor.centerA);
64+
Serial.print(", centerB: ");
65+
Serial.println(sensor.centerB);
66+
// link the motor to the sensor
67+
motor.linkSensor(&sensor);
68+
// align sensor and start FOC
69+
motor.initFOC();
70+
71+
// add target command T
72+
command.add('T', doTarget, "target voltage");
73+
74+
Serial.println(F("Motor ready."));
75+
Serial.println(F("Set the target voltage using serial terminal:"));
76+
_delay(1000);
77+
}
78+
79+
80+
void loop() {
81+
82+
// main FOC algorithm function
83+
// the faster you run this function the better
84+
// Arduino UNO loop ~1kHz
85+
// Bluepill loop ~10kHz
86+
motor.loopFOC();
87+
88+
// Motion control function
89+
// velocity, position or voltage (defined in motor.controller)
90+
// this function can be run at much lower frequency than loopFOC() function
91+
// You can also use motor.move() and set the motor.target in the code
92+
motor.move(target_voltage);
93+
94+
// user communication
95+
command.run();
96+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/**
2+
*
3+
* Velocity motion control example
4+
* Steps:
5+
* 1) Configure the motor and sensor
6+
* 2) Run the code
7+
* 3) Set the target velocity (in radians per second) from serial terminal
8+
*/
9+
#include <SimpleFOC.h>
10+
11+
// BLDC motor & driver instance
12+
BLDCMotor motor = BLDCMotor(11);
13+
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6, 8);
14+
// Stepper motor & driver instance
15+
//StepperMotor motor = StepperMotor(50);
16+
//StepperDriver4PWM driver = StepperDriver4PWM(9, 5, 10, 6, 8);
17+
18+
// hall sensor instance
19+
LinearHall sensor = LinearHall(A0, A1, 11);
20+
21+
// velocity set point variable
22+
float target_velocity = 0;
23+
// instantiate the commander
24+
Commander command = Commander(Serial);
25+
void doTarget(char* cmd) { command.scalar(&target_velocity, cmd); }
26+
27+
void setup() {
28+
29+
// driver config
30+
// power supply voltage [V]
31+
driver.voltage_power_supply = 12;
32+
driver.init();
33+
// link the motor and the driver
34+
motor.linkDriver(&driver);
35+
36+
// aligning voltage [V]
37+
motor.voltage_sensor_align = 3;
38+
39+
// set motion control loop to be used
40+
motor.controller = MotionControlType::velocity;
41+
42+
// contoller configuration
43+
// default parameters in defaults.h
44+
45+
// velocity PI controller parameters
46+
motor.PID_velocity.P = 0.2f;
47+
motor.PID_velocity.I = 2;
48+
motor.PID_velocity.D = 0;
49+
// default voltage_power_supply
50+
motor.voltage_limit = 6;
51+
// jerk control using voltage voltage ramp
52+
// default value is 300 volts per sec ~ 0.3V per millisecond
53+
motor.PID_velocity.output_ramp = 1000;
54+
55+
// velocity low pass filtering time constant
56+
motor.LPF_velocity.Tf = 0.01f;
57+
58+
// use monitoring with serial
59+
Serial.begin(115200);
60+
// comment out if not needed
61+
motor.useMonitoring(Serial);
62+
63+
// initialize motor
64+
motor.init();
65+
// initialize sensor hardware. This moves the motor to find the min/max sensor readings and
66+
// averages them to get the center values. The motor can't move until motor.init is called, and
67+
// motor.initFOC can't do its calibration until the sensor is intialized, so this must be done inbetween.
68+
// You can then take the values printed to the serial monitor and pass them to sensor.init to
69+
// avoid having to move the motor every time. In that case it doesn't matter whether sensor.init
70+
// is called before or after motor.init.
71+
sensor.init(&motor);
72+
Serial.print("LinearHall centerA: ");
73+
Serial.print(sensor.centerA);
74+
Serial.print(", centerB: ");
75+
Serial.println(sensor.centerB);
76+
// link the motor to the sensor
77+
motor.linkSensor(&sensor);
78+
// align sensor and start FOC
79+
motor.initFOC();
80+
81+
// add target command T
82+
command.add('T', doTarget, "target voltage");
83+
84+
Serial.println(F("Motor ready."));
85+
Serial.println(F("Set the target velocity using serial terminal:"));
86+
_delay(1000);
87+
}
88+
89+
90+
void loop() {
91+
// main FOC algorithm function
92+
// the faster you run this function the better
93+
// Arduino UNO loop ~1kHz
94+
// Bluepill loop ~10kHz
95+
motor.loopFOC();
96+
97+
// Motion control function
98+
// velocity, position or voltage (defined in motor.controller)
99+
// this function can be run at much lower frequency than loopFOC() function
100+
// You can also use motor.move() and set the motor.target in the code
101+
motor.move(target_velocity);
102+
103+
// function intended to be used with serial plotter to monitor motor variables
104+
// significantly slowing the execution down!!!!
105+
// motor.monitor();
106+
107+
// user communication
108+
command.run();
109+
}

src/SimpleFOC.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ void loop() {
104104
#include "sensors/MagneticSensorAnalog.h"
105105
#include "sensors/MagneticSensorPWM.h"
106106
#include "sensors/HallSensor.h"
107+
#include "sensors/LinearHall.h"
107108
#include "sensors/GenericSensor.h"
108109
#include "drivers/BLDCDriver3PWM.h"
109110
#include "drivers/BLDCDriver6PWM.h"

0 commit comments

Comments
 (0)