SimpleFOC Shield 2.0.4 torque control voltage limit

Hello Community,

I am attempting to control a Gimbal Motor (T-Motor GB54-1) using a cheap 600PPR Encoder in torque control mode (voltage control) with a SimpleFOC Shield 2.0.4 and an Arduino UNO. The motor voltage limit, driver voltage limit, and driver voltage power supply are set to 12V. The number of pole pairs is set to 7.

Here is my code:

#include <SimpleFOC.h>

BLDCMotor motor = BLDCMotor(7);
BLDCDriver3PWM driver = BLDCDriver3PWM(5, 9, 6, 8);

Encoder encoder = Encoder(2, 3, 600);

void doA() { encoder.handleA(); }
void doB() { encoder.handleB(); }

float target_voltage = 2;
Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_voltage, cmd); }

void setup() {
encoder.init();
encoder.enableInterrupts(doA, doB);
motor.linkSensor(&encoder);

driver.voltage_limit = 12;
driver.voltage_power_supply = 12;
driver.init();
motor.linkDriver(&driver);
motor.voltage_sensor_align = 5;

motor.torque_controller = TorqueControlType::voltage;
motor.controller = MotionControlType::torque;

Serial.begin(115200);
motor.useMonitoring(Serial);

motor.voltage_limit = 12;

motor.init();
motor.initFOC();

command.add(‘T’, doTarget, “target voltage”);

Serial.println(F(“Motor ready.”));
Serial.println(F(“Set the target voltage using serial terminal:”));
_delay(1000);
}

void loop() {
motor.loopFOC();
motor.move(target_voltage);

encoder.update();
Serial.print(“Enc1 Angle: “);
Serial.print(encoder.getAngle());
Serial.print(”\t”);
Serial.print(“Enc1 Velocity: “);
Serial.print(encoder.getVelocity());
Serial.print(”\t”);
Serial.print("Target Voltage: ");
Serial.println(target_voltage);

command.run();
}

The power supply has an output of 12V and 5A = 60W. Unfortunately, the motor doesn’t reach the expected velocity of about 41 Rad/s but stops at 25 Rad/s because the output voltage stagnates at 9V. I have already tried to use the internal resistance of the motor of 15.6 Ohms, which leads to a constant speed of 25 Rad/s regardless of the input.

Do you see the issue?
Thanks in advance.

Hi @Thomas_J , welcome to SimpleFOC!

Please remove the encoder.update() from the main loop, this is already called for you in motor.loopFOC() and it not useful to call it twice.

Please change the way your main loop prints to the Serial port. The loopFOC() function, and hence the main loop need to be called as fast as possible. Printing to the Serial port in a tight loop will result in overflowing the transmit buffer and causing blocking IOs. Change the code so the printlns happen only 1x per second, or every 1000 iterations or so.

After this you could repeat your experiment.

If the PSU voltage is 12V, and driver limit is 12V, then the modulation will be centred around 6V. Note that the commanded target voltages are in the FOC DQ coordinate frame, which can have positive or negative voltages. So I would recommend setting a motor.voltage_limit of 6V - this corresponds to ±6V and therefore a 12V range, like the PSU and driver limits (where voltages cannot be negative).

After this, when you command a voltage of 6V to the motor, you should indeed see a peak to peak amplitude of 12V on the output. You will have to check it with an oscilloscope. On a multi-meter, you can’t really measure this voltage…

You will then also get a feeling for the speed you can achieve. Depending on the motor setup, the speed will probably be limited either by the motor KV vs the drive voltage, or – also very likely – by the slow speed of the Arduino UNO to do the FOC updates.

Looking at this motor it is rated 3s-6s - so I guess you’d need 24v to get at all of that speed.

Hi @runger, Hi @Owen_Williams,

Thank you both for your responses. I made the recommended changes in my code, which increased the RPM, but the motor still didn’t perform as expected. Subsequently, I switched to a 20V power supply, and now everything works fine.

1 Like