کامپیوتر خود را با استفاده از آردوینو و با حرکات دست کنترل کنید.
تکنیک Leap motion
اخیرا کامپیوترها و لپتاپهای کنترل شونده با اشارات، محبوبیت زیادی پیدا کردهاند. این تکنیک Leap motion نامیده شده است که ما را قادر میسازد عملکردهای بخصوصی را روی لپ تاپ یا کامپیوترمان به سادگی با تکان دادن دست در جلوی آن کنترل کنیم. این کار بسیار جالب و هیجان انگیز است اما لپ تاپهای مجهز به این سیستم بسیار گران قیمت هستند. بنابراین ما در این پروژه لپ تاپ/کامپیوتر کنترل شونده با اشاره خودمان را با تلفیق قدرت آردوینو و زبان برنامه نویسی پایتون میسازیم.
ما از دو سنسور اولتراسونیک برای تشخیص موقعیت دستها و کنترل یک برنامه مدیاپلیر(VLC) استفاده میکنیم. البته این تنها برای نمایش عملکرد دستگاه است و هنگامی که پروژه را به طور کامل فرا گرفتید میتوانید هر برنامهای را تنها با تغییر چند خط کد به شکل دلخواه خود کنترل کنید.
پیش نیازها:
در این پروژه فرض بر این است که شما نرم افزار پایتون و کتابخانه سریال آن را نصب کردهاید و پروژههای سادهای مانند ال ای دی چشمک زن را با استفاده از آن با موفقیت پیاده سازی کردهاید.
ایده کلی پروژه:
ایده کلی پروژه بسیار ساده است. ما دو سنسور اولتراسونیک را بالای صفحه نمایش قرار میدهیم و با آردوینو فاصله بین صفحه نمایش و دستهایمان را اندازه میگیریم و بر اساس این اندازه دستورات خاصی را اجرا میکنیم. برای اجرای دستورات روی کامپیوتر از کتابخانه pyautogui استفاده میکنیم. دستورات از طریق پورت سریال(USB) به کامپیوتر فرستاده میشوند و توسط پایتون خوانده و اجرا میشوند.
اتصالات مدار کنترل کامپیوتر با حرکات دست با آردوینو و ماژول اولتراسونیک:
برای کنترل کامپیوتر با اشارات دست فقط اتصال دو سنسور اولتراسونیک به آردوینو کافیست. از آنجایی که سنسورهای اولتراسونیک با ولتاژ 5 ولت کار میکنند میتوان آنها را از رگولاتور آن بورد(روی برد) آردوینو تغذیه کرد. آردوینو برای تغذیه کردن سنسورها و ارتباط سریال به کامپیوتر/لپ تاپ متصل میشود. بعد از به هم بستن اجزای مدار سنسورها را مانند شکل زیر روی مانیتور خود قرار دهید. میتوانید از چسب دوطرفه برای محکم کردن سنسورها در جای خود استفاده کنید یا اینکه از خلاقیت خود بهره ببرید. بعد از اتمام نصب نوبت به برنامه ریزی میرسد.
پروگرام کردن آردوینو:
آردوینو باید برنامه ریزی شود تا بتواند فاصله بین دست و سنسور را اندازه بگیرد. کد کامل برنامه در انتهای صفحه آورده شده است و توضیحات بخشهای مختلف کد در زیر قابل مشاهده است.
با اندازهگیری فاصله میتوان اعمال مختلفی را با اشاره انجام داد برای مثال در این برنامه 5 عملکرد به عنوان نمونه برنامه ریزی شده است.
عملکرد 1:
با قرار دادن هر دو دست در مقابل سنسور در فاصله “دور” از پیش تعیین شده ویدیو در VLC player پخش یا متوقف میشود.
عملکرد 2 :
با قرار دادن دست راست در مقابل سنسور در فاصله “دور”از پیش تعیین شده ویدیو یک مرحله Fast Forward میشود.
عملکرد 3:
با قراردادن دست چپ در مقابل سنسور در فاصله “دور” از پیش تعیین شده ویدیو یک مرحله Rewind میشود.
عملکرد 4:
با قرار دادن دست راست در مقابل سنسور در فاصله “نزدیک” از پیش تعیین شده و حرکت دست به سمت سنسور ویدیو FastForward می شود و با دور کردن دست ویدیو Rewind میشود.
عملکرد 5:
با قرار دادن دست چپ در مقابل سنسور در فاصله “نزدیک” از پیش تعیین شده و حرکت آن به سمت سنسور شدت صدا زیاد و با دور کردن دست شدت صدا کم میشود.
ارتباط سریال بین آردوینو و پایتون در baud rate 9600 صورت میگیرد.
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 void setup() { Serial.begin(9600); pinMode(trigger1, OUTPUT); pinMode(echo1, INPUT); pinMode(trigger2, OUTPUT); pinMode(echo2, INPUT); }
ما باید هر بار قبل از نتیجهگیری و اجرای یک عملکرد فاصله بین دست و سنسور را اندازهگیری کنیم. بنابراین این کار دفعات متعددی تکرار خواهد شد پس آن را به عنوان یک تابع تعریف میکنیم به نام 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; }
درون حلقه main فاصله را چک میکنیم و بر اساس آن یکی از عملکردهای ذکر شده در بالا را انجام میدهیم.
قبل از آن از دو متغییر به نامهای 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 سانتیمتری قرار داشته باشند ویدیو را پخش یا متوقف میکنیم.
برای این کار کلمه “Play/Pause” از طریق پورت سریال فرستاده میشود.
if ((distL >40 && distR>40) && (distL <50 && distR<50)) //Detect both hands {Serial.println("Play/Pause"); delay (500);}
اگر تنها دست راست در مقابل سنسور باشد آنگاه ویدیو را یک مرحله fast forward میکنیم و اگر تنها دست چپ در مقابل سنسور باشد یک مرحله rewind. براساس عملکرد “Rewind” یا “Forward” از طریق پورت سریال فرستاده میشود.
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);}
برای کنترل دقیق شدت صدا و زمان فیلم از شیوهی متفاوتی استفاده میکنیم تا از تحریک ناخواسته جلوگیری شود. برای کنترل شدت صدا باید دستمان را تقریبا در فاصله 15سانتی متری از سنسور قرار دهیم و بعد از آن با دور یا نزدیک کردن دست میتوان شدت صدا را کم یا زیاد کرد. براساس دستور کلمه “Vup” یا “Vdown” از طریق پورت سریال فرستاده خواهد شد.
//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);} } } }
میتوانیم از همین شیوه در سنسور سمت راست برای جلو و عقب بردن ویدیو نیز استفاده کنیم. که در این حالت اگر دست راستمان ر از سنسور دور کنیم ویدیو rewind و اگر به آن نزدیک کنیم ویدیو fast forward خواهد شد. در این حالت نیز با توجه دستور مورد نظر کلمه “Rewind” یا “Forward” از طریق پورت سریال ارسال خواهد شد.
شما اکنون میتوانید کد کامل کامپیوتر کنترل شونده با اشاره دست را در پایین صفحه مطالعه کنید و آن را در IDE آردوینو کپی کنید.
برنامه نویسی پایتون:
برنامه پایتون این پروژه بسیار ساده است. تنها باید یک ارتباط سریال در baud rate درست با آردوینو برقرار کنیم و سپس چند عمل ساده کیبردی انجام دهیم. اولین مرحله برای پایتون نصب pyautogui است. از پیروی از دستورات زیر اطمینان حاصل کنید زیرا برنامه بدون ماژول pyautogui کار نخواهد کرد.
نصب ماژول pyautogui برای ویندوز:
برای نصب pyautogui مراحل زیر را دنبال کنید. نصب این ماژول در سیستم عاملهای دیگر نیز تقریبا مشابه میباشد. مطمئن شوید که دستگاه شما به اینترنت متصل است و سپس مراحل زیر را دنبال کنید.
مرحله 1 :
Cmd را باز کنید و آدرس را به محلی که در آن پایتون را نصب کرده اید تغییر دهید. در حالت عادی دستور باید به شکل زیر باشد:
cd C:\Python27
مرحله 2 :
در دایرکتوری پایتون از دستور python –m pip install –upgrade استفاده کنید تا pip خود را بروزرسانی کنید. pip ابزاری در پایتون است که به ما در نصب راحت ماژول ها کمک میکند. بعد از بروزرسانی pip به مرحله بعد بروید.
python –m pip install –upgrade pip
مرحله 3 :
با استفاده از دستور “python –m pip install pyautogui” ماژول pyautogui را نصب کنید. اگر نصب موفقیت آمیز باشد پیغامی مانند زیر روی صفحه نمایش داده میشود:
python –m pip install –upgrade pip
اکنون که ماژولهای pyautogui و pyserial روی سیستم نصب هستند میتوانیم به سراغ برنامه پایتون برویم. کد کامل پایتون در انتهای مطلب آورده شده است و در زیر توضیحات قسمت به قسمت کد ارائه شده است.
ابتدا 3 ماژول موردنیاز برای این پروژه را import میکنیم که pyautogui , serial python , time هستند.
import serial #Serial imported for Serial communication import time #Required to use delay functions import pyautogui
سپس ارتباط با آردوینو را از طریق پورت COM برقرار میکنیم. در کامپیوتر من آردوینو به COM 18 متصل است. با استفاده از Device Manager پورت COM متصل به آردوینو خود را پیدا کنید و با توجه به آن خط آخر کد زیر را اصلاح کنید.
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 به طور مکرر ورودی پورت COM را چک میکنیم و کلمات کلیدی را با کلمات از پیش تعیین شده مقایسه میکنیم و بر اساس آن دکمه کیبورد متناظر را درون برنامه فشار میدهیم.
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')
همان طور که مشاهده میکنید برای فشار دادن یک دکمه به طور مجازی و از داخل برنامه از دستور “pyautogui.typewrite([‘space’], 0.2)” استفاده میکنیم که برای مثال دکمه فاصله را به مدت 0.2 ثانیه فشار میدهد. اگر شما به میانبرهایی(hot key) مانند ctrl+S نیاز دارید میتوانید از دستور “pyautogui.hotkey(‘ctrl’, ‘s’)” استفاده کنید.
من از این ترکیبهای دکمهها استفاده کردهام به این دلیل که در VLC کار میکنند. شما میتوانید آنها را به هرچیزی که دوست دارید تغییر دهید و هر چیزی را در کامپیوتر خود کنترل کنید.
کنترل کامپیوتر با حرکات دست در عمل:
با توجه به توضیحات بالا اتصالات مدار را برقرار کنید و کد آردوینو را روی بورد آپلود نمایید. سپس از اسکریپت پایتون زیر استفاده کنید و برنامه را روی لپ تاپ خود باز کنید.
اکنون میتوانید هر ویدیویی را با استفاده از VLC پخش کنید و مانند ویدیوی زیر با استفاده از دست خود آن را کنترل کنید.
امیدوارم که این پروژه را به خوبی متوجه شده باشید و از کار با آن لذت برده باشید. این تنها یک پیش نمایش است و شما میتوانید با استفاده از خلاقیت خود کارهای جالبتری را با استفاده از این پروژه انجام دهید.
سورس کد کنترل کامپیوتر با حرکات دست با آردوینو:
Arduino Code:
/* * Program for gesture control VLC Player * Controlled uisng Python * Code by B.Aswinth Raj * Dated: 11-10-2017 * Website: www.circuitdigest.com * translator site https:melec.ir */ 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; //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); }
سورس کد پایتون:
Python Code:
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 = "";
منابع :