-1
\$\begingroup\$

I'm using a standard board for control this type of motor (SimpleBGC), this board uses an atmeg328p e some brushless drivers. I'm writing a simple code for turn left/right with some velocity, but i'm having some troubles. The motors are overheating, and the torque is very low. The motor have 12 poles??(Poles: 12N14P), how I adjust the correct frequency of pwm for this number of poles? And I want understand the relationship between number of poles and frequency of pwm timers.

1) EDIT The board that I'm using - https://goo.gl/kaeOot This board uses a atmega328p, and for drive power to the motors with this MOSFET 4606

The motor that I'm trying to use - http://rctimer.com/product-1075.html

The code

//main loop--------------------------------------------------------
#include <math.h>

#define LEDPIN   A1

bool power = false;            //run when power is true

uint16_t freqCounter = 0;
uint16_t oldfreqCounter = 0;
uint16_t loop_time = 0;         //how fast is the main loop running

//motor control-------------------------------------------------------
#define PWM_A_MOTOR1 OCR2A
#define PWM_B_MOTOR1 OCR1B
#define PWM_C_MOTOR1 OCR1A

#define PWM_A_MOTOR0 OCR0A
#define PWM_B_MOTOR0 OCR0B
#define PWM_C_MOTOR0 OCR2B

#define RESOLUTION 255
#define MOTOR_POWER 255 // 0 to 255, 255==100% power

uint8_t idl_motor_power = 80;

// motor numbers
#define L_Motor 0
#define R_Motor 1

// motor pole angle, 0->255 overflow to loop after >>8 shift
uint16_t R_MotorStep = 0;
uint16_t L_MotorStep = 0;

float robot_speed;

//rotation speed for turning
int8_t rot_Speed = 0;

// speed of motors, -127 to 127
int16_t R_Speed = 0;
int16_t L_Speed = 0;

float R_pos = 0;
float L_pos = 0;

//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
//------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------
//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

void setup()
{
  // Start Serial Port
  Serial.begin(11520);

  //Setup brushless motor Controller
  Bl_Setup();
  Serial.println("BL motor setup - ok");

  while (Serial.available())  Serial.read();        // empty RX buffer
}


void loop()
{
  //run main loop every ~4ms
  R_Speed = 50;
  L_Speed = 100;
}

//--------------------------------------------------------------------
//Motor control stuff-------------------------------------------------
//--------------------------------------------------------------------

void Bl_Setup()
{
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);

  digitalWrite(LEDPIN, HIGH);

  cli();//stop interrupts

  //timer setup for 31.250KHZ phase correct PWM
  TCCR0A = 0;
  TCCR0B = 0;
  TCCR0A = _BV(COM0A1) | _BV(COM0B1) | _BV(WGM00);
  TCCR0B = _BV(CS00);
  TCCR1A = 0;
  TCCR1B = 0;
  TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10);
  TCCR1B = _BV(CS10);
  TCCR2A = 0;
  TCCR2B = 0;
  TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM20);
  TCCR2B = _BV(CS20);

  // enable Timer 1 interrupt
  TIMSK1 = 0;
  TIMSK1 |= _BV(TOIE1);
  // disable arduino standard timer interrupt
  TIMSK0 &= ~_BV(TOIE1);

  sei(); // Start Interrupt

  //turn off all PWM signals
  OCR2A = 0;  //11  APIN
  OCR2B = 0;  //D3
  OCR1A = 0;  //D9  CPIN
  OCR1B = 0;  //D10 BPIN
  OCR0A = 0;  //D6
  OCR0B = 0;  //D5

  // switch off PWM Power
  motorPowerOff();
}

// switch off motor power
void motorPowerOff() {
  MoveMotors(L_Motor, 0, 0);
  MoveMotors(R_Motor, 0, 0);
  R_Speed = 0;
  L_Speed = 0;
}

void MoveMotors(uint8_t motorNumber, uint8_t posStep, uint16_t power)
{
  int16_t pwm_a;
  int16_t pwm_b;
  int16_t pwm_c;

  pwm_a = (int16_t) 128+128*sin(2*M_PI*(double)(posStep)/RESOLUTION);
  pwm_b = (int16_t) 128+128*sin(2*M_PI*(0.33+(double)(posStep)/RESOLUTION));
  pwm_c = (int16_t) 128+128*sin(2*M_PI*(0.66+(double)(posStep)/RESOLUTION));

  // scale motor power
  pwm_a *= power/255;
  pwm_b *= power/255;
  pwm_c *= power/255;

  // set motor pwm variables
  if (motorNumber == 0)
  {
    PWM_A_MOTOR0 = (uint8_t)pwm_a;
    PWM_B_MOTOR0 = (uint8_t)pwm_b;
    PWM_C_MOTOR0 = (uint8_t)pwm_c;
  }

  if (motorNumber == 1)
  {
    PWM_A_MOTOR1 = (uint8_t)pwm_a;
    PWM_B_MOTOR1 = (uint8_t)pwm_b;
    PWM_C_MOTOR1 = (uint8_t)pwm_c;
  }
}

//--------------------------------------------------------------
// code loop timing---------------------------------------------
//--------------------------------------------------------------
// minimize interrupt code length
// is called every 31.875us (510 clock cycles)  ???????
ISR( TIMER1_OVF_vect )
{
  //every 32 count of freqCounter ~1ms
  freqCounter++;

  if ((freqCounter & 0x01f) == 0)
  {
    // record when loop starts
    oldfreqCounter = freqCounter;

    if(R_pos>RESOLUTION) R_pos=0;
    if(L_pos>RESOLUTION) L_pos=0;
    MoveMotors(R_Motor, (uint8_t) R_pos, MOTOR_POWER);
    MoveMotors(L_Motor, (uint8_t) L_pos, MOTOR_POWER);
    R_pos+=R_Speed/20;
    L_pos+=L_Speed/20;

    //calculate loop time
    if (freqCounter > oldfreqCounter)
    {
      if (loop_time < (freqCounter - oldfreqCounter)) loop_time = freqCounter - oldfreqCounter;
    }

  }

}
\$\endgroup\$
  • \$\begingroup\$ Please provide a link to the datasheet for the control board and brushless motors (BLDC). Please post your code. We need a lot more information to help you. When you say "I'm writing a simple code for turn left/right with some velocity" what library are you using to control the BLDC? Do you understand that a Brushless motor needs three signal phases, and can not be easily driven with a raw PWM signal? They are somewhat more complex to drive than a stepper motor. I apologise, but your post reads as if you don't understand how to drive them. \$\endgroup\$ – gbulmer May 3 '16 at 19:54
  • \$\begingroup\$ Ok, I will try rewriting my question, thank you for the answer!!! \$\endgroup\$ – payton_2624784 May 3 '16 at 20:31
0
\$\begingroup\$

The motors are overheating, and the torque is very low.

This is to be expected. Brushless gimbal motors are designed to stabilize a camera platform, and are operated 'stalled' with continuous holding current (like a stepper motor). They are wound with many turns of fine wire to get high resistance and low torque. This is desirable for gimbals because you want just enough torque to rotate the camera (or hold it in position) without shaking. The camera and gimbals are mechanically balanced, so very little torque is required.

To get enough torque for traction you may need to operate the motors on a much higher voltage. These motors may not be suitable for your application.

The motor have 12 poles??(Poles: 12N14P)

'14P' is the number of magnet poles facing the stator. Your motors have 14 magnets and 14 poles. '12N' is the number of stator arms. For a 3 phase motor this will be a multiple of 3.

how I adjust the correct frequency of pwm for this number of poles?

PWM frequency is not related to the number of poles. The frequency just has to be high enough for current to be smoothed out by the winding inductance. Your motors have quite high inductance so they shouldn't need a very high PWM frequency (though using >=20KHz will avoid the annoying whining sound that the motor makes with audio frequency PWM).

And I want understand the relationship between number of poles and frequency of pwm timers.

A normal sensorless controller doesn't need to know anything about how many poles the motor has - it simply commutates the 3 phases in a 6 step sequence. A motor with more poles will spin slower because it takes more 6 step cycles to do a full rotation, but the controller only sees the back-emf from each coil and doesn't know how fast the motor is turning mechanically.

However a brushless gimbal controller is a bit different. Instead of sensing back-emf it gets feedback from gyros attached to the camera platform. The controller then uses a PID algorithm to stabilize the camera. Such a controller will not be able to spin a traction motor at high rpm and torque because without a feedback mechanism it cannot determine the correct commutation points.

\$\endgroup\$
  • \$\begingroup\$ I change a bit a question, add some information!! Thank you very much for the answer!! \$\endgroup\$ – payton_2624784 May 3 '16 at 22:30
0
\$\begingroup\$

Your question is a mess. I guess, it's sensorless motor. It should be commutated very certain way, otherwise the current will not cause torque and will be very high heating the motor. But you already knkw it.

So you can't write a program to operate PWM directly. You in fact must detect what is the motor position within electrical cycle. Then you cen apy voltage to certain phase. And then the current will be effective.

\$\endgroup\$
  • \$\begingroup\$ Ok, I will try rewriting my question, thank you for the answer! \$\endgroup\$ – payton_2624784 May 3 '16 at 20:29
  • \$\begingroup\$ Welcome... Most importantly understand what you have got. The motor has three phases. I am almost sure is trapezoidal, meaning one phase should be driven at each time. Commutation is the process of changing the phase. To change it you have to know, that the motor rotated to a other phase. And to know that you have to measure voltage on the phase when it's not driven. Now that's pretty complicated. Doing it for the first time is a fun challenge. But maybe your driver already does it. So know what you have exactly. \$\endgroup\$ – Gregory Kornblum May 3 '16 at 20:35

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.