有沒有想過我們的世界是如何走向沉浸式現(xiàn)實的。我們不斷尋找新的方式和方法來使用虛擬現(xiàn)實、混合現(xiàn)實、增強現(xiàn)實等與周圍環(huán)境進行交互。每天都有新設備出現(xiàn),這些快節(jié)奏的技術給我們留下了深刻的印象。
這些沉浸式技術用于游戲、互動活動、娛樂和許多其他應用。在本教程中,我們將了解這種交互方法,它為您提供了一種與系統(tǒng)交互的新方法,而不是使用無聊的鼠標。我們的游戲愛好者一定知道,幾年前任天堂的一家游戲公司推出了一種 3D 交互方法的想法,該方法在稱為 Wii 控制器的手持控制器的幫助下與他們的控制臺進行交互。它使用加速度計來定位您的游戲手勢并將其無線發(fā)送到系統(tǒng)。
受這個想法的啟發(fā),我們將制作一個“空中鼠標”,只需通過在空中移動控制臺就可以與系統(tǒng)交互,但我們不會使用 3 維坐標參考,我們只會使用 2 維坐標參考,所以我們可以模仿計算機鼠標的動作,因為鼠標在 X 和 Y 兩個維度上工作。
這款無線 3D Air Mouse背后的概念非常簡單,我們將使用加速度計來獲取“Air mouse”沿 x 和 y 軸的動作和運動的加速度值,然后根據加速度計我們將控制鼠標光標并在計算機上運行的 python 軟件驅動程序的幫助下執(zhí)行某些操作。
先決條件
Arduino Nano(任何型號)
加速度計 ADXL335 模塊
藍牙 HC-05 模塊
按按鈕
Python 安裝的計算機
電路原理圖
要通過手部的動作控制計算機,您需要一個加速度計,它可以沿 X 軸和 Y 軸發(fā)出加速度,并使整個系統(tǒng)無線化,藍牙模塊用于將信號無線傳輸?shù)侥南到y(tǒng)。
這里使用了 ADXL335 加速度計,它是一個基于 MEMS 的三軸模塊,輸出沿 X、Y 和 Z 軸的加速度,但如前所述,用于控制鼠標,我們只需要沿 X 和 Y 軸的加速度。
這里加速度計的 Xout 和 Yout 引腳連接到 Arduino 的 Analog、A0 和 A1 引腳,用于將信號從 Arduino 傳輸?shù)较到y(tǒng)此處使用藍牙模塊 HC-05,因為藍牙通過 Tx 和 Rx 工作引腳連接,因此我們使用軟件串行引腳 D2 和 D3。它是使用軟件串行連接的,因為如果我們將藍牙與硬件串行連接并開始通過 python 控制臺獲取讀數(shù),它將顯示不匹配波特率的錯誤,因為藍牙將以自己的波特率與 python 通信。通過使用包括 Arduino 在內的不同微控制器完成各種基于藍牙的項目,了解有關使用藍牙模塊的更多信息。
這里我們使用了三個按鈕 - 一個用于觸發(fā) Air 鼠標,另外兩個用于左右單擊,如下圖所示:
空中鼠標的流程
流程圖顯示了基于 Arduino 的 Air Mouse 的處理流程:
1.系統(tǒng)不斷檢查機械扳機是否被按下,直到沒有按下,我們可以用電腦鼠標正常工作。
2.當系統(tǒng)檢測到按鍵按下時,鼠標的控制權轉移到空中鼠標。
3. 按下觸發(fā)按鈕時,系統(tǒng)開始將鼠標的讀數(shù)傳輸?shù)接嬎銠C。系統(tǒng)讀數(shù)包括加速度計讀數(shù),以及左鍵和右鍵的讀數(shù)。
4.系統(tǒng)讀數(shù)由1字節(jié)或8位的數(shù)據流組成,其中前三位為X坐標,后三位為Y坐標,倒數(shù)第二位為獲取狀態(tài)位鼠標左鍵的狀態(tài),最后一位是獲取右鍵狀態(tài)的狀態(tài)位。
5.前三位的取值,即X坐標的范圍為100《=Xcord《=999,而Y坐標的取值范圍為100《=Ycord《=800。右鍵單擊和左鍵單擊的值是二進制值 0 或 1,其中 1 表示單擊,0 表示用戶未單擊。
6. 為了不讓按鈕的彈跳影響光標的位置,每次點擊鼠標的觸發(fā)按鈕后都會保持 4 秒的已知延遲。
7. 空中鼠標的左右點擊,我們必須先按下左鍵或右鍵,然后按下觸發(fā)鍵移動到我們想要的空中鼠標位置。
為空中鼠標編程 Arduino
應將 Arduino 編程為讀取 X 軸和 Y 軸的加速度值。最后給出了完整的程序,下面是代碼中的重要片段。
設置全局變量
如前所述,我們將使用軟件串行引腳連接藍牙模塊。因此,要設置軟件串行,我們需要聲明軟件串行庫并設置 Tx 和 Rx 的引腳。在 Arduino Nano 和 Uno 中,引腳 2 和 3 可以作為軟件串行工作。接下來,我們從軟件串行庫中聲明藍牙對象,以設置 Tx 和 Rx 的引腳。
?
#include const int rxpin = 2, txpin = 3; 軟件串行藍牙(rxpin,txpin); 常量 int x=A0; 常量 int y=A1; 整數(shù) xh, yh; int xcord,ycord; 常量 int 觸發(fā)器 = 5; 詮釋 lstate = 0; int rstate = 0; 常量 int lclick = 6; 常量 int rclick = 7; 常量 int led = 8;
?
無效設置()
在setup函數(shù)中,我們將設置變量來告訴程序它們將作為輸入還是輸出。觸發(fā)按鈕將被設置為輸入上拉,左右點擊被聲明為輸入并設置為高以使其充當輸入上拉。
還將串行和藍牙通信的波特率設置為 9600。
?
無效設置() { pinMode(x,INPUT); pinMode(y,輸入); pinMode(觸發(fā)器,INPUT_PULLUP) pinMode(lclick,INPUT); pinMode(rclick,輸入); pinMode(LED,輸出); 數(shù)字寫入(lclick,HIGH); digitalWrite(rclick,HIGH); 序列號.開始(9600); 藍牙.開始(9600); }
?
無效循環(huán)()
因為我們需要觸發(fā)按鈕來告訴我們何時需要向系統(tǒng)發(fā)送數(shù)據流,所以我們在while循環(huán)中設置了整個代碼,它將持續(xù)監(jiān)控上拉觸發(fā)器的數(shù)字狀態(tài),當它變低時它會將其進一步傳遞以進行處理。
由于我們已經連接了一個 LED 來讓我們知道按下觸發(fā)按鈕時系統(tǒng)的狀態(tài),我們最初將 LED 在while循環(huán)之外設置為低電平,因為它是默認條件,而在while循環(huán)內部設置為高電平,這將點亮 LED每當按下觸發(fā)按鈕時。
為了讀取左右單擊按鈕的狀態(tài),我們全局聲明了兩個變量lclick和rclick?,它們的值最初設置為 0。
并在循環(huán)中,根據左右按鈕的數(shù)字狀態(tài)設置這些變量的值,以檢查按鈕是否被按下。
我們將使用模擬讀取函數(shù)讀取加速度計的 X 和 Y 輸出引腳的值,并將這些值映射到屏幕大小,以使鼠標指針在整個屏幕上移動。由于屏幕大小是屏幕中的像素,我們需要相應地設置它,并且由于我們需要輸出值是三位數(shù),我們特意將 X 的范圍設置為 100<=X<=999 和類似的Y 的值為 100<=Y<=800。請記住,像素是從左上角讀取的,即左上角的值是 (0,0),但是由于我們已經為 x 和 y 聲明了三位數(shù)字,我們的值將從點 (100,100) 讀取。
此外,在Serial.print和bluetooth.print函數(shù)的幫助下,在串行和藍牙上打印坐標值和點擊狀態(tài),它們有助于通過藍牙在串行監(jiān)視器和系統(tǒng)上獲取值。
最后,由于按鈕的彈跳,可能會重復單個值,這會導致鼠標光標停留在單個位置上,因此為了擺脫這種情況,我們必須添加此延遲。
?
無效循環(huán)() { 數(shù)字寫入(領導,低); 而(digitalRead(觸發(fā)器)==LOW) { digitalWrite(LED,HIGH); lstate = digitalRead(lclick); rstate = digitalRead(rclick); xh=模擬讀?。▁); yh=analogRead(y); xcord=map(xh,286,429,100,999); ycord=map(yh,282,427,100,800); 串行打?。▁cord); Serial.print(ycord); if (lstate == LOW) Serial.print(1); 否則 Serial.print(0); if (rstate == LOW) Serial.print(1); 否則 Serial.print(0); 藍牙.print(xcord); 藍牙.print(ycord); if (lstate == LOW) bluetooth.print(1); 否則 bluetooth.print(0); if (rstate == LOW) bluetooth.print(1); 否則 bluetooth.print(0); 延遲(4000); } }
?
計算機的Python 驅動程序腳本
到目前為止,我們已經完成了硬件及其固件部分,現(xiàn)在要讓空中鼠標工作,我們需要一個驅動程序腳本,可以將空中鼠標的信號解碼為光標移動,所以為此,我們選擇了Python。Python是一種腳本語言,這里的腳本是指它可以幫助我們控制其他程序,因為這里我們控制的是鼠標光標。
因此,打開您的 python shell 并使用以下命令安裝以下庫:
?
pip install 串行 pip install pyautogui
?
serial是 python的庫,它可以幫助我們從串行接口(例如 com 端口)獲取數(shù)據,還可以讓我們對其進行操作,而pyautogui是 python 的庫,用于控制 GUI 功能,在本例中為鼠標。
現(xiàn)在我們來看看驅動的代碼,首先我們需要導入serial和pyautogui庫,然后從serial庫中,我們必須設置通信的com端口,波特率為9600,與Bluetooth.serial相同。為此,您必須將藍牙模塊連接到系統(tǒng),然后在系統(tǒng)設置中檢查它連接到哪個 com 端口。
接下來的事情是讀取從藍牙到系統(tǒng)的串行通信,并在 while 1 的幫助下保持其連續(xù)運行,使其余代碼保持連續(xù)循環(huán)。
如前所述,Arduino 發(fā)送 8 位,前 6 位用于坐標,后 2 位用于單擊按鈕的狀態(tài)。因此,在ser.read的幫助下讀取所有位并將其長度設置為 8 位。
接下來,通過切片將光標坐標和點擊的位分割,然后進一步將光標位分別切割為 X 和 Y 坐標。左鍵和右鍵也一樣。
現(xiàn)在從通信中,我們得到一個字節(jié)字符串,我們需要將其轉換為整數(shù),以便它們適合坐標,我們通過解碼它們然后將它們類型轉換為整數(shù)來做到這一點。
現(xiàn)在要移動光標,我們使用 pyautogui?moveto函數(shù),該函數(shù)將這些整數(shù)坐標作為參數(shù)并將光標移動到該位置。
接下來檢查點擊,我們使用最后兩位和 pyautogui 的 click 函數(shù)來做到這一點,它的默認點擊是左一個,但是我們可以通過將按鈕值聲明為右來將其設置為右,我們也可以定義點擊次數(shù)通過將 clicks 參數(shù)設置為 2 將其設置為雙擊。
以下是要在計算機上運行的完整 Python 代碼:
?
導入串口 import pyautogui ser=serial.Serial('com3',9600) while 1: k=ser.read(8) cursor=k[:6] click=k[6:] x=cursor[:3] y= cursor[3:] l=click[0] r=click[1] xcor=int(x.decode('utf-8')) ycor=int(y.decode('utf-8')) pyautogui.moveTo (xcor,ycor) 如果 l==49: pyautogui.click(clicks=2) elif r==49: pyautogui.click(button='right', clicks=2)
?
測試 Arduino 空中鼠標
因此,要操作 Air Mouse,請為其連接電源。它可以來自 Arduino Nano USB 插槽或來自使用 7805 IC 的 5v 穩(wěn)壓電源。然后通過設置藍牙連接到的 com 端口來運行 python 驅動程序腳本。當腳本運行時,您會看到藍牙閃爍的時間滯后,這意味著它已連接到您的系統(tǒng)。然后操作它點擊觸發(fā)按鈕,你會看到坐標的位置會改變,如果你想要左擊或右擊,然后先按下左或右按鈕和觸發(fā)按鈕,你會看到點擊的動作光標位置的改變。
Python腳本:
導入串口
import pyautogui
ser=serial.Serial('com3',9600)
while 1:
k=ser.read(8)
cursor=k[:6]
click=k[6:]
x=cursor[:3]
y= cursor[3:]
l=click[0]
r=click[1]
xcor=int(x.decode('utf-8'))
ycor=int(y.decode('utf-8'))
pyautogui.moveTo (xcor,ycor)
如果 l==49:
pyautogui.click(clicks=2)
elif r==49:
pyautogui.click(button='right', clicks=2)
Arduino代碼:
#include
const int rxpin = 2, txpin = 3;
軟件串行藍牙(rxpin,txpin);
常量 int x=A0;
常量 int y=A1;
整數(shù) xh, yh;
int xcord,ycord;
常量 int 觸發(fā)器 = 5;
詮釋 lstate = 0;
int rstate = 0;
常量 int lclick = 6;
常量 int rclick = 7;
常量 int led = 8;
無效設置()
{
pinMode(x,INPUT);
pinMode(y,輸入);
pinMode(觸發(fā)器,INPUT_PULLUP);
pinMode(lclick,輸入);
pinMode(rclick,輸入);
pinMode(LED,輸出);
數(shù)字寫入(lclick,HIGH);
digitalWrite(rclick,HIGH);
序列號.開始(9600);
藍牙.開始(9600);
}
無效循環(huán)()
{
數(shù)字寫入(領導,低);
而(digitalRead(觸發(fā)器)==LOW)
{
digitalWrite(LED,HIGH);
lstate = digitalRead(lclick);
rstate = digitalRead(rclick);
xh=模擬讀取(x);
yh=analogRead(y);
xcord=map(xh,286,429,100,999);
ycord=map(yh,282,427,100,800);
串行打?。▁cord);
Serial.print(ycord);
if (lstate == LOW)
Serial.print(1);
否則
Serial.print(0);
if (rstate == LOW)
Serial.print(1);
否則
Serial.print(0);
藍牙.print(xcord);
藍牙.print(ycord);
if (lstate == LOW)
bluetooth.print(1);
否則
bluetooth.print(0);
if (rstate == LOW)
bluetooth.print(1);
否則
bluetooth.print(0);
延遲(4000);
}
}
Python驅動腳本
導入串口
import pyautogui
ser=serial.Serial('com3',9600)
while 1:
k=ser.read(8)
cursor=k[:6]
click=k[6:]
x=cursor[:3]
y= cursor[3:]
l=click[0]
r=click[1]
xcor=int(x.decode('utf-8'))
ycor=int(y.decode('utf-8'))
pyautogui.moveTo (xcor,ycor)
如果 l==49:
pyautogui.click(clicks=2)
elif r==49:
pyautogui.click(button='right', clicks=2)
?
評論