forked from simplefoc/Arduino-FOC
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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.
- Loading branch information
1 parent
1bad770
commit 241e8c0
Showing
6 changed files
with
477 additions
and
0 deletions.
There are no files selected for viewing
117 changes: 117 additions & 0 deletions
117
examples/motion_control/position_motion_control/linear_hall/angle_control/angle_control.ino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/** | ||
* | ||
* Position/angle motion control example | ||
* Steps: | ||
* 1) Configure the motor and hall sensor | ||
* 2) Run the code | ||
* 3) Set the target angle (in radians) from serial terminal | ||
*/ | ||
#include <SimpleFOC.h> | ||
|
||
// BLDC motor & driver instance | ||
BLDCMotor motor = BLDCMotor(11); | ||
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6, 8); | ||
// Stepper motor & driver instance | ||
//StepperMotor motor = StepperMotor(50); | ||
//StepperDriver4PWM driver = StepperDriver4PWM(9, 5, 10, 6, 8); | ||
|
||
// hall sensor instance | ||
LinearHall sensor = LinearHall(A0, A1, 11); | ||
|
||
// angle set point variable | ||
float target_angle = 0; | ||
// instantiate the commander | ||
Commander command = Commander(Serial); | ||
void doTarget(char* cmd) { command.scalar(&target_angle, cmd); } | ||
|
||
void setup() { | ||
|
||
// driver config | ||
// power supply voltage [V] | ||
driver.voltage_power_supply = 12; | ||
driver.init(); | ||
// link the motor and the driver | ||
motor.linkDriver(&driver); | ||
|
||
|
||
// aligning voltage [V] | ||
motor.voltage_sensor_align = 3; | ||
// index search velocity [rad/s] | ||
motor.velocity_index_search = 3; | ||
|
||
// set motion control loop to be used | ||
motor.controller = MotionControlType::angle; | ||
|
||
// contoller configuration | ||
// default parameters in defaults.h | ||
|
||
// velocity PI controller parameters | ||
motor.PID_velocity.P = 0.2f; | ||
motor.PID_velocity.I = 2; | ||
motor.PID_velocity.D = 0; | ||
// default voltage_power_supply | ||
motor.voltage_limit = 6; | ||
// jerk control using voltage voltage ramp | ||
// default value is 300 volts per sec ~ 0.3V per millisecond | ||
motor.PID_velocity.output_ramp = 1000; | ||
|
||
// velocity low pass filtering time constant | ||
motor.LPF_velocity.Tf = 0.01f; | ||
|
||
// angle P controller | ||
motor.P_angle.P = 20; | ||
// maximal velocity of the position control | ||
motor.velocity_limit = 4; | ||
|
||
|
||
// use monitoring with serial | ||
Serial.begin(115200); | ||
// comment out if not needed | ||
motor.useMonitoring(Serial); | ||
|
||
// initialize motor | ||
motor.init(); | ||
// initialize sensor hardware. This moves the motor to find the min/max sensor readings and | ||
// averages them to get the center values. The motor can't move until motor.init is called, and | ||
// motor.initFOC can't do its calibration until the sensor is intialized, so this must be done inbetween. | ||
// You can then take the values printed to the serial monitor and pass them to sensor.init to | ||
// avoid having to move the motor every time. In that case it doesn't matter whether sensor.init | ||
// is called before or after motor.init. | ||
sensor.init(&motor); | ||
Serial.print("LinearHall centerA: "); | ||
Serial.print(sensor.centerA); | ||
Serial.print(", centerB: "); | ||
Serial.println(sensor.centerB); | ||
// link the motor to the sensor | ||
motor.linkSensor(&sensor); | ||
// align sensor and start FOC | ||
motor.initFOC(); | ||
|
||
// add target command T | ||
command.add('T', doTarget, "target angle"); | ||
|
||
Serial.println(F("Motor ready.")); | ||
Serial.println(F("Set the target angle using serial terminal:")); | ||
_delay(1000); | ||
} | ||
|
||
void loop() { | ||
// main FOC algorithm function | ||
// the faster you run this function the better | ||
// Arduino UNO loop ~1kHz | ||
// Bluepill loop ~10kHz | ||
motor.loopFOC(); | ||
|
||
// Motion control function | ||
// velocity, position or voltage (defined in motor.controller) | ||
// this function can be run at much lower frequency than loopFOC() function | ||
// You can also use motor.move() and set the motor.target in the code | ||
motor.move(target_angle); | ||
|
||
// function intended to be used with serial plotter to monitor motor variables | ||
// significantly slowing the execution down!!!! | ||
// motor.monitor(); | ||
|
||
// user communication | ||
command.run(); | ||
} |
96 changes: 96 additions & 0 deletions
96
examples/motion_control/torque_control/linear_hall/voltage_control/voltage_control.ino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/** | ||
* | ||
* Torque control example using voltage control loop. | ||
* | ||
* Most of the low-end BLDC driver boards doesn't have current measurement therefore SimpleFOC offers | ||
* you a way to control motor torque by setting the voltage to the motor instead of the current. | ||
* | ||
* This makes the BLDC motor effectively a DC motor, and you can use it in a same way. | ||
*/ | ||
#include <SimpleFOC.h> | ||
|
||
|
||
// BLDC motor & driver instance | ||
BLDCMotor motor = BLDCMotor(11); | ||
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6, 8); | ||
// Stepper motor & driver instance | ||
//StepperMotor motor = StepperMotor(50); | ||
//StepperDriver4PWM driver = StepperDriver4PWM(9, 5, 10, 6, 8); | ||
|
||
// hall sensor instance | ||
LinearHall sensor = LinearHall(A0, A1, 11); | ||
|
||
|
||
// voltage set point variable | ||
float target_voltage = 2; | ||
// instantiate the commander | ||
Commander command = Commander(Serial); | ||
void doTarget(char* cmd) { command.scalar(&target_voltage, cmd); } | ||
|
||
void setup() { | ||
|
||
// driver config | ||
// power supply voltage [V] | ||
driver.voltage_power_supply = 12; | ||
driver.init(); | ||
// link driver | ||
motor.linkDriver(&driver); | ||
|
||
// aligning voltage | ||
motor.voltage_sensor_align = 3; | ||
|
||
// choose FOC modulation (optional) | ||
motor.foc_modulation = FOCModulationType::SpaceVectorPWM; | ||
|
||
// set motion control loop to be used | ||
motor.controller = MotionControlType::torque; | ||
|
||
// use monitoring with serial | ||
Serial.begin(115200); | ||
// comment out if not needed | ||
motor.useMonitoring(Serial); | ||
|
||
// initialize motor | ||
motor.init(); | ||
// initialize sensor hardware. This moves the motor to find the min/max sensor readings and | ||
// averages them to get the center values. The motor can't move until motor.init is called, and | ||
// motor.initFOC can't do its calibration until the sensor is intialized, so this must be done inbetween. | ||
// You can then take the values printed to the serial monitor and pass them to sensor.init to | ||
// avoid having to move the motor every time. In that case it doesn't matter whether sensor.init | ||
// is called before or after motor.init. | ||
sensor.init(&motor); | ||
Serial.print("LinearHall centerA: "); | ||
Serial.print(sensor.centerA); | ||
Serial.print(", centerB: "); | ||
Serial.println(sensor.centerB); | ||
// link the motor to the sensor | ||
motor.linkSensor(&sensor); | ||
// align sensor and start FOC | ||
motor.initFOC(); | ||
|
||
// add target command T | ||
command.add('T', doTarget, "target voltage"); | ||
|
||
Serial.println(F("Motor ready.")); | ||
Serial.println(F("Set the target voltage using serial terminal:")); | ||
_delay(1000); | ||
} | ||
|
||
|
||
void loop() { | ||
|
||
// main FOC algorithm function | ||
// the faster you run this function the better | ||
// Arduino UNO loop ~1kHz | ||
// Bluepill loop ~10kHz | ||
motor.loopFOC(); | ||
|
||
// Motion control function | ||
// velocity, position or voltage (defined in motor.controller) | ||
// this function can be run at much lower frequency than loopFOC() function | ||
// You can also use motor.move() and set the motor.target in the code | ||
motor.move(target_voltage); | ||
|
||
// user communication | ||
command.run(); | ||
} |
109 changes: 109 additions & 0 deletions
109
.../motion_control/velocity_motion_control/linear_hall/velocity_control/velocity_control.ino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/** | ||
* | ||
* Velocity motion control example | ||
* Steps: | ||
* 1) Configure the motor and sensor | ||
* 2) Run the code | ||
* 3) Set the target velocity (in radians per second) from serial terminal | ||
*/ | ||
#include <SimpleFOC.h> | ||
|
||
// BLDC motor & driver instance | ||
BLDCMotor motor = BLDCMotor(11); | ||
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6, 8); | ||
// Stepper motor & driver instance | ||
//StepperMotor motor = StepperMotor(50); | ||
//StepperDriver4PWM driver = StepperDriver4PWM(9, 5, 10, 6, 8); | ||
|
||
// hall sensor instance | ||
LinearHall sensor = LinearHall(A0, A1, 11); | ||
|
||
// velocity set point variable | ||
float target_velocity = 0; | ||
// instantiate the commander | ||
Commander command = Commander(Serial); | ||
void doTarget(char* cmd) { command.scalar(&target_velocity, cmd); } | ||
|
||
void setup() { | ||
|
||
// driver config | ||
// power supply voltage [V] | ||
driver.voltage_power_supply = 12; | ||
driver.init(); | ||
// link the motor and the driver | ||
motor.linkDriver(&driver); | ||
|
||
// aligning voltage [V] | ||
motor.voltage_sensor_align = 3; | ||
|
||
// set motion control loop to be used | ||
motor.controller = MotionControlType::velocity; | ||
|
||
// contoller configuration | ||
// default parameters in defaults.h | ||
|
||
// velocity PI controller parameters | ||
motor.PID_velocity.P = 0.2f; | ||
motor.PID_velocity.I = 2; | ||
motor.PID_velocity.D = 0; | ||
// default voltage_power_supply | ||
motor.voltage_limit = 6; | ||
// jerk control using voltage voltage ramp | ||
// default value is 300 volts per sec ~ 0.3V per millisecond | ||
motor.PID_velocity.output_ramp = 1000; | ||
|
||
// velocity low pass filtering time constant | ||
motor.LPF_velocity.Tf = 0.01f; | ||
|
||
// use monitoring with serial | ||
Serial.begin(115200); | ||
// comment out if not needed | ||
motor.useMonitoring(Serial); | ||
|
||
// initialize motor | ||
motor.init(); | ||
// initialize sensor hardware. This moves the motor to find the min/max sensor readings and | ||
// averages them to get the center values. The motor can't move until motor.init is called, and | ||
// motor.initFOC can't do its calibration until the sensor is intialized, so this must be done inbetween. | ||
// You can then take the values printed to the serial monitor and pass them to sensor.init to | ||
// avoid having to move the motor every time. In that case it doesn't matter whether sensor.init | ||
// is called before or after motor.init. | ||
sensor.init(&motor); | ||
Serial.print("LinearHall centerA: "); | ||
Serial.print(sensor.centerA); | ||
Serial.print(", centerB: "); | ||
Serial.println(sensor.centerB); | ||
// link the motor to the sensor | ||
motor.linkSensor(&sensor); | ||
// align sensor and start FOC | ||
motor.initFOC(); | ||
|
||
// add target command T | ||
command.add('T', doTarget, "target voltage"); | ||
|
||
Serial.println(F("Motor ready.")); | ||
Serial.println(F("Set the target velocity using serial terminal:")); | ||
_delay(1000); | ||
} | ||
|
||
|
||
void loop() { | ||
// main FOC algorithm function | ||
// the faster you run this function the better | ||
// Arduino UNO loop ~1kHz | ||
// Bluepill loop ~10kHz | ||
motor.loopFOC(); | ||
|
||
// Motion control function | ||
// velocity, position or voltage (defined in motor.controller) | ||
// this function can be run at much lower frequency than loopFOC() function | ||
// You can also use motor.move() and set the motor.target in the code | ||
motor.move(target_velocity); | ||
|
||
// function intended to be used with serial plotter to monitor motor variables | ||
// significantly slowing the execution down!!!! | ||
// motor.monitor(); | ||
|
||
// user communication | ||
command.run(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.