Control a servo motor with an Arduino and a potentiometer
مبتدئ
أو تصفّح كل الدروس.
- 503قطعة على المنضدة
- 44لوحة تعمل الآن
- 1.00xزمن حقيقي، على كل لوحة
سيرفو الهواة أسهل طريقة لجعل Arduino تحرّك شيئًا إلى زاوية دقيقة: ثلاثة أسلاك، وطرف إشارة واحد، ورقم من 0 إلى 180. الدائرة أعلاه سيرفو من نوع SG90 على الطرف 9 من Arduino Uno، ومقاومة متغيرة منزلقة على A0 تحدد أين يشير الذراع. وهي تعمل في متصفحك على ATmega328P محاكاة.
افتحه في المحرر واسحب المنزلق أثناء التشغيل: يسير الذراع إلى الزاوية الجديدة بالسرعة التي يفعلها SG90 حقيقي، وتطبع الشاشة التسلسلية القراءة والزاوية في كل مرة تتغير.
What you need
- Arduino Uno
- سيرفو هواة SG90 (أو مشابه)
- مقاومة متغيرة 10 k (منزلقة هنا؛ والدوارة توصَّل بالطريقة نفسها)
- لوحة تجارب وأسلاك توصيل
Wiring
| القطعة والطرف | يتصل بـ | ملاحظة |
|---|---|---|
| سلك السيرفو البني (GND) | GND | |
| سلك السيرفو الأحمر (VCC) | 5 V | تحت 4 V لا يتحرك السيرفو على الإطلاق |
| سلك السيرفو البرتقالي (الإشارة) | الطرف 9 | يصلح أي طرف رقمي |
| طرف المقاومة المتغيرة 1 | 5 V | |
| طرف المقاومة المتغيرة 3 | GND | |
| ممسحة المقاومة المتغيرة | A0 | تقرأ 0 إلى 1023 على امتداد المدى |
ما الذي يصغي إليه السيرفو فعلًا
سلك إشارة السيرفو لا يأخذ PWM بالمعنى الذي يأخذه LED. دورة العمل لا تعني له شيئًا. ما يقيسه هو عرض كل نبضة: بأرقام مكتبة Servo، 544 ميكرو ثانية تضع الذراع عند أحد الطرفين، و2400 ميكرو ثانية عند الآخر، و1472 ميكرو ثانية في المنتصف، وتتكرر نحو خمسين مرة في الثانية. يحتفظ السيرفو بآخر ما قيل له، ويسير إليه بسرعته، نحو عُشر ثانية لستين درجة.
وهذا أيضًا سبب أنك لا تستطيع قيادة سيرفو بـanalogWrite() على Uno. يعمل PWM في Uno عند نحو 490 أو 980 هرتز، وهذا أسرع بكثير من أن يقرأه سيرفو كعرض نبضة. أما مكتبة Servo فتصنع النبضة بنفسها.
الكود، مشروحًا
يقرأ الكود المقاومة المتغيرة أربع مرات ويأخذ متوسط القراءات، فلا يرتجف الذراع بسبب البت الأخير المشوَّش من المحوّل. وتحوّل map() المدى 0 إلى 1023 إلى 0 إلى 180 درجة، وترسل write() النبضة المقابلة، وتنتظر الحلقة 20 ملي ثانية، وهي فترة إطار السيرفو نفسه. وتُطبع الزاوية فقط عندما تتغير، فتُقرأ الشاشة التسلسلية كجملة لا كشلال.
void loop() {
long sum = 0;
for (int i = 0; i < 4; i++) {
sum += analogRead(FADER);
}
int reading = (int)(sum / 4);
int angle = (int)map(reading, 0, 1023, 0, 180);
horn.write(angle);
delay(20);
}الشيء نفسه بمكتبة Servo
يستخدم المثال المدمج ملف Servo الرأسي الخاص بـMokxi، لكن استدعاءات مكتبة Arduino Servo تُترجَم كما هي، على كل لوحة تُترجَم في المتصفح. يعمل كود المسح الكلاسيكي أدناه دون تغيير، بعروض المكتبة الأصلية: تستخدم attach(pin) من 544 إلى 2400 ميكرو ثانية، وترسل write(90) القيمة 1472، وتضبط attach(pin, min, max) نافذة أخرى. وثمة فرق صغير يستحق أن تعرفه: كل write() ترسل نبضة واحدة بدل أن تبدأ مؤقتًا، لذلك فإن كودًا يحتاج إلى إبقاء السيرفو ثابتًا تحت حمل يستدعي refresh() من loop().
وفي شروح ESP32، تكون ESP32Servo.h الصنف نفسه بالاسم الذي تستخدمه تلك الشروح.
#include <Servo.h>
Servo myservo;
void setup() {
myservo.attach(9);
}
void loop() {
for (int pos = 0; pos <= 180; pos++) {
myservo.write(pos);
delay(15);
}
}جرّبه في المحرر
افتح الدائرة في المحرر وغيّر استدعاء map() إلى map(reading, 0, 1023, 45, 135). يغطي المنزلق الآن التسعين درجة الوسطى فقط، وهكذا تعطي المقبض إحساسًا أدق على مدى أصغر.
ثم اختر السيرفو وانظر إلى خصائصه: min_pulse وmax_pulse وrange وspeed. اضبط speed على 60 درجة في الثانية وحرّك المنزلق بسرعة؛ سيزحف الذراع خلفه، كما يفعل سيرفو كبير بطيء. وقيمتا min_pulse وmax_pulse هما 544 و2400 افتراضيًا، نافذة مكتبة Servo؛ والسيرفو المُعدّ بـattach(pin, 1000, 2000) يريد 1000 و2000 هناك أيضًا.
لقيادة سيرفو ثانٍ، اسحب آخر إلى مساحة العمل، ووصّل إشارته بالطرف 10، وأضف كائن Servo ثانيًا في الكود.
Common mistakes
تغذية السيرفو من اللوحة وتوقّع أن يكون ذلك مقبولًا. على منضدة حقيقية قد يسحب SG90 ربع أمبير عندما يتعطل، وهذا يكفي لإسقاط جهد Uno تعمل من USB، وهو أشهر سبب لأن يعيد مشروع سيرفو تشغيل نفسه. لا يحاكي المحاكي تيار التغذية، لذلك تعمل هنا بسلاسة دائرة كانت ستهبط على مكتبك. وإذا بنيتها حقيقيةً، فأعطِ السيرفو مصدر 5 فولت خاصًا به ووصّل الأرضيات.
نسيان الأرضي المشترك. تُقاس الإشارة نسبةً إلى أرضي السيرفو نفسه، فإذا لم يتشارك المصدران في شيء فلا معنى للنبضة.
طلب زوايا لا يستطيع السيرفو بلوغها. النبضة التي تتجاوز أيًّا من طرفي نافذة السيرفو تترك الذراع عند ذلك الطرف، كما يجهد SG90 حقيقي ضد مانع نهايته. وإذا توقف الذراع قبل 0 أو 180، فتحقق من أن النافذة في attach() تطابق min_pulse وmax_pulse للسيرفو.
تحديث السيرفو في حلقة ضيقة دون delay. إرسال النبضات أسرع من كل 20 ملي ثانية لا يفيد، لأن السيرفو لا يتحدث إلا بمعدل إطاره الخاص.
الأسئلة
أي أطراف Arduino تستطيع قيادة سيرفو؟
أي طرف رقمي. تصنع المكتبة النبضة برمجيًا، فلا يحتاج السيرفو إلى أحد أطراف PWM المعلّمة بعلامة التيلدا.
هل أستطيع قيادة سيرفوين معًا؟
نعم. أنشئ كائني Servo على طرفين واكتب في كل منهما. وأعطِ السيرفوهات الحقيقية مصدرها الخاص عندما يزيد عددها على واحد، لأن التيار يتراكم.
لماذا يرتجف السيرفو؟
عادةً لأن القراءة التي يتبعها مشوَّشة. تستقر الحركة بأخذ متوسط عدة عينات من analogRead()، كما يفعل هذا الكود، أو بتجاهل تغيرات درجة أو درجتين. وفي العتاد الحقيقي يسبّب هبوط المصدر ارتجافًا أيضًا.
ما الفرق بين السيرفو والمحرك الخطوي؟
يذهب السيرفو إلى زاوية ويثبت عندها، مع تغذية راجعة خاصة به في داخله، وعادةً على مدى 180 درجة. أما المحرك الخطوي فيدور بخطوات معدودة، إلى أي مدى تشاء، ولا يعرف أين هو إلا إذا عددت أنت. ويغطي شرح المحرك الخطوي 28BYJ-48.
واصل
ابنِ هذا على أرض الواقع
افتح المحرر وغيّر قيمة وشاهد الرقم يتحرك معها. لا شيء لتثبّته ولا حاجة إلى حساب.