最近手勢(shì)控制的筆記本電腦或計(jì)算機(jī)變得非常有名。這種技術(shù)稱(chēng)為L(zhǎng)eap運(yùn)動(dòng),它使我們能夠通過(guò)簡(jiǎn)單地在計(jì)算機(jī)/筆記本電腦前揮手來(lái)控制計(jì)算機(jī)/筆記本電腦上的某些功能。這樣做非常酷和有趣,但這些筆記本電腦的價(jià)格確實(shí)很高。因此,在這個(gè)項(xiàng)目中,讓我們嘗試通過(guò)結(jié)合Arduino和Python的強(qiáng)大功能來(lái)構(gòu)建我們自己的手勢(shì)控制筆記本電腦/計(jì)算機(jī)。
我們將使用兩個(gè)超聲波傳感器來(lái)確定我們手的位置并根據(jù)位置控制媒體播放器 (VLC)。我已經(jīng)使用它進(jìn)行演示,但是一旦您了解了該項(xiàng)目,您只需更改幾行代碼并以您喜歡的方式控制您最喜歡的應(yīng)用程序,您就可以做任何事情。
項(xiàng)目背后的概念:
該項(xiàng)目背后的概念非常簡(jiǎn)單。我們將在顯示器頂部放置兩個(gè)超聲波(US)傳感器,并使用Arduino讀取顯示器和手之間的距離,根據(jù)此距離值,我們將執(zhí)行某些操作。為了在我們的計(jì)算機(jī)上執(zhí)行操作,我們使用Pythonpyautogui庫(kù)。來(lái)自Arduino的命令通過(guò)串行端口(USB)發(fā)送到計(jì)算機(jī)。然后,該數(shù)據(jù)將由計(jì)算機(jī)上運(yùn)行的python讀取,并根據(jù)讀取的數(shù)據(jù)執(zhí)行操作。
電路圖:
要使用手勢(shì)控制PC,只需將兩個(gè)超聲波傳感器與Arduino連接即可。我們知道美國(guó)傳感器使用 5V 工作,因此它們由 Arduino 的板載穩(wěn)壓器供電。Arduino可以連接到PC /筆記本電腦,為模塊供電,也可以進(jìn)行串行通信。連接完成后,將它們放在顯示器上,如下所示。我用雙面膠帶把它貼在我的顯示器上,但你可以發(fā)揮自己的創(chuàng)造力。將其固定在一個(gè)地方后,我們可以繼續(xù)進(jìn)行編程。
對(duì) Arduino 進(jìn)行編程:
Arduino應(yīng)該被編程為讀取手與美國(guó)傳感器的距離。本頁(yè)末尾給出了完整的程序;就在下面,我已經(jīng)給出了該程序的解釋。如果您不熟悉超聲波傳感器,只需通過(guò)Arduino和超聲波傳感器基于距離測(cè)量。
通過(guò)讀取距離的值,我們可以到達(dá)某些要用手勢(shì)控制的動(dòng)作,例如,在這個(gè)程序中,我已經(jīng)編程了5 個(gè)動(dòng)作作為演示。
操作 1:當(dāng)兩只手都放在傳感器前的特定遠(yuǎn)距離時(shí),VLC播放器中的視頻應(yīng)播放/暫停。
行動(dòng)2:當(dāng)右手放在傳感器前的特定遠(yuǎn)距離時(shí),視頻應(yīng)快進(jìn)一步。
行動(dòng)3:當(dāng)左手放在傳感器前的特定遠(yuǎn)距離時(shí),視頻應(yīng)倒帶一步。
行動(dòng)4:當(dāng)右手放在傳感器前的特定近距離,然后如果向傳感器移動(dòng),視頻應(yīng)快進(jìn),如果移開(kāi),視頻應(yīng)倒帶。
行動(dòng)5:當(dāng)左手以特定的近距離放在傳感器之前,然后如果朝向傳感器移動(dòng),視頻的音量應(yīng)該增加,如果移開(kāi),音量應(yīng)該減小。
讓我們看看如何編寫(xiě)程序來(lái)執(zhí)行上述操作。因此,像所有程序一樣,我們從定義I / O引腳開(kāi)始,如下所示。兩個(gè)美國(guó)傳感器連接到數(shù)字引腳2、3、4和5,由+5V引腳供電。觸發(fā)引腳是輸出引腳,回顯引腳是輸入引腳。
Arduino和python之間的串行通信以9600的波特率進(jìn)行。
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);
}
在結(jié)束任何動(dòng)作之前,我們需要每次計(jì)算傳感器和手之間的距離。所以我們必須做很多次,這意味著這段代碼應(yīng)該作為一個(gè)函數(shù)使用。我們編寫(xiě)了一個(gè)名為 calculate_distance() 的函數(shù),它將返回傳感器和手之間的距離。
/*###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;
}
在我們的主循環(huán)中,我們檢查距離的值并執(zhí)行上述操作。在此之前,我們使用兩個(gè)變量 distL 和 distR,它們使用當(dāng)前距離值進(jìn)行更新。
calculate_distance(trigger1,echo1);
distL =dist; //get distance of left sensor
calculate_distance(trigger2,echo2);
distR =dist; //get distance of right sensor
由于我們知道兩個(gè)傳感器之間的距離,因此我們現(xiàn)在可以將其與預(yù)定義的值進(jìn)行比較并得出某些操作。例如,如果兩只手都放在 40 mc 的距離,那么我們播放/暫停視頻。這里“播放/暫停”一詞將通過(guò)串口發(fā)送出去
if ((distL >40 && distR>40) && (distL <50 && distR<50)) //Detect both hands
{Serial.println("Play/Pause"); delay (500);}
如果將右手單獨(dú)放在模塊之前,那么我們將視頻快進(jìn)一步,如果是左手,我們將倒帶一步。根據(jù)動(dòng)作,這里“倒帶”或“轉(zhuǎn)發(fā)”一詞將通過(guò)串口發(fā)送出去
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);}
敵人對(duì)音量和軌道的詳細(xì)控制我們使用不同的方法來(lái)防止錯(cuò)誤觸發(fā)。為了控制音量,我們必須將左手放在大約。在距離 15 厘米 ,然后您可以將其移向傳感器以減少體積,將其移離傳感器以增加體積。相同的代碼如下所示。根據(jù)動(dòng)作,這里“Vup”或“Vdown”一詞將通過(guò)串口發(fā)送出去
//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);}
}
}
}
我們也可以對(duì)右側(cè)傳感器使用相同的方法來(lái)控制視頻的軌跡。也就是說(shuō),如果我們將右手移向傳感器,它將快進(jìn)電影,如果您將其移離傳感器,它將倒帶電影。根據(jù)動(dòng)作,這里“倒帶”或“轉(zhuǎn)發(fā)”一詞將通過(guò)串口發(fā)送出去
您現(xiàn)在可以閱讀頁(yè)面末尾給出的此手勢(shì)控制PC的完整代碼,并嘗試將其作為一個(gè)整體進(jìn)行輕描淡寫(xiě),然后將其復(fù)制到Arduino IDE。
對(duì)你的 Python 進(jìn)行編程:
這個(gè)項(xiàng)目的python程序非常簡(jiǎn)單。我們只需要通過(guò)正確的波特率與Arduino建立串行通信,然后執(zhí)行一些基本的鍵盤(pán)操作。python的第一步是安裝pyautogui模塊。確保遵循此步驟,因?yàn)槿绻麤](méi)有pyautogui模塊,該程序?qū)o(wú)法運(yùn)行。
為 Windows 安裝 pyautogui 模塊:
請(qǐng)按照以下步驟安裝 pyautogui for Windows。如果您使用的是其他平臺(tái),則步驟也或多或少相似。確保您的計(jì)算機(jī)/筆記本電腦已連接到互聯(lián)網(wǎng),然后繼續(xù)執(zhí)行以下步驟
第 1 步:打開(kāi)Windows命令提示符,并將目錄更改為已安裝python的文件夾。默認(rèn)情況下,該命令應(yīng)為
cd C:Python27
第 2 步:在你的 python 目錄中使用命令 python –m pip install –upgrade pip 來(lái)升級(jí)你的 pip。Pip 是 python 中的一個(gè)工具,可以幫助我們輕松安裝 python 模塊。升級(jí)此模塊后(如下圖所示),繼續(xù)下一步。
python –m pip install –upgrade pip
第 3 步:使用命令“python –m pip install pyautogui”來(lái)安裝 pyautogui 模塊。該過(guò)程成功后,您應(yīng)該會(huì)看到類(lèi)似于下面的屏幕。
python –m pip install –upgrade pip
現(xiàn)在 pyautogui 模塊和 pyserial 模塊(安裝在前面的教程中)已成功與 python 一起安裝,我們可以繼續(xù)使用 python 程序了。完整的 python 代碼在本教程末尾給出,但解釋如下。
讓我們導(dǎo)入此項(xiàng)目所需的所有三個(gè)模塊。它們是pyautogui,serial python和time。
import serial #Serial imported for Serial communication
import time #Required to use delay functions
import pyautogui
接下來(lái),我們通過(guò)COM端口與Arduino建立連接。在我的電腦中,Arduino連接到COM 18。使用設(shè)備管理器查找Arduino連接到的COM端口,并相應(yīng)地更正以下行。
ArduinoSerial = serial.Serial('com18',9600) #Create Serial port object called arduinoSerialData
time.sleep(2) #wait for 2 seconds for the communication to get established
在無(wú)限的while循環(huán)中,我們反復(fù)收聽(tīng)COM端口,并將關(guān)鍵字與任何預(yù)先確定的作品進(jìn)行比較,并相應(yīng)地按下鍵盤(pán)。
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')
如您所見(jiàn),要按下一個(gè)鍵,我們只需要使用命令“pyautogui.typewrite(['space'], 0.2)”,它將按下鍵空格 0.2 秒。如果您需要像ctrl + S這樣的熱鍵,那么您可以使用熱鍵命令“pyautogui.hotkey('ctrl', 's')”。
我使用這些組合是因?yàn)樗鼈冞m用于 VLC 媒體播放器,您可以按照您喜歡的任何方式調(diào)整它們,以創(chuàng)建自己的應(yīng)用程序以通過(guò)手勢(shì)控制計(jì)算機(jī)中的任何內(nèi)容。
動(dòng)作中的手勢(shì)控制計(jì)算機(jī):
按照上面定義建立連接,并將Arduino代碼上傳到Arduino板上。然后使用下面的python腳本并在筆記本電腦/計(jì)算機(jī)上啟動(dòng)該程序。
現(xiàn)在,您可以使用VLC媒體播放器在計(jì)算機(jī)上播放任何電影,并用手控制電影,如下面的視頻所示。
Arduino Code:
/*
* Program for gesture control VLC Player
* Controlled uisng Python
* Code by B.Aswinth Raj
* Dated: 11-10-2017
*/
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 = "";
-
計(jì)算機(jī)
+關(guān)注
關(guān)注
19文章
7423瀏覽量
87719 -
超聲波傳感器
+關(guān)注
關(guān)注
18文章
577瀏覽量
35900 -
python
+關(guān)注
關(guān)注
56文章
4782瀏覽量
84456 -
Arduino
+關(guān)注
關(guān)注
187文章
6464瀏覽量
186657 -
手勢(shì)控制
+關(guān)注
關(guān)注
4文章
44瀏覽量
21687
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論