#include <SimpleFOC.h>
// software interrupt library
#include <PciManager.h>
#include <PciListenerImp.h>
// DRV8302 pins connections
#define INH_A 9
#define INH_B 10
#define INH_C 11
#define EN_GATE 8
#define M_PWM 6
#define M_OC 5
#define OC_ADJ 7
// set up pins on arduino board
#define HallA 2 // yellow
#define HallB 3 // blue
#define HallC 4// green
// polar pairs
int pp = 15; // motor has 30 outer magnets
// motor instance
BLDCMotor motor = BLDCMotor(pp);
// driver instance
BLDCDriver3PWM driver = BLDCDriver3PWM(INH_A, INH_B, INH_C, EN_GATE);
// hall sensor instance
HallSensor sensor = HallSensor(HallA, HallB, HallC, pp);
// Interrupt routine intialisation
// channel A and B callbacks
void doA(){sensor.handleA();}
void doB(){sensor.handleB();}
void doC(){sensor.handleC();}
// If no available hadware interrupt pins use the software interrupt
PciListenerImp listenC(sensor.pinC, doC);
// 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() {
// initialize Hall sensor hardware
//sensor.pullup = Pullup::USE_EXTERN;
//sensor.velocity_max = 30;
// initialize sensor sensor hardware
sensor.init();
sensor.enableInterrupts(doA, doB); //, doC);
// software interrupts
PciManager.registerListener(&listenC);
// link the motor to the sensor
motor.linkSensor(&sensor);
// DRV8302 specific code
// M_OC - enable over-current 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 over-current limit possible
// Better option would be to use voltage divisor to set exact value
pinMode(OC_ADJ,OUTPUT);
digitalWrite(OC_ADJ,HIGH);
//driver.pwm_frequency = 32000;
// configure driver
driver.voltage_power_supply = 36;
driver.init();
motor.linkDriver(&driver);
//motor.velocity_limit = 1; // [rad/s] cca 50rpm
// aligning voltage [V]
motor.voltage_sensor_align = 3;
// choose FOC modulation
//motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
// set control loop type to be used
motor.controller = MotionControlType::velocity;
// controller configuration based on the control type
motor.PID_velocity.P = 0.2;
motor.PID_velocity.I = 20;
motor.PID_velocity.D = 0;
// default voltage_power_supply
motor.voltage_limit = 12;
// 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 loop velocity limit
// angle loop controller
//motor.P_angle.P = 20;
//motor.velocity_limit = 50;
// use monitoring with serial
// default voltage_power_supply
//motor.voltage_limit = 36;
Serial.begin(115200);
// comment out if not needed
motor.useMonitoring(Serial);
//motor.monitor_variables = _MON_TARGET | _MON_VEL | _MON_ANGLE;
// downsampling
//motor.monitor_downsample = 10; // default 10
// initialize motor
motor.init();
// align encoder and start FOC
motor.initFOC();
// set the initial target value
//motor.target = 2;
// define the motor id
command.add(‘T’, doTarget, “target velocity”);
Serial.println(F(“Motor ready.”));
Serial.println(F(“Set the target velocity using serial terminal:”));
_delay(1000);
}
void loop() {
// iterative setting FOC phase voltage
//sensor.min_elapsed_time = 0.0001; // 0.0001 by default
// update the sensor values
// sensor.update();
motor.loopFOC();
// iterative function setting the outer loop target
// velocity, position or voltage
// if target not set in parameter uses motor.target variable
motor.move(target_velocity);
// user communication
command.run();
}