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

آموزش کنترل موتور DC با آردوینو (PWM – L298 – پل اچ ) به همراه کد

کنترل موتور DC با آردوینو (PWM - L298 - پل اچ )

به نام خدا

آموزش کنترل موتور DC با آردوینو (PWM – L298 – پل اچ ) به همراه کد برنامه

کنترل موتور DC با آردوینو (PWM - L298 - پل اچ )

در این پروژه ما یاد میگیریم چگونه موتور های DC را با آردوینو کنترل کنیم، به برخی از تکنیک های اولیه برای کنترل موتور های DC  نگاهی خواهیم کرد و دو نمونه برای یادگیری بهتر کنترل موتور DC با درایور L298N و برد آردوینو خواهیم آورد. برای کنترل سرعت موتور DC باید ولتاژ ورودی به موتور را کنترل کرد، متداول ترین راه این کار استفاده از سیگنال PWM است.

 

کنترل موتور DC با آردوینو (PWM - L298 - پل اچ )

 

کنترل موتور DC با PWM :

 

PWM یا مدولاسیون پهنای باند یک روش است که به ما کمک میکند که مقدار متوسط ولتاژ که به وسیله ی آن دستگاه های الکتریکی روشن و خاموش میشوند، کنترل کرد.

مقدار متوسط ولتاژ به چرخه ی کار یا به مقدار زمانی که سیگنال وصل است در مقابل مقدار زمانی که سیگنال قطع است در یک دوره ی زمانی بستگی دارد .

 

کنترل موتور DC با آردوینو (PWM - L298 - پل اچ )

 

بنابراین بسته به اندازه ی موتور ما میتوانیم به راحتی خروجی PWM از آردوینو را به BASE ترانزیستور یا گیت MOSFET وصل کنیم و سرعت متور را با کنترل PWM کنترل کنیم.

سیگنال PWM آردوینو قطع و وصل میکند گیت MOSTET که یک موتور پرقدرت را کنترل میکند .

 

کنترل موتور DC با آردوینو (PWM - L298 - پل اچ )

 

کنترل موتور DC با استفاده از H-Bridge :

 

از سوی دیگر برای کنترل جهت چرخش موتور ما باید تنها جهت جریان عبوری از موتور را عوض کنیم. متداول ترین راه برای این کار استفاده از یک درایور H-Bridge است.

یک H-Bridge شامل چهار سویچ ،ترانزیستور یا MOSFET ها و موتور در مرکز یک مدار H مانند از این المان ها قرار میگیرد.

با فعال کردن دو سویچ خاص در یک زمان میتوان جهت جریان عبوری از موتور را تغییر داد ، بدین صورت جهت چرخش موتور تغییر خواهد کرد.

 

کنترل موتور DC با آردوینو (PWM - L298 - پل اچ )

 

بنابراین اگه ما دو روش PWM و پل اچ را با هم ترکیب کنیم میتوانیم یک موتور DC را به طور کامل تحت کنترل داشته باشیم. بسیاری از درایور های موتور DC دارای این ویژگی ها هستند و L298N یکی از آنهاست.

 

درایور L298N :

L298N یک پل H دوتایی است که اجازه می دهد سرعت و جهت چرخش موتور DC را هم زمان کنترل کرد . این ماژول میتواند موتور هایی با ولتاژ ۵ تا ۳۵ ولت با جریان حداکثر ۲ آمپر را کنترل کند.

 

کنترل موتور DC با آردوینو (PWM - L298 - پل اچ )

 

این ماژول دارای دو ترمینال پیچ برای دو موتور A و B و ترمینال پیچ های دیگر زمین ، VCC برای موتور و پین ۵V است که میتواند ورودی یا خروجی باشد.

 

کنترل موتور DC با آردوینو (PWM - L298 - پل اچ )

 

این بستگی به ولتاژ نامی موتور دارد.

این ماژول دارای یک رله ی ۵ ولت است که با یک فرکانس فعال یا غیر فعال میشود.

اگر ولتاژ منبع تغذیه موتور ۱۲ ولت باشد ، ما میتوانیم رله ۵ ولت را فعال کنیم و پین ۵ ولت میتواند به عنوان خروجی استفاده شود، به عنوان مثال برای تغذیه برد آردوینو میتوان استفاده کرد.

اما اگر ولتاژ بیشتر از ۱۲ ولت باشد ما باید رله را غیر فعال کنیم، زیرا این ولتاژ باعث خسارت زدن به برد در محل پین ۵ ولت میشود.

در این مورد پین ۵ ولت به عنوان ورودی مود استفاده قرار میگیرد زیرا ما باید آن را به منبع تغذیه ۵ ولت وصل کنیم تا ماژول به درستی کار کند .

باید ذکر کنیم که این ماژول ۲ ولت از ولتاژ منبع تغذیه را مصرف میکند بنابراین اگه ولتاژ منبع تغذیه ۱۲ ولت باشد، ولتاژ در ترمینال موتور ۱۰ ولت خواهد بود و ما نمیتوانیم از حداکثر توان موتور ۱۲ ولت استفاده کنیم.

 

کنترل موتور DC با آردوینو (PWM - L298 - پل اچ )

 

ورودی های کنترل منطق در درایور یعنی Enable A و  Enable B ، از این ورودی ها برای کنترل سرعت موتور استفاده می شود . اگر یک فرکانس در این پین وجود داشته باشد، موتور فعال خواهد شد و در حداکثر سرعت کار میکند.

اگر ما جامپر را از این پین حذف کینم میتوانیم PWM را به آن وصل کنیم به این ترتیب سرعت موتور را کنترل کنیم، اگر این پین را به زمین وصل کنیم، موتور غیر فعال میشود.

 

کنترل موتور DC با آردوینو (PWM - L298 - پل اچ )

 

پین های INPUT1 و INPUT2 برای کنترل جهت چرخش موتور A و INPUT 3 ,4 برای موتور B  استفاده میشود.

با استفاده از این پین ها ما در واقع پل اچ را در ماژول L298N کنترل میکنیم.

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

اگر ورودی ۱ پایی (۰ منطقی ) و ورودی ۲ بالا ( ۱منطقی) باشد، موتور به جلو حرکت میکند، و اگر برعکس باشد موتور به عقب حرکت میکند.

در صورتی که به هر دو پین مشابه باشند (بالا یا پایین ) موتور متوقف خواهد شد. همین امر برای پین های ۳ و ۴ برای موتور B همین اعمال را انجام میدهد.

 

آردوینو و L298N :

 

حال برخی از برنامه های عملی را انجام میدهیم.

در مثال اول ما با استفاده از یک پتانسیومتر سرعت موتور را کنترل میکنیم و با استفاده از یک میکرو سوئیچ جهت چرخش را تغییر میدهیم.

 

کنترل موتور DC با آردوینو (PWM - L298 - پل اچ )

 

بنابراین ما به درایور L298N ، یک موتور DC ،یک پتانسیومتر ، یک میکرو سوئیچ و برد آردوینو  نیاز داریم.

کد آردوینو:

 

کد آردونیو برای این مثال در زیر آمده است.

 

#define enA 9
#define in1 6
#define in2 7
#define button 4

int rotDirection = 0;
int pressed = false;

void setup() {
  pinMode(enA, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(button, INPUT);
  // Set initial rotation direction
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
}

void loop() {
  int potValue = analogRead(A0); // Read potentiometer value
  int pwmOutput = map(potValue, 0, 1023, 0 , 255); // Map the potentiometer value from 0 to 255
  analogWrite(enA, pwmOutput); // Send PWM signal to L298N Enable pin

  // Read button - Debounce
  if (digitalRead(button) == true) {
    pressed = !pressed;
  }
  while (digitalRead(button) == true);
  delay(20);

  // If button is pressed - change rotation direction
  if (pressed == true  & rotDirection == 0) {
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    rotDirection = 1;
    delay(20);
  }
  // If button is pressed - change rotation direction
  if (pressed == false & rotDirection == 1) {
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    rotDirection = 0;
    delay(20);
  }
}

 

توضیحات :

 

ابتدا باید پین های و برخی از متغیر های مورد نیاز برنامه را تعریف کنیم. در حلقه Setup باید حالت پین و جهت چرخش اولیه موتور را تنظیم کنیم.

در حلقه loop ما با خواندن مقدار پتانسیومتر شروع میکنیم و مقدار آن را که از تا ۱۰۲۳  به مقدار ۰ تا ۲۵۵ یا آن را ۰ تا ۱۰۰ درصد duty cycl برای سیگنال PWM تغییر میدهیم، سپس با تابع analogWrite() ، سیگنال pwm را به پین Enable درایور l298n میفرستیم که موتور به آن وصل است.

بعد ما بررسی میکنیم که آیا میکروسوییچ فشار داده شده یا نه ، اگر فشار داده شده مقدار ورودی ۱ و ۲ را تغییر میدهیم. از میکروسوییچ برای تغییر جهت چرخش موتور استفاده میشود.

 

کنترل ماشین  با استفاده از L298N :

 

وقتی ما مطالب بالا را فرا گرفتیم میتوانیم یک ماشین  را بسازیم، مدار این خودرو در زیر آمده است.

 

کنترل موتور DC با آردوینو (PWM - L298 - پل اچ )

 

ما به دو عدد موتور DC ، درایور L298N ، برد آردوینو و یک joystik برای کنترل نیاز داریم.

برای منبع تغذیه ما از سه باتری لیتیوم ۳/۷ ولت استفاده کرده ایم که مجموع آن ۱۱ ولت میشود.

برای شاسی از تخته سه لا ( تخته چند لایه ۳ میلیمتری) استفاده کرده ایم.

موتور ها را با استفاده از بست فلزی به تخته محکم کرده ایم و در جلو از یک چرخ گردان استفاده کرده ایم. شما میتوانید از چرخ هرزگرد استفاده کنید.

 

کنترل موتور DC با آردوینو (PWM - L298 - پل اچ )

 

کد و توضیحات کنترل موتور DC با آردوینو (PWM – L298 – پل اچ ) :

 

int xAxis = analogRead(A0); // Read Joysticks X-axis
int yAxis = analogRead(A1); // Read Joysticks Y-axis

پس از تعریف پین ها در بخش loop ، ما با خواندن مقادیر محور joystik شروع میکنیم.

joystik در واقع از د پتانسیومتر ساخته شده است که به ورودی های آنالوگ آردوینو وصل میشود و مقادیر آن از ۰ تا ۱۰۲۳ می باشد.

هنگامی که joystick در مرکر قرار میگیرد مقدار پتانسیومتر برابر ۵۱۲ است.

 

کنترل موتور DC با آردوینو (PWM - L298 - پل اچ )

 

حرکت به جلو و عقب :

 

ما مقدار تلرانس را کمی افزارش میدهیم و ارزش ها را از ۵۵۰ تا ۴۷۰ به عنوان مرکز در نظر میگیریم.

دو جهت چرخش را با استفاده از ۴ پین ورودی تنظیم میکنیم. سپس ، مقادیر معکوس را از ۴۷۰ به ۰ به مقادیر pwm  از ۰ تا ۲۵۵ که در واقع سرعت موتور را کنترل میکند.

 

// Y-axis used for forward and backward control
  if (yAxis < 470) {
    // Set Motor A backward
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    // Set Motor B backward
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
    // Convert the declining Y-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
    motorSpeedA = map(yAxis, 470, 0, 0, 255);
    motorSpeedB = map(yAxis, 470, 0, 0, 255);
  }

 

بیشتر بخوانید...  ایجاد صدای آژیر با استفاده از آردوینو

به طور مشابه اگر محور y از joystick به سمت جلو حرکت دهیم مقدار بیش از ۵۵۰ میشود.

مقادیر را از ۵۵۰ تا ۱۰۲۳ به مقادیر pwm از ۰ تا ۲۵۵ تبدیل میکنیم و اگر محور در مرکز باشد باید سرعت موتور صفر باشد.

 

حرکت به چپ و راست:

 

// X-axis used for left and right control
  if (xAxis < 470) {
    // Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value
    int xMapped = map(xAxis, 470, 0, 0, 255);
    // Move to left - decrease left motor speed, increase right motor speed
    motorSpeedA = motorSpeedA - xMapped;
    motorSpeedB = motorSpeedB + xMapped;
    // Confine the range from 0 to 255
    if (motorSpeedA < 0) {
      motorSpeedA = 0;
    }
    if (motorSpeedB > 255) {
      motorSpeedB = 255;
    }
  }

 

ابتدا مقادیر محور x را به مقادیر pwm از ۰ تا ۲۵۵  تبدیل میکنیم.

برای حرکت به چپ از این مقدار برای کاهش سرعت موتور سمت چپ و افزایش سرعت موتور راست استفاده میکنیم.

در اینجا از if برای محدوده سرعت موتور از ۰ تا ۲۵۵ استفاده کرده ایم.

 

کنترل موتور DC با آردوینو (PWM - L298 - پل اچ )

 

از روش ذکر شده به طور مشابه برای حرکت به راست استفاده میکنیم.

توجه :

بسته به ولتاژ نامی موتور ها ،در pwm های پایین موتور ها قادر به حرکت نخواهند بود.

در مورد موتور های استفاده شده ی ما در pwm  های زیر ۷۰ موتور ها حرکت نمیکردند.

بنابراین  از مقدار pwm در محدوده ۷۰ تا ۲۵۵ استفاده میکنیم.

 

// Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)
  if (motorSpeedA < 70) {
    motorSpeedA = 0;
  }
  if (motorSpeedB < 70) {
    motorSpeedB = 0;
  }
  analogWrite(enA, motorSpeedA); // Send PWM signal to motor A
  analogWrite(enB, motorSpeedB); // Send PWM signal to motor B

 

دانلود کد برنامه:

 

 

#define enA 9
#define in1 4
#define in2 5
#define enB 10
#define in3 6
#define in4 7

int motorSpeedA = 0;
int motorSpeedB = 0;

void setup() {
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
}

void loop() {
  int xAxis = analogRead(A0); // Read Joysticks X-axis
  int yAxis = analogRead(A1); // Read Joysticks Y-axis

  // Y-axis used for forward and backward control
  if (yAxis < 470) {
    // Set Motor A backward
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    // Set Motor B backward
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
    // Convert the declining Y-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
    motorSpeedA = map(yAxis, 470, 0, 0, 255);
    motorSpeedB = map(yAxis, 470, 0, 0, 255);
  }
  else if (yAxis > 550) {
    // Set Motor A forward
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    // Set Motor B forward
    digitalWrite(in3, LOW);
    digitalWrite(in4, HIGH);
    // Convert the increasing Y-axis readings for going forward from 550 to 1023 into 0 to 255 value for the PWM signal for increasing the motor speed
    motorSpeedA = map(yAxis, 550, 1023, 0, 255);
    motorSpeedB = map(yAxis, 550, 1023, 0, 255);
  }
  // If joystick stays in middle the motors are not moving
  else {
    motorSpeedA = 0;
    motorSpeedB = 0;
  }

  // X-axis used for left and right control
  if (xAxis < 470) {
    // Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value
    int xMapped = map(xAxis, 470, 0, 0, 255);
    // Move to left - decrease left motor speed, increase right motor speed
    motorSpeedA = motorSpeedA - xMapped;
    motorSpeedB = motorSpeedB + xMapped;
    // Confine the range from 0 to 255
    if (motorSpeedA < 0) {
      motorSpeedA = 0;
    }
    if (motorSpeedB > 255) {
      motorSpeedB = 255;
    }
  }
  if (xAxis > 550) {
    // Convert the increasing X-axis readings from 550 to 1023 into 0 to 255 value
    int xMapped = map(xAxis, 550, 1023, 0, 255);
    // Move right - decrease right motor speed, increase left motor speed
    motorSpeedA = motorSpeedA + xMapped;
    motorSpeedB = motorSpeedB - xMapped;
    // Confine the range from 0 to 255
    if (motorSpeedA > 255) {
      motorSpeedA = 255;
    }
    if (motorSpeedB < 0) {
      motorSpeedB = 0;
    }
  }
  // Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)
  if (motorSpeedA < 70) {
    motorSpeedA = 0;
  }
  if (motorSpeedB < 70) {
    motorSpeedB = 0;
  }
  analogWrite(enA, motorSpeedA); // Send PWM signal to motor A
  analogWrite(enB, motorSpeedB); // Send PWM signal to motor B
}

 

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

*
*

    محمد مهمان فروردین 22, 1397 پاسخ

    با سلام
    ممنون میشم نحوه ساخت ربات تشخیص موانع با چهار سنسور التراسونیک رو برای بنده ارسال نمایید یا در سایت قرار دهید. (بطور مثال ربات بخواهد مسیر uشکل به عرض 50 سانت و ارتفاع 40 سانت را تشخیص دهد و قسمت انحنای مسیر را دور بزند.)
    با تشگر
    mh.jaavidan@gmail.com

      Admin مدیر کل شهریور 8, 1397 پاسخ

      سلام
      برای سفارش پروژه می توانید با شماره 09157567087 تماس بگیرید .
      روشنی

    علی مهمان اسفند 22, 1398 پاسخ

    سلام از چه ماژولی یا مداری برای کنترل چپ گرد راست گرد موتور دی سی فقط با به میکرو سویچ یعنی یه میکرو سویچ بزنم به راست بچرخه و مدت کوتاهی بچرخه البته تایمر نه میزان چرخشش با لیمیت سوئیچ کنترل بشه و بایسته دوباره سویچ زدم به چب بچرخه یعنی خودکار چپ و راست نچرخه مثل درب دی وی دی رایتر

      Admin مدیر کل آبان 14, 1399 پاسخ

      سلام. مدار چپ گرد راستگرد توی سایت هست میتونید استفاده کنید

    امیر مهمان شهریور 4, 1399 پاسخ

    سلام
    ممکنه کد برنامه رو بدون استفاده از joystick هم قرار بدین؟

      Admin مدیر کل آبان 16, 1399 پاسخ

      سلام به همکاران تولید محتوا اطلاع داده میشه