در آموزش راهاندازی یک Brushed Motor با Transistor و کنترل جهت و سرعت با H-Bridge از آموزش آردوینو به راهاندازی یک Brushed Motor با استفاده از Transistor، کنترل جهت یک Brushed Motor با H-Bridge و کنترل جهت و سرعت یک Brushed Motor با H-Bridge پرداختیم. در این قسمت قصد داریم درباره استفاده از سنسورها برای کنترل جهت و سرعت Brushed Motors و راهاندازی یک موتور پلهای (Stepper) دو قطبی صحبت کنیم.
فرض کنید میخواهید جهت و سرعت Brushed Motorها را با استفاده از بازخوردی که از حسگرها میگیرید کنترل کنید. به عنوان مثال، میخواهید دو حسگر نوری سرعت و جهت یک موتور را کنترل کنند تا ربات به سمت یک پرتو نور حرکت کند. این راهحل از اتصالات موتوری مشابه آنچه در راهاندازی یک Brushed Motor با Transistor و کنترل جهت و سرعت با H-Bridge نشان داده شده استفاده میکند، اما دو photoresistors نیز اضافه شدهاند؛ این اتصال در شکل ( 1 ) قابل مشاهده است. برای خازنهای ۰٫۱ µF از خازنهای سرامیکی استفاده کنید.

شکل 1- دو موتور که با استفاده از سنسورها کنترل میشوند
این sketch سطح نور روی حسگرها را بررسی میکند و موتورها را به گونهای راه میاندازد که به سمت حسگری که نور بیشتری دریافت کرده است هدایت شوند:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
/* * Brushed_H_Bridge_Direction sketch * uses photo sensors to control motor direction * robot moves in the direction of a light */ int leftPins[] = {5,7,4}; // on pin for PWM, two pins for motor direction int rightPins[] = {6,3,2}; const int MIN_PWM = 64; // this can range from 0 to MAX_PWM const int MAX_PWM = 128; // this can range from around 50 to 255 const int leftSensorPin = A0; // analog pins with sensors const int rightSensorPin = A1; int sensorThreshold = 0; // must have this much light on a sensor to move void setup() { for(int i=1; i < 3; i++) { pinMode(leftPins[i], OUTPUT); pinMode(rightPins[i], OUTPUT); } } void loop() { int leftVal = analogRead(leftSensorPin); int rightVal = analogRead(rightSensorPin); if(sensorThreshold == 0) // have the sensors been calibrated? { // if not, calibrate sensors to something above the ambient average sensorThreshold = ((leftVal + rightVal) / 2) + 100 ; } if( leftVal > sensorThreshold || rightVal > sensorThreshold) { // if there is adequate light to move ahead setSpeed(rightPins, map(rightVal,0,1023, MIN_PWM, MAX_PWM)); setSpeed(leftPins, map(leftVal ,0,1023, MIN_PWM, MAX_PWM)); } } void setSpeed(int pins[], int speed ) { if(speed < 0) { digitalWrite(pins[1],HIGH); digitalWrite(pins[2],LOW); speed = -speed; } else { digitalWrite(pins[1],LOW); digitalWrite(pins[2],HIGH); } analogWrite(pins[0], speed); } |
این اسکچ سرعت دو موتور را بر اساس میزان نوری که توسط دو فوتوسل دریافت میشود کنترل میکند. فوتوسلها به گونهای قرار گرفتهاند که افزایش نور در یک طرف باعث افزایش سرعت موتور سمت دیگر میشود. این عمل باعث میشود ربات به سمت طرفی که روشنتر است گردش کند. اگر نور به هر دو فوتوسل به یک اندازه بتابد، ربات به صورت مستقیم به جلو حرکت میکند. نور ناکافی باعث توقف ربات میشود.
اگر این مدار را به صورت یک ربات بسازید و ربات شما به جای دنبال کردن نور از آن بترسد، قطبیت هر دو موتور را برعکس کنید. اگر ربات شما در حالی که باید به جلو حرکت کند درجا میچرخد، قطبیت فقط یکی از موتورها را برعکس کنید.
نور از طریق ورودیهای آنالوگ و با استفاده از تابع analogRead اندازهگیری میشود. هنگامی که برنامه شروع میشود، نور محیط اندازهگیری و این مقدار به عنوان آستانهای برای حداقل نور مورد نیاز جهت حرکت ربات استفاده میشود. حاشیهای به اندازه ۱۰۰ به میانگین سطح دو حسگر اضافه میشود تا ربات به دلیل تغییرات جزئی در نور محیط حرکت نکند. مقدار نور که با analogRead اندازهگیری میشود، با استفاده از تابع map به مقدار PWM تبدیل میشود. MIN_PWM را روی مقداری قرار دهید که تقریباً باعث حرکت ربات شما میشود (مقادیر کم گشتاور کافی را فراهم نمیکنند؛ این مقدار را با آزمون و خطا روی ربات خود پیدا کنید). MAX_PWM را روی مقداری (حداکثر تا ۲۵۵) قرار دهید که سریعترین سرعت مطلوب شما برای ربات است.
سرعت موتور در تابع setSpeed کنترل میشود. برای هر موتور دو پایه برای کنترل جهت و یک پایه دیگر برای کنترل سرعت استفاده میشود. شماره پایهها در آرایههای leftPins و rightPins نگهداری میشود. اولین مقدار در هر آرایه پایه مربوط به سرعت است و دو مقدار دیگر برای جهت استفاده میشوند.
جایگزین L293، تراشه Toshiba TB6612FNG است. از این تراشه میتوان در هرکدام از مثالهای این بخش که از L293D استفاده شده است بهره برد. شکل ( 2 ) نحوه سیمکشی این تراشه روی برد Pololu (کد کالای ۷۱۳ Pololu) را نشان میدهد.

شکل 2- سیمکشی H‑Bridge روی برد Pololu
شما میتوانید با افزودن سختافزار جانبی تعداد پایههای مورد نیاز را کاهش دهید. در این روش برای هر موتور تنها یک پایه برای کنترل جهت استفاده میشود و با استفاده از یک ترانزیستور یا گیت منطقی سطح ورودی دیگر H‑Bridge معکوس میشود. نمودارهای مداری این روش در ویکی آردوینو موجود است؛ اما اگر بردی آماده میخواهید میتوانید از شیلدهای H‑Bridge مانند Arduino Motor Shield (شناسه ۷۶۳۰۰۴۹۲۰۰۳۷۱) یا Ardumoto از SparkFun (DEV‑09213) استفاده کنید. هر دو این بردها بر اساس تراشه L298 هستند که جایگزینی برای L293 بوده و جریان بیشتری را میتواند راهاندازی کند. این شیلدها مستقیماً روی آردوینو قرار میگیرند و فقط نیاز به اتصال به منبع تغذیه موتور و سیمپیچها دارند.
در ادامه sketch اصلاحشده برای استفاده از Arduino Motor Shield (ورودیهای آنالوگ برای اندازهگیری جریان به کار میروند، بنابراین sketch از A2 و A3 استفاده میکند) آورده شده است:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
/* * Brushed_H_Bridge_Direction sketch for motor shield * uses photo sensors to control motor direction * robot moves in the direction of a light */ int leftPins[] = {3,12}; // one pin for PWM, one pin for motor direction int rightPins[] = {11,13}; const int MIN_PWM = 64; // this can range from 0 to MAX_PWM const int MAX_PWM = 128; // this can range from around 50 to 255 const int leftSensorPin = A2; // analog pins with sensors const int rightSensorPin = A3; int sensorThreshold = 0; // must have this much light on a sensor to move void setup() { pinMode(leftPins[1], OUTPUT); pinMode(rightPins[1], OUTPUT); } void loop() { int leftVal = analogRead(leftSensorPin); int rightVal = analogRead(rightSensorPin); if(sensorThreshold == 0) // have the sensors been calibrated? { // if not, calibrate sensors to something above the ambient average sensorThreshold = ((leftVal + rightVal) / 2) + 100 ; } if( leftVal > sensorThreshold || rightVal > sensorThreshold) { // if there is adequate light to move ahead setSpeed(rightPins, map(rightVal,0,1023, MIN_PWM, MAX_PWM)); setSpeed(leftPins, map(leftVal, 0,1023, MIN_PWM, MAX_PWM)); } } void setSpeed(int pins[], int speed ) { if(speed < 0) { digitalWrite(pins[1], HIGH); speed = -speed; } else { digitalWrite(pins[1], LOW); } analogWrite(pins[0], speed); } |
تابع loop دقیقاً مشابه sketch قبلی است. تابع setSpeed به دلیل اینکه سختافزار روی شیلد اجازه میدهد تنها یک پایه جهت موتور را کنترل کند، کد کمتری دارد.
شیلد Ardumoto از پایههای متفاوتی استفاده میکند؛ بنابراین باید کد را مطابق زیر تغییر دهید:
|
1 2 |
int leftPins[] = {3, 2}; // one pin for PWM, one pin for motor direction int rightPins[] = {11, 4}; |
همان کارایی را با استفاده از Adafruit Motor Shield V2 پیادهسازی کردهایم؛ شکل ( 3 ) را ببینید. برای استفاده از این شیلد باید کتابخانهای به نام Adafruit_MotorShield را با استفاده از مدیر کتابخانه نصب کنید.

شکل 3- استفاده از Adafruit Motor Shield
شیلد Adafruit چهار اتصال برای سیمپیچهای موتور فراهم میکند؛ sketch زیر موتورها را به کانکتورهای ۳ و ۴ متصل کرده است:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
/* * Brushed_H_Bridge_Direction sketch for Adafruit Motor shield * uses photo sensors to control motor direction * robot moves in the direction of a light */ #include <Wire.h> #include <Adafruit_MotorShield.h> // Adafruit motor shield library // Create an object for the shield Adafruit_MotorShield AFMS = Adafruit_MotorShield(); Adafruit_DCMotor *leftMotor = AFMS.getMotor(1); Adafruit_DCMotor *rightMotor = AFMS.getMotor(2); const int MIN_PWM = 64; // this can range from 0 to MAX_PWM const int MAX_PWM = 128; // this can range from around 50 to 255 const int leftSensorPin = A0; // analog pins with sensors const int rightSensorPin = A1; int sensorThreshold = 0; // must be more light than this on sensors to move void setup() { AFMS.begin(); // create with the default frequency 1.6KHz } void loop() { int leftVal = analogRead(leftSensorPin); int rightVal = analogRead(rightSensorPin); if(sensorThreshold == 0) // have the sensors been calibrated? { // if not, calibrate sensors to something above the ambient average sensorThreshold = ((leftVal + rightVal) / 2) + 100 ; } if( leftVal > sensorThreshold || rightVal > sensorThreshold) { // if there is adequate light to move ahead setSpeed(rightMotor, map(rightVal,0,1023, MIN_PWM, MAX_PWM)); setSpeed(leftMotor, map(leftVal ,0,1023, MIN_PWM, MAX_PWM)); } } void setSpeed(Adafruit_DCMotor *motor, int speed ) { if(speed < 0) { motor->run(BACKWARD); speed = -speed; } else { motor->run(FORWARD); } motor->setSpeed(speed); } |
اگر شیلد دیگری غیر از آنهایی که در این دستورالعمل ذکر شده دارید، باید به دیتاشیت آن مراجعه کنید و مطمئن شوید مقادیری که در اسکچ استفاده شده با پایههای مربوط به PWM و جهت تطبیق دارند.
فرض کنید یک موتور پلهای دو قطبی (چهار سیم) دارید و میخواهید آن را با استفاده از یک H‑Bridge تحت کنترل برنامه حرکت دهید. این sketch، موتور را با توجه به دستورات سریال حرکت میدهد. یک مقدار عددی که با علامت + دنبال شود موتور را در یک جهت پله قرار میدهد؛ علامت - موتور را در جهت دیگر میچرخاند. برای مثال، «۲۴+» یک موتور ۲۴ پلهای را یک دور کامل در یک جهت میچرخاند و «۱۲‑» نصف دور را در جهت دیگر حرکت میدهد. قطعات را مطابق شکل ( 4 ) متصل کنید. برای خازنهای ۰٫۱ µF از خازنهای سرامیکی استفاده کنید. در ادامه sketch آمده است:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
/* * Stepper_bipolar sketch * stepper is controlled from the serial port. * a numeric value followed by '+' or '-' steps the motor */ #include <Stepper.h> // change this to the number of steps on your motor #define STEPS 24 // create an instance of the stepper class, specifying // the number of steps of the motor and the pins it's // attached to Stepper stepper(STEPS, 2, 3, 4, 5); int steps = 0; void setup() { // set the speed of the motor to 30 RPM stepper.setSpeed(30); Serial.begin(9600); } void loop() { if ( Serial.available()) { char ch = Serial.read(); if(isDigit(ch)) // is ch a number? { steps = steps * 10 + ch - '0'; // yes, accumulate the value } else if(ch == '+') { stepper.step(steps); steps = 0; } else if(ch == '-') { stepper.step(steps * -1); steps = 0; } } } |

شکل 4- موتور پلهای چهار سیم دو قطبی با استفاده از L293 H‑Bridge
این نوع موتور دارای دو دسته سیمپیچ مجزا است که هر دسته یک فاز از موتور پلهای را تشکیل میدهد. هنگامی که یک فاز در جهتی خاص تحریک شود، موتور یک پله در آن جهت حرکت میکند. با پالس دادن متناوب به فازها، موتور میتواند چندین پله حرکت کند.
موتور دارای چهار سیم است و هر جفت سیم مربوط به یک فاز است. برای اطمینان از اینکه ولتاژ و تعداد پلهها (define STEPS#)با موتور شما مطابقت دارد باید به دیتاشیت یا مستندات دیگر آن مراجعه کنید، اما اگر ترتیب سیمبندی آن را نمیدانید میتوانید با یک مولتیمتر آزمایشی ساده انجام دهید، مقاومت بین جفتهای مختلف سیم را اندازه بگیرید؛ دو جفت سیم وجود خواهد داشت که مقاومت یکسانی دارند و تمامی جفتهای دیگر مقاومت بینهایت خواهند داشت، زیرا ارتباطی بین آنها وجود ندارد.
اگر موتور پلهای شما به جریان بیشتری نسبت به آنچه L293 میتواند فراهم کند (۶۰۰ میلیآمپر برای L293D) نیاز داشت، میتوانید از تراشه SN754410 برای جریان تا ۱ آمپر با همان سیمکشی و کد L293 استفاده کنید. برای جریان تا ۲ آمپر میتوانید از تراشه L298 استفاده کنید. تراشه L298 میتواند از همان sketch نشاندادهشده در راهحل این بخش استفاده کند و باید مطابق شکل ( 5 ) متصل شود. برای خازنهای ۰٫۱ µF از خازنهای سرامیکی استفاده کنید.

شکل 5- موتور پلهای Unipolar با L298
سادهترین راه برای اتصال یک L298 به آردوینو استفاده از Arduino Motor Shield (شناسه ۷۶۳۰۰۴۹۲۰۰۳۷۱) است. این شیلد روی برد آردوینو نصب میشود و تنها نیاز به اتصال خارجی به سیمپیچهای موتور دارد؛ توان موتور از پین Vin (ولتاژ ورودی خارجی) آردوینو تأمین میشود. پایههای In1/2 توسط پایه ۱۲ و پایه ENA توسط پایه ۳ کنترل میشوند. پایههای In3/4 به پایه ۱۳ و ENB به پایه ۱۱ متصلاند. برای استفاده از sketch قبلی با Arduino Motor Shield تغییرات زیر را اعمال کنید:
|
1 |
Stepper stepper(STEPS, 12, 13); |
سپس تمام کد داخل تابع setup() را با موارد زیر جایگزین کنید:
|
1 2 3 4 5 6 |
pinMode(3, OUTPUT); digitalWrite(3, HIGH); // enable A, use LOW to turn off the motor pinMode(11, OUTPUT); digitalWrite(11, HIGH); // enable B, use LOW to turn off the motor stepper.setSpeed(60); // set the speed of the motor to 60 rpm Serial.begin(9600); |
کد تابع loop همان کد sketch قبلی است.
موتورهای پلهای میتوانند مقدار زیادی جریان بکشند، حتی زمانی که حرکت نمیکنند. اگر به آرامی (بدون اینکه واقعاً آن را بچرخانید) سعی کنید یک موتور پلهای برقدار را بچرخانید، مقاومت احساس خواهید کرد. یک L293 یا حتی L298 روی بردبرد در طول زمان بسیار داغ خواهد شد و این گرما ممکن است برای ترکیب پلاستیکی بردبرد زیاد باشد. به همین دلیل توصیه میکنیم از شیلد موتور استفاده کنید که در ادامه توصیف میشود.
شیلد موتور دارای heat sink و تحمل حرارتی مناسب برای این کاربرد است. اگر میخواهید توان مصرفی را کاهش دهید، میتوانید زمانی که موتورهای پلهای استفاده نمی شوند آنها را با صفر کردن پایههای ENA و ENB خاموش کنید. این کار یعنی موتور موقعیت خود را در جای خود، و در بین پلهها نگه میدارد).
آموزش راهاندازی یک Brushed Motor با Transistor و...
من کاپیتان آردوینو، اسمم میلاده و اینجا هستم تا تجربیاتم در رابطه با آردوینو رو با شما به اشتراک بزارم!
سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.