In the void loop() have some delay function

Move to target angle, i can see the motor so slowly,what i can do for this,use the interrupt?

It’s not really clear what you are trying to do from your short question.

You don’t want to use a delay(micros) in loop as it is blocking and any delay more than 1ms is going to badly effect motor.loopFOC() which needs to be called regularly.

Yes you could use an timer interrupt

Another approach is to keep track of your own time.

long action_interval_ms = 50;
long last_action_ms = 0;
float target_angle = 0.0;

void loop() {
  long now = _millis();
  if ((now - last_action_ms) > action_interval_ms) {
   // do stuff here, e.g change angle
   target_angle += 0.1;  // radians
   motor.move(target_angle);
    last_action_ms = now;
  } 
  // normal simplefoc
  motor.loopFOC();

}

OK, thanks.use the millis() to dealwith this problem,the motor have strong vibration,It was not before when i use the same pid.

In addition to the motor, there are also have 3 servos to be control,so i use the delay().

I try to use the timer interrupt to solve this problem now.Can I place the motor.loopfoc() to the interrupt.

Basically, you should be calling loopFOC regularly, and several 1000 times per second. Maybe 10kHz is good. On a fast MCU you might be able to call it from an interrupt handler.

Basically, a MCU that is running FOC algorithm probably can’t do a whole lot of other things as well. If you want to do this, you’ll have to be very careful about timings. Using delay() anywhere is basically a no-go. A 1ms delay means your loop will now be slower than 1kHz. Use delayMicros() if you must, but not for more than a few microseconds per loop.

See here https://community.simplefoc.com/t/running-foc-control-loop-inside-to-pwm-timer-overflow-interrupt-handler-or-adc-sample-finish-interrupt-handler/723
for a bit of discussion on this topic.

Thank you for your answer.I take the servos to the interrupt,and loopFOC it’s still in loop.

Hi, we tried to use this method and put target_angle +=1. The motor stop at the target angle, however it uses the longest path each time i.e. spins CW to 1rad, then spins CCW to 2rad etc.

How do we make the motor spins at one direction only? Is the angle displayed in motor.monitor() the same as sensor.getSensorAngle()? Our setup is Arduino Mega + AS5600 + Nanotec DB59 6pp motor + DRV8302

Thanks.

This is a bit of an old thread, and your question seems a bit different.

You are probably going to have to show us your code as target_angle is used in a bunch of examples as a variable and is also the arg to a few functions in the library. My guess is that your ‘target_angle’ is a variable in your main.cpp and that you are in ‘position control’ and are passing this variable to motor.move(target_angle)

motor.move takes an absolute position value as argument. So adding +=1 to it will make it move 1 radian in the same direction. But this is only true if your target_angle has its value initially set to the correct value.

I’m making big guesses about what your code might look like but perhaps calling this in your setup() function might give you what you expect:

target_angle = motor.shaft_angle;

my guess is that the shaft angle is actually at 2 radians initially but your target_angle is set (wrongly) to zero. When you increment from zero you are incrementing from a value that is not the real value.

This is a little difficult to explain - I hope you understand what I’m trying to say!