Skip to content

Commit 88d383b

Browse files
committed
FEAT added low-side esp32 BRV8302 example
1 parent e59f38c commit 88d383b

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
/**
2+
* Comprehensive BLDC motor control example using encoder and the DRV8302 board
3+
*
4+
* Using serial terminal user can send motor commands and configure the motor and FOC in real-time:
5+
* - configure PID controller constants
6+
* - change motion control loops
7+
* - monitor motor variabels
8+
* - set target values
9+
* - check all the configuration values
10+
*
11+
* check the https://docs.simplefoc.com for full list of motor commands
12+
*
13+
*/
14+
#include <SimpleFOC.h>
15+
16+
// DRV8302 pins connections
17+
// don't forget to connect the common ground pin
18+
#define INH_A 21
19+
#define INH_B 19
20+
#define INH_C 18
21+
22+
#define EN_GATE 5
23+
#define M_PWM 25
24+
#define M_OC 26
25+
#define OC_ADJ 12
26+
#define OC_GAIN 14
27+
28+
#define IOUTA 34
29+
#define IOUTB 35
30+
#define IOUTC 32
31+
32+
// Motor instance
33+
BLDCMotor motor = BLDCMotor(7);
34+
BLDCDriver3PWM driver = BLDCDriver3PWM(INH_A, INH_B, INH_C, EN_GATE);
35+
36+
// DRV8302 board has 0.005Ohm shunt resistors and the gain of 12.22 V/V
37+
LowsideCurrentSense cs = LowsideCurrentSense(0.005f, 12.22f, IOUTA, IOUTB, IOUTC);
38+
39+
// encoder instance
40+
Encoder encoder = Encoder(22, 23, 500);
41+
42+
// Interrupt routine intialisation
43+
// channel A and B callbacks
44+
void doA(){encoder.handleA();}
45+
void doB(){encoder.handleB();}
46+
47+
48+
// commander interface
49+
Commander command = Commander(Serial);
50+
void onMotor(char* cmd){ command.motor(&motor, cmd); }
51+
52+
void setup() {
53+
54+
// initialize encoder sensor hardware
55+
encoder.init();
56+
encoder.enableInterrupts(doA, doB);
57+
// link the motor to the sensor
58+
motor.linkSensor(&encoder);
59+
60+
// DRV8302 specific code
61+
// M_OC - enable overcurrent protection
62+
pinMode(M_OC,OUTPUT);
63+
digitalWrite(M_OC,LOW);
64+
// M_PWM - enable 3pwm mode
65+
pinMode(M_PWM,OUTPUT);
66+
digitalWrite(M_PWM,HIGH);
67+
// OD_ADJ - set the maximum overcurrent limit possible
68+
// Better option would be to use voltage divisor to set exact value
69+
pinMode(OC_ADJ,OUTPUT);
70+
digitalWrite(OC_ADJ,HIGH);
71+
pinMode(OC_GAIN,OUTPUT);
72+
digitalWrite(OC_GAIN,LOW);
73+
74+
75+
// driver config
76+
// power supply voltage [V]
77+
driver.voltage_power_supply = 12;
78+
driver.pwm_frequency = 15000;
79+
driver.init();
80+
// link the motor and the driver
81+
motor.linkDriver(&driver);
82+
motor.voltage_sensor_align = 0.5;
83+
84+
// control loop type and torque mode
85+
motor.torque_controller = TorqueControlType::voltage;
86+
motor.controller = MotionControlType::torque;
87+
motor.motion_downsample = 0.0;
88+
89+
// velocity loop PID
90+
motor.PID_velocity.P = 0.2;
91+
motor.PID_velocity.I = 5.0;
92+
// Low pass filtering time constant
93+
motor.LPF_velocity.Tf = 0.02;
94+
// angle loop PID
95+
motor.P_angle.P = 20.0;
96+
// Low pass filtering time constant
97+
motor.LPF_angle.Tf = 0.0;
98+
// current q loop PID
99+
motor.PID_current_q.P = 3.0;
100+
motor.PID_current_q.I = 100.0;
101+
// Low pass filtering time constant
102+
motor.LPF_current_q.Tf = 0.02;
103+
// current d loop PID
104+
motor.PID_current_d.P = 3.0;
105+
motor.PID_current_d.I = 100.0;
106+
// Low pass filtering time constant
107+
motor.LPF_current_d.Tf = 0.02;
108+
109+
// Limits
110+
motor.velocity_limit = 100.0; // 100 rad/s velocity limit
111+
motor.voltage_limit = 12.0; // 12 Volt limit
112+
motor.current_limit = 2.0; // 2 Amp current limit
113+
114+
115+
// use monitoring with serial for motor init
116+
// monitoring port
117+
Serial.begin(115200);
118+
// comment out if not needed
119+
motor.useMonitoring(Serial);
120+
motor.monitor_variables = _MON_CURR_Q | _MON_CURR_D; // monitor the two currents d and q
121+
motor.monitor_downsample = 1000;
122+
123+
// initialise motor
124+
motor.init();
125+
126+
cs.init();
127+
cs.driverSync(&driver);
128+
// driver 8302 has inverted gains on all channels
129+
cs.gain_a *=-1;
130+
cs.gain_b *=-1;
131+
cs.gain_c *=-1;
132+
motor.linkCurrentSense(&cs);
133+
134+
// align encoder and start FOC
135+
motor.initFOC();
136+
137+
// set the inital target value
138+
motor.target = 0;
139+
140+
// define the motor id
141+
command.add('M', onMotor, "motor");
142+
143+
Serial.println(F("Full control example: "));
144+
Serial.println(F("Run user commands to configure and the motor (find the full command list in docs.simplefoc.com) \n "));
145+
Serial.println(F("Initial motion control loop is voltage loop."));
146+
Serial.println(F("Initial target voltage 2V."));
147+
148+
_delay(1000);
149+
}
150+
151+
152+
void loop() {
153+
// iterative setting FOC phase voltage
154+
motor.loopFOC();
155+
156+
// iterative function setting the outter loop target
157+
motor.move();
158+
159+
// monitoring the state variables
160+
motor.monitor();
161+
162+
// user communication
163+
command.run();
164+
}

0 commit comments

Comments
 (0)