/** * * 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 // magnetic sensor instance - SPI // MagneticSensorSPI sensor = MagneticSensorSPI(AS5048_SPI, 7); // MagneticSensorSPI(int cs, float _cpr, int _angle_register) // cs - SPI chip select pin // bit_resolution - magnetic sensor resolution // angle_register - (optional) angle read register - default 0x3FFF MagneticSensorSPI sensor = MagneticSensorSPI(1, 14); // Chip select pin is 1 for Xiao RP2040 and 7 for Xiao SAMD21 // try: // MagneticSensorSPI sensor = MagneticSensorSPI(7, 14); // 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(int pp, (optional R, KV)) // - pp - pole pair number // - R - phase resistance value - optional // - KV - motor KV rating [rpm/V] - optional //BLDCMotor motor = BLDCMotor(11, 10.5, 120); BLDCMotor motor = BLDCMotor(7); // Number of pole pairs // BLDCDriver3PWM driver = BLDCDriver3PWM(pwmA, pwmB, pwmC, Enable(optional)); BLDCDriver3PWM driver = BLDCDriver3PWM(29, 6, 0, 7); // The pins are 29, 6, 0, 7 for Xiao RP2040 and 3, 4, 6, 5 for Xiao SAMD21 (Modular Thing) and 0, 7, 6, 29 for SimpleFOC Mini with Xiao RP2040 // 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); } // Define the DAC pin // #define DAC_PIN A0 void setup() { // Set up the DAC resolution (the DAC is on pin 1): // analogWriteResolution(10); // Set analog out resolution to max, 10-bits // analogReadResolution(12); // Set analog input resolution to max, 12-bits // Set the COMPN pin on the MS8313 motor driver as an output, get the other settings in the DAC test // pinMode(1, OUTPUT); // I didn't include pinMode in the DAC test and it worked fine // The measured USB supply voltage is 5.188 V and the IC operating voltage is 3.310 V. // 0.2V/3.31V * 1024 (or maybe 1023) = 61.8 // OK, so to get the right reference voltage out of the DAC, measure the 3.3V voltage and put into the formula above // analogWrite(DAC_PIN, 62); // Set the SLEEP pin on the MS8313 motor driver HIGH // pinMode(1, OUTPUT); // digitalWrite(1, HIGH); // initialise magnetic sensor hardware sensor.init(); // link the motor to the sensor motor.linkSensor(&sensor); // driver config // power supply voltage [V] driver.voltage_power_supply = 10; 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; //ORIGINALLY 0.2f -Svavar motor.PID_velocity.I = 5; //ORIGINALLY 20 -Svavar motor.PID_velocity.D = 0; //ORIGINALLY 0 -Svavar // maximal voltage to be set to the motor motor.voltage_limit = 8; // velocity low pass filtering time constant // the lower the less filtered motor.LPF_velocity.Tf = 0.01f; //ORIGINALLY 0.01f -Svavar // angle P controller motor.P_angle.P = 5; // this was originally 20 -Svavar // maximal velocity of the position control motor.velocity_limit = 10; // this was originally 20 -Svavar // use monitoring with serial Serial.begin(115200); // comment out if not needed motor.useMonitoring(Serial); // VERBOSE MONITORING OUTPUT command.verbose = VerboseMode::machine_readable; // can be set using the webcontroller - optional // 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() { // OUTPUT MONITORING DATA TO SIMPLEFOC STUDIO motor.monitor(); // 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(); }