0
\$\begingroup\$

I'm trying to rotate BLDC motor using FOC method without sensing anything from the motor. I just slowly increment angle from 0 to 2PI and then use Park-Clarke transform with Vq and Vd equal to 1.0 to get 3 phase which I then use for Space Vector modulation. The problem is that the motor doesn't rotate smoothly, here is a video of Rotating motor and here is my code for arduino platform:

#include "CDFraction.h"
#include <Arduino.h>
#include <SPI.h>
#include <limits.h>



#define CLAMP(x, a, b) ((x) < (a) ? (a) : ((x) > (b) ? (b) : (x)))



float angleIncrement = 3.141592653589793 * 0.001f;
float angle = 0;

float Vsq = 1.0; 
float Vsd = 1.0;

float Va = 0;
float Vb = 0;
float Vc = 0;

int16_t Ta = 0;
int16_t Tb = 0;
int16_t Tc = 0;




SPISettings drv8305SPISettings(1000000, MSBFIRST, SPI_MODE1);
uint8_t drvSelectPin = 5;
uint8_t drvEnablePin = 4;

void setup() 
{
  pinMode(3, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(drvSelectPin, OUTPUT);
  digitalWrite (drvSelectPin, HIGH);
  pinMode(drvEnablePin, OUTPUT);
  digitalWrite (drvEnablePin, LOW);

  TCCR1B &= B11111000;
  TCCR1B |= B00000001;
  TCCR2B &= B11111000;
  TCCR2B |= B00000001;

  //initialize Serial
  Serial.begin(115200);
  // initialize SPI:
  SPI.begin();

  uint16_t drvCmd = (0 << 15) | (0x7 << 11) | 0x0296;
  uint16_t drvRes = 0;


  SPI.beginTransaction(drv8305SPISettings);
  digitalWrite (drvSelectPin, LOW);
  // reading only, so data sent does not matter
  drvRes = SPI.transfer16(drvCmd);
  digitalWrite (drvSelectPin, HIGH);
  SPI.endTransaction();
  Serial.println(drvRes, BIN);

  digitalWrite (drvEnablePin, HIGH);

}


void loop() 
{

  float VsqSinA = Vsq * sinf(angle);
  float VsdCosA = Vsd * cosf(angle);

  float Valpha = VsdCosA - VsqSinA;
  float Vbeta = VsdCosA + VsqSinA;

  float Valpha_temp = -0.5f * Valpha;
  float Vbeta_temp = 0.866025403784439 * Vbeta;

  Va = Valpha;
  Vb = Valpha_temp + Vbeta_temp; //-05f * alpha + sqrt(3)/2 * beta
  Vc = Valpha_temp - Vbeta_temp; //-05f * alpha - sqrt(3)/2 * beta

  float Vmax = 0;
  float Vmin = 0;

  if(Va > Vb)
  {
    Vmax = Va;
    Vmin = Vb;
  }
  else
  {
    Vmax = Vb;
    Vmin = Va;
  }


  if(Vc > Vmax)
  {
    Vmax = Vc;
  }
  else if (Vc < Vmin)
  {
    Vmin = Vc;
  }

  float Vcom = (Vmax + Vmin) * 0.5f;

  Ta = floor((Va - Vcom + 1.2246778011322)/2.4493556022644 * 12 + 0.5f);
  Tb = floor((Vb - Vcom + 1.2246778011322)/2.4493556022644 * 12 + 0.5f);
  Tc = floor((Vc - Vcom + 1.2246778011322)/2.4493556022644 * 12 + 0.5f);

  analogWrite( 3, CLAMP (Ta,  0, 255));
  analogWrite( 9, CLAMP (Tb,  0, 255));
  analogWrite(10, CLAMP (Tc,  0, 255));

//  Serial.print(Va);
//  Serial.print(" ");
//  Serial.print(Vb);
//  Serial.print(" ");
//  Serial.println(Vc);
//
//  delay(10);

  angle += angleIncrement;
  if(angle > 6.283185307179586)angle = 0;

}

What I'm doing wrong?

\$\endgroup\$
  • \$\begingroup\$ You should add a bit more about your schematic...such as the DRV8305 you're using \$\endgroup\$ – scld Jan 26 '17 at 0:48
  • \$\begingroup\$ It's a simple DRV8305 board which is in 3 PWM mode \$\endgroup\$ – Harry Jan 26 '17 at 0:50
0
\$\begingroup\$

Your motor has a silicon steel stator core which increases the magnetic strength of the coils. Unfortunately the rotor magnets are attracted to the stator polefaces, creating a 'cogging torque' which makes the movement jerky. Here's an example of cogging torque in a 14 pole brushless motor:-

enter image description here

To cancel out the cogging torque you must modify the drive current waveforms. The exact waveform required depends on the particular geometry of your motor (poleface shape, magnet size and positions, airgap etc.). In a motor with strong Neodym magnets there is a fine balance of forces, so any slight misalignments can greatly affect the cogging torque waveform. Therefore for best results you will have to customize the drive waveforms to match your particular motor.

However without any feedback it is not possible to measure the actual cogging torque, so all you can do is try different waveforms until you get the smoothest movement. I would start by mixing in varying amplitudes and phase of 3rd and 5th harmonics.

\$\endgroup\$
  • \$\begingroup\$ Got it, can you tell me how can I add harmonics to Park transform. For exemple if I want to add 3rd harmonics? when I'm adding to sinf(angle) sinf(angle*3) and to cosf(angle) cosf(angle*3) it mess up phases \$\endgroup\$ – Harry Jan 26 '17 at 19:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.