拇指操纵杆连接指南

γ
贡献者: 追随米克格鲁辛博博霍
喜爱的 最喜欢的

Arduino示例:Shield

硬件连接

对于本教程的范围,我们将集中在前两个示例中,阅读使用护罩的操纵杆和按钮。

叠放在Arduino上的操纵杆护罩的摩擦图

如果你有操纵杆分接头,只要所有东西都像屏蔽一样接线,并且使用代码中的管脚定义作为参考,您仍然可以遵循。也,如果您有其他硬件,如压电蜂鸣器或串行启用的LCD,可以查看其他示例。

Arduino示例代码

操纵杆护罩提供简单的模拟输入,以及四个单独的按钮和操纵杆下方的一个按钮。操纵杆可用于控制屏幕上的输出,如旋律或像素。按钮可用于导航或游戏控制。如果要直接跳到示例草图中,从github repo下载并解压示例以深入了解。

  • Joystickarduino基本示例.ino-在控制台上打印操纵杆值和按钮。
  • Joystickarduino中间示例.ino-此代码与基本代码的作用相同,但在操纵杆上包含更多的位置。
  • 欢乐音乐控制.ino-用操纵杆和压电蜂鸣器控制旋律和节奏。
  • 亚博官网sparkfunjoystickshieldsamplesketch.ino公司-演示视频中的示例,用于支持串行的LCD。

让我们看看Github回购的三个示例中的两个。

基本实例

下载示例后,打开Joystickarduino基本示例.ino草图,选择Arduino/Genuino乌诺作为板上枚举的板和COM端口,点击上传按钮。打开串行监视器九千六百波特和测试出操纵杆护罩,观察操纵杆和按钮的行为。

拇指操纵手柄护罩原始输出

如果你一直跟着教程走,输出看起来与接线板示例.分接头和护罩有两种不同。一个明显的区别是输出。由于增加了四个按钮,每行有更多的值。如果没有按下按钮,它们将读作1。如果按下按钮,它们将读取为0。

第二个区别更微妙。操纵杆的方向旋转90度。“垂直”位置以X轴当“水平”被引用为Y轴“。输出指示值在520左右时操纵杆不移动。将操纵杆向上移动至“AREF”销,操纵杆将读取X轴的相同值,而Y轴组件将跳转到1023。顺时针向右移动,X轴将读取约0的值,而Y轴组件将再次位于约520的静止值。当操纵杆向下移动时,您会注意到X轴将再次位于其静止值,而Y轴组件将降至0。向左移动操纵杆,您会注意到X轴组件跳到1023,而Y轴组件则回到其静止值。最后,按下操纵杆时,选择按钮将显示为0。

中间示例

打开Joystickarduino中间示例.ino草图,选择Arduino/Genuino乌诺作为板上枚举的板和COM端口,点击上传按钮。以9600波特的速度打开串行监视器并测试操纵杆护罩,以观察操纵杆和按钮的行为。

拇指操纵手柄护罩未加工

再一次,您将注意到原始输出与基本示例相同。然而,还有一行指示操纵手柄的位置。代码有点复杂嵌套的如果声明检查操纵杆的位置。代码将位置分解为9个位置:

  • 中心
  • 向上的
  • 右上
  • 正确的
  • 右下
  • 向下
  • 左下
  • 左边
  • 左上

需要注意的代码

一旦你装配好防护罩,您可以开始更改示例代码,使操纵杆执行您的出价。下面是一些关于代码的深入解释。

如何找到操纵杆的当前位置?

操纵手柄的位置由操纵手柄中的两个电位计计算得出。操纵杆可以二维移动,通常表示X和Y坐标,但可以表示任何二维量。要读取电位计,我们使用类比读数()函数,返回从0到1023的数字。我们需要为功能提供一个模拟管脚编号-对于操纵杆护罩,X位置从模拟管脚0读取,Y位置从模拟管脚1读取:

语言:cserial.println(analogread(0));//打印当前X位置序列.println(analogread(1));//打印当前Y位置

这是一种很好的技术——因为它明确了您的意图——对运行草图时不会改变的值使用“常量”。考虑到这一点,以下草图片段为所用的模拟管脚设置常量,并将当前X和Y位置打印到串行控制台:

语言:cconst int pin_analyc_x=0;const int pin_analyc_y=1;void setup()serial.begin(9600);void loop()serial.print(“x”);串行打印(模拟读取(Pin_Analog_x));serial.print(“”);序列号打印(“Y”);串行打印(模拟读取(Pin_Analog_y));serial.print(“”);serial.println();

如何找到操纵杆的当前方向?

使用X和Y位置的值来确定操纵杆是否在8个方向(即起来,马上,正确的,右下,下来,左下角,左,左上)。

因为我们知道每个维度的值将在0到1023之间,所以您可能会期望中心值大约为511或512,但由于操纵手柄是物理设备,实际值不太可能是如此精确。如果我们选择了错误的值,我们会发现我们的操纵杆会被检测到朝着某个特定方向移动,即使它是居中的。

为了解决这个问题,我们指定了两个“阈值”值,并考虑在该范围内的任何值都应被视为“居中”:

语言:bash

根据操纵杆的不同,您选择的阈值可能不同。我们在代码中将这些值指定为常量:

语言:cconst int x_threshold_low=505;const int x_threshold_high=515;const int y_threshold_low=500;const int y_threshold_high=510;

下一步,我们要将每个维度的值从0到1023的位置范围映射到-1到1的方向值。对于X,尺寸-1表示向左移动,0表示X维度中未移动,1表示向右移动。对于Y尺寸-1意味着向下移动,0表示Y维度中未移动,1表示向上移动。

我们首先将每个维度的方向设置为0(“居中”),然后使用如果/其他用于检查维度中的位置值是否高于或低于阈值的语句:

语言:cx _方向=0;y _方向=0;x _位置=肛门(pin _模拟_x);y _位置=肛门(pin _模拟_y);if(x _位置>x _阈值_高);x _方向=1;;else if(x _位置<x _阈值U低);x U方向=1;;if(y _位置>y _阈值U高);y _方向=1;;else if(y _位置<y _阈值_阈值_阈值_阈值_阈值U高);if(低)Y轴方向=-1;

Arduino提供了MAP()在理论上我们可以使用的函数如果/其他但是由于中心问题的存在,这个方法很复杂,所以我们在这里不考虑这种方法。

正如您在下一个完整的示例中看到的,然后我们使用如果/其他打印方向的语句-可以修改此示例以执行所需的任何操作:

语言:cconst byte pin_analyc_x=0;const byte pin_analyc_y=1;const int x_threshold_low=505;const int x_threshold_high=515;const int y_threshold_low=500;const int y_threshold_high=510;int x_position;int y_position;int x_direction;int y_direction;void setup()serial.begin(9600);void loop()x_direction=0;Y轴方向=0;x_位置=模拟读数(pin_模拟_x);Y_位置=模拟读取(Pin_Analog_Y);如果(x_位置>x_阈值_高)x_方向=1;}否则,如果(x_位置<x_阈值_低)x_方向=-1;}如果(y_位置>y_阈值_高)y_方向=1;}否则,如果(y_位置<y_阈值_低)y_方向=-1;}if(x_direction=-1)if(y_direction=-1)serial.println(“左下”);}否则,如果(y_direction==0)serial.println(“left”);}else//y_direction==1 serial.println(“左上”);}}else if(x_direction==0)if(y_direction==1)serial.println(“down”);}否则,如果(y_direction==0)serial.println(“centraled”);}else//y_direction==1 serial.println(“up”);}}else//x_direction==1 if(y_direction=-1)serial.println(“right down”);}否则,如果(y_direction==0)serial.println(“right”);}else//y_direction==1 serial.println(“right up”);} }

如何设置Arduino,以便知道何时按下操纵杆护罩上的按钮?

在你知道屏蔽上的按钮是否被按下之前,您需要设置Arduino来识别按钮。毫不奇怪,您将在中执行此设置…设置()功能!

第一,我们为与每个按钮关联的Arduino管脚定义常量:

语言:C//按下操纵杆时触发选择按钮const byte pin_button_select=2;const byte pin_button_right=3;const byte pin_button_up=4;const byte pin_button_down=5;const byte pin_button_left=6;

如果您在注意到之前使用过按钮开关,通常需要一个电阻来检测未按下按钮时的已知电压。为了减少所需零件的数量,本屏蔽设计为不需要在屏蔽上安装电阻。你在想自己吗?如果按钮需要电阻,而屏蔽没有电阻,我们如何才能使屏蔽工作?“?如果你不这么想,那么你可能会跳过这一点。(如果你想的话)我真的很饿“也许是时候放下电子设备,买点食物了。”

事实证明,你的Arduino实际上有内部电阻连接到微控制器内部的管脚上。为了使用内部电阻,我们需要启用内部上拉电阻器“。如果你觉得这样的话”吊起起起起重臂,解开主撑。“然后我可以解释更多:

当“上拉“电阻器与按钮相连,这意味着未按下按钮时的电压水平将很高,因为电阻器”将电压水平拉高“当按钮未按下时,变为高。在典型的Arduino上,高电压为5伏。当按下按钮时,由于针脚和接地之间的电阻小于针脚和5伏之间的电阻,因此针脚的读数将变低。

要启用管脚的上拉电阻器,首先将管脚设置为输入,然后启用上拉:

语言:cpinmode(pin_按钮_右,输入插拔);

如果你从字面上看的话,启用下拉功能的实际代码没有任何意义,但这就是它的工作方式。

除了记住一个未按下的按钮会用上拉电阻读得很高之外,一个按下的按钮读得很低,你不需要记住或理解其他细节。

为了将每个针脚配置为输入并启用上拉电阻,我们使用以下代码:

语言:cvoid setup()/././././/。PinMode(Pin_按钮_右,输入插拔);PinMode(Pin_按钮_左,输入插拔);PinMode(Pin_按钮向上,输入插拔);PinMode(Pin_按钮_向下,输入插拔);PinMode(Pin_按钮\选择,输入-上拉);}

请参阅下一节了解如何读取按钮是否被按下。亚博在线娱乐官网

我如何知道何时按下操纵杆护罩上的按钮?

一旦设置好Arduino识别按钮(见上文),您就可以判断是否使用数字读入()功能。当读取值低时,按下按钮;当读取值高时,不按下按钮。

语言:CIF(数字读取(pin_button_left)==low)//按钮按下否则//按钮未按下

以下完整示例将每个按钮的状态和操纵杆的值打印到Arduino串行控制台:

语言:C//存储与每个输入相关的Arduino管脚//按下操纵杆时触发选择按钮const byte管脚_按钮_select=2;const byte pin_button_right=3;const byte pin_button_up=4;const byte pin_button_down=5;const byte pin_button_left=6;const byte pin_analogular_x=0;const byte pin_analogular_y=1;void setup()serial.begin(9600);PinMode(Pin_按钮_右,输入);数字写入(Pin_按钮_右,高);PinMode(Pin_按钮_左,输入);数字写入(Pin_按钮_左,高);PinMode(Pin_按钮向上,输入);数字写入(Pin_按钮向上,高);PinMode(Pin_按钮_向下,输入);数字写入(Pin_按钮向下,高);PinMode(Pin_按钮\选择,输入);数字写入(Pin_按钮\选择,高);}void loop()serial.print(“l:”);串行打印(DigitalRead(Pin_按钮_Left));serial.print(“”);序列号打印(“R”);串行打印(数字读取(Pin_按钮_右));serial.print(“”);serial.print(“U:”);串行打印(DigitalRead(Pin_按钮_-up));serial.print(“”);serial.print(“d:”);串行打印(数字读取(Pin_按钮_向下));serial.print(“”);serial.print(“x:”);串行打印(模拟读取(Pin_Analog_x));serial.print(“”);序列号打印(“Y”);串行打印(模拟读取(Pin_Analog_y));serial.print(“”);serial.print(“s:”);串行打印(数字读取(Pin_按钮_选择));serial.print(“”);serial.println();