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