的Xbox 360无线控制器控制的Arduino机械臂

这是谢尔盖·狄恩斯(Sergei Dines)的嘉宾贡献
人们常说机器人有一天可以统治世界。而且,由于如今在我们的私人住宅中制造机器人的便利性和便捷性,我们可能相距不远。从本质上讲,每个机器人项目都会为机电一体化世界带来新的见解。因此,以下文章介绍了一种使用XBOX 360无线控制器控制机械臂的简单方法。这个项目的灵感来自 Barrett Anderies的遥控车由PS3控制器控制.

要求

要构建此项目,您将需要:

  • Arduino的 Uno($23.25)
  • Arduino的 Uno的USB主机屏蔽($15.99)
  • XBOX 360控制器($16.00)
  • XBOX 360无线适配器($17.49)

如果您还没有机械臂:

软件:

  • 欧特克 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

将Arduino USB主机板连接到Arduino UNO

2. 的Xbox 360适配器到屏蔽板上的USB插孔

的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 出

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;               // USBHub 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.的XboxReceiver已连接 || 的Xbox.的Xbox360已连接) {
   对于(uint8_t i=0;i<4;i++) {       如果(的Xbox.的Xbox360已连接[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 < SERVO1_MIN) s1 = SERVO1_MIN;            如果 (的Xbox.getAnalogHat(i,权利) &gt ; STICK_CENTER + 盲区 || 的Xbox.getAnalogHat(i,权利) < STICK_CENTER - 盲区) {                  //  Elbow Joint PIN3                  // s2 = s2 +(Xbox.getAnalogHat(i,RightHatY)-STICK_CENTER)* SERVO2_RATE * SERVO2_DIRECTION;           }           如果(s2> SERVO2_MAX)s2 = SERVO2_MAX;
          如果(s2 < SERVO2_MIN) s2 = SERVO2_MIN; 如果 (的Xbox.getAnalogHat(i,左帽子) &gt ; STICK_CENTER + 盲区 || 的Xbox.getAnalogHat(i,左帽子) < 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 < SERVO3_MIN) s3 = SERVO3_MIN;                           如果 (的Xbox.getAnalogHat(i,左帽子) &gt ; STICK_CENTER + 盲区 || 的Xbox.getAnalogHat(i,左帽子) < STICK_CENTER - 盲区) {                    // 伺服4 爪子2 Pin5            s4 = s4 +(Xbox.getAnalogHat(i,LeftHatY)-  STICK_CENTER)* SERVO4_RATE * SERVO4_DIRECTION;           }           如果(s4> SERVO4_MAX)s4 = SERVO4_MAX;
          如果(s4 < SERVO4_MIN) s4 = SERVO4_MIN;                                             如果 (的Xbox.getAnalogHat(i,左帽子X) &gt ; STICK_CENTER + 盲区 || 的Xbox.getAnalogHat(i,左帽子X) < STICK_CENTER - 盲区) {          // 伺服5旋转Pin6            s5 = s5 +(Xbox.getAnalogHat(i,LeftHatX)-STICK_CENTER)* SERVO5_RATE * SERVO5_DIRECTION;           }           如果(s5> SERVO5_MAX)s5 = SERVO5_MAX;
          如果(s5 < SERVO3_MIN) s5 = SERVO5_MIN;                      如果 (的Xbox.getAnalogHat(i,RightHatX) &gt ; STICK_CENTER + 盲区 || 的Xbox.getAnalogHat(i,RightHatX) < STICK_CENTER - 盲区) {         // 伺服6旋转爪Pin7            s6 = s6 +(Xbox.getAnalogHat(i,RightHatX)-STICK_CENTER)* SERVO6_RATE * SERVO6_DIRECTION;           }           如果(s6> s6 = SERVO6_MAX;
          如果(s6 < 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 < 4; i++) {
      如果 (的Xbox.的Xbox360已连接[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,RT2
右帽子Y3
左帽Y4
左帽Y5
左帽子X6
右帽子X7
控制捕获决赛

控制捕获决赛

控制表

控制表

步骤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机械臂

由Xbox 360控制的Arduino机械臂

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

7条评论 » Write a comment

  1. 嘿,我’我试图做这个确切的项目,但是更加复杂,并且没有屏蔽罩,所以我想让控制器与arduino连接,您知道该怎么做才能将其和另外3个电机合并

  2. 看来此项目需要多个(6)伺服器,但我只能看到其中一个伺服器的接线…可能错过了一些东西,但是您能帮我理解吗?谢谢!

  3. 您从哪里得到钱来做这些东西?我知道您可能有工作,但是。机器人看起来也不像’t非常稳定。机器人有没有摔坏过?

  4. xbox360_wireless:61:错误:‘USB’没有命名类型…..怎么解决这个错误?

发表回覆 沃尔特·斯塔克勒 取消回复

您的电子邮件地址不会被公开。 必需的地方已做标记 *