制作一个基于Arduino的空中鼠标

通信网络

630人已加入

描述

  有没有想过我们的世界是如何走向沉浸式现实的。我们不断寻找新的方式和方法来使用虚拟现实、混合现实、增强现实等与周围环境进行交互。每天都有新设备出现,这些快节奏的技术给我们留下了深刻的印象。

  这些沉浸式技术用于游戏、互动活动、娱乐和许多其他应用。在本教程中,我们将了解这种交互方法,它为您提供了一种与系统交互的新方法,而不是使用无聊的鼠标。我们的游戏爱好者一定知道,几年前任天堂的一家游戏公司推出了一种 3D 交互方法的想法,该方法在称为 Wii 控制器的手持控制器的帮助下与他们的控制台进行交互。它使用加速度计来定位您的游戏手势并将其无线发送到系统。

空中鼠标

  受这个想法的启发,我们将制作一个“空中鼠标”,只需通过在空中移动控制台就可以与系统交互,但我们不会使用 3 维坐标参考,我们只会使用 2 维坐标参考,所以我们可以模仿计算机鼠标的动作,因为鼠标在 X 和 Y 两个维度上工作。

  这款无线 3D Air Mouse背后的概念非常简单,我们将使用加速度计来获取“Air mouse”沿 x 和 y 轴的动作和运动的加速度值,然后根据加速度计我们将控制鼠标光标并在计算机上运行的 python 软件驱动程序的帮助下执行某些操作。

  先决条件

  Arduino Nano(任何型号)

  加速度计 ADXL335 模块

  蓝牙 HC-05 模块

  按按钮

  Python 安装的计算机

  电路原理图

空中鼠标

空中鼠标

  要通过手部的动作控制计算机,您需要一个加速度计,它可以沿 X 轴和 Y 轴发出加速度,并使整个系统无线化,蓝牙模块用于将信号无线传输到您的系统。

  这里使用了 ADXL335 加速度计,它是一个基于 MEMS 的三轴模块,输出沿 X、Y 和 Z 轴的加速度,但如前所述,用于控制鼠标,我们只需要沿 X 和 Y 轴的加速度。

  这里加速度计的 Xout 和 Yout 引脚连接到 Arduino 的 Analog、A0 和 A1 引脚,用于将信号从 Arduino 传输到系统此处使用蓝牙模块 HC-05,因为蓝牙通过 Tx 和 Rx 工作引脚连接,因此我们使用软件串行引脚 D2 和 D3。它是使用软件串行连接的,因为如果我们将蓝牙与硬件串行连接并开始通过 python 控制台获取读数,它将显示不匹配波特率的错误,因为蓝牙将以自己的波特率与 python 通信。通过使用包括 Arduino 在内的不同微控制器完成各种基于蓝牙的项目,了解有关使用蓝牙模块的更多信息。

  这里我们使用了三个按钮 - 一个用于触发 Air 鼠标,另外两个用于左右单击,如下图所示:

空中鼠标

  空中鼠标的流程

  流程图显示了基于 Arduino 的 Air Mouse 的处理流程:

空中鼠标

  1.系统不断检查机械扳机是否被按下,直到没有按下,我们可以用电脑鼠标正常工作。

  2.当系统检测到按键按下时,鼠标的控制权转移到空中鼠标。

  3. 按下触发按钮时,系统开始将鼠标的读数传输到计算机。系统读数包括加速度计读数,以及左键和右键的读数。

  4.系统读数由1字节或8位的数据流组成,其中前三位为X坐标,后三位为Y坐标,倒数第二位为获取状态位鼠标左键的状态,最后一位是获取右键状态的状态位。

  5.前三位的取值,即X坐标的范围为100《=Xcord《=999,而Y坐标的取值范围为100《=Ycord《=800。右键单击和左键单击的值是二进制值 0 或 1,其中 1 表示单击,0 表示用户未单击。

  6. 为了不让按钮的弹跳影响光标的位置,每次点击鼠标的触发按钮后都会保持 4 秒的已知延迟。

  7. 空中鼠标的左右点击,我们必须先按下左键或右键,然后按下触发键移动到我们想要的空中鼠标位置。

  为空中鼠标编程 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; 
整数 xh, yh; 
int xcord,ycord;
常量 int 触发器 = 5; 
诠释 lstate = 0; 
int rstate = 0; 
常量 int lclick = 6; 
常量 int rclick = 7; 
常量 int led = 8;

 

无效设置()

在setup函数中,我们将设置变量来告诉程序它们将作为输入还是输出。触发按钮将被设置为输入上拉,左右点击被声明为输入并设置为高以使其充当输入上拉。

还将串行和蓝牙通信的波特率设置为 9600。

 

  无效设置()
{ 
  pinMode(x,INPUT);
  pinMode(y,输入);
  pinMode(触发器,INPUT_PULLUP)
  pinMode(lclick,INPUT);
  pinMode(rclick,输入);
  pinMode(LED,输出);
  数字写入(lclick,HIGH);
  digitalWrite(rclick,HIGH); 
  序列号.开始(9600);
  蓝牙.开始(9600);
}

 

无效循环()

因为我们需要触发按钮来告诉我们何时需要向系统发送数据流,所以我们在while循环中设置了整个代码,它将持续监控上拉触发器的数字状态,当它变低时它会将其进一步传递以进行处理。

由于我们已经连接了一个 LED 来让我们知道按下触发按钮时系统的状态,我们最初将 LED 在while循环之外设置为低电平,因为它是默认条件,而在while循环内部设置为高电平,这将点亮 LED每当按下触发按钮时。

为了读取左右单击按钮的状态,我们全局声明了两个变量lclick和rclick ,它们的值最初设置为 0。

并在循环中,根据左右按钮的数字状态设置这些变量的值,以检查按钮是否被按下。

我们将使用模拟读取函数读取加速度计的 X 和 Y 输出引脚的值,并将这些值映射到屏幕大小,以使鼠标指针在整个屏幕上移动。由于屏幕大小是屏幕中的像素,我们需要相应地设置它,并且由于我们需要输出值是三位数,我们特意将 X 的范围设置为 100<=X<=999 和类似的Y 的值为 100<=Y<=800。请记住,像素是从左上角读取的,即左上角的值是 (0,0),但是由于我们已经为 x 和 y 声明了三位数字,我们的值将从点 (100,100) 读取。

此外,在Serial.print和bluetooth.print函数的帮助下,在串行和蓝牙上打印坐标值和点击状态,它们有助于通过蓝牙在串行监视器和系统上获取值。

最后,由于按钮的弹跳,可能会重复单个值,这会导致鼠标光标停留在单个位置上,因此为了摆脱这种情况,我们必须添加此延迟。

 

无效循环()
{
数字写入(领导,低);
  而(digitalRead(触发器)==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); 
    串行打印(xcord);
    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 驱动程序脚本

到目前为止,我们已经完成了硬件及其固件部分,现在要让空中鼠标工作,我们需要一个驱动程序脚本,可以将空中鼠标的信号解码为光标移动,所以为此,我们选择了Python。Python是一种脚本语言,这里的脚本是指它可以帮助我们控制其他程序,因为这里我们控制的是鼠标光标。

因此,打开您的 python shell 并使用以下命令安装以下库:

 

pip install 串行
pip install pyautogui

 

serial是 python的库,它可以帮助我们从串行接口(例如 com 端口)获取数据,还可以让我们对其进行操作,而pyautogui是 python 的库,用于控制 GUI 功能,在本例中为鼠标。

现在我们来看看驱动的代码,首先我们需要导入serial和pyautogui库,然后从serial库中,我们必须设置通信的com端口,波特率为9600,与Bluetooth.serial相同。为此,您必须将蓝牙模块连接到系统,然后在系统设置中检查它连接到哪个 com 端口。

接下来的事情是读取从蓝牙到系统的串行通信,并在 while 1 的帮助下保持其连续运行,使其余代码保持连续循环。

如前所述,Arduino 发送 8 位,前 6 位用于坐标,后 2 位用于单击按钮的状态。因此,在ser.read的帮助下读取所有位并将其长度设置为 8 位。

接下来,通过切片将光标坐标和点击的位分割,然后进一步将光标位分别切割为 X 和 Y 坐标。左键和右键也一样。

现在从通信中,我们得到一个字节字符串,我们需要将其转换为整数,以便它们适合坐标,我们通过解码它们然后将它们类型转换为整数来做到这一点。

现在要移动光标,我们使用 pyautogui moveto函数,该函数将这些整数坐标作为参数并将光标移动到该位置。

接下来检查点击,我们使用最后两位和 pyautogui 的 click 函数来做到这一点,它的默认点击是左一个,但是我们可以通过将按钮值声明为右来将其设置为右,我们也可以定义点击次数通过将 clicks 参数设置为 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 稳压电源。然后通过设置蓝牙连接到的 com 端口来运行 python 驱动程序脚本。当脚本运行时,您会看到蓝牙闪烁的时间滞后,这意味着它已连接到您的系统。然后操作它点击触发按钮,你会看到坐标的位置会改变,如果你想要左击或右击,然后先按下左或右按钮和触发按钮,你会看到点击的动作光标位置的改变。

空中鼠标

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;

整数 xh, yh;

int xcord,ycord;

常量 int 触发器 = 5;

诠释 lstate = 0;

int rstate = 0;

常量 int lclick = 6;

常量 int rclick = 7;

常量 int led = 8;


无效设置()

{

pinMode(x,INPUT);

pinMode(y,输入);

pinMode(触发器,INPUT_PULLUP);

pinMode(lclick,输入);

pinMode(rclick,输入);

pinMode(LED,输出);

数字写入(lclick,HIGH);

digitalWrite(rclick,HIGH);

序列号.开始(9600);

蓝牙.开始(9600);

}


无效循环()

{

数字写入(领导,低);

而(digitalRead(触发器)==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);

串行打印(xcord);

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)
 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分