Hello, Friend.
My Motor Don’t run and I could have cooked my motor almost.
I try to set up FOC testing environment using Arduino UNO + DRV8302 + AS5147 + XXD2217 KV960 BLDC.
I Connect AS5147 to UNO using normal UNO’s SPI pin(cs-10, 11,12,13) and give 5v and gnd.
And I upload angle_control.ino(example) to UNO after mapping DRV8302’s PIN as below code.
My motor has 14 magnet, So I type 7 in BLDCMotor instance.
But, Motor don’t run. Plz Help Me~
/**
*
* Position/angle motion control example
* Steps:
* 1) Configure the motor and magnetic sensor
* 2) Run the code
* 3) Set the target angle (in radians) from serial terminal
*
*/
#include <SimpleFOC.h>
#define EN_GATE 8
#define M_PWM 6
#define M_OC 5
#define OC_ADJ 7
// magnetic sensor instance - SPI
MagneticSensorSPI sensor = MagneticSensorSPI(AS5147_SPI, 10);
// magnetic sensor instance - MagneticSensorI2C
//MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);
// magnetic sensor instance - analog output
// MagneticSensorAnalog sensor = MagneticSensorAnalog(A1, 14, 1020);
// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(7);
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 2, 3, 8);
// Stepper motor & driver instance
//StepperMotor motor = StepperMotor(50);
//StepperDriver4PWM driver = StepperDriver4PWM(9, 5, 10, 6, 8);
// 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() {
// initialise magnetic sensor hardware
sensor.init();
// link the motor to the sensor
motor.linkSensor(&sensor);
// DRV8302 specific code
// M_OC - enable overcurrent protection
pinMode(M_OC,OUTPUT);
digitalWrite(M_OC,LOW);
// M_PWM - enable 3pwm mode
pinMode(M_PWM,OUTPUT);
digitalWrite(M_PWM,HIGH);
// OD_ADJ - set the maximum overcurrent limit possible
// Better option would be to use voltage divisor to set exact value
pinMode(OC_ADJ,OUTPUT);
digitalWrite(OC_ADJ,HIGH);
// driver config
// power supply voltage [V]
driver.voltage_power_supply = 12;
driver.init();
// link the motor and the driver
motor.linkDriver(&driver);
// choose FOC modulation (optional)
motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
// 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 = 20;
motor.PID_velocity.D = 0;
// maximal voltage to be set to the motor
motor.voltage_limit = 6;
// velocity low pass filtering time constant
// the lower the less filtered
motor.LPF_velocity.Tf = 0.01f;
// angle P controller
motor.P_angle.P = 20;
// maximal velocity of the position control
motor.velocity_limit = 20;
// use monitoring with serial
Serial.begin(115200);
// comment out if not needed
motor.useMonitoring(Seria1);
// initialize motor
motor.init();
// 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();
}```
Hey @DennyKing,
Using drv8302 chip can easily be fatal for your motor, so please take this step by step.
Angle control mode is the most complex one, and you should start with torque control ( using voltage).
However, your code should still work, the only big issue I see in it is the pin 2 is not pwm pin. You’ll have to use Arduino uno’s pwm pins for the driver 4,5,6,9,10 or 11.
1 Like
Thanks for your reply.
I follow your recommandtions. So I changed settings.
/**
* Comprehensive BLDC motor control example using encoder and the DRV8302 board
*
* Using serial terminal user can send motor commands and configure the motor and FOC in real-time:
* - configure PID controller constants
* - change motion control loops
* - monitor motor variabels
* - set target values
* - check all the configuration values
*
* check the https://docs.simplefoc.com for full list of motor commands
*
*/
#include <SimpleFOC.h>
// DRV8302 pins connections
// don't forget to connect the common ground pin
#define INH_A 3
#define INH_B 5
#define INH_C 6
#define EN_GATE 8
#define M_PWM A1
#define M_OC A2
#define OC_ADJ A3
// Motor instance
BLDCMotor motor = BLDCMotor(7);
BLDCDriver3PWM driver = BLDCDriver3PWM(INH_A, INH_B, INH_C);
MagneticSensorSPI sensor = MagneticSensorSPI(AS5147_SPI, 10);
// commander interface
Commander command = Commander(Serial);
void onMotor(char* cmd){ command.motor(&motor, cmd); }
void setup() {
// initialise magnetic sensor hardware
sensor.init();
// link the motor to the sensor
motor.linkSensor(&sensor);
// DRV8302 specific code
// M_OC - enable overcurrent protection
pinMode(M_OC,OUTPUT);
digitalWrite(M_OC,LOW);
// M_PWM - enable 3pwm mode
pinMode(M_PWM,OUTPUT);
digitalWrite(M_PWM,HIGH);
// OD_ADJ - set the maximum overcurrent limit possible
// Better option would be to use voltage divisor to set exact value
pinMode(OC_ADJ,OUTPUT);
digitalWrite(OC_ADJ,HIGH);
// driver config
// power supply voltage [V]
driver.voltage_power_supply = 12;
driver.init();
// link the motor and the driver
motor.linkDriver(&driver);
// choose FOC modulation
motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
// set control loop type to be used
motor.controller = MotionControlType::torque;
// contoller configuration based on the controll type
motor.PID_velocity.P = 0.2f;
motor.PID_velocity.I = 20;
// default voltage_power_supply
motor.voltage_limit = 12;
// velocity low pass filtering time constant
motor.LPF_velocity.Tf = 0.01f;
// angle loop controller
motor.P_angle.P = 20;
// angle loop velocity limit
motor.velocity_limit = 50;
// use monitoring with serial for motor init
// monitoring port
Serial.begin(115200);
// comment out if not needed
motor.useMonitoring(Serial);
// initialise motor
motor.init();
// align encoder and start FOC
motor.initFOC();
// set the inital target value
motor.target = 2;
// define the motor id
command.add('A', onMotor, "motor");
Serial.println(F("Full control example: "));
Serial.println(F("Run user commands to configure and the motor (find the full command list in docs.simplefoc.com) \n "));
Serial.println(F("Initial motion control loop is voltage loop."));
Serial.println(F("Initial target voltage 2V."));
_delay(1000);
}
void loop() {
// iterative setting FOC phase voltage
motor.loopFOC();
// iterative function setting the outter loop target
// velocity, position or voltage
// if tatget not set in parameter uses motor.target variable
motor.move();
// user communication
command.run();
}
In the serial monitor, like this.
--------------------------
MOT: Monitor enabled!
MOT: Init
MOT: Enable driver.
MOT: Align sensor.
MOT: sensor_direction==CCW
MOT: PP check: fail - estimated pp: 16383.95
MOT: Zero elec. angle: 0.39
MOT: No current sense.
MOT: Ready.
Full control example:
Run user commands to configure and the motor (find the full command list in docs.simplefoc.com)
Initial motion control loop is voltage loop.
Initial target voltage 2V.
----------------------------------
is it working or not?
DC-supply is 11.9v(no chnage) and no ampere.
Is there any other key command to run motor?
because AS5147U has an ABI interface, I want to set up like the above, but not working.
So, I use above code. but now I do not connect nOCTW and nFAULT pin. Should I connect the pin nOCTW and nFAULT to UNO? IF so, where?
It seems like a good code. However in your monitoring output it looks like the sensor has not really well read the pole pairs number. That probably means that something is wrong.
Did you try using only the sensor?
You have one example in the library examples with which you can test if your sensor works properly.
Another question is: is your motor moving during the i it phase?
Of is it completely static?
Fault and octw pins are diagnostic pins that you are not required to read. You can lave them unconnected for now.
I tested sensor using example. <magnetic_sensor_spi_example>
In the serial monitor, I think the value is rad and velocity.
this is the result of parts.
3.93 |
5.57 |
3.94 |
5.13 |
3.94 |
4.73 |
3.95 |
3.91 |
3.95 |
3.52 |
3.95 |
2.36 |
3.96 |
1.56 |
3.96 |
0.78 |
3.96 |
0.00 |
3.96 |
-0.41 |
3.95 |
-1.51 |
3.95 |
-2.26 |
3.95 |
-3.03 |
3.95 |
-3.42 |
3.94 |
-1.49 |
3.94 |
-2.26 |
3.94 |
-1.50 |
3.94 |
-2.66 |
3.94 |
-2.25 |
3.93 |
-2.98 |
3.93 |
-3.41 |
3.92 |
-3.73 |
3.92 |
-3.40 |
3.92 |
-4.14 |
3.91 |
-4.10 |
3.91 |
-4.55 |
3.90 |
-5.24 |
3.90 |
-5.64 |
3.89 |
-6.42 |
3.88 |
-7.12 |
3.88 |
-7.93 |
3.87 |
-8.61 |
3.86 |
-10.19 |
3.84 |
-12.25 |
3.83 |
-13.29 |
3.81 |
-14.05 |
3.80 |
-15.80 |
3.78 |
-17.11 |
3.76 |
-16.63 |
3.74 |
-17.17 |
3.72 |
-17.11 |
3.70 |
-17.27 |
3.69 |
-17.66 |
3.67 |
-17.75 |
3.65 |
-19.17 |
3.62 |
-20.39 |
3.60 |
-21.74 |
3.58 |
-22.81 |
3.55 |
-23.52 |
3.53 |
-23.70 |
3.50 |
-24.24 |
3.47 |
-24.50 |
3.44 |
-26.67 |
3.42 |
-26.89 |
3.39 |
-27.90 |
3.36 |
-27.70 |
3.32 |
-29.47 |
3.29 |
-30.05 |
3.26 |
-31.12 |
3.22 |
-31.49 |
3.19 |
-30.05 |
3.16 |
-28.51 |
3.13 |
-30.42 |
3.09 |
-31.48 |
3.06 |
-32.20 |
3.02 |
-33.75 |
2.99 |
-32.56 |
2.95 |
-31.96 |
2.92 |
-32.91 |
2.88 |
-33.96 |
2.84 |
-35.42 |
2.81 |
-33.86 |
2.77 |
-33.15 |
2.74 |
-32.08 |
2.70 |
-33.16 |
2.67 |
-32.67 |
2.63 |
-31.25 |
2.60 |
-31.48 |
2.57 |
-31.84 |
2.53 |
-32.55 |
2.49 |
-33.27 |
2.46 |
-33.38 |
2.42 |
-33.73 |
2.38 |
-34.34 |
2.35 |
-34.93 |
2.31 |
-33.61 |
2.28 |
-32.90 |
2.24 |
-32.20 |
2.21 |
-32.19 |
2.17 |
-32.67 |
2.14 |
-32.08 |
2.10 |
-30.54 |
2.07 |
-28.73 |
2.04 |
-29.69 |
2.01 |
-31.48 |
motor is static.