Go Down

Topic: Brushless Motor Basic Programming Question (Read 755 times) previous topic - next topic

mamette

Hi everyone..

I have try code for rotating my brushless motor from here:
http://elabz.com/bldc-motor-with-arduino-circuit-and-software/

Because i just want to rotating my brushless motor, i modify the code to be like this:
Code: [Select]
/*
Driving a DVD drive spindle three-phase motor

This code was used for the stroboscope project
 
This example code is in the public domain. Based on several Arduino code samples

http://elabz.com/

*/

// constants won't change. They're used here to
// set pin numbers:
const int motorPin1 =3;
const int motorPin2 =6;
const int motorPin3 =5;
const int motorDelay=0; // together with pot controls the RPM
const int potState=0;       // controls the RPM speed

// Variables will change:
boolean direct = true; // direction true=forward, false=backward


/*
int pwmSin[] = {127,110,94,78,64,50,37,26,17,10,4,1,0,1,4,10,17,26,37,50,64,78,94,110,127,144,160,176,191,204,217,228,237,244,250,253,254,253,250,244,237,228,217,204,191,176,160,144,127
}; // array of PWM duty values for 8-bit timer - sine function
*/

int pwmSin[]={511,444,379,315,256,200,150,106,68,39,17,4,0,4,17,39,68,106,150,200,256,315,379,444,511,578,643,707,767,822,872,916,954,983,1005,1018,1022,1018,1005,983,954,916,872,822,767,707,643,578,511
}; // array of PWM duty values for 10-bit timer - sine function

int increment;
int currentStepA=0;
int currentStepB=16;
int currentStepC=32;

// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long motorDelayActual = 0;  // the actual delay, based on pot value and motor delay set above
long lastMotorDelayTime = 0;



void setup() {
 
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
 
  TCCR1B = TCCR1B & 0b11111000 | 0x01; // set PWM frequency @ 31250 Hz for Pins 9 and 10
  TCCR2B = TCCR2B & 0b11111000 | 0x01; // set PWM frequency @ 31250 Hz for Pins 11 and 3 (3 not used)

  //ICR1 = 255 ; // 8 bit resolution
  ICR1 = 1023 ; // 10 bit resolution




}

void loop() {

motorDelayActual =   potState * motorDelay / 100;
move();
   
}



void move() {
if((millis() - lastMotorDelayTime) >  motorDelayActual)
{ // delay time passed, move one step

  if (direct==true)
  {
    increment = 1;
  }
    else
    {
     increment = -1; 
    }
  currentStepA = currentStepA + increment;
  if(currentStepA > 47) currentStepA = 0;
  if(currentStepA<0) currentStepA =47;
   
  currentStepB = currentStepB + increment;
  if(currentStepB > 47) currentStepB = 0;
  if(currentStepB<0) currentStepB =47;
   
    currentStepC = currentStepC + increment;
  if(currentStepC > 47) currentStepC = 0;
  if(currentStepC<0) currentStepC =47;

lastMotorDelayTime = millis();
}
   
analogWrite(motorPin1, pwmSin[currentStepA]);
analogWrite(motorPin2, pwmSin[currentStepB]);
analogWrite(motorPin3, pwmSin[currentStepC]);
   
}


And it's works..

But, there is something that i not understand. I use ATMega 328p and use pins 3,6 and 5 as PWM output. And i set the PWM register is like this:
Code: [Select]
TCCR1B = TCCR1B & 0b11111000 | 0x01; // set PWM frequency @ 31250 Hz for Pins 9 and 10
  TCCR2B = TCCR2B & 0b11111000 | 0x01; // set PWM frequency @ 31250 Hz for Pins 11 and 3 (3 not used)

  //ICR1 = 255 ; // 8 bit resolution
  ICR1 = 1023 ; // 10 bit resolution


TCCR1B is PWM register for pins 9 and 10 (OC1A and OC1B), then TCCR2B is PWM register for pins 11 and 3 (OC2A and OC2B). But, i use pins 3, 6 and 5. It is ok for TCCR1B because it is for pin 3, but how about TCCR2B? TCCR2B is for pin 9 and 10, not for pins 6 and 5. But the code is works well..

Then, i change the PWM register to be like this:
Code: [Select]
  TCCR2B = TCCR2B & 0b11111000 | 0x01; // set PWM frequency @ 31250 Hz for Pins 11 and 3 (3 not used)
  TCCR0B = TCCR0B & 0b11111000 | 0x01; // set PWM frequency @ 31250 Hz for Pins 5 and 6


I change TCCR1B with TCCR0B because TCCR0B is for pins 6 and 5 (OC0A and OC0B). But, the code is not works when i change it. This is confusing, when i use the right register, the code not works. But when i use wrong register, the code works well..

Does anybody know why this happen?

Thank You..

MarkT

timer0 controls PWM on pins 5 and 6 but also does the timer interrupts for millis(), so if you change its
clock then mills(), micros() and delay() will stop working properly.

timers 0, 1 and 2 are all different in details.  only timer1 can do more than 8 bits.
[ I won't respond to messages, use the forum please ]

mamette


timer0 controls PWM on pins 5 and 6 but also does the timer interrupts for millis(), so if you change its
clock then mills(), micros() and delay() will stop working properly.

timers 0, 1 and 2 are all different in details.  only timer1 can do more than 8 bits.


So, if i use TCCR0B, then mills(), micros() and delay() will stop working properly? So, using TCCR1B for pins 5 and 6 is OK?

MarkT

timer0 controls pins 5,6
timer1 controls pins 9,10
timer2 controls pins 11,3

This is hardware fixed, cannot be changed.
[ I won't respond to messages, use the forum please ]

mamette

Now i try to just use one of TCCR2B or TCCR1B and use 8 bit PWM resolution. When i use TCCR2B or TCCR1B, it's works well, but if i use TCCR0B, the brushless motor is not rotating.

The code is become like this:

Code: [Select]
// constants won't change. They're used here to
// set pin numbers:
const int motorPin1 =3;
const int motorPin2 =6;
const int motorPin3 =5;

// Variables will change:
boolean direct = true; // direction true=forward, false=backward

int pwmSin[] = {127,110,94,78,64,50,37,26,17,10,4,1,0,1,4,10,17,26,37,50,64,78,94,110,127,144,160,176,191,204,217,228,237,244,250,253,254,253,250,244,237,228,217,204,191,176,160,144,127
}; // array of PWM duty values for 8-bit timer - sine function


//int pwmSin[]={511,444,379,315,256,200,150,106,68,39,17,4,0,4,17,39,68,106,150,200,256,315,379,444,511,578,643,707,767,822,872,916,954,983,1005,1018,1022,1018,1005,983,954,916,872,822,767,707,643,578,511
//}; // array of PWM duty values for 10-bit timer - sine function

int increment;
int currentStepA=0;
int currentStepB=16;
int currentStepC=32;

// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
//long motorDelayActual = 0;  // the actual delay, based on pot value and motor delay set above
long lastMotorDelayTime = 0;

void initBLDC() {

  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
 
  //TCCR1B = TCCR1B & 0b11111000 | 0x01; // set PWM frequency @ 31250 Hz for Pins 9 and 10
  TCCR2B = TCCR2B & 0b11111000 | 0x01; // set PWM frequency @ 31250 Hz for Pins 11 and 3 (3 not used)
  //TCCR0B = TCCR0B & 0b11111000 | 0x01; // set PWM frequency @ 31250 Hz for Pins 5 and 6
 
  ICR1 = 255 ; // 8 bit resolution
}


void setup() {
 
  initBLDC();
 
}


void loop() {

BLDCmove();
   
}



void BLDCmove() {
if((millis() - lastMotorDelayTime) > 0)
{ // delay time passed, move one step

  if (direct==true)
  {
    increment = 1;
   
  currentStepA = currentStepA + increment;
  if(currentStepA > 47) currentStepA = 0;
  if(currentStepA<0) currentStepA =47;
   
  currentStepB = currentStepB + increment;
  if(currentStepB > 47) currentStepB = 0;
  if(currentStepB<0) currentStepB =47;
   
    currentStepC = currentStepC + increment;
  if(currentStepC > 47) currentStepC = 0;
  if(currentStepC<0) currentStepC =47;
 
  }
   
   
  if (direct==false)
  {
    increment = -1;
   
  currentStepA = currentStepA + increment;
  if(currentStepA > 47) currentStepA = 0;
  if(currentStepA<0) currentStepA =47;
   
  currentStepB = currentStepB + increment;
  if(currentStepB > 47) currentStepB = 0;
  if(currentStepB<0) currentStepB =47;
   
    currentStepC = currentStepC + increment;
  if(currentStepC > 47) currentStepC = 0;
  if(currentStepC<0) currentStepC =47;
  }
 
lastMotorDelayTime = millis();

}
   
analogWrite(motorPin1, pwmSin[currentStepA]);
analogWrite(motorPin2, pwmSin[currentStepB]);
analogWrite(motorPin3, pwmSin[currentStepC]);
   
}


So, it is ok if i just use 1 PWM register?

Go Up