setPhaseVoltage() works, but open-loop outputs 0V - pico2&Simple Foc mini

Hi everyone,

I am working on a project using a Raspberry Pi Pico2 and a SimpleFOC Mini board to drive a 2805 140KV Gimbal Motor.

I have a strange issue where open-loop control fails completely, even though manual voltage control works.

Code 1 (setPhaseVoltage): Works perfectly. The driver outputs voltage and the motor spins.

Code 2 (velocity_openloop + motor.move): Does not work. Multimeter shows exactly 0V on the motor phases, and motor.Ua, Ub, Uc constantly print 0.00 in the Serial monitor.

Tested on both Pico (RP2040) and Pico 2 (RP2350) — same issue on both.

Code 1:

#include <Arduino.h>
#include <SimpleFOC.h>

BLDCMotor motor = BLDCMotor(7);
BLDCDriver3PWM driver = BLDCDriver3PWM(10, 11, 12, 13);
float test_angle = 0.0;

void setup() {
  Serial.begin(115200);
  delay(3000); 
  driver.voltage_power_supply = 12.0;
  if(!driver.init()) {
    Serial.println("Driver Init Failed!");
    return;
  }
  motor.linkDriver(&driver);
  motor.voltage_limit = 5.0;

  motor.init();
  driver.enable();
  motor.enable();
}

void loop() {
  test_angle += 0.05; 
  if(test_angle > _2PI) test_angle = 0;

  motor.setPhaseVoltage(3.0, 0.0, test_angle);

  Serial.print("Ua: "); Serial.print(motor.Ua);
  Serial.print(" | Ub: "); Serial.print(motor.Ub);
  Serial.print(" | Uc: "); Serial.println(motor.Uc);

  delay(10); 
}

Code 2:

#include <Arduino.h>
#include <SimpleFOC.h>

BLDCMotor motor = BLDCMotor(7);
BLDCDriver3PWM driver = BLDCDriver3PWM(10, 11, 12, 13);

void setup() {
  Serial.begin(115200);
  delay(3000); 
  driver.voltage_power_supply = 12.0;
  driver.voltage_limit = 12.0;
  if(!driver.init()) {
    Serial.println("Driver Init Failed");
    return;
  }
  motor.linkDriver(&driver);
  motor.voltage_limit = 5.0; // tested 3 ~ 12
  
  motor.controller = MotionControlType::velocity_openloop;
  motor.init();
  // tested with and without motor.initFOC(), still 0V
  // motor.initFOC();
  driver.enable();
  motor.enable();
}

void loop() {
  motor.move(2.0);

  Serial.print("Ua: "); Serial.print(motor.Ua);
  Serial.print(" | Ub: "); Serial.print(motor.Ub);
  Serial.print(" | Uc: "); Serial.println(motor.Uc);
  delay(1); // tested 0 ~ 10
}

Any advice would be appreciated!

2 Answers

2

You’ll need to add motor.loopFOC() to the loop.

It is required from the version 2.4.0+

Strange, that’s basically what open loop does.

I’d go into the SimpleFOC source (may be difficult to track down exactly where it is on your hard drive, it’s C:\Arduino\libraries\Arduino-FOC on mine, but I think it was originally buried in the Windows user data folders or something) src/common/base_classes/FOCMotor.cpp, search loopFOC, go down to the bottom where it calls setPhaseVoltage, and add Serial.print("voltage.q: "); Serial.print(voltage.q); to find out if it’s even calling setPhaseVoltage, and if so is it setting it to 0 instead of voltage_limit like it should.