أردوينو – الدرس الخامس عشر – محرك السيرفو Servo Motor

مقدمة

في هذا الدرس ستتعلم كيفية التحكم بدوران محرك السيرفو ‘servo motor’.

أولاً ، ستقوم بتعلم كيفية تحريك المحرك بمختلف الاتجاهات، ومن ثم ستقوم باضافة مقاوم متغير ‘pot’ للتحكم بوضعيته.

محرك السيرفو

المواد والأدوات

محرك السيرفو

1× محرك سيرفو (TowerPro MG946R Servo)

arduino-lesson-12-lcd

1× مقاوم متغير 10kΩ variable resistor (pot)

Half-size Breadboard

1× لوحة التجارب (Half-size Breadboard)

Arduino Uno R3

 1× اردوينو اونو

Jumper wire pack

حزمة أسلاك توصيل (ذكر-ذكر)

Arduino cable

1× سلك اردوينو

100µF capacitor

1× مكثف (100µF capacitor)
اختياري

محرك السيرفو ‘servo motors’

موضع محرك السيرفو يعتمد على طول الذبذبة. حيث يستقبل ذبذبة كل مايقارب  20 جزء من الثانية . اذا كانت الذبذبة بجزء واحد من الثانية فإن زاوية السيرفو تساوي صفر، واذا كانت 1.5 جزء من الثانية فإنها ستكون بالمنتصف ، واذا كانت جزئين من الثانية فستكون بزاوية 180 درجة.

servo motors

توصيل الدائرة محرك السيرفو

في هذه التجربة، اربط  محرك السيرفو ‘servo motor’ بالاردوينو.

محرك السيرفو

محرك السيرفو ‘servo motor’ لديه ثلاثة رؤوس ، اللون الأحمر لطاقة 5V ، اللون الأسود/أو البني للمخرج الأرضي GND ، واللون الأخير عادة مايكون برتقالي/أو أصفر يتم ربطه بالمنفذ الرقمي 9 ‘digital pin’.

يوجد مقبس بنهاة اسلاك محرك السيرفو ‘servo motor’ تسمح بوضع وربط اسلاك الـ jumper wires بها للربط مع لوح التجارب والأردوينو.

محرك السيرفو

الكود البرمجي محرك السيرفو

قم برفع الكود التالي على متحكم الاردوينو وستجد أن محرك السيرفو ‘servo motor’ يبدأ بالحركة مباشرة باتجاه واحد ثم العوده للاتجاه الآخر.

الكود يعتمد على المثال البرمجي ‘sweep’  الموجود بمكتبة أمثلة الأردوينو
File> Examples> Servo> Sweep

#include <Servo.h>
 
int servoPin = 9;
 
Servo servo;  
 
int angle = 0;   // servo position in degrees
 
void setup()
{
  servo.attach(servoPin);
}
 
 
void loop()
{
  // scan from 0 to 180 degrees
  for(angle = 0; angle < 180; angle++)  
  {                                  
    servo.write(angle);               
    delay(15);                   
  }
  // now scan back from 180 to 0 degrees
  for(angle = 180; angle > 0; angle--)    
  {                                
    servo.write(angle);           
    delay(15);       
  }
}

 

يتم التحكم بمحرك السيرفو ‘servo motor’ عبر سلسلة من الذبذبات ، ولجعل العملية سهله  تم توفير مكتبة كود للاردوينو  ليسهل عليك عملية توجيه محرك السيرفو ‘servo motor’ للتوجيه لزاوية معينة.

الاوامر البرمجية للتحكم بمحرك السيرفو تماماً كالاوامر الأخرى في برنامج الأردوينو ولكن لأننا لانستخدمها بشكل دائم في كل المشاريع ، لذلك عليك استدعاء مكتبة اوامر التحكم بمحرك السيرفو ‘servo motor’ وذلك عبر الأمر التالي

#include <Servo.h>

 

وكالعادة نقوم بتحديد وتعريف المنفذ الذي يتم ربطه بمحرك السيرفو عبر المتغير ‘servoPin’ .

Servo servo;

 

لنقم برمجياً بتعريف محرك سيرفو من نوع سيرفو . المكتبة البرمجية وفرت لنا نوع للتعريف وهو ‘servo’ تماماً كالتعريفات الاخرى مثل ‘int’ و ‘float’ ..الخ

لذلك باستخدام تعريف النوع ‘servo’ يمكنك من أن تعرف حتى 8 محركات سيرفو مرتبطه بالأردوينو . التعريف يتم كالتالي

Servo servo1;
Servo servo2;

في دالة setup علينا ربط متغير ‘servo’ بالمنفذ الذي سيتحكم بمحرك السيرفو ، وذلك عبر الأمر التالي

  servo.attach(servoPin);

المتغير ‘angle’ يستخدم لتحديد الزاوية الحالية لمحرك السيرفو . بداخل دالة loop استخدمنا حلقتين ‘for loop’ وذلك لزيادة الزاوية في اتجاه واحد حتى 180 درجة ثم العودة والذهاب للجهة الأخرى.

الأمر

   servo.write(angle);

يطلب من السيرفو لتحديث موضعه من الزاوية التي تم تحديدها له.

توصيل الدائرة للموجه

الخطوة التالية هي وضع المقاوم المتغير واستخدامه كموجه يسمح لنا بتغيير زاوية محرك السيرفو عبر توجيهه.

كل ماعلينا فعله هو وضع المقاوم المتغير ‘pot’ وربطه بالمنفذ A0 بالأردوينو.

محرك السيرفو

الكود البرمجي للموجه

الكود البرمجي لتوجيه محرك السيرفو عبر المقبض أسهل من الكود السابق

#include <Servo.h>
 
int potPin = 0;  
int servoPin = 9;
Servo servo;
 
void setup()
{
  servo.attach(servoPin);  
}
 
void loop()
{
  int reading = analogRead(potPin);     // 0 to 1023
  int angle = reading / 6;              // 0 to 180
  servo.write(angle);  
}

 

هنالك متغير آخر يدعى ‘potPin’ .

لتحديد موضع السيرفو ، علينا تحويل القراءة التناظرية ‘analogRead’ من المنفذ A0. هذا سيعطينا قيمة مابين 0 و 1023 . وبما أن السيرفو يستطيع التحرك حتى زاوية 180 درجة كحد أقصى لذا علينا خفض الحد الأقصى من القيمة المقروءة. وذلك عبر قسمة الرقم على 6 وذلك سيعطينا قيمة مابين 0 و 170 والتي ستكون مناسبة.

المشاكل والإصلاحات

قد يحدث خلل أثناء عمل السيرفو ‘servo motor’. وقد يحصل هذا عندما يكون متحكم الأردوينو مرتبط “ببعض” منافذ الـUSB . هذا لأن المحرك يوجه الكثير من الطاقه، خصوصاً عند بدء عمل المحرك،مما قد يخفض الجهد Voltage بالأردوينو،فيتم اعادة تشغيله

يتم حل هذه المشكلة عبر اضافة مكثف عالي ‘capacitor’  (470uF أو أعلى) يتم وضعه مابين 5V و GND.

capacitor breadboard design

المكثف ‘capacitor’ يعمل كخزان للتيار الكهربائي حيث يسمح للمحرك عند بدء تشغيله بأخذ التيار المخزن بالمكثف اضافة للتيار الذي يقوم بأخذه من الأردوينو.

النهاية الأطول للمكثف ‘capacitor’ هي النهاية الموجبة والتي يجب ربطها بـ5V. النهاية السالبة عادة يكون علامة ‘ – ‘ عليها.

أنشطة أخرى

حاول تقليل معدل التأخير ‘delay’ من 15 جزء من الثانية إلى 5 جزء من الثانية .
لاحظ اختلاف سرعة السيرفو.

حاول التحكم بمحرك السيرفو عن طريق شاشة الاتصال التسلسلي عوضاً عن المقاوم المتغير.

ملاحظة: لتتمكن من قراءة الرقم من شاشة الاتصال التسلسلي serial monitor تستطيع استخدام دالة Serial.parseInt() لقراءة الأرقام من شاشة الاتصال التسلسلي serial monitor




التحكم في محرك تيار مستمر باستخدام H-Bridge

في هذا المشروع سنتعلم فكرة عمل الH-Bridge  وكيفية استعماله للتحكم في تشغيل وايقاف محرك تيار مستمر وايضا عكس اتجاه حركته. قد يستخدم في روبوت متتبع الخط او اي روبوت نحتاج للتحكم في اتجاه حركته

التحكم-فى-اتجاه-دوران-محرك-تيار-مستمر-ب

المكونات المطلوبة

arduino uno r3

Arduino Uno

1k Ω Resistor

1K Resistor

NPN Transistor 2N2222

2n2222 NPN Transistor

9V DC Motor

DC Motor

9VDC 1000mA regulated switching power adapter

DC Power Supply

Full size breadboard 830

Breadboard

Breadboard Jumper Wire 65 pcs

Wires

الترانزستور Transistor :

هو عبارة عن مفتاح إلكتروني يتم التحكم في فتحه وإغلاقه إلكترونيا. ويتركب الترانزستور من مواد شبه موصلة وله ثلاث أطراف، الطرف الأول يسمة مشع (emitter)  والثاني يسمى القاعدة (base)، والثالث يمسى المجمع (collector) .

فكرة عمله :

عند مرور التيار إلى طرف القاعدة يصبح الترانزستور في حالة توصيل وسيتم مرور التيار بين المشع والمجمع. وعند قطع التيار يصبح في حالة القطع أي لا يتم مرور أي تيار بين المشع والمجمع.

التحكم-فى-اتجاه-دوران-محرك-تيار-مستمر-ب

H-Bridge :

هو عبارة عن أربعة ترانزستور موصلين معا بشكل معين لتمكين المحرك من الدوران في إتجاهين مختلفين.

فكرة عمله :

الصورة التالية توضح كيف يتركب الـ H-Bridge:

hbridge-arduino

عند تشغيل كلا الترانزستور 1 و 4 يعمل المحرك نحو الإتجاه الأول وعند تشغيل الترانزستور 2 و 3 يعمل المحرك في الإتجاه المعاكس للإتجاه السابق.

وبذلك، يتم عكس الدوران اتوماتيكيا دون الحاجة إلى تغيير التوصيل يدويا. على عكس محرك التيار المستمر، الذي يتم تعكس اتجاهه عن طريق عكس اطراف المحرك مع مصدر التيار الكهربائي.

التحكم-فى-اتجاه-دوران-محرك-تيار-مستمر-ب
التحكم-فى-اتجاه-دوران-محرك-تيار-مستمر-ب

في الحالة الأولى، سيدور المحرك مع إتجاه عقارب الساعة. وبعكس توصيل الأطراف (كما هو موضح بالحالة الثانية) سينعكس إتجاه الدوران ليصبح عكس عقارب الساعة.

توصيل الدارة :

لا يمكن توصيل محرك التيار المستمر مباشرة مع الأردوينو. وذلك لأن المحرك يحتاج إلى تيار عالي لا يستطيع الأردوينو إعطاءه له. لذلك، سنقوم بإستخدام الترانزستور كدائرة بين الاردوينو الذي يعمل مع تيار صغيرة وبين المحرك الذي يحتاج إلى تيار عالي.

قم بتوصيل الدارة كما هو موضح بالصورة :

التحكم-فى-اتجاه-دوران-محرك-تيار-مستمر-ب
ولنتمكن من تشغيل المحرك في إتجاهين، يتم تشغيل الطرف الأول من الـ H-Bridge للأردوينو في المحرك، فيدور المحرك في الإتجاه الأول. وعند تشغيل الطرف الثاني سيدور بالإتجاه المعاكس.
التحكم-فى-اتجاه-دوران-محرك-تيار-مستمر-ب

الكود البرمجي

في هذا المشروع، سيدور المحرك في الإتجاه الأول لمدة ثلاث ثوان، ثم يتوقف لمدة ثلاث ثوان. ثم يدور المحرك بالإتجاه المعاكس لمدرة ثلاث ثوان، ثم يتوقف لمدة ثلاث ثوان أخرى. وهكذا حتى يتم فصل التيار الكهربائي.

قم بتحميل الكود التالي إلى الأردوينو :

#define MOTOR_IN1 12
#define MOTOR_IN2 13  

void motor_forward(void);  // a function that will be called to rotate it clockwise
void motor_reverse(void);  // a function that will be called to totate it counter-clockwise
void motor_stop(void);     // a function that will be called to stop the rotation

void setup() {
  pinMode(MOTOR_IN1, OUTPUT);  // set the first pin of the relay as output
  pinMode(MOTOR_IN2, OUTPUT);  // set the 2nd pin of the relay as output
}

void loop() {
  motor_forward();             // move forward/clockwise
  delay(3000);                 // keep rotating cw for 3 seconds
  motor_stop();                // stop rotating
  delay(3000);                 // stand still for 3 seconds
  motor_reverse();             // reverse the rotation direction/ccw
  delay(3000);                 // keep rotating ccw for 3 seconds
  motor_stop();                // stop rotating
  delay(3000);                 // stand still for 3 seconds
}

void motor_forward(void)       // the function that will cause the motor to rotate cw
{
  digitalWrite(MOTOR_IN1, HIGH);
  digitalWrite(MOTOR_IN2, LOW);
}

void motor_reverse(void)       // the function that will cause the motor to rotate ccw
{
  digitalWrite(MOTOR_IN1, LOW);
  digitalWrite(MOTOR_IN2, HIGH);
}

void motor_stop(void)          // the function that will cause the motor to stop rotating
{
  digitalWrite(MOTOR_IN1, LOW);
  digitalWrite(MOTOR_IN2, LOW);
}

شرح الكود :

قمنا سابقا بتوصيل طرفى كلا من الترانزستور (IN1,IN2) بمنفذ 12 و 13 للأردوينو . لذلك قمنا بتسمية كلا المنفذين للأردونو تبعا لما تم توصيله بالدارة.

#define MOTOR_IN1 12
#define MOTOR_IN2 13

نقوم بتعرف المتغيرات IN1 و IN2 ( أطراف الـ H-bridge الموصله بالاردوينو) كمخرج.

void setup() {
  pinMode(MOTOR_IN1, OUTPUT);  // set the first pin of the relay as output
  pinMode(MOTOR_IN2, OUTPUT);  // set the 2nd pin of the relay as output
}

في دالة ()loop، نقوم أولا بإستدعاء الدالة ()motor_forward . تقوم هذه الدالة بتشغيل المحرك مع اتجاه عقارب الساعة لمدة 3 ثوان ((delay(3000)  . ثم نقوم باستخدام الدالة ()motor_stop ، لإيقاف المحرك عن العمل لمدة 3 ثوان. ثم يتم عكس اتجاه حركة المحرك باستخدام الدالة ()motor_reverse لمدة 3 ثوان. ومن ثم يعود ليكرر نفس هذه المهمة من البداية مرة أخرى.

void loop() {
  motor_forward();             // move forward/clockwise
  delay(3000);                 // keep rotating cw for 3 seconds
  motor_stop();                // stop rotating
  delay(3000);                 // stand still for 3 seconds
  motor_reverse();             // reverse the rotation direction/ccw
  delay(3000);                 // keep rotating ccw for 3 seconds
  motor_stop();                // stop rotating
  delay(3000);                 // stand still for 3 seconds
}

الدلة ()motor_forward، تقوم بتحريك المحرك بإتجاه عقارب الساعة. تتم هذه العملية عن طريق جعل قيمة IN1  للمرحل HIGH والطرف الآخر LOW .

void motor_forward(void)       // the function that will cause the motor to rotate cw
{
  digitalWrite(MOTOR_IN1, HIGH);
  digitalWrite(MOTOR_IN2, LOW);
}

تعمل هذه الدالة ()motor_reverse بشكل مشابه للدالة السابقة، إلا أنها تعكس اتجاه دوران المحرك. تتم هذه العملية عن طريق جعل قيمة IN2 للمرحل HIGH، وIN1 قيمة LOW .

void motor_reverse(void)       // the function that will cause the motor to rotate ccw
{
  digitalWrite(MOTOR_IN1, LOW);
  digitalWrite(MOTOR_IN2, HIGH);
}

دالة ()motor_stop، تقوم بإيقاف المحرك تماما عن الحركة، عن طريق جعل قيمة كلا الطرفين LOW فلا يصل التيار للمحرك فيتوقف.

void motor_stop(void)          // the function that will cause the motor to stop rotating
{
  digitalWrite(MOTOR_IN1, LOW);
  digitalWrite(MOTOR_IN2, LOW);
}