BLDC senssorles dengan bantuan ir2110 dan Arduino UNO (full program + rangkaian + video)


         
          Motor dc brushless adalah motor dc tiga fase yang membutuhkan pengontrolan untuk menyalakan motor 3 fase. Pengontrol ini disebut ESC (Pengendali Kecepatan Elektronik). Pada Topik ini menunjukkan cara mengendarai motor BLDC menggunakan Arduino di mana kecepatannya dikontrol dengan potensiometer.

Motor brushless dc (BLDC) adalah motor 3 fase yang datang dalam dua tipe utama: sensored and sensorless. Teknik kontrol motor BLDC tanpa sensor didasarkan pada BEMF (Gaya Electromotive Kembali) yang diproduksi dalam belitan stator.

Di blog ini ada banyak topik yang menunjukkan bagaimana mengendalikan motor DC tanpa sensor menggunakan Arduino dan beberapa mikrokontroler PIC lainnya.
Salah satu proyek ini menunjukkan bagaimana membangun ESC sederhana menggunakan Arduino di mana kecepatan motor BLDC dikendalikan dengan dua tombol push. Dalam proyek ini saya akan membuat pengontrol yang sama tetapi potensiometer digunakan sebagai pengganti dua tombol push.

Saya menggunakan komparator analog internal Atmega328P (Arduino UNO) untuk mendeteksi peristiwa zero crossing dari 3 fase, tetapi itu bukan ide yang baik (dapat memberikan hasil yang buruk) untuk menggunakan komparator ini dan modul ADC karena mereka berbagi multiplexer yang sama. Jadi, saya menggunakan chip eksternal yang merupakan komparator quad LM339 IC.

rangkaian yang terhubung di LM339





Semua terminal ground terhubung bersama.
Seperti disebutkan di atas, motor dc brushless adalah motor 3 fase. Dalam diagram sirkuit di atas 3 fase diberi nama: Fase A, Fase B dan Fase C.Tiga buah resistor 33k pertama (terhubung ke fase motor) dan tiga resistor 10k digunakan sebagai pembagi tegangan, tiga 33k resistor lainnya menghasilkan titik alami virtual.

Dalam proyek ini kita membutuhkan 3 pembanding untuk membandingkan BEMF dari setiap fase sehubungan dengan titik alami virtual karena kita perlu mendeteksi zero crossing dari setiap fase, di sini saya menggunakan chip komparator quad LM339. Titik virtual terhubung ke input pembalik (-) dari tiga pembanding seperti yang ditunjukkan pada diagram sirkuit di atas. BEMF A terhubung ke pin non-pembalik (+) dari komparator nomor 1, BEMF B terhubung ke terminal positif komparator 2 dan BEMF C terhubung ke terminal positif komparator 3. Komparator 4 tidak digunakan dan inputnya terminal harus di-ground.
Seperti diketahui output komparator adalah logika 1 jika tegangan non-pembalik lebih besar dari tegangan pembalik dan sebaliknya.
Keluaran LM339 adalah kolektor terbuka yang berarti resistor pull up diperlukan untuk setiap output, untuk itu saya menggunakan tiga resistor 10k ohm.
Keluaran dari 3 pembanding dihubungkan ke pin Arduino 2, 3 dan 4 masing-masing untuk BEMF A, BEMF B dan BEMF C.
Pin Arduino UNO 2, 3 dan 4 masing-masing adalah pin interupsi eksternal mikrokontroler ATmega328P PCINT18, PCINT19 dan PCINT20.

Chip IR2110 digunakan untuk mengontrol Mosfet sisi tinggi dan sisi rendah dari setiap fase. Pergantian antara sisi tinggi dan sisi rendah dilakukan sesuai dengan garis kontrol HIN dan LIN. Gambar di bawah ini menunjukkan diagram waktu input dan output:




Garis HIN dari ketiga IR2110 dihubungkan ke pin 11, 10 dan 9 masing-masing untuk fase A, fase B dan fase C. Arduino UNO dapat menghasilkan sinyal PWM pada pin di mana hanya mosfet sisi tinggi yang PWMed.
Garis LIN terhubung ke pin Arduino 7, 6 dan 5 masing-masing untuk fase A, fase B dan fase C.



Potensiometer 10k digunakan untuk memvariasikan kecepatan motor BLDC, outputnya terhubung ke saluran analog Arduino 0 (A0).

Kontrol motor dc brushless dengan kode Arduino:
Pin Arduino 9, 10 dan 11 dapat menghasilkan sinyal PWM di mana pin 9 dan pin 10 terkait dengan modul Timer1 (OC1A dan OC1B) dan pin 11 terkait dengan modul Timer2 (OC2A). Kedua modul Timer dikonfigurasikan untuk menghasilkan sinyal PWM dengan frekuensi sekitar 31KHz dan resolusi 8 bit. Siklus tugas sinyal PWM diperbarui ketika modul ADC menyelesaikan konversinya dengan menulis ke register OCR1A, OCR1B dan OCR2A.

Sisa kode dijelaskan melalui komentar!

Program arudino !!!

#define PWM_MAX_DUTY      255
#define PWM_MIN_DUTY      50
#define PWM_START_DUTY    100

byte bldc_step = 0, motor_speed, pin_state;

void setup()
{
  DDRD  |= 0xE0;  // configure pins 5, 6 and 7 as outputs
  PORTD  = 0x00;
  DDRB  |= 0x0E;  // configure pins 9, 10 and 11 as outputs
  PORTB  = 0x31;
  // Timer1 module setting: set clock source to clkI/O / 1 (no prescaling)
  TCCR1A = 0;
  TCCR1B = 0x01;
  // Timer2 module setting: set clock source to clkI/O / 1 (no prescaling)
  TCCR2A = 0;
  TCCR2B = 0x01;
  // ADC module configuration
  ADMUX  = 0x60;   // configure ADC module and select channel 0
  ADCSRA = 0x84;   // enable ADC module with 16 division factor (ADC clock = 1MHz)

  PCICR  = EIMSK = 0;  // disable all external interrupts

  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
}

// pin change interrupt 2 (PCINT2) ISR
ISR (PCINT2_vect)
{
  if( (PIND & PCMSK2) != pin_state )
    return;
  // BEMF debounce
  for(byte i = 0; i < 20; i++)
  {
    if(bldc_step & 1){
      if(PIND & PCMSK2)     i -= 1;
    }
    else {
      if(!(PIND & PCMSK2))  i -= 1;
    }
  }

  bldc_move();
  bldc_step++;
  bldc_step %= 6;
}

// BLDC motor commutation function
void bldc_move()
{
  switch(bldc_step)
  {
    case 0:
      AH_BL();
      BEMF_C_FALLING();
      break;
    case 1:
      AH_CL();
      BEMF_B_RISING();
      break;
    case 2:
      BH_CL();
      BEMF_A_FALLING();
      break;
    case 3:
      BH_AL();
      BEMF_C_RISING();
      break;
    case 4:
      CH_AL();
      BEMF_B_FALLING();
      break;
    case 5:
      CH_BL();
      BEMF_A_RISING();
  }
}

void loop()
{
  SET_PWM_DUTY(PWM_START_DUTY);  // setup starting PWM with duty cycle = PWM_START_DUTY
  int i = 5000;

  // motor start
  while(i > 100)
  {
    delayMicroseconds(i);
    bldc_move();
    bldc_step++;
    bldc_step %= 6;
    i = i - 20;
  }

  motor_speed = PWM_START_DUTY;
 
  PCICR  = 4;  // enable pin change interrupt for pins PCINT23..16 (Arduino 0 to 7)
 
  while(1)
  {
    ADCSRA |= 1 << ADSC;    // start conversion
    while(ADCSRA & 0x40);   // wait for conversion complete
    motor_speed = ADCH;     // read ADC data (8 bits only)
    if(motor_speed < PWM_MIN_DUTY)
      motor_speed = PWM_MIN_DUTY;
    SET_PWM_DUTY(motor_speed);
  }
}

void BEMF_A_RISING()
{
  PCMSK2 = 0x04;    // enable Arduino pin 2 (PCINT18) interrupt, others are disabled
  pin_state = 0x04;
}
void BEMF_A_FALLING()
{
  PCMSK2 = 0x04;    // enable Arduino pin 2 (PCINT18) interrupt, others are disabled
  pin_state = 0;
}
void BEMF_B_RISING()
{
  PCMSK2 = 0x08;    // enable Arduino pin 3 (PCINT19) interrupt, others are disabled
  pin_state = 0x08;
}
void BEMF_B_FALLING()
{
  PCMSK2 = 0x08;    // enable Arduino pin 3 (PCINT19) interrupt, others are disabled
  pin_state = 0;
}
void BEMF_C_RISING()
{
  PCMSK2 = 0x10;    // enable Arduino pin 4 (PCINT20) interrupt, others are disabled
  pin_state = 0x10;
}
void BEMF_C_FALLING()
{
  PCMSK2 = 0x10;    // enable Arduino pin 4 (PCINT20) interrupt, others are disabled
  pin_state = 0;
}

void AH_BL()
{
  PORTD &= ~0xA0;
  PORTD |=  0x40;
  TCCR1A =  0;      // turn pin 11 (OC2A) PWM ON (pin 9 & pin 10 OFF)
  TCCR2A =  0x81;   //
}
void AH_CL()
{
  PORTD &= ~0xC0;
  PORTD |=  0x20;
  TCCR1A =  0;      // turn pin 11 (OC2A) PWM ON (pin 9 & pin 10 OFF)
  TCCR2A =  0x81;   //
}
void BH_CL()
{
  PORTD &= ~0xC0;
  PORTD |=  0x20;
  TCCR2A =  0;       // turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF)
  TCCR1A =  0x21;    //
}
void BH_AL()
{
  PORTD &= ~0x60;
  PORTD |=  0x80;
  TCCR2A =  0;      // turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF)
  TCCR1A =  0x21;   //
}
void CH_AL()
{
  PORTD &= ~0x60;
  PORTD |=  0x80;
  TCCR2A =  0;       // turn pin 9 (OC1A) PWM ON (pin 10 & pin 11 OFF)
  TCCR1A =  0x81;    //
}
void CH_BL()
{
  PORTD &= ~0xA0;
  PORTD |=  0x40;
  TCCR2A =  0;       // turn pin 9 (OC1A) PWM ON (pin 10 & pin 11 OFF)
  TCCR1A =  0x81;    //
}

void SET_PWM_DUTY(byte duty)
{
  OCR1A  = duty;  // set pin 9  PWM duty cycle
  OCR1B  = duty;  // set pin 10 PWM duty cycle
  OCR2A  = duty;  // set pin 11 PWM duty cycle
}

video on youtube


No comments:

Post a Comment

Pages