一板网电子技术论坛

风筝
发表于: 2019-6-27 14:59:24 | 显示全部楼层

曾经想知道我们的世界是如何走向沉浸式现实的。我们不断寻找与周围环境互动的新方式和方法,使用虚拟现实、混合现实、增强现实等。每天都有新设备通过这些快速技术推出,以通过他们的新互动技术给我们留下深刻印象。


这些沉浸式技术用于游戏、互动活动、娱乐和许多其他应用。在本篇文章中,我们将了解这种交互式方法,它为您提供了一种与系统交互的新方法,而不是使用无聊的鼠标。我们的游戏爱好者必须知道,几年前任天堂游戏公司在借助称为Wii控制器的手持式控制器的帮助下推出了一种3D交互方法与其游戏机交互的想法。它使用加速度计来定位游戏的手势并以无线方式将其发送到系统。如果您想了解有关该技术的更多信息,可以查看他们的专利EP1854518B1,这将让您全面了解该技术的工作原理。

Nintend-Wifi-Module.png

任天堂Wifi模块


受这个想法的启发,我们将制作一个“空中鼠标”,只需在空中移动控制台即可与系统进行交互,但不是使用三维坐标参考,我们只会使用二维坐标参考我们可以模仿电脑鼠标的动作,因为鼠标在X和Y两个维度上工作。


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


先决条件

●     Arduino Nano开发板

●     加速度计ADXL335模块

●     蓝牙HC-05模块

●     按钮

●     安装Python的计算机


电路原理图

Circuit-Diagram-for-DIY-Gesture-Controlled-Arduino-based-Air-Mouse-using-Accelerometer.png

Circuit-Hardware-for-DIY-Gesture-Controlled-Arduino-based-Air-Mouse-using-Accele.jpg

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


这里使用的是ADXL335加速度计,它是一个基于MEMS的三轴模块,输出沿X、Y和Z轴的加速度,但正如之前所说的控制鼠标,我们只需要沿X轴和Y轴加速。这里加速度计的Xout和Yout引脚连接到Arduino的模拟A0和A1引脚,并且使用蓝牙模块HC-05将信号从Arduino传输到系统,因为蓝牙需要连接Tx和Rx引脚,所以我们使用软件串行引脚D2和D3。它使用软件串口连接,因为如果我们将蓝牙与硬件串口连接并开始通过python控制台获取读数,它将显示错配波特率的错误,因为蓝牙将以其自己的波特率与python通信。


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

Gesture-Controlled-Arduino-based-Air-Mouse-using-Accelerometer.jpg


空中鼠标的处理流程

流程图显示了基于Arduino的空中鼠标的流程:

Process-Flow-for-the-Air-Mouse.png


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 Pin 2和3中可以作为软件串口使用。接下来,我们从软件串口库声明蓝牙对象,以设置Tx和Rx的引脚。

  1. #include <SoftwareSerial.h>
  2. const int rxpin = 2, txpin = 3;
  3. SoftwareSerial bluetooth(rxpin, txpin);
  4. const int x=A0;
  5. const int y=A1;
  6. int xh, yh;
  7. int xcord, ycord;
  8. const int trigger = 5;
  9. int lstate = 0;
  10. int rstate = 0;
  11. const int lclick = 6;
  12. const int rclick = 7;
  13. const int led = 8;
复制代码

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

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

  1.   void setup()
  2. {
  3.   pinMode(x,INPUT);
  4.   pinMode(y,INPUT);
  5.   pinMode(trigger,INPUT_PULLUP)
  6.   pinMode(lclick,INPUT);
  7.   pinMode(rclick,INPUT);
  8.   pinMode(led, OUTPUT);
  9.   digitalWrite(lclick,HIGH);
  10.   digitalWrite(rclick,HIGH);
  11.   Serial.begin(9600);
  12.   bluetooth.begin(9600);
  13. }
复制代码

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

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

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

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

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

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

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

  1. void loop()
  2. {
  3. digitalWrite(led,LOW);
  4.   while(digitalRead(trigger)==LOW)
  5.   {
  6.     digitalWrite(led, HIGH);
  7.     lstate = digitalRead(lclick);
  8.     rstate = digitalRead(rclick);
  9.     xh=analogRead(x);
  10.     yh=analogRead(y);
  11.     xcord=map(xh,286,429,100,999);
  12.     ycord=map(yh,282,427,100,800);
  13.     Serial.print(xcord);
  14.     Serial.print(ycord);
  15.     if (lstate == LOW)
  16.     Serial.print(1);
  17.     else
  18.     Serial.print(0);
  19.     if (rstate == LOW)
  20.     Serial.print(1);
  21.     else
  22.     Serial.print(0);
  23.     bluetooth.print(xcord);
  24.     bluetooth.print(ycord);
  25.     if (lstate == LOW)
  26.     bluetooth.print(1);
  27.     else
  28.     bluetooth.print(0);
  29.     if (rstate == LOW)
  30.     bluetooth.print(1);
  31.     else
  32.     bluetooth.print(0);
  33.     delay(4000);
  34.    } }
复制代码

计算机的Python驱动程序脚本

截至目前,我们已经完成了硬件及其固件部分,现在为了让空中鼠标工作,我们需要有一个驱动程序脚本,可以解码来自空中鼠标的信号来移动光标,所以为此,我们选择了Python。 Python是一种脚本语言,通过编写脚本,我们的意思是它可以帮助我们控制其他程序,就像我们控制鼠标光标一样。


所以打开你的python shell并使用以下命令安装以下库:

  1. pip install serial
  2. pip install pyautogui
复制代码

serial是python的一个库,它可以帮助我们从com端口等串行接口获取数据,也让我们操作它,而pyautogui是python的库,可以控制GUI功能,在本例中是鼠标。

现在让我们来看看驱动程序的代码,我们需要做的第一件事就是导入串口和pyautogui库,然后从串口库中,我们必须设置用于通信的com端口,波特率为9600,与Bluetooth.serial相同。为此,您必须将蓝牙模块连接到您的系统,然后在系统设置中,您必须检查它连接到哪个COM端口。

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

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

接下来,将光标坐标和位点的位分开,将它们切片,然后再将光标位分别切成X和Y坐标。左右键同样如此。

现在通过通信,我们得到一个字节字符串,我们需要将它转换为一个整数,以便它们可以适应坐标,我们通过解码它们然后将它们转换为整数来完成。

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

接下来检查点击,我们通过使用最后两位和pyautogui的点击功能来做到这一点,它的默认点击是一个,但我们可以通过向右声明按钮值将其设置为右,我们也可以定义点击次数通过将clicks参数设置为2将其设置为双击。


以下是要在计算机上运行的完整Python代码:

  1. import serial
  2. import pyautogui
  3. ser=serial.Serial('com3',9600)
  4. while 1:
  5.     k=ser.read(8)
  6.     cursor=k[:6]
  7.     click=k[6:]
  8.     x=cursor[:3]
  9.     y=cursor[3:]
  10.     l=click[0]
  11.     r=click[1]
  12.     xcor=int(x.decode('utf-8'))
  13.     ycor=int(y.decode('utf-8'))
  14.     pyautogui.moveTo(xcor,ycor)
  15.     if l==49:
  16.         pyautogui.click(clicks=2)
  17.     elif r==49:
  18.         pyautogui.click(button='right', clicks=2)
复制代码

测试Arduino空中鼠标

因此,为了操作空中鼠标,请为其连接电源。 它可以来自Arduino Nano USB插槽或使用7805 IC的5v稳压电源。 然后通过设置蓝牙连接的com端口运行python驱动程序脚本。 当脚本运行时,您会看到蓝牙停止闪烁时,这意味着它已连接到您的系统。 然后操作它点击触发按钮,你会看到坐标的位置会改变,如果你想要左键或右键,那么先按左或右按钮和触发按钮,你会看到点击的动作更改了光标的位置。

DIY-Gesture-Controlled-Arduino-based-Air-Mouse-using-Accelerometer.jpg


代码

本文使用的完整代码: main.rar (749 Bytes, 下载次数: 1)

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 345 | 回复: 634



Archiver|手机版|小黑屋|

GMT+8, 2019-8-23 19:30 , Processed in 0.031250 second(s), 32 queries . Powered by Discuz! X3.4

YiBoard一板网 © 2015-2018 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表