Arduino-FOC icon indicating copy to clipboard operation
Arduino-FOC copied to clipboard

Strange SVPWM waveform using atmega328p

Open z13660 opened this issue 4 years ago • 11 comments

motor running at open_loop_velocity_example.ino,motor can spin like normal,but when I connect to the oscilloscope, it is not a standard svpwm waveform I tried to change several atmega328p s,but the same. https://user-images.githubusercontent.com/23288802/116771035-d028d100-aa7a-11eb-9048-c2614f32f1c7.mp4

z13660 avatar May 01 '21 04:05 z13660

Hey @z13660 It doesn't look like space vector owl indeed. Did you enable it in code? motor.foc_modulation =FOCmodulationTtype::SpaceVectorPWM By default it's sinusoidal pwm, and in the scope it looks like sine owl to me :)

askuric avatar May 01 '21 07:05 askuric

Hey @z13660, have you had some time to investigate more the pwm signals?

askuric avatar May 07 '21 06:05 askuric

I will test it these days. The oscilloscope is at school. Please wait for a little longer. (^_^)

z13660 avatar May 07 '21 10:05 z13660

I tested it. Add motor.foc_modulation =FOCmodulationTtype::SpaceVectorPWM, the waveform did change a little, but still not the standerd SVPWM. In SVPWM MODE the waveform will bounce around at the Edge. https://user-images.githubusercontent.com/23288802/117557701-78a4e980-b0a8-11eb-80b0-0ccf2f6b7bac.mp4

// Open loop motor control example
#include <SimpleFOC.h>


// BLDC motor & driver instance
// BLDCMotor motor = BLDCMotor(pole pair number);
BLDCMotor motor = BLDCMotor(5);
// BLDCDriver3PWM driver = BLDCDriver3PWM(pwmA, pwmB, pwmC, Enable(optional));
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 10, 11, 8);



// instantiate the commander
Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_velocity, cmd); }

void setup() {

  // driver config
  // power supply voltage [V]
  driver.voltage_power_supply = 12;
  driver.init();
  // link the motor and the driver
  motor.linkDriver(&driver);

  // limiting motor movements
  motor.voltage_limit = 3;   // [V]
  motor.velocity_limit = 5; // [rad/s] cca 50rpm
  motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
  //motor.foc_modulation = FOCModulationType::SinePWM;
  // open loop control config
  motor.controller = MotionControlType::velocity_openloop;

  // init motor hardware
  motor.init();

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

  Serial.begin(115200);
  Serial.println("Motor ready!");
  Serial.println("Set target velocity [rad/s]");
  _delay(1000);
}

void loop() {

  // open loop velocity movement
  // using motor.voltage_limit and motor.velocity_limit
  motor.move(0.5);

  // user communication
  command.run();
}

z13660 avatar May 09 '21 01:05 z13660

OK I think I figure it out. Is it the timer2 problem? Changed the pin BLDCDriver3PWM(9, 10, 5, 8); and it work perfectly. Again if I use BLDCDriver3PWM(9, 10, 3, 8); pin3 still output the wrong waveform. It seem that we can not use Timer2

https://user-images.githubusercontent.com/23288802/117557894-6deb5400-b0aa-11eb-94da-9be0eec21149.mp4

z13660 avatar May 09 '21 01:05 z13660

Hey @z13660 , Can you elaborate a bit more about what do you mean that it is not a good waveform?

askuric avatar May 09 '21 07:05 askuric

1 2

z13660 avatar May 09 '21 07:05 z13660

I don`t know if the phase shift will cause any problems. e.g. like causing the motor spinning less smooth.

z13660 avatar May 09 '21 07:05 z13660

Hey @z13660,

Yes, I see what you mean. This is true, and if you look more closely you'll see that even in the image above pin3 is not perfectly aligned. This is due to the fact that the pins do not belong to the same timer. So far in the library, at least for arduino we did not do the timer synchonisation, mostly because arduinos are very limited in their capabilities and a lot of standard features do not even exist for them.

The shifted phase will not do much harm, at least if the shift is not too severe and if the pwm frequency is high. So that is why we did no see many complaints so far. But you're right that we should dig into this more carefully.

I've tested a quick code that was posted in this site and it worked for me: http://www.openmusiclabs.com/learning/digital/synchronizing-timers/index.html

So basically add this code right after your driver.init():

  // use only one of the following 3 lines
GTCCR = (1<<TSM)|(1<<PSRASY)|(1<<PSRSYNC); // halt all timers

// place all timer setup code here
// do not do any timer setup before this section

// set all timers to the same value
TCNT0 = 0; // set timer0 to 0
TCNT1H = 0; // set timer1 high byte to 0
TCNT1L = 0; // set timer1 low byte to 0
TCNT2 = 0; // set timer2 to 0

GTCCR = 0; // release all timers

This code should sync all the timers.

askuric avatar May 09 '21 07:05 askuric

Hey @askuric, Thanks for your codes. (^_^)

z13660 avatar May 09 '21 08:05 z13660

I'll leqve this issue opened for a bit. I'd like to get to the bottom of this. :D

askuric avatar May 09 '21 08:05 askuric

Included in the dev branch, and will be in the next release

askuric avatar Dec 22 '22 11:12 askuric