
به نام خدا
کنترل موتور براشلس دی سی بدون سنسور با آردوینو به همراه کد
در این آموزش ساخت کنترلر موتور براشلس دی سی (BLDC) یا ساده تر ESC (کنترلر سرعت الکترونیکی) بوسیله آردوینو UNO را یاد خواهیم گرفت. موتور های براشلس دو مدل دارند : موتور براشلس با سنسور و موتور براشلس بدون سنسور. در داخل موتور براشلس با سنسور، ۳ سنسور اثر هال وجود دارد. این سنسور وظیفه تشخیص دادن موقعیت رتور را در این موتور ها دارد. تعویض فاز(commutation) موتور های BLDC سنسور دار به وسیله وضعیت سنسور های اثر حال مشخص می شود.
موتور های BLDC بدون سنسور ، سنسوری برای تشخیص موقعیت رتور ندارند. تعویض فاز این نوع موتور با نیروی عکس العمل (BEMF) سیم پیچ استاتور مشخص می شود.
طرز کار:
چطور تغییر علامت ولتاژ (zero crossing) را پیدا کنیم:
ساده ترین راه پیدا کردن تغییر علامت ولتاژ استفاده از مقایسه کننده ها است. مقایسه کننده ها ۳ پایه اصلی دارد: ۲ ورودی (مثبت و منفی) و یک خروجی. وقتی ولتاژ پایه مثبت از منفی بزرگ تر باشد ، خروجی مقایسه کننده یک منطقی می شود و بلعکس. برای این پروژه ۳ مقایسه کننده لازم است، شکل زیر اتصال مقایسه کننده به فاز B موتور را نشان می دهد (برای فاز های دیگر نیز همینگونه است).

وقتی که سیگنال BEMF سیم پیچ شناور، ازصفر به سمت مثبت می رود، خروجی مقایسه کننده از صفر به یک تغییر پیدا می کند و بلعکس ، وقتی که سیگنال BEMF سیم پیچ شناور از صفر به منفی می رود، خروجی مقایسه کننده از یک به صفر تغییر پیدا می کند. با وجود این مقایسه کننده ها در هر فاز سه سیگنال متناظر با سیگنال BEMF سیم پیچ ها تولید می شود. ترکیب این سیگنال های خروجی مقایسه کننده ها دنباله تعویض فاز را تشکیل می دهد.
قطعات مورد نیاز کنترل موتور براشلس دی سی بدون سنسور با آردوینو :
- آردوینو UNO
- موتور براشلس دی سی (BLCD)
- ۶ عدد ترانزیستور ۰۶N03LA N-type mosfet
- ۳ عدد آی سی IR2104S
- ۶ عدد مقاومت ۳۳ کیلو اهم
- ۳ عدد مقاومت ۱۰ کیلو اهمی
- ۶ عدد مقاومت ۱۰۰ اهمی
- ۳ عدد دیود IN4148
- ۳ عدد خازن ۱۰ میکرو فاراد
- ۲ عدد میکروسوئیچ
- منبع تغذیه ۱۲ ولت
- برد بورد
- سیم برد بورد
شماتیک مدار:
شماتیک پروژه را در زیر مشاهده می کنید.

همه زمین های مدار به یکدیگر متصل شده اند.
۲ میکروسوئیچ استفاده شده در این مدار برای افزایش و کاهش سرعت موتور BLDC می باشد.
۳ مقاومت ۳۳ کیلو اهمی (متصل به سر های موتور) و ۳ مقاومت ۱۰ کیلو اهمی بعنوان تقسیم کننده ولتاژ استفاده شده اند. از انجا که نمی توانیم آردوینو را با ۱۲ ولت تغذیه کنیم مجبور به استفاده از این مقسم شده ایم. علاوه بر این مقاومت ۳۳ کیلو اهمی برای ایجاد کردن نقطه بی طرف مجازی می باشد. این نقطه به پین ۶ آردوینو متصل می شود.
برد آردوینو UNO بر اساس میکروکنترلر ATmega328P که دارای یک مقایسه کننده می باشد. پایه مثبت مقایسه کننده به پین ۶ آردوینو و پایه منفی به هر کدام از پین های pin 7 (AIN1), A0 (ADC0), A1 (ADC1), A2 (ADC2), A3 (ADC3), A4 (ADC4) , A5 (ADC5 متصل شود. پس نقطه بی طرف مجازی به پایه مثبت مقایسه کننده آنالوگ (پین ۶) ، فاز A موتور به پین ۷ ، فاز B به پین A2 و فاز C به پین A3 متصل می شود.برنامه باید طوری نوشته شود که هر دفعه فقط BEMF یکی از فاز ها با نقطه بی طرف مجازی مقایسه می شود.
چیپ IR2104S برای کنترل ماسفت ها در هر فاز است. تعویض حالت ماسفت ها به وسیله خطوط کنترل IN و SD انجام می شود. در شکل زیر دیاگرام زمان ورودی و خروجی را می بینیم.

کد های پروژه:
در کد های این پروژه از کتابخانه موتور براشلس استفاده نشده است.
دانلود کد برنامه کنترل موتور براشلس دی سی بدون سنسور :
دانلود فایل// Sensorless brushless DC (BLDC) motor control with Arduino UNO (Arduino DIY ESC).
// This is a free software without any warranty.
#define SPEED_UP A0
#define SPEED_DOWN A1
#define PWM_MAX_DUTY 255
#define PWM_MIN_DUTY 50
#define PWM_START_DUTY 100
byte bldc_step = 0, motor_speed;
unsigned int i;
void setup() {
DDRD |= 0x38; // Configure pins 3, 4 and 5 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;
// Analog comparator setting
ACSR = 0x10; // Disable and clear (flag bit) analog comparator interrupt
pinMode(SPEED_UP, INPUT_PULLUP);
pinMode(SPEED_DOWN, INPUT_PULLUP);
}
// Analog comparator ISR
ISR (ANALOG_COMP_vect) {
// BEMF debounce
for(i = 0; i < 10; i++) {
if(bldc_step & 1){
if(!(ACSR & 0x20)) i -= 1;
}
else {
if((ACSR & 0x20)) i -= 1;
}
}
bldc_move();
bldc_step++;
bldc_step %= 6;
}
void bldc_move(){ // BLDC motor commutation function
switch(bldc_step){
case 0:
AH_BL();
BEMF_C_RISING();
break;
case 1:
AH_CL();
BEMF_B_FALLING();
break;
case 2:
BH_CL();
BEMF_A_RISING();
break;
case 3:
BH_AL();
BEMF_C_FALLING();
break;
case 4:
CH_AL();
BEMF_B_RISING();
break;
case 5:
CH_BL();
BEMF_A_FALLING();
break;
}
}
void loop() {
SET_PWM_DUTY(PWM_START_DUTY); // Setup starting PWM with duty cycle = PWM_START_DUTY
i = 5000;
// Motor start
while(i > 100) {
delayMicroseconds(i);
bldc_move();
bldc_step++;
bldc_step %= 6;
i = i - 20;
}
motor_speed = PWM_START_DUTY;
ACSR |= 0x08; // Enable analog comparator interrupt
while(1) {
while(!(digitalRead(SPEED_UP)) && motor_speed < PWM_MAX_DUTY){
motor_speed++;
SET_PWM_DUTY(motor_speed);
delay(100);
}
while(!(digitalRead(SPEED_DOWN)) && motor_speed > PWM_MIN_DUTY){
motor_speed--;
SET_PWM_DUTY(motor_speed);
delay(100);
}
}
}
void BEMF_A_RISING(){
ADCSRB = (0 << ACME); // Select AIN1 as comparator negative input
ACSR |= 0x03; // Set interrupt on rising edge
}
void BEMF_A_FALLING(){
ADCSRB = (0 << ACME); // Select AIN1 as comparator negative input
ACSR &= ~0x01; // Set interrupt on falling edge
}
void BEMF_B_RISING(){
ADCSRA = (0 << ADEN); // Disable the ADC module
ADCSRB = (1 << ACME);
ADMUX = 2; // Select analog channel 2 as comparator negative input
ACSR |= 0x03;
}
void BEMF_B_FALLING(){
ADCSRA = (0 << ADEN); // Disable the ADC module
ADCSRB = (1 << ACME);
ADMUX = 2; // Select analog channel 2 as comparator negative input
ACSR &= ~0x01;
}
void BEMF_C_RISING(){
ADCSRA = (0 << ADEN); // Disable the ADC module
ADCSRB = (1 << ACME);
ADMUX = 3; // Select analog channel 3 as comparator negative input
ACSR |= 0x03;
}
void BEMF_C_FALLING(){
ADCSRA = (0 << ADEN); // Disable the ADC module
ADCSRB = (1 << ACME);
ADMUX = 3; // Select analog channel 3 as comparator negative input
ACSR &= ~0x01;
}
void AH_BL(){
PORTB = 0x04;
PORTD &= ~0x18;
PORTD |= 0x20;
TCCR1A = 0; // Turn pin 11 (OC2A) PWM ON (pin 9 & pin 10 OFF)
TCCR2A = 0x81; //
}
void AH_CL(){
PORTB = 0x02;
PORTD &= ~0x18;
PORTD |= 0x20;
TCCR1A = 0; // Turn pin 11 (OC2A) PWM ON (pin 9 & pin 10 OFF)
TCCR2A = 0x81; //
}
void BH_CL(){
PORTB = 0x02;
PORTD &= ~0x28;
PORTD |= 0x10;
TCCR2A = 0; // Turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF)
TCCR1A = 0x21; //
}
void BH_AL(){
PORTB = 0x08;
PORTD &= ~0x28;
PORTD |= 0x10;
TCCR2A = 0; // Turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF)
TCCR1A = 0x21; //
}
void CH_AL(){
PORTB = 0x08;
PORTD &= ~0x30;
PORTD |= 0x08;
TCCR2A = 0; // Turn pin 9 (OC1A) PWM ON (pin 10 & pin 11 OFF)
TCCR1A = 0x81; //
}
void CH_BL(){
PORTB = 0x04;
PORTD &= ~0x30;
PORTD |= 0x08;
TCCR2A = 0; // Turn pin 9 (OC1A) PWM ON (pin 10 & pin 11 OFF)
TCCR1A = 0x81; //
}
void SET_PWM_DUTY(byte duty){
if(duty < PWM_MIN_DUTY)
duty = PWM_MIN_DUTY;
if(duty > PWM_MAX_DUTY)
duty = PWM_MAX_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
}

دیدگاهها (0)