مقدمة
أصبحت التكنولوجيا الحديثة تسهل علينا حياتنا، وتجعلها أبسط ومن ضمن ما طوره الباحثون في التقنية هو التحكم بالأجهزة عن بعد عن طريق حركات اليد ويعد نهجًا جديدًا للتحكم والسيطرة عن طريق مطابقة الحركة، في هذا الدرس ستتعلم كيفية التحكم بالحاسوب بحركات اليد بدلًا من الفأرة وذلك باستخدام الاردوينو وحساس الموجات فوق الصوتية.
سوف تتمكن من برمجة الاردوينو مع حساس الموجات فوق الصوتية، بحيث يقوم بمهام كإيقاف الفيديو أو تقديم وترجيع الفيديو وكذلك مهام التحكم بالصوت.
المواد والأدوات
1× اردوينو اونو
1× شريط لاصق ذو وجهين
توصيل الدائرة
المفهوم بسيط جدًا سنضع حساسي الموجات فوق الصوتية أعلى شاشة الحاسوب وسنقوم بإدخال المسافة بين الشاشة ويدنا باستخدام الاردوينو، بناءً على هذه القيمة سنقوم بإجراءات معينة.
للمزيد حول حساس الموجات فوق الصوتية يمكنك الرجوع للدرس التالي حساب المسافة بإستخدام حساس الموجات فوق صوتية
تثبيت القطع على جهاز الحاسوب
قم بقص الشريط اللاصق لثلاث قطع صغيرة وثبتها على جهاز الحاسوب كما هو واضح بالصورة:
ثبت الدائرة الكهربائية كما هو موضح:
الكود البرمجي للتحقق من قراءة المدخلات
في البداية سنقوم برفع كود برمجي لمحاكاة مشروع التحكم بالحاسوب بحركات اليد بدلًا من الفأرة والتحقق من أن الحساس يعطي قراءات صحيحة، ويتم طباعة الأوامر على شاشة الاتصال التسلسلي
ارفع الكود التالي إلى لوحة الاردوينو عن طريق (IDE) وافتح شاشة الاتصال التسلسلي.
const int trigger1 = 2; //Trigger pin of 1st Sesnor
const int echo1 = 3; //Echo pin of 1st Sesnor
const int trigger2 = 4; //Trigger pin of 2nd Sesnor
const int echo2 = 5;//Echo pin of 2nd Sesnor long time_taken;
int dist,distL,distR; void setup() { Serial.begin(9600);
pinMode(trigger1, OUTPUT); pinMode(echo1, INPUT);
pinMode(trigger2, OUTPUT);
pinMode(echo2, INPUT);
} /*###Function to calculate distance###*/ void calculate_distance(int trigger, int echo) { digitalWrite(trigger, LOW); delayMicroseconds(2);
digitalWrite(trigger, HIGH);
delayMicroseconds(10);
digitalWrite(trigger, LOW); time_taken = pulseIn(echo, HIGH);
dist= time_taken*0.034/2;
if (dist>50)
dist = 50; } void loop() { //infinite loopy calculate_distance(trigger1,echo1); distL =dist; //get distance of left sensor
calculate_distance(trigger2,echo2);
distR =dist; //get distance of right sensor //Uncomment for debudding
/*Serial.print("L=");
Serial.println(distL); Serial.print("R="); Serial.println(distR);
*/ //Pause Modes -Hold
if ((distL >40 && distR>40) && (distL <50 && distR<50)) //Detect both hands
{Serial.println("Play/Pause"); delay (500);} calculate_distance(trigger1,echo1);
distL =dist;
calculate_distance(trigger2,echo2);
distR =dist; if ((distL >40 && distL<50) && (distR ==50)) //Detect Left Hand {Serial.println("Rewind"); delay (500);} if ((distR >40 && distR<50) && (distL ==50)) //Detect Right Hand {Serial.println("Forward"); delay (500);} //Control Modes
//Lock Left - Control Mode if (distL>=13 && distL<=17) {
delay(100); //Hand Hold Time calculate_distance(trigger1,echo1);
distL =dist; if (distL>=13 && distL<=17) { Serial.println("Left Locked"); while(distL<=40) {
calculate_distance(trigger1,echo1);
distL =dist;
if (distL<10) //Hand pushed in {Serial.println ("Vup"); delay (300);} if (distL>20) //Hand pulled out
{Serial.println ("Vdown"); delay (300);} }
} } //Lock Right - Control Mode if (distR>=13 && distR<=17) { delay(100); //Hand Hold Time calculate_distance(trigger2,echo2); distR =dist;
if (distR>=13 && distR<=17)
{ Serial.println("Right Locked");
while(distR<=40)
{ calculate_distance(trigger2,echo2); distR =dist; if (distR<10) //Right hand pushed in {Serial.println ("Rewind"); delay (300);} if (distR>20) //Right hand pulled out
{Serial.println ("Forward"); delay (300);} }
}
} delay(200); }
شرح الكود البرمجي
عرفنا المتغيرات اللازمة التي يستخدمها كلا حساسي الموجات فوق الصوتية.
المخرج للحساس الأول (trigger1) والمدخل للحساس الأول (echo1).
المخرج للحساس الثاني (trigger2) والمدخل للحساس الثاني (echo2).
const int trigger1 = 2; //Trigger pin of 1st Sesnor
const int echo1 = 3; //Echo pin of 1st Sesnor
const int trigger2 = 4; //Trigger pin of 2nd Sesnor
const int echo2 = 5;//Echo pin of 2nd Sesnor long time_taken;
int dist,distL,distR; void setup() { Serial.begin(9600);
pinMode(trigger1, OUTPUT); pinMode(echo1, INPUT);
pinMode(trigger2, OUTPUT);
pinMode(echo2, INPUT);
}.
عند تشغيل أي مقطع فيديو على مشغل الفيديو (VLC) أو اليوتيوب سيتم حساب المسافة بين كلا حساسي الموجات فوق الصوتية واليدين في كل مرة من خلال الدالة ()calculate_distance، وسيكون هناك عدة اجراءات بناء على تلك القراءات.
/*###Function to calculate distance###*/ void calculate_distance(int trigger, int echo) { digitalWrite(trigger, LOW); delayMicroseconds(2);
digitalWrite(trigger, HIGH);
delayMicroseconds(10);
digitalWrite(trigger, LOW); time_taken = pulseIn(echo, HIGH);
dist= time_taken*0.034/2;
if (dist>50)
dist = 50; }
داخل دالة ()Loop، يتم التحقق من قيمة المسافة وعلى أساسها يتم الاختيار من بين الاجراءات.
نستخدم المتغير distL ويشير إلى مقدار المسافة بين حساس الموجات الصوتية و اليد الموجود باليسار
نستخدم المتغير distR ويشير إلى مقدار المسافة بين حساس الموجات الصوتية و اليد الموجود باليمين
calculate_distance(trigger1,echo1); distL =dist; //get distance of left sensor calculate_distance(trigger2,echo2); distR =dist; //get distance of right sensor
بناء على المسافة (عند وضع كلتا اليدين على الحساسين في نفس الوقت وكانت المسافة أكبر من 40 وأصغر من 50) سيتوقف الفيديو وعند الرغبة بتشغيل الفيديو مرة أخرى يمكنك إرجاع كلتا يديك لكلا الحساسين.
if ((distL >40 && distR>40) && (distL <50 && distR<50)) //Detect both hands {Serial.println("Play/Pause"); delay (500);}
بناء على المسافة (المسافة بين الحساس الأيسر واليد اليسرى أكبر من 40 وأقل من 50 والمسافة بين الحساس الأيمن واليد اليمنى تساوي 50) سيتم ترجيع الفيديو للخلف.
بناء على المسافة (المسافة بين الحساس الأيمن واليد اليمنى أكبر من 40 وأقل من 50 والمسافة بين الحساس الأيسر واليد اليسرى تساوي 50) سيتم تقديم الفيديو للامام.
if ((distL >40 && distL<50) && (distR ==50)) //Detect Left Hand {Serial.println("Rewind"); delay (500);} if ((distR >40 && distR<50) && (distL ==50)) //Detect Right Hand {Serial.println("Forward"); delay (500);}
إذا كانت المسافة (المسافة بين الحساس الأيسر ويدك اليسرى أقل من 10) سيزيد حجم الصوت.
إذا كانت المسافة (المسافة بين الحساس الأيسر ويدك اليسرى أكبر من 20) سينقص حجم الصوت.
//Lock Left - Control Mode if (distL>=13 && distL<=17) { delay(100); //Hand Hold Time calculate_distance(trigger1,echo1); distL =dist; if (distL>=13 && distL<=17) { Serial.println("Left Locked"); while(distL<=40) { calculate_distance(trigger1,echo1); distL =dist; if (distL<10) //Hand pushed in {Serial.println ("Vup"); delay (300);} if (distL>20) //Hand pulled out {Serial.println ("Vdown"); delay (300);} } } }
إذا كانت المسافة (المسافة بين الحساس الأيمن ويدك اليمنى أقل من 10) سيتم ترجيع الفيديو للخلف.
إذا كانت المسافة (المسافة بين الحساس الأيمن ويدك اليمنى أكبر من 20) سيتم تقديم الفيديو للأمام.
//Lock Right - Control Mode if (distR>=13 && distR<=17) { delay(100); //Hand Hold Time calculate_distance(trigger2,echo2); distR =dist; if (distR>=13 && distR<=17) { Serial.println("Right Locked"); while(distR<=40) { calculate_distance(trigger2,echo2); distR =dist; if (distR<10) //Right hand pushed in {Serial.println ("Rewind"); delay (300);} if (distR>20) //Right hand pulled out {Serial.println ("Forward"); delay (300);} } } } delay(200); }
تنصيب (Python IDLE) و (Pyserial)
1- تنصيب (Python IDLE)
تثبيت البايثون على نظام ويندوز سوا كان نظام تشغيل 32 بت أو 64 بت هو نفسه.
انقر على الرابط التالي Python 3.9.2 وثبت البرنامج على جهاز الحاسوب.
حمّل نسخة 32 بت دائمًا مهما كان نظام التشغيل.
افتح ملف exe الذي تم تنزيله واتبع التعليمات لا تقم بتغيير المسار الذي يتم فيه تثبيت Python.
سيكون المسار C:\Program Files (x86)\Python39-32 بشكل افتراضي اتركه كما هو عليه.
2- ضبط إعدادات لوحة الأوامر
بعد تنصيب البايثون على جهازك، علينا اجراء التعديلات ليتم السماح بتنفيذ أوامره في شاشة الأوامر Command Prompt.
علينا اضافة مترجم اوامر البايثون إلى امتدادات الأوامر – PATH environment variable.
عليك الذهاب للوحة التحكم بويندوز واتباع المسار التالي:
Control Panel\System and Security\System
اختر من القائمة Advanced system setting:
انقر على Environment variable:
انقر على Path من قائمة System Variables.
انقر على New وأضف المسار التالي (أو المسار الذي قمت بتحميل البرنامج عليه):
C:\Program Files (x86)\Python39-32
انقر على New مرة أخرى وضع مسار مجلد Scripts:
C:\Program Files (x86)\Python39-32\Scripts
بعد اتمامك للخطوات سيكتمل تنصيب البرنامج، يمكنك التحقق من وجوده وذلك بالبحث عنه مع قائمة البرامج Python IDLE.
3- تنصيب (Pyserial)
بعد ذلك علينا تنصيب Pyserial انقر على الرابط التالي وحمله على حاسوبك Pyserial 3.5
بعد تحميله فك الضغط عنه وانسخ المسار الذي يتواجد فيه ملف Pyserial.
انقر بالسهم اليمين على Command Prompt واختر من القائمة Run as administrator.
اكتب الأمر التالي وضع المسار الذي قمت بتحميل Pyserial فيه:
cd (Pyserial المسار لبرنامج)
حمل setup.py.
python setup.py install
4- تنصيب مكتبة (Pyautogui)
تركيب وحدة Pyautogui للويندوز:
تأكد من أن جهاز الحاسوب متصل بالإنترنت واتبع الخطوات أدناه:
الخطوة 1: افتح صفحة الأوامر بويندوز Windows prompt وقم بتغيير المسار إلى المجلد الذي قمت بتثبيت به البايثون.
cd C:\Program Files (x86)\Python39-32
الخطوة 2: داخل مسار بايثون، سنقوم بترقية Pip وهي أداة في البايثون تساعدنا على تثبيت وحدات البايثون بسهولة استخدم الأمر التالي لترقيتها.
pip install –-upgrade pip
الخطوة 3: ثبت وحدة Pyautogui.
pip install pyautogui
الكود البرمجي (بايثون)
افتح برنامج IDLE (Python 3.9 32-bit) من قائمة File اختر New File والصق الكود البرمجي التالي.
ارفع الكود البرمجي للوحة الاردوينو من قائمة Run انقر على Run module.
import serial #Serial imported for Serial communication import time #Required to use delay functions import pyautogui ArduinoSerial = serial.Serial('com18',9600) #Create Serial port object called arduinoSerialData time.sleep(2) #wait for 2 seconds for the communication to get established while 1: incoming = str (ArduinoSerial.readline()) #read the serial data and print it as line print (incoming) if 'Play/Pause' in incoming: pyautogui.typewrite(['space'], 0.2) if 'Rewind' in incoming: pyautogui.hotkey('ctrl', 'left') if 'Forward' in incoming: pyautogui.hotkey('ctrl', 'right')
if 'Vup' in incoming: pyautogui.hotkey('ctrl', 'down') if 'Vdown' in incoming: pyautogui.hotkey('ctrl', 'up')
incoming = "";
شرح الكود البرمجي
افتح صفحة جديدة في IDLE Python وقم باستدعاء المكتبات المطلوبة pyautogui, serial python و time.
import serial #Serial imported for Serial communication import time #Required to use delay functions import pyautogui
حدد المنفذ COM المستخدم في الاتصال مع الاردوينو.
(هذا سطر قابل للتغيير بناء على نوع المنفذ الذي ستستخدمه في المشروع يمكنك تعيينه عن طريق برنامج اردوينو IDE من قائمة Port).
ArduinoSerial = serial.Serial('com18',9600) #Create Serial port object called arduinoSerialData time.sleep(2) #wait for 2 seconds for the communication to get established
في هذا السطر تتم قراءة المسافة بين اليدين والحساس من المنفذ التسلسلي.
وعلى أساس تلك المسافة يتم تنفيذ الاجراءات وربطها مع اختصارات لوحة المفاتيح.
الاختصارات المستخدمة في هذا الدرس من مشغل VLC:
Space :ايقاف/تشغيل الملف
Ctrl + السهم يمين أو يسار: التقديم أو الترجيع دقيقة
Ctrl + السهم للأعلى والأسفل: رفع وخفض مستوي الصوت
while 1: incoming = str (ArduinoSerial.readline()) #read the serial data and print it as line print incoming if 'Play/Pause' in incoming: pyautogui.typewrite(['space'], 0.2) if 'Rewind' in incoming: pyautogui.hotkey('ctrl', 'left') if 'Forward' in incoming: pyautogui.hotkey('ctrl', 'right') if 'Vup' in incoming: pyautogui.hotkey('ctrl', 'down') if 'Vdown' in incoming: pyautogui.hotkey('ctrl', 'up')
ستلاحظ كقدرتك على التحكم بالحاسوب بحركات اليد بدلًا من الفأرة باستخدام الاردوينو يمكنك اختبار صحة الخطوات والاجراءات من خلال الصفحة المنبثقة بعد النقر على Run modul ستظهر صفحة IDLE Shell.
لا تنسى إيقاف مصدر الطاقة بعد الانتهاء من استخدام النظام.