Skip to content

Commit 0dd52e1

Browse files
authored
Merge pull request #10 from owennewo/hall_sensor
Hall sensor support (and changes to calibration)
2 parents 47f0b7f + 9007efd commit 0dd52e1

File tree

9 files changed

+730
-15
lines changed

9 files changed

+730
-15
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
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+
*
10+
* NOTE :
11+
* > This is for Arduino UNO example code for running angle motion control specifically
12+
* > Since Arduino UNO doesn't have enough interrupt pins we have to use software interrupt library PciManager.
13+
*
14+
* > If running this code with Nucleo or Bluepill or any other board which has more than 2 interrupt pins
15+
* > you can supply doIndex directly to the sensr.enableInterrupts(doA,doB,doC) and avoid using PciManger
16+
*
17+
*
18+
*/
19+
#include <SimpleFOC.h>
20+
// software interrupt library
21+
#include <PciManager.h>
22+
#include <PciListenerImp.h>
23+
24+
// motor instance
25+
BLDCMotor motor = BLDCMotor(9, 10, 11, 11, 8);
26+
27+
// hall sensor instance
28+
HallSensor sensor = HallSensor(2, 3, 4, 11);
29+
30+
// Interrupt routine intialisation
31+
// channel A and B callbacks
32+
void doA(){sensor.handleA();}
33+
void doB(){sensor.handleB();}
34+
void doC(){sensor.handleC();}
35+
// If no available hadware interrupt pins use the software interrupt
36+
PciListenerImp listenerIndex(sensor.pinC, doC);
37+
38+
39+
void setup() {
40+
41+
// initialize sensor hardware
42+
sensor.init();
43+
sensor.enableInterrupts(doA, doB); //, doC);
44+
// software interrupts
45+
PciManager.registerListener(&listenerIndex);
46+
// link the motor to the sensor
47+
motor.linkSensor(&sensor);
48+
49+
// power supply voltage [V]
50+
motor.voltage_power_supply = 12;
51+
// aligning voltage [V]
52+
motor.voltage_sensor_align = 3;
53+
// index search velocity [rad/s]
54+
motor.velocity_index_search = 3;
55+
56+
// set motion control loop to be used
57+
motor.controller = ControlType::angle;
58+
59+
// contoller configuration
60+
// default parameters in defaults.h
61+
62+
// velocity PI controller parameters
63+
motor.PI_velocity.P = 0.2;
64+
motor.PI_velocity.I = 2;
65+
// default voltage_power_supply
66+
motor.PI_velocity.voltage_limit = 6;
67+
// jerk control using voltage voltage ramp
68+
// default value is 300 volts per sec ~ 0.3V per millisecond
69+
motor.PI_velocity.voltage_ramp = 1000;
70+
71+
// velocity low pass filtering time constant
72+
motor.LPF_velocity.Tf = 0.01;
73+
74+
// angle P controller
75+
motor.P_angle.P = 20;
76+
// maximal velocity of the position control
77+
motor.P_angle.velocity_limit = 4;
78+
79+
80+
// use monitoring with serial
81+
Serial.begin(115200);
82+
// comment out if not needed
83+
motor.useMonitoring(Serial);
84+
85+
// initialize motor
86+
motor.init();
87+
// align sensor and start FOC
88+
motor.initFOC();
89+
90+
91+
Serial.println("Motor ready.");
92+
Serial.println("Set the target angle using serial terminal:");
93+
_delay(1000);
94+
}
95+
96+
// angle set point variable
97+
float target_angle = 0;
98+
99+
void loop() {
100+
// main FOC algorithm function
101+
// the faster you run this function the better
102+
// Arduino UNO loop ~1kHz
103+
// Bluepill loop ~10kHz
104+
motor.loopFOC();
105+
106+
// Motion control function
107+
// velocity, position or voltage (defined in motor.controller)
108+
// this function can be run at much lower frequency than loopFOC() function
109+
// You can also use motor.move() and set the motor.target in the code
110+
motor.move(target_angle);
111+
112+
// function intended to be used with serial plotter to monitor motor variables
113+
// significantly slowing the execution down!!!!
114+
// motor.monitor();
115+
116+
// user communication
117+
serialReceiveUserCommand();
118+
}
119+
120+
// utility function enabling serial communication with the user to set the target values
121+
// this function can be implemented in serialEvent function as well
122+
void serialReceiveUserCommand() {
123+
124+
// a string to hold incoming data
125+
static String received_chars;
126+
127+
while (Serial.available()) {
128+
// get the new byte:
129+
char inChar = (char)Serial.read();
130+
// add it to the string buffer:
131+
received_chars += inChar;
132+
// end of user input
133+
if (inChar == '\n') {
134+
135+
// change the motor target
136+
target_angle = received_chars.toFloat();
137+
Serial.print("Target angle: ");
138+
Serial.println(target_angle);
139+
140+
// reset the command buffer
141+
received_chars = "";
142+
}
143+
}
144+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
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+
// motor instance
13+
BLDCMotor motor = BLDCMotor(9, 10, 11, 11, 7);
14+
15+
// hall sensor instance
16+
HallSensor sensor = HallSensor(2, 3, 4, 11);
17+
18+
// Interrupt routine intialisation
19+
// channel A and B callbacks
20+
void doA(){sensor.handleA();}
21+
void doB(){();}
22+
void doC(){sensor.handleC();}
23+
24+
void setup() {
25+
26+
// initialize encoder sensor hardware
27+
sensor.init();
28+
sensor.enableInterrupts(doA, doB, doC);
29+
// link the motor to the sensor
30+
motor.linkSensor(&sensor);
31+
32+
// power supply voltage
33+
// default 12V
34+
motor.voltage_power_supply = 12;
35+
// aligning voltage
36+
motor.voltage_sensor_align = 3;
37+
38+
// choose FOC modulation (optional)
39+
motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
40+
41+
// set motion control loop to be used
42+
motor.controller = ControlType::voltage;
43+
44+
// use monitoring with serial for motor init
45+
// comment out if not needed
46+
motor.useMonitoring(Serial);
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+
// align sensor and start FOC
56+
motor.initFOC();
57+
58+
Serial.println("Motor ready.");
59+
Serial.println("Set the target voltage using serial terminal:");
60+
_delay(1000);
61+
}
62+
63+
// target voltage to be set to the motor
64+
float target_voltage = 2;
65+
66+
void loop() {
67+
68+
// main FOC algorithm function
69+
// the faster you run this function the better
70+
// Arduino UNO loop ~1kHz
71+
// Bluepill loop ~10kHz
72+
motor.loopFOC();
73+
74+
// Motion control function
75+
// velocity, position or voltage (defined in motor.controller)
76+
// this function can be run at much lower frequency than loopFOC() function
77+
// You can also use motor.move() and set the motor.target in the code
78+
motor.move(target_voltage);
79+
80+
// communicate with the user
81+
serialReceiveUserCommand();
82+
}
83+
84+
85+
// utility function enabling serial communication with the user to set the target values
86+
// this function can be implemented in serialEvent function as well
87+
void serialReceiveUserCommand() {
88+
89+
// a string to hold incoming data
90+
static String received_chars;
91+
92+
while (Serial.available()) {
93+
// get the new byte:
94+
char inChar = (char)Serial.read();
95+
// add it to the string buffer:
96+
received_chars += inChar;
97+
// end of user input
98+
if (inChar == '\n') {
99+
100+
// change the motor target
101+
target_voltage = received_chars.toFloat();
102+
Serial.print("Target voltage: ");
103+
Serial.println(target_voltage);
104+
105+
// reset the command buffer
106+
received_chars = "";
107+
}
108+
}
109+
}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
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+
*
10+
*
11+
* NOTE :
12+
* > Specifically for Arduino UNO example code for running velocity motion control using a hall sensor
13+
* > Since Arduino UNO doesn't have enough interrupt pins we have to use software interrupt library PciManager.
14+
*
15+
* > If running this code with Nucleo or Bluepill or any other board which has more than 2 interrupt pins
16+
* > you can supply doC directly to the sensor.enableInterrupts(doA,doB,doC) and avoid using PciManger
17+
*
18+
*/
19+
#include <SimpleFOC.h>
20+
// software interrupt library
21+
#include <PciManager.h>
22+
#include <PciListenerImp.h>
23+
24+
// motor instance
25+
BLDCMotor motor = BLDCMotor(9, 10, 11, 11, 8);
26+
27+
// hall sensor instance
28+
HallSensor sensor = HallSensor(2, 3, 4, 11);
29+
30+
// Interrupt routine intialisation
31+
// channel A and B callbacks
32+
void doA(){sensor.handleA();}
33+
void doB(){sensor.handleB();}
34+
void doC(){sensor.handleC();}
35+
// If no available hadware interrupt pins use the software interrupt
36+
PciListenerImp listenerIndex(sensor.pinC, doC);
37+
38+
39+
void setup() {
40+
41+
// initialize sensor sensor hardware
42+
sensor.init();
43+
sensor.enableInterrupts(doA, doB); //, doC);
44+
// software interrupts
45+
PciManager.registerListener(&listenerIndex);
46+
// link the motor to the sensor
47+
motor.linkSensor(&sensor);
48+
49+
// power supply voltage [V]
50+
motor.voltage_power_supply = 12;
51+
// aligning voltage [V]
52+
motor.voltage_sensor_align = 3;
53+
54+
// set motion control loop to be used
55+
motor.controller = ControlType::velocity;
56+
57+
// contoller configuration
58+
// default parameters in defaults.h
59+
60+
// velocity PI controller parameters
61+
motor.PI_velocity.P = 0.2;
62+
motor.PI_velocity.I = 2;
63+
// default voltage_power_supply
64+
motor.PI_velocity.voltage_limit = 6;
65+
// jerk control using voltage voltage ramp
66+
// default value is 300 volts per sec ~ 0.3V per millisecond
67+
motor.PI_velocity.voltage_ramp = 1000;
68+
69+
// velocity low pass filtering time constant
70+
motor.LPF_velocity.Tf = 0.01;
71+
72+
// use monitoring with serial
73+
Serial.begin(115200);
74+
// comment out if not needed
75+
motor.useMonitoring(Serial);
76+
77+
// initialize motor
78+
motor.init();
79+
// align sensor and start FOC
80+
motor.initFOC();
81+
82+
Serial.println("Motor ready.");
83+
Serial.println("Set the target velocity using serial terminal:");
84+
_delay(1000);
85+
}
86+
87+
// velocity set point variable
88+
float target_velocity = 0;
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+
serialReceiveUserCommand();
109+
}
110+
111+
// utility function enabling serial communication with the user to set the target values
112+
// this function can be implemented in serialEvent function as well
113+
void serialReceiveUserCommand() {
114+
115+
// a string to hold incoming data
116+
static String received_chars;
117+
118+
while (Serial.available()) {
119+
// get the new byte:
120+
char inChar = (char)Serial.read();
121+
// add it to the string buffer:
122+
received_chars += inChar;
123+
// end of user input
124+
if (inChar == '\n') {
125+
126+
// change the motor target
127+
target_velocity = received_chars.toFloat();
128+
Serial.print("Target velocity: ");
129+
Serial.println(target_velocity);
130+
131+
// reset the command buffer
132+
received_chars = "";
133+
}
134+
}
135+
}
136+

0 commit comments

Comments
 (0)