# Rotate BLDC motor with Clark and Park transform

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?

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