宜昌老张

任天堂Wii手柄遥控慧鱼车

0
阅读(4136)

 

    Wii 是日本任天堂公司(nintendo)2006年11月19日所推出的第5代家用游戏主机,是GameCube的后续机种。其特点是前所未有的体感控制器操作,怀旧游戏下载和待机网络连线功能(WiiConnect24)。

    任天堂Wii系统,包含主机,专用感应器和左手控制器NunChuck 、右手控制器Wii Remote,也就是国内俗称的“双节棍手柄”,一左一右遥控器都内置了3轴重力加速度传感器,通过蓝牙与主机通信。

    无线和动作感应是Wii系统提供了一种直观而自然的游戏操作方式。通过双手挥动左右手柄,可以面对银幕,感受拳击,冲浪甚至驾驶飞机的感受。

    您手握Wii手柄,面对屏幕数位世界的动漫,一定玩得很嗨!那么能不能用Wii手柄操控物理世界的机器人呢?是不是也很有趣。应该是的,而且现在有办法了,可以利用Arduino系统,来完成操控机器人的项目。

    这是用Wii左手柄NunChuck,来遥控慧鱼车的实验照片和视频。

实验照片:

实验视频:

     实验用的三轮慧鱼车,前面是一个万向轮,后面两个是主动轮,由两个直流电机带动,通过两个电机的转速和转向的变化实现小车的前后、左右的行走,小车的前方还有一个车灯,天黑时,可以照亮周围活动场地。看看慧鱼的底盘结构。

 

   如果您已经具备了Arduino控制器和DFRobot公司的 Arduino Xbee传感器扩展板V5 、APC220无线通信模块以及Wii的“鸡腿”NunChuck手柄和直流电机驱动的小车,另外还需要一硬一软两个利器,一是Wii Nunchuck 转换器,二是WiiChuck库文件。

    APC220无线通信模块的使用方法见我的博客文章《双Arduino控制器之间的无线通讯实验》:http://blog.chinaaet.com/detail/25849.html

 

这个WiiChuck转换器的购买地址:http://item.taobao.com/item.htm?id=5474710217&

Wii“鸡腿”Nunchuck手柄的购买地址:http://item.taobao.com/item.htm?id=7538287788

    Wii手柄、WiiChuck转换器与Arduino三者之间连接非常简单,先把WiiChuck转换器插到Wii Nunchuck手柄接口上(注意正反),然后再把WiiChuck的c、d、+、-,插到Arduino Xbee传感器扩展板V5的模拟量接口5,4,3,2上就可以了。为什么要把WiiChuck转换器插到传感器扩展板上,而不直接插到Arduino控制板上,是因为这个项目需要APC220无线通信模块,而APC220模块可以方便地插到扩展板专用APC插槽中,所以要先把扩展板层叠在控制板上,再在扩展板上插入无线模块和WiiChuck转换器,这样它们可以集成在一起,方便遥控操作。如下图:


WiiChuck库文件在这里下载:4274969033205.zip

     您可以将zip文件下载并解压缩后,复制到您的Arduino安装目录下的libraries文件夹里面,如图。

    然后您的Arduino编程环境,菜单栏Sketch→Import Library...里,就可以看到WiiChuck库文件了。

     现在有了Arduino系统、Wii“鸡腿”手柄、Wii Nunchuck 转换器和WiiChuck库文件,那就编写一个“鸡腿”手柄数据采集测试程序,在Arduino串口监控窗口,看看动作手柄上的各部件,采集到的对应数据有何变化。

    看下面测试程序的注释以及Arduino串口监控窗口的数据变化,应该可以了解到哪一个命令,对应采集手柄中哪个部件数据,例如:wii.getAccelAxisY()是手握Wii手柄,前倾或后仰时三轴加速度感应的Y轴数据采集命令,Y轴数据是在监控窗口的“accel:121,115,185”的第二列。

 

//加入头文件
#include <math.h>
#include <stdlib.h>
#include "Wire.h"
#include "WiiChuck.h"
//定义wii为WiiChuck类变量
WiiChuck wii = WiiChuck();
//初始化
void setup()
{
 wii.initWithPower(); 
 Serial.begin(9600);
}
//主程序
void loop() 
{
  static int count = 0;

  if (true == wii.read()) {
    Serial.print(count, DEC);
    Serial.print("\t");
    //Wii手柄中的摇杆左右摇动为X轴,前后摇动为Y轴
    Serial.print("joystick:");
    Serial.print(wii.getJoyAxisX(), DEC);
    Serial.print(",");
    Serial.print(wii.getJoyAxisY(), DEC);
    Serial.print(" \t");
    //手握Wii手柄,手腕向右或向左拧动为三轴加速度感应的X轴
    Serial.print("accel:");
    Serial.print(wii.getAccelAxisX(), DEC);
    Serial.print(",");
    //手握Wii手柄,前倾或后仰为三轴加速度感应的Y轴
    Serial.print(wii.getAccelAxisY(), DEC);
    Serial.print(",");
    Serial.print(wii.getAccelAxisZ(), DEC);
    Serial.print(" \t");
    //按动手柄前端面的“Z”或“C”按钮
    Serial.print("button:");
    Serial.print(wii.getButtonZ(), DEC);
    Serial.print(",");
    Serial.print(wii.getButtonC(), DEC);

    Serial.println(" ");
    count ++;
  }  
  delay(1000);
}

观察Arduino串口监控窗口的数据变化。

    如何把手柄中某些部件数据进行处理,通过无线通信,向慧鱼车发出命令,让小车前后左右行走,和开关车灯?我举例来说明,手柄前倾时,三轴加速度感应的Y轴数据如果大于155,则向小车发出前进命令;手柄后仰时,三轴加速度感应的Y轴数据如果小于115,则向小车发出后退命令。

 

与WII手柄手柄相连的遥控器Arduino主机程序:

/*Wii手柄使用说明:

手握Wii手柄,前倾或后仰,发出小车前进或者后退命令;
手握手柄,手腕向左或向右拧动手柄,发出小车左转或右转命令;
手握手柄居中不动,则小车不动;
按动Wii手柄前端的Z按键,开关车灯。*/

//加入头文件
#include <math.h>
#include <stdlib.h>
#include "Wire.h"
#include "WiiChuck.h"
//定义wii为WiiChuck类变量
WiiChuck wii = WiiChuck();

char flag;//存储遥控器主机向遥控车上的从机发送“标志”数据
int val;//存储Wii的Z按键的当前读取值
int old_val;//存储Wii的Z按键上次程序执行时的读取值
int state=0;//存储主机向遥控车上的LED灯发送的亮灭状态
//初始化
void setup()
{
  wii.initWithPower(); 
  Serial.begin(9600); // 启动串口通信,通信波特率为9600 bps
}
//主程序
void loop()
{
    if (wii.read() == true) 
    {            
        //如果手握Wii手柄,并使它前倾
        if(wii.getAccelAxisY()>155)
        {
           flag='a';
           Serial.print(flag);//向遥控车从机发送小车前进命令
        }
        //如果手握Wii手柄,并使它后仰
        else if(wii.getAccelAxisY()<115)
        {
           flag='b';
           Serial.print(flag);//向遥控车从机发送小车后退命令
        }
        //如果手握Wii手柄,手腕向左拧动手柄
        else if(wii.getAccelAxisX()<95)
        {
           flag='c';
           Serial.print(flag);//向遥控车从机发送小车向左命令
        }
        //如果手握Wii手柄,手腕向右拧动手柄
        else if(wii.getAccelAxisX()>155)
        {
           flag='d';
           Serial.print(flag);//向遥控车从机发送小车向右命令
        }
        //否则
        else
        {
           flag='e';
           Serial.print(flag);//向遥控车从机发送小车停止命令
        }
        //读取Wii手柄的Z按键数字量信息
        //按下Z按键,遥控车上的LED亮,
        //再按一次Z按键,遥控车上的LED灭,以此往复
        val=wii.getButtonZ();
        if((val==0)&&(old_val==1))
        {
          state=1-state;
          delay(10);
        }
        old_val=val;
        if(state==1)
        {
           flag='f';
           Serial.print(flag);//向从机发送灯亮标志
        }
        else
        {
          flag='g';
          Serial.print(flag);//向从机发送灯灭标志
        }
        delay(50); 
    }
}
 
遥控车从机程序:
 
    见《《Arduino开发实战指南》与慧鱼遥控车》一文中,慧鱼车从机程序。网址:http://blog.chinaaet.com/detail/25929.html
 
    Wii NunChuck“鸡腿”手柄和Arduino配合还可以制作出更多更炫的作品,我在优酷搜索到两个视频,大家不妨看看。