这是谢尔盖·狄恩斯(Sergei Dines)的嘉宾贡献
人们常说机器人有一天可以统治世界。而且,由于如今在我们的私人住宅中制造机器人的便利性和便捷性,我们可能相距不远。从本质上讲,每个机器人项目都会为机电一体化世界带来新的见解。因此,以下文章介绍了一种使用XBOX 360无线控制器控制机械臂的简单方法。这个项目的灵感来自 Barrett Anderies的遥控车由PS3控制器控制.
要求
要构建此项目,您将需要:
如果您还没有机械臂:
软件:
- 欧特克 Inventor 2014
- Arduino IDE
- USB Host Shield库
- 最终代码使用XBOXRECV
可选软件: Fritzing:电路图软件
机械:
- 面包板[400磅]
- 标准伺服
电气:
- 跳线
- 电源:3000 mAh或更高,7伏特或更高:最好是镍氢毒液电池,如照片所示
- 跳线
- 电工胶带
步骤1:重要零件先购买
带适配器的Xbox控制器,Arduino UNO(带电缆),Arduino UNO的USB主机护罩,伺服器和电线是您应立即订购的核心部件。推理;您要确保Xbox控制器,适配器,USB主机护罩和Arduino彼此之间都能很好地通信。

重要零件先买
步骤2:将所有内容放在一起
购买核心材料。其中一些零件的到达日期可能会有所不同。在工程设计社区中有一个玩笑,您首先要购买所需的东西,然后再进行设计。
1.将Arduino USB 主机板连接到Arduino UNO

将Arduino USB 主机板连接到Arduino UNO
2. 的Xbox 360适配器到屏蔽板上的USB插孔

的Xbox 360适配器到屏蔽板上的USB插孔
警告 :确保不要强行压下引脚,轻轻摆动USB主机护盖,直到引脚完全覆盖
注意 :确保它是Microsoft适配器
3.伺服到数字引脚2的黄/白线
注意 :屏蔽罩上的引脚与直接在下面的Arduino引脚相同
4.伺服到地的黑/棕线
5.伺服至5V的红色/橙色线
6.从Arduino到GND轨的GND
7. V_in从Arduino到Red rail
您的接线应如下所示:

您的接线应如下所示
8. Connect 出 + [ of Regulator] to Red Rail
9. Connect 出 – [of Regulator] to GND rail

Connect 出
10.剥去鳄鱼夹(电池充电器随附)的另一端,如下所示:

剥去鳄鱼夹的另一端
警告 :确保如图所示在端子中时电线不会接触(我用胶带)。
很重要:
调节器会降低电压,以便Arduino板和伺服器可以工作。“Out”调节器一侧应读取4.8 – 6伏特(取决于您的伺服器)。我的矿山电压设置为5.5 V,它运作良好。 –不要仅在未将金色电位器(金色圆圈上带有箭头的箭头)旋转至该电压的情况下连接调节器。

不要只在不转动金色电位器的情况下连接调节器
一个。将红色鳄鱼夹连接到电池
b。将另一端连接到In +
C。将黑色鳄鱼夹连接到黑色电池
d。将另一端连接到–

连接鳄鱼皮
如果接线正确,您将看到以下内容:

如果接线正确,您将看到以下内容
步骤3:程式码
为了使Xbox控制器和适配器与USB防护板和Arduino通讯,您需要下载在以下位置找到的USB主机防护库: //github.com/felis/USB_Host_Shield_2.0 只需点击“download zip” on right hand side.
注意:您可能可以找到带有类似示例的其他网站,只需确保获得XBOXRECV,因为这是所需的Xbox 360无线库。
不知道如何在Arduino IDE中放置新库?到这里: 图书馆
我包含了许多版本的代码以及最终代码。 Barrett Anderies帮助开发了PS3代码,该代码的控件比以前的尝试要平滑得多。先前的尝试是为了说明完成相同任务的其他可能途径。建议您仔细阅读评论和方法,以扩大视野。
六个伺服控制器(Xbox360无线)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | //六个伺服控制器(Xbox360无线) // Barrett Anderies // 2014年5月25日 //由Sergei Dines修改 // 2014年8月3日 #包括 #包括 //满足IDE,仅需在ino中查看include语句。 #ifdef dobogusinclude #包括 #万一 #define LOOPTIME 25 //定义定时循环周期之间的延迟。 //定义每个伺服器的连接位置// #define SERVO1 2 // 左/右扳机:基础关节 #define SERVO2 3 // RightHat Y : Elbow Joint #define SERVO3 4 // LeftHat Y : CLAW 1 #define SERVO4 5 // LeftHat Y : 爪子2 #define SERVO5 6 // LeftHat X : Swivel #define SERVO6 7 // RightHatX : Spin Claw #define SERVO1_INIT 90 //定义初始伺服位置(初始条件)& (在按下“开始”按钮时启动)。 #定义SERVO2_INIT 90 #定义SERVO3_INIT 90 #定义SERVO4_INIT 90 #定义SERVO5_INIT 90 #定义SERVO6_INIT 90 #定义SERVO1_STEP 8 // L / R Tripper [基本关节]的步长值 //定义由D-pad控制的伺服的步长(越大越快)。 #定义SERVO2_RATE 4/32000 //注:组织SERVO2_STEP 10 //通过摇杆为伺服控制器定义速率(越大速度越快)。 #定义SERVO3_RATE 5/32000 #定义SERVO4_RATE 5/32000 #定义SERVO5_RATE 2/32000 #定义SERVO6_RATE 4/32000 #define SERVO1_DIRECTION 1 //设置为-1以反转伺服方向。 #define SERVO2_DIRECTION 1 //设置为-1以反转伺服方向。 #define SERVO3_DIRECTION -1 //设置为-1以反转伺服方向。爪子1 #define SERVO4_DIRECTION 1 //设置为-1以反转伺服方向。 CLAW 2 #define SERVO5_DIRECTION 1 //设置为-1以反转伺服方向。 #define SERVO6_DIRECTION 1 //设置为-1以反转伺服方向。 #define SERVO1_MIN 2 //定义最小伺服角度 #定义SERVO2_MIN 2 #define SERVO3_MIN 2 // EDIT ***:爪-更改值以避免碰撞 #define SERVO4_MIN 2 // EDIT ***:爪-更改值以避免碰撞 #定义SERVO5_MIN 2 #定义SERVO6_MIN 2 #define SERVO1_MAX 178 //定义最大伺服角度。 #定义SERVO2_MAX 178 #define SERVO3_MAX 178 //编辑***:爪-更改值以避免碰撞 #define SERVO4_MAX 178 //编辑***:爪-更改值以避免碰撞 #定义SERVO5_MAX 178 #定义SERVO6_MAX 178 #define STICK_CENTER 0 //当操纵杆居中时来自控制器的值(对于PS3控制器为127,对于xbox控制器为0) #定义DEADZONE 7500 //死区以防止不必要的移动。为Xbox360控制器定义为7500 // == =============================全局变量=============== == ================ // USB USB ; // USB Hub Hub1(& USB ); //有些加密狗内部有一个集线器。试试看,这是因为您的加密狗无法正常工作。 XBOXRECV 的Xbox (& 安培 ; USB ); 伺服 servo1; //实例化伺服变量 伺服 servo2; 伺服 servo3; 伺服 servo4; 伺服 servo5; 伺服 servo6; 未签名 长 PreviousTime = 0; //用于循环计时 整型 s1 = SERVO1_INIT; //定义变量以存储伺服位置并设置为初始位置 整型 s2 = SERVO2_INIT; 整型 s3 = SERVO3_INIT; 整型 s4 = SERVO4_INIT; 整型 s5 = SERVO5_INIT; 整型 s6 = SERVO6_INIT; // == =============================设置=============== == =============== // 虚空 建立 () //设置循环 { 序列号 . 开始 (115200); 而 (! 序列号 ); //等待串行端口连接-在Leonardo,Teensy和其他带有内置USB CDC串行连接的板上使用 如果 ( USB . 在里面 () == -1) { 序列号 . 打印 (F(“ \ r \ nOSC没有启动”)); 而 (1); //停止 } 序列号 . 打印 (F(“ \ r \ nXbox无线接收器已启动”)); servo1. 分离 (); //最初禁用所有Servos //等待按钮初始化[MAKE课程的要求] servo2. 分离 (); servo3. 分离 (); servo4. 分离 (); servo5. 分离 (); servo6. 分离 (); } // == =============================循环================ == =============== // 虚空 循环 () { //主运行时循环 USB . 任务 (); //任务USB 如果 ( 的Xbox . 的Xbox Receiver已连接 || 的Xbox . 的Xbox 360已连接) { 对于 (uint8_t i=0;i& lt ;4;i ++ ) { 如果 ( 的Xbox . 的Xbox 360已连接[i]) { //仅在连接Xbox 360控制器时执行此循环 if(millis()-previousTime> LOOPTIME) { //定时开始 如果 ( 的Xbox .getButtonClick(i,L2)) { //基础联合伺服PIN2 s1 = s1 + SERVO1_STEP *SERVO1_DIRECTION; } 其他 如果 ( 的Xbox .getButtonClick(i,R2)) { s1 = s1 - SERVO1_STEP *SERVO1_DIRECTION; } 如果 (s1 & gt ; SERVO1_MAX) s1 = SERVO1_MAX; 如果 (s1 & lt ; SERVO1_MIN) s1 = SERVO1_MIN; 如果 ( 的Xbox .getAnalogHat(i,权利) & gt ; STICK_CENTER + 盲区 || 的Xbox .getAnalogHat(i,权利) & lt ; STICK_CENTER - 盲区) { // Elbow Joint PIN3 // s2 = s2 +(Xbox.getAnalogHat(i,RightHatY)-STICK_CENTER)* SERVO2_RATE * SERVO2_DIRECTION; } 如果(s2> SERVO2_MAX)s2 = SERVO2_MAX; 如果 (s2 & lt ; SERVO2_MIN) s2 = SERVO2_MIN; 如果 ( 的Xbox .getAnalogHat(i,左帽子 ) & gt ; STICK_CENTER + 盲区 || 的Xbox .getAnalogHat(i,左帽子 ) & lt ; STICK_CENTER - 盲区) { // 伺服 3 CLAW 1 PIN4 s3 = s3 +(Xbox.getAnalogHat(i,LeftHatY)- STICK_CENTER)* SERVO3_RATE * SERVO3_DIRECTION; } 如果(s3> SERVO3_MAX)s3 = SERVO3_MAX; 如果 (s3 & lt ; SERVO3_MIN) s3 = SERVO3_MIN; 如果 ( 的Xbox .getAnalogHat(i,左帽子 ) & gt ; STICK_CENTER + 盲区 || 的Xbox .getAnalogHat(i,左帽子 ) & lt ; STICK_CENTER - 盲区) { // 伺服 4 爪子2 Pin5 s4 = s4 +(Xbox.getAnalogHat(i,LeftHatY)- STICK_CENTER)* SERVO4_RATE * SERVO4_DIRECTION; } 如果(s4> SERVO4_MAX)s4 = SERVO4_MAX; 如果 (s4 & lt ; SERVO4_MIN) s4 = SERVO4_MIN; 如果 ( 的Xbox .getAnalogHat(i,左帽子X) & gt ; STICK_CENTER + 盲区 || 的Xbox .getAnalogHat(i,左帽子X) & lt ; STICK_CENTER - 盲区) { // 伺服 5旋转Pin6 s5 = s5 +(Xbox.getAnalogHat(i,LeftHatX)-STICK_CENTER)* SERVO5_RATE * SERVO5_DIRECTION; } 如果(s5> SERVO5_MAX)s5 = SERVO5_MAX; 如果 (s5 & lt ; SERVO3_MIN) s5 = SERVO5_MIN; 如果 ( 的Xbox .getAnalogHat(i,RightHatX) & gt ; STICK_CENTER + 盲区 || 的Xbox .getAnalogHat(i,RightHatX) & lt ; STICK_CENTER - 盲区) { // 伺服 6旋转爪Pin7 s6 = s6 +(Xbox.getAnalogHat(i,RightHatX)-STICK_CENTER)* SERVO6_RATE * SERVO6_DIRECTION; } 如果(s6> s6 = SERVO6_MAX; 如果 (s6 & lt ; SERVO6_MIN) s6 = SERVO6_MIN; 序列号 . 打印 (" s1 = "); //调试有关伺服位置的信息。确定伺服极限时,请取消注释。 序列号 . 打印 (s1); 序列号 . 打印 (" s2 = "); 序列号 . 打印 (s2); 序列号 . 打印 (" s3 = "); 序列号 . 打印 (s3); 序列号 . 打印 (" s4 = "); 序列号 . 打印 (s4); 序列号 . 打印 (" s5 = "); 序列号 . 打印 (s5); 序列号 . 打印 (" s6 = "); 序列号 . 打印 (s6); 如果 ( 的Xbox .getButtonClick(i,B)) { //安全发布 //分离所有伺服器-等待按钮重新接合 servo1. 分离 (); servo2. 分离 (); servo3. 分离 (); servo4. 分离 (); servo5. 分离 (); servo6. 分离 (); } //安全还原 //还:初始化按钮:启动机器人的创新方式 如果 ( 的Xbox .getButtonClick(i,A)) { servo1. 连接 (2); servo2. 连接 (3); servo3. 连接 (4); servo4. 连接 (5); servo5. 连接 (6); servo6. 连接 (7); 如果 ( 的Xbox .getButtonClick(i, 开始 )) { //按下“开始”按钮时,将所有伺服系统重置到初始位置 s1 = SERVO1_INIT; s2 = SERVO2_INIT; s3 = SERVO3_INIT; s4 = SERVO4_INIT; s5 = SERVO5_INIT; s6 = SERVO6_INIT; } //以下是用于其他应用程序的可重新编程分离按钮 //注意:不必仅限于伺服器 //I.e. could 连接 , 分离 led when servo is 连接 ed, 分离 ed 如果 ( 的Xbox .getButtonClick(i,X)) //分离底座 { servo1. 分离 (); } 如果 ( 的Xbox .getButtonClick(i,Y)) { //分离肘关节 servo2. 分离 (); } 如果 ( 的Xbox .getButtonClick(i, 向上 )) { //分离爪1 servo3. 分离 (); } 如果 ( 的Xbox .getButtonClick(i, 下 )) { //分离爪2 servo4. 分离 (); } 如果 ( 的Xbox .getButtonClick(i, 对 )) { //分离旋转 servo5. 分离 (); } 如果 ( 的Xbox .getButtonClick(i, 剩下 )) { //分离旋转爪 servo6. 分离 (); } PreviousTime = 毫 (); //在循环结束时保存时间 } //定时循环 servo1. 写 (s1); //写入伺服器。 servo2. 写 (s2); servo3. 写 (s3); servo4. 写 (s4); servo5. 写 (s5); servo6. 写 (s6); } } } } } |
使用Xbox 360控制器的伺服增量控制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | //名称:Sergei Dines //日期:2014年8月6日 //目的:使用Xbox 360 Controller增量控制伺服 #包括 #ifdef dobogusinclude #包括< #万一 #包括 //来自org的5行以上 USB USB ; XBOXRECV 的Xbox (& 安培 ; USB ); 伺服 servo1; 整型 var1; //正确获取xbox模拟值 整型 var2; //将xbox模拟量映射到伺服值 整型 var3; //增量控制 虚空 建立 () { 序列号 . 开始 (115200); 而 (! 序列号 ); //等待串口连接 如果 ( USB . 在里面 () == -1) { 序列号 . 打印 (F(“ \ r \ n0SC没有启动”)); 而 (1); //停止 } 序列号 . 打印 (F(“ \ r \ nXbox无线接收器库已启动”)); pinMode (9, 输出值 ); servo1. 连接 (9); } 虚空 循环 () { USB . 任务 (); 对于 (uint8_t i = 0; i & lt ; 4; i ++ ) { 如果 ( 的Xbox . 的Xbox 360已连接[i]) { //根据原始代码的定义 如果 ( 的Xbox .getAnalogHat(i,左帽子X)){ //原始定义 var1 = 的Xbox .getAnalogHat(i,左帽子X); // Var1获取组织。定义 var2 = 地图 (var1, 0, 255, 0, 79); // Var2将此代码转换为可用的伺服控制 servo1. 写 (var2); } 序列号 . 打印 (F(“ 左帽子X:”)); 序列号 . 打印 ( 的Xbox .getAnalogHat(i,左帽子X)); 序列号 . 打印 ( “ \ t” ); / *此代码完成了将伺服器移至特定位置并将其固定在那里的目标 但是这里有问题: 1]控制太敏感 2]发生抖动 3]无速度控制 4]必须缓慢移动操纵杆才能输出准确的动作 * / } } } |
默认情况下,该代码将输出:
注意:必须按A才能通过默认代码启动机器人
起停功能 | |
A | 启动机器人 |
B | 安全停止 |
纽扣 | 数字针 |
LT,RT | 2 |
右帽子Y | 3 |
左帽Y | 4 |
左帽Y | 5 |
左帽子X | 6 |
右帽子X | 7 |

控制捕获决赛

控制表
步骤4 [可选]:构建完整的AXIOM ARM或您自己的机械臂
如果要从头到尾设计机械臂,则以下机械零件可能是有用的机械零件: 下载机械零件
1.下载Autodesk Inventor 2014
- 去: 欧特克 创建一个免费的个人资料
- 注意:出现提示时,材料内容库很有用,但不是必需的
2.下载AXIOM ARM Inventor零件
3.爪准备好按原样进行3D打印
但是:伺服支架可能需要调整。亚马逊有一个很棒的伺服支架套件 $90,如果您不打算设计和修改支架零件;
部分:
- 多写
- 带蓝灯的拨动开关
- 3D打印零件
- 购买SainSmart 17DOF Biped黑色教育机器人套件
- 或:3D打印部件(以下提供部件)
- 橡皮筋
一切保持不变,唯一的区别是您的电路看起来像这样:

电路制造

公理臂

的Xbox 360无线控制器控制的Arduino机械臂
由Xbox 360控制的Arduino机械臂
关于塞尔吉美食:
谢尔盖·狄恩斯 是佛罗里达州USF的机械工程师高级。他的兴趣包括产品设计和机器人技术。他说,“从头开始进行设计过程是非常有益的;它使您思考一切之间的联系,并迫使您寻求帮助并与志趣相投的机器人爱好者联系”.
他要亲自感谢Barrett Anderies,Schlaf博士[USF]和Anthony Rose [USF]的专业知识。