به نام خدا
پروژه ی کنترل موتور براشلس دی سی بدون سنسور با آردوینو و IR2101 به همراه کد
در این مقاله قصد داریم تا با استفاده از آردوینو و آی سی IR2101 موتور براشلس بدون سنسور را راه اندازی کنیم .
قطعات مورد نیاز کنترل موتور براشلس دی سی بدون سنسور با آردوینو و IR2101:
- بردآردوینو UNO
- موتور براشلس مستقیم (BLDC)
- ۶ قطعه ترانزیستور ماسفت نوع N مدل ۰۶N03LA
- ۳قطعه آی سی (IR2101 (IR2101S
- ۶ قطعه مقاومت ۳۳k
- ۳ قطعه مقاومت ۱۰K
- ۶ قطعه مقاومت ۱۰ اهم
- ۳ قطعه دیود IN4148
- ۳ قطعه خازن ۱۰uF
- ۳ قطعه خازن ۲٫۲uF
- ۲ قطعه میکروسوییچ
- منبع تغذیه ۱۲V
- برد برد
- سیم برد بردی
کنترل موتور براشلس دی سی بدون سنسور با آردوینو :
شماتیک مدار در تصویر بالا نشان داده شده است .
در این مدار ۲ میکروسوییچ وجود دارد ، یکی برای افزایش سرعت موتور براشلس دی سی و دیگری برای کاهش سرعت آن است.
۳ مقاومت ۳۳ کیلو اهمی (متصل به سر های موتور) و ۳ مقاومت ۱۰ کیلو اهمی بعنوان تقسیم کننده ولتاژ استفاده شده اند. از آنجا که نمی توانیم آردوینو را با ۱۲ ولت تغذیه کنیم مجبور به استفاده از این مقسم شده ایم. علاوه بر این مقاومت ۳۳ کیلو اهمی برای ایجاد کردن نقطه بی طرف مجازی می باشد. این نقطه به پین ۶ آردوینو متصل می شود.
برد آردوینو UNO بر اساس میکروکنترلر ATmega328P که دارای یک مقایسه کننده می باشد. پایه مثبت مقایسه کننده به پین ۶ آردوینو و پایه منفی به هر کدام از پین های pin 7 (AIN1), A0 (ADC0), A1 (ADC1), A2 (ADC2), A3 (ADC3), A4 (ADC4) , A5 (ADC5 متصل شود. پس نقطه بی طرف مجازی به پایه مثبت مقایسه کننده آنالوگ (پین ۶) ، فاز A موتور به پین ۷ ، فاز B به پین A2 و فاز C به پین A3 متصل می شود.برنامه باید طوری نوشته شود که هر دفعه فقط BEMF یکی از فاز ها با نقطه بی طرف مجازی مقایسه می شود.
خط های HIN هر سه آی سی IR2101 به ترتیب برای فاز های A و B وC به پین های ۱۱ ، ۱۰ و ۹ متصل شده اند . آردوینو می تواند سیگنال PWM تولید کند .
کد های کنترل موتور براشلس دی سی بدون سنسور با آردوینو و IR2101 :
در کد هایی که در پایین برای دانلود و مشاهده آورده شده اند از هیچ کتابخانه ی موتور براشلس استفاده نشده است .
همانطور که در بالا ذکر شد پین های ۹ و ۱۰ و ۱۱ آردوینو می توانند سیگنال PWM تولید کنند که پین های ۹ و ۱۰ مربوط به تایمر ۱ هستند (OC1A و OC1B) و پین ۱۱ مربوط به تایمر ۲ (OC2A) داخلی میکروکنترلر هستند . هر دو ماژول تایمر برای تولید یک سیگنال PWM با فرکانس حدود ۳۱KHz و رزولوشن ۸ بیت پیکربندی شده اند . دیوتی سایکل سیگنال های PWM زمانی که یک دکمه فشار داده می شود (سرعت بخشیدن یا کاهش سرعت) با نوشتن مقدار جدید در رجیستر خود (OCR1A، OCR1B و OCR1A) به روز می شوند.
دانلود کد برنامه کنترل موتور براشلس دی سی بدون سنسور با آردوینو و IR2101 :
دانلود فایل// Sensorless brushless DC (BLDC) motor control with Arduino UNO and IR2101 (Arduino DIY ESC). // This is a free software without any warranty. #define SPEED_UP A0 // BLDC motor speed-up button #define SPEED_DOWN A1 // BLDC motor speed-down button #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(){ PORTD &= ~0x28; PORTD |= 0x10; TCCR1A = 0; // Turn pin 11 (OC2A) PWM ON (pin 9 & pin 10 OFF) TCCR2A = 0x81; // } void AH_CL(){ PORTD &= ~0x30; PORTD |= 0x08; TCCR1A = 0; // Turn pin 11 (OC2A) PWM ON (pin 9 & pin 10 OFF) TCCR2A = 0x81; // } void BH_CL(){ PORTD &= ~0x30; PORTD |= 0x08; TCCR2A = 0; // Turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF) TCCR1A = 0x21; // } void BH_AL(){ PORTD &= ~0x18; PORTD |= 0x20; TCCR2A = 0; // Turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF) TCCR1A = 0x21; // } void CH_AL(){ PORTD &= ~0x18; PORTD |= 0x20; TCCR2A = 0; // Turn pin 9 (OC1A) PWM ON (pin 10 & pin 11 OFF) TCCR1A = 0x81; // } void CH_BL(){ PORTD &= ~0x28; PORTD |= 0x10; 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)