رباتیک و هوافضا

پروژه ی کنترل موتور براشلس دی سی بدون سنسور با آردوینو و IR2101 به همراه کد

کنترل موتور براشلس دی سی با آردوینو و IR2101

به نام خدا

پروژه ی کنترل موتور براشلس دی سی بدون سنسور با آردوینو و IR2101 به همراه کد

 

کنترل موتور براشلس دی سی با آردوینو و 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 یکی از فاز ها با نقطه بی طرف مجازی مقایسه می شود.

تراشه های IR2101 برای کنترل MOSFET های جانبی یک و صفر هر فاز استفاده می شود. سوئیچینگ بین یک و صفر بر اساس خطوط کنترل HIN و LIN انجام می شود. شکل زیر نمودار زمان ورود و خروجی را نشان می دهد:

 

کنترل موتور براشلس دی سی با آردوینو و IR2101

خط های HIN  هر سه آی سی IR2101 به ترتیب برای فاز های A و B  وC   به  پین های ۱۱ ، ۱۰ و ۹ متصل شده اند . آردوینو می تواند سیگنال PWM تولید کند .

کد های کنترل موتور براشلس دی سی بدون سنسور با آردوینو و IR2101 :

 

بیشتر بخوانید...  آموزش پروژه محور آردوینو – جلسه ششم ورودی و خروجی 1

در کد هایی که در پایین برای دانلود و مشاهده آورده شده اند از هیچ کتابخانه ی موتور براشلس استفاده نشده است .
همانطور که در بالا ذکر شد پین های ۹ و ۱۰ و ۱۱ آردوینو می توانند سیگنال PWM تولید کنند که پین های ۹ و ۱۰ مربوط به تایمر ۱ هستند  (OC1A و OC1B) و پین ۱۱ مربوط به تایمر ۲  (OC2A)  داخلی  میکروکنترلر هستند . هر دو ماژول تایمر  برای تولید یک سیگنال PWM با فرکانس حدود ۳۱KHz و رزولوشن ۸ بیت پیکربندی شده اند . دیوتی سایکل سیگنال های PWM زمانی که یک دکمه فشار داده می شود (سرعت بخشیدن یا کاهش سرعت) با نوشتن مقدار جدید در  رجیستر خود (OCR1A، OCR1B و OCR1A) به روز می شوند.

مقایسه کننده آنالوگ ، ورودی مثبت آردوینو (پین ۶) را با ورودی منفی مقایسه می کند (که می تواند AIN1 (پین ۷)، ADC2 (پین A2) یا ADC3 (پین A3) باشد). هنگامی که ولتاژ پین مثبت بالاتر از ولتاژ پین منفی باشد، خروجی آنالوگ (ACO) یک می شود و بلعکس.در این پروژه برای شناسایی تغییر علامت ولتاژ (zero crossing) از وقفه مقایسه کننده آنالوگ استفاده شده است.
 برای درک بهتر کد ، دیتاشیت ATmega328p را بخوانید.

دانلود کد برنامه کنترل موتور براشلس دی سی بدون سنسور با آردوینو و 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
}

 

بیشتر بخوانید...  راه اندازی سنسور PIR با آردوینو

دیدگاه‌ها (0)

*
*