Motor keeps spinning in whatever direction you spin it in

Hello,
I’ve been trying to get this library working on a teensy 4.1 with a SimpleFOC Mini and an AS5147U magnetic sensor, but i’ve been experiencing a few issues:

At first the motor was making a high pitch squealing sound; the only thing that fixed this was manually setting the PWM frequency of each pin with analogWriteFrequency to 25000 like in src/drivers/hardware_specific/teensy/teensy_mcu.h.

When I tried to use torque control, the motor would do nothing at all no matter what value I passed to move(). If I manually moved the motor, it would keep moving in that direction (the torque can be at 0). While the motor was moving, I could change its direction by setting the torque, but if I stopped it, I had to manually restart it. video

This is my code:

#include <SimpleFOC.h>

// init BLDC motor
BLDCMotor motor = BLDCMotor(7, 5.6, 160);
// init driver
BLDCDriver3PWM driver = BLDCDriver3PWM(3, 4, 5, 2);
//  init encoder
MagneticSensorSPI sensor = MagneticSensorSPI(10, 14, 0x3FFF);

// target variable
float target = 0;

// commander interface
Commander command = Commander(Serial);
void onTarget(char* cmd){ command.scalar(& target, cmd); }

void setup() {
  delay(2000);
  Serial.begin(115200);
  SimpleFOCDebug::enable(&Serial);

  analogWriteFrequency(3, 25000);
  analogWriteFrequency(4, 25000);
  analogWriteFrequency(5, 25000);
  
  sensor.clock_speed = 10000000;
  sensor.init();

  // link the motor to the sensor
  motor.linkSensor(&sensor);

  // power supply voltage
  // default 12V
  driver.voltage_power_supply = 12;

  driver.pwm_frequency = 25000;

  driver.init();
  // link the motor to the driver
  motor.linkDriver(&driver);

  // set control loop to be used
  motor.controller = MotionControlType::torque;
  
  //default voltage_power_supply
  motor.voltage_limit = 2;
  
  // initialize motor
  motor.init();

  // align encoder and start FOC
  motor.initFOC();

  // add target command T
  command.add('T', onTarget, "target");

  motor.useMonitoring(Serial);
  motor.monitor_variables = _MON_TARGET | _MON_VEL | _MON_ANGLE;

  Serial.println("Motor ready.");
  _delay(5000);
}

void loop() {
  motor.monitor();

  // iterative FOC function
  motor.loopFOC();

  // function calculating the outer position loop and setting the target position 
  motor.move(target);

  // user communication
  command.run();
}

I also tried velocity_openloop, which worked well, and velocity, which had similar issues as torque.

Most likely the kv passed to the BLDCMotor constructor needs tuning. Add a command to change motor.KV_rating and fiddle it up and down until it acts right. This is using voltage-based current limiting to apply a constant torque regardless of speed, so an un-loaded motor should accelerate to full speed even if the target is fairly small. But target 0 should still stop moving.

1 Like

Are you sure the sensor is working as expected? you could print the sensor value without any of the motor and driver code to verify its functionality.

1 Like

This solved it! I had previously just trusted the manufacturer’s 160 KV rating, but when I calculated it, it was more like 335. Thanks!

1 Like

Ive printed it out using the monitor, but it looks correct. The position goes up by a bit over 6 radians every rotation.