说说我折腾DFR0182无线手柄遥控乐高ev3的过程

2016-12-082.3万
精华项目
AI 快速预览详细 收起
本文介绍了使用DFR0182无线手柄通过蓝牙功能遥控乐高EV3的过程。文中提到,乐高EV3通常使用红外遥控器,但红外遥控器的按键操控性不如手柄方便。DFR0182手柄支持蓝牙2.0版本,可以替代红外遥控器。文章还提到了一些安装和调试过程中遇到的问题,如USB转换板插上去松动、按键容易脱落等,并提供了解决方案。通过这种方式,用户可以更方便地遥控乐高EV3,实现更多创意项目。


    乐高EV3的遥控一般采用红外遥控器和传感器,合计400多毛大大。EV3本身带有蓝牙(2.1版本)功能,如果使用蓝牙,就不需要安装红外传感器了。同时红外遥控器的按键操控性不如手柄方便,所以我打算找一款带蓝牙功能的可编程手柄。问度娘古哥和某宝,目前看来,dfrobot是唯一选择。等拿到dfr0182手柄,感觉比预想的大,做工相当好,不过请允许我先吐几个槽点:
说说我折腾DFR0182无线手柄遥控乐高ev3的过程图11、贵!手柄加蓝牙模块508毛大大,蓝牙2.0居然卖到140毛大大,比BLE4.0的蓝牙贵了近一倍!和EV3红外比,没有优势了(当然蓝牙模块可以买第三方的,便宜一些)。另外还从dfrobot的另一家店铺买了DFR0008手柄,其实是一款带摇杆和按键的Arduino扩展板,以后再介绍。两个店铺看起来是同一个发货地址,收到两个包裹,运费免了一份;
2、上传程序的usb转换板插上去很松,容易脱落,不知道是否由于我曾拆开手柄装蓝牙模块,导致哪里没有卡到位?原包装不带mini usb线,买手柄的亲们要自己准备一根mini usb线;3、拆开手柄安装蓝牙后,发现手柄左上和右上四个按键容易脱落,而且按键内侧的小塑料圈也容易掉落,导致按键不起作用,琢磨了一会,发现窍门是,要从里往外按,才能卡住按键,然后再合上手柄外壳;
4、手柄内部的两根黑红电池线容易断,不方便调试,后来我干脆把线拔了,等电脑上程序调试通过,再找人焊线。

未完待续


创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(17)
gada888
gada888
学习下
Ember
Ember
xbee和ev3的通信速率设为多少?
mauree
mauree
可以设置和EV3的配对密码吗?连接稳定吗?
凌风清羽
凌风清羽
质量不错,就是略贵啊~~~~
砖头墙
砖头墙
叼 牛 资料不错
Robotforyou
Robotforyou
真心不错呀
taelons
taelons
作者
同样的方法可以实现用任天堂wii chuck手柄(俗称鸡腿)配合arduino操控,前天拿到dfrobot的wii 转接板,记录下鸡腿的摇杆XY轴坐标值:
[align=left]Y轴(上下):25~131~228[/align]
[align=left][font="]X轴(左右):[/font]34~128~232[/align][align=left]
[/align][align=left]鸡腿还有一个三轴加速传感器,任意摇动鸡腿时(不是摇杆),XYZ三个坐标值会变,不过这种方式操控ev3有点别扭。[/align]
R2D2
R2D2
这个帖子要赞一下。 把乐高并入到Arduino的世界。
微笑的rockets
微笑的rockets
arduino的便利性就在这里,如果玩的溜,乐高都是给arduino打工的……
taelons
taelons
作者
经过以上几步,EV3已能通过蓝牙接收手柄按键和摇杆数据,剩下的事情就简单了,在LEGO MINDSTORMS EV3 Home Edition中用程序块拖放编程,这里就不打算说了。
开头提到还入手了一块便宜DFR0008手柄,带四个按建和一个摇杆,足够用了,arduino程序相对简单,我就不重复了,只贴一张靓照。

手柄插上蓝牙模块,再插在arduino上,arduino固定在乐高搭成的支架里,下面绑一块电池供电,非常牢固。
如果能找一个便宜的xbee 2.0蓝牙模块,全部加起来不超过200元,便宜实惠。:lol
等有时间再上传操控乐高EV3小车的视频。
接下来准备加一个红外模块,用手柄遥控乐高PF马达 :lol
taelons
taelons
作者
我的EV3 usb口貌似有故障,暂时不能调试程序,摇杆的程序先贴出来。
[code]unsigned char hexLJoystickX[15] = {0x0d,0x00,0x00,0x00,0x81,0x9e,0x02,0x78,0x00,0x40,0x00,0x00,0x00,0x00,0x00};
unsigned char hexLJoystickY[15] = {0x0d,0x00,0x00,0x00,0x81,0x9e,0x02,0x79,0x00,0x40,0x00,0x00,0x00,0x00,0x00};
unsigned char hexRJoystickX[15] = {0x0d,0x00,0x00,0x00,0x81,0x9e,0x02,0x76,0x00,0x40,0x00,0x00,0x00,0x00,0x00};
unsigned char hexRJoystickY[15] = {0x0d,0x00,0x00,0x00,0x81,0x9e,0x02,0x77,0x00,0x40,0x00,0x00,0x00,0x00,0x00};
int RJoystickY = joystick[2];
int RJoystickX = joystick[3];
int LJoystickY = AnalogButton[0];
int LJoystickX = AnalogButton[1];
union data
{
unsigned char c[4];
float f;
};
union data x;
x.f = RJoystickY;
hexRJoystickY[11] = x.c[0];
hexRJoystickY[12] = x.c[1];
hexRJoystickY[13] = x.c[2];
hexRJoystickY[14] = x.c[3];
Serial1.write(hexRJoystickY,15);
x.f = RJoystickX;
hexRJoystickX[11] = x.c[0];
hexRJoystickX[12] = x.c[1];
hexRJoystickX[13] = x.c[2];
hexRJoystickX[14] = x.c[3];
Serial1.write(hexRJoystickX,15);
x.f = LJoystickY;
hexLJoystickY[11] = x.c[0];
hexLJoystickY[12] = x.c[1];
hexLJoystickY[13] = x.c[2];
hexLJoystickY[14] = x.c[3];
Serial1.write(hexLJoystickY,15);
x.f = LJoystickX;
hexLJoystickX[11] = x.c[0];
hexLJoystickX[12] = x.c[1];
hexLJoystickX[13] = x.c[2];
hexLJoystickX[14] = x.c[3];
Serial1.write(hexLJoystickX,15);[/code]
然后在EV3上测试是否能收到摇杆值:

运行后,在EV3液晶屏上显示左右摇杆数据:
LX:484
LY:505
RX:498
RY:497
拨动摇杆,显示随之变化。
未完待续。。。。。。。
iooops
iooops
666
Ash1
Ash1
坐等楼主更新
luna
luna
大写的赞~
taelons
taelons
作者
上面的程序是单个键的蓝牙数据发送,这里不需要考虑组合按键,因为手柄的17个键足够分配不同功能了,四个按键就可以完成前进后退左右转向,要玩些花哨功能,如原地打转或漂移等,手柄左上右上四个按键很适合,组合按键徒增操控和编码的复杂度。接下来是摇杆功能的设计,一个摇杆就能完成所有常用功能。此时要向EV3发送坐标值XY。按上面的raw值分布表,Y值代表速度,介意0-1023之间,0代表后退最高速度,在EV3里对应马达功率-100,1023是前进最高速度,在EV3里对应+100。很简单,EV3只需将收到的raw值转换成-100到+100就可以了。
同样,坐标X值代表转向,0-1023对应乐高转向功率-100到+100,偏离0功率越大,转向越急:

由于XY是动态值,无法按前面17个按键那样分配固定的值,需要在arduino里用union类型,把XY值转换成32位浮点数:
[code]union data
{ int i;
unsigned char c[4];
float f;
};
union data x;
union data y;[/code]
把XY坐标值赋给x.f、y.f,这样就可以得到坐标值的XY值对应的32位浮点数x.c、y.c,再按二楼的方式拼装一个16进制字符数组,将[font=微软雅黑, Tahoma, Helvetica, SimSun, sans-serif]16进制字符数组发送到EV3上不同名称的mailbox程序块,比如将X坐标的[/font][font=微软雅黑, Tahoma, Helvetica, SimSun, sans-serif]16进制字符数组,发送到EV3中名称为x的[/font][font=微软雅黑, Tahoma, Helvetica, SimSun, sans-serif]mailbox[/font][font=微软雅黑, Tahoma, Helvetica, SimSun, sans-serif],[/font][font=微软雅黑, Tahoma, Helvetica, SimSun, sans-serif]将Y坐标的[/font][font=微软雅黑, Tahoma, Helvetica, SimSun, sans-serif]16进制字符数组,发送到[/font][font=微软雅黑, Tahoma, Helvetica, SimSun, sans-serif]EV3中名称为y的mailbox。蓝牙数据包中,以x078、0x79代替上面的0x61。EV3收到XY坐标后,分别转换成转向功率和速度功率。[/font][font=微软雅黑, Tahoma, Helvetica, SimSun, sans-serif]
[/font]注意由于摇杆XY值分布不均匀,中间值并非1023/2,需要在EV3程序里分两段进行raw值到功率的转换。
未完待续。。。。。。
dsweiliang
dsweiliang
楼主加油更新啊
taelons
taelons
作者
接下来上传DFR提供的手柄按键检测程序,arduino ide里执行无误,串口监视界面里能显示按下了哪个键。14个键连接到arduino的数字口,低电平0表示按下,从串口监视器和代码里很容易看出。接下来要确定摇杆不同位置的键值分布(姑且称之为raw值),我不懂电路,摇杆是电位器,其raw值应该是模拟的电压值转换成数字值。为方便辨识,将程序中的延迟加大,经多次运行代码,记录如下摇杆raw值分布:

由于乐高EV3使用特有的蓝牙数据包格式,为方便在蓝牙主从两端的程序中处理,我将17个按键按1-17编号,发送给EV3,EV3解包后,根据收到的数字,在EV3程序中做相应的处理,如前进后退转向加减速等等。数据包格式如下图:

在arduino里,如何发送蓝牙数据包给EV3呢?请看下面程序片断,修改了DFR的按键检测程序:
[code]unsigned char hexS2[15] = {0x0d,0x00,0x00,0x00,0x81,0x9e,0x02,0x61,0x00,0x40,0x00,0x00,0x00,0x60,0x41};
unsigned char hexS1[15] = {0x0d,0x00,0x00,0x00,0x81,0x9e,0x02,0x61,0x00,0x40,0x00,0x00,0x00,0x50,0x41};
unsigned char hexUP[15] = {0x0d,0x00,0x00,0x00,0x81,0x9e,0x02,0x61,0x00,0x40,0x00,0x00,0x00,0xa0,0x40};
unsigned char hexLEFT[15] = {0x0d,0x00,0x00,0x00,0x81,0x9e,0x02,0x61,0x00,0x40,0x00,0x00,0x00,0xe0,0x40};
unsigned char hexDOWN[15] = {0x0d,0x00,0x00,0x00,0x81,0x9e,0x02,0x61,0x00,0x40,0x00,0x00,0x00,0xc0,0x40};
unsigned char hexRIGHT[15] = {0x0d,0x00,0x00,0x00,0x81,0x9e,0x02,0x61,0x00,0x40,0x00,0x00,0x00,0x00,0x41};
unsigned char hex1[15] = {0x0d,0x00,0x00,0x00,0x81,0x9e,0x02,0x61,0x00,0x40,0x00,0x00,0x00,0x80,0x3f};
unsigned char hex4[15] = {0x0d,0x00,0x00,0x00,0x81,0x9e,0x02,0x61,0x00,0x40,0x00,0x00,0x00,0x80,0x40};
unsigned char hex2[15] = {0x0d,0x00,0x00,0x00,0x81,0x9e,0x02,0x61,0x00,0x40,0x00,0x00,0x00,0x00,0x40};
unsigned char hex3[15] = {0x0d,0x00,0x00,0x00,0x81,0x9e,0x02,0x61,0x00,0x40,0x00,0x00,0x00,0x40,0x40};
unsigned char hexRZ1[15] = {0x0d,0x00,0x00,0x00,0x81,0x9e,0x02,0x61,0x00,0x40,0x00,0x00,0x00,0x30,0x41};
unsigned char hexRZ2[15] = {0x0d,0x00,0x00,0x00,0x81,0x9e,0x02,0x61,0x00,0x40,0x00,0x00,0x00,0x40,0x41};
unsigned char hexLZ1[15] = {0x0d,0x00,0x00,0x00,0x81,0x9e,0x02,0x61,0x00,0x40,0x00,0x00,0x00,0x10,0x41};
unsigned char hexLZ2[15] = {0x0d,0x00,0x00,0x00,0x81,0x9e,0x02,0x61,0x00,0x40,0x00,0x00,0x00,0x20,0x41};
unsigned char hexJ1[15] = {0x0d,0x00,0x00,0x00,0x81,0x9e,0x02,0x61,0x00,0x40,0x00,0x00,0x00,0x70,0x41};
unsigned char hexJ2[15] = {0x0d,0x00,0x00,0x00,0x81,0x9e,0x02,0x61,0x00,0x40,0x00,0x00,0x00,0x80,0x41};
void printData(){
for(int i = 0; i < 17; i++) Serial.print(buttonState),Serial.print(" ");
for(int i = 0; i < 4; i++) Serial.print(joystick),Serial.print(" ");
for(int i = 0; i < 2; i++) Serial.print(AnalogButton),Serial.print(" ");
Serial.println("");
Serial.print("Button Pressed:");
for(int i = 0; i < 2; i++)
{
if(buttonState < 100)
{
Serial.print(Buttons),Serial.print(",");
if ( i == 0 )
Serial1.write(hexJ2,15);
else
Serial1.write(hexJ1,15);
}
}
for(int i = 3; i < 17; i++)
if(buttonState == 0)
{
Serial.print(Buttons);
Serial.print(",");
switch (i)
{
case 3:
Serial1.write(hexS2,15);
break;
case 4:
Serial1.write(hexS1,15);
break;
case 5:
Serial1.write(hexUP,15);
break;
case 6:
Serial1.write(hexLEFT,15);
break;
case 7:
Serial1.write(hexDOWN,15);
break;
case 8:
Serial1.write(hexRIGHT,15);
break;
case 9:
Serial1.write(hex1,15);
break;
case 10:
Serial1.write(hex4,15);
break;
case 11:
Serial1.write(hex2,15);
break;
case 12:
Serial1.write(hex3,15);
break;
case 13:
Serial1.write(hexRZ1,15);
break;
case 14:
Serial1.write(hexRZ2,15);
break;
case 15:
Serial1.write(hexLZ1,15);
break;
case 16:
Serial1.write(hexLZ2,15);
}
}
Serial.println("");
Serial.print("Analog Sticks:");
for(int i = 0; i < 4; i++) Serial.print(joystick),Serial.print(",");
Serial.println("---");
for(int i = 0; i < 2; i++) Serial.print(AnalogButton),Serial.print(",");
Serial.println("");
Serial.println("");
}[/code]
[i][i][i][i][i][i][i][i]
EV3程序里,用一个循环加一个名称为a,读取数字的mailbox块,就可以得到arduino发来的蓝牙按键对应的数字了。当然,事先要在EV3液晶屏里进行蓝牙配对,或程序里配对,应该能看到一个名为“bluetooth_xbee“的设备,就是手柄里的蓝牙模块了。
[/i][/i][/i][/i][/i][/i][/i][/i][i][i][i][/i][/i][/i]
[i][i][i][i][i][i][i][i]未完待续。。。。。。
[/i][/i][/i][/i][/i][/i][/i][/i]
- 没有更多了 -