极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 20056|回复: 10

自制天猫机顶盒游戏手柄遥控器

[复制链接]
发表于 2016-6-16 20:20:21 | 显示全部楼层 |阅读模式
自制天猫机顶盒游戏手柄遥控器
这是我的第一个作品,最真实的感慨是,拿来模块测试是一回事,真是做个成品,过程是很曲折的,先来说下体验过程,供大家参考。
一天,看到儿子拿着遥控器玩游戏,就一个手在操作,感觉很麻烦,就突发奇想,要制作个游戏手柄遥控器。
一、第一次搜索,看到了“使用IRremote库红外遥控家里的电器”的文章(网址http://www.arduino.cn/thread-3618-1-1.html
),按照下列网站提示,使用提取遥控器编码的方法读取了获取红外原始编码。
二、编写程序,测试游戏手柄及单按键(确认键)(用的的低电平触发,感觉低电平保险),成功,制作框架模型,安装。
三、加了个返回键,在使用过程中发现,确认和返回经常发生交叉出现,不是想要的按键。
四、无聊翻翻例程,偶尔发现本库带的测试程序:test2,经测试发现遥控器类型为NEC,这下问题简单了,可以直接调用sendNEC发生代码,不用再定义漫长的原始编码了,节省了好多变量运行空间。
五、修改程序后,还是出现上述问题,测量发现,几个数字端口的电压飘忽不定,琢磨了琢磨,最后想加个上拉电阻,直接把端口弄成高电平(未触发时),后来发现一个参数(把输入参数INPUT,改为INPUT_PULLUP),可以启用内部的上拉电阻,修改程序后,一切正常。
参考网址:http://www.geek-workshop.com/thread-2874-1-1.html
六、关于端口的选择,有几个键用万用表量着不加负载为低,有几个却为高,选低的那几个不知道为什么不行,而选高的却可以,希望找到这一问题解决方法的老师们告诉一声,谢谢
七、最后加上了4*4键盘阵列(这得益于test2程序,省了好多空间),这一可以把好多键的功能加上去,扔掉其他遥控器就成了现实。
八、接线方式:红外发射接3,确认接7,返回接9(这两个键是在调试的时候试着接上去的,后来也没改,只要是在第六条为高的都行),最后是键盘阵列接12, 11, 10, 8,6, 5, 4, 2。
九、对游戏手柄,X接模拟0口,Y接模拟1口
下面附上程序
//游戏摇杆控制机顶盒
//程序中XY坐标已经过换算,以游戏杆的初始位置为(0,0),即中心位置
//程序中仅 发送但指令,以转弯优先,当判断为转弯状态时,仅发送转弯指令
//                      |  y值小于-500时,向上
//                      +  -500
//                      |
//                      |
//                      +  -200   y值在20和-500之间时,不发送指令
//                      |
//                      |
//-------+--------------0----------------+----------
//    -500              |              500   x值小于-500时向左; x值大于500时,向右。
//                      |
//                      +  200   y值在20和500之间时,不发送指令
//                      |
//                      |
//                      +  500
//                      |       y值大于500时,向下
//X接模拟0口,Y接模拟1口
//
#include <IRremote.h>
#include <Keypad.h>
int FirstShotX = 0;
int FirstShotY = 0;
int x = 0;
int y = 0;

//++++++++++++++++++++以下定义按键特征码
IRsend irsend;
unsigned long left1=0xF9609F;//根据自己遥控器修改,下同
unsigned long right1=0xF9708F;   
unsigned long up1=0xF9C23D;   
unsigned long down1=0xF950AF;   
unsigned long ok1=0xF940BF;  
unsigned long return1=0xF9F20D;  

//++++++++++++++++++++以上定义按键特征码

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//定义键值,可任意,但是下面对应的ASCII码需要更换
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','4'},
  {'5','6','7','8'},
  {'9','A','B','C'},
  {'D','E','F','G'}
};
byte rowPins[ROWS] = {12, 11, 10, 8}; //连接到行数字小键盘的管脚,可更改,
byte colPins[COLS] = {6, 5, 4, 2}; //连接到列数字小键盘的管脚

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);  
void ReadX()//读出X轴坐标
{ int sensorValue = analogRead(A0);
  if (FirstShotX == 0)
  {
    FirstShotX = sensorValue; //先初始化X轴的初始位置
    // Serial.print("X: ");
    // Serial.print(FirstShotX);
    //x=FirstShotX;
  }
  else
  {
    x = sensorValue - FirstShotX;
  }

}
void ReadY()//读出Y轴坐标
{ int sensorValue = analogRead(A1);

  if (FirstShotY == 0)
  {
    FirstShotY = sensorValue; //先初始化Y轴的初始位置
    //Serial.print("| Y: ");
    //Serial.print(FirstShotY);
    //y=FirstShotY;
  }
  else
  {
    y = sensorValue - FirstShotY;
  }

}
void setup()
{
  pinMode(7, INPUT_PULLUP);//连确认按钮,启用内部上拉电阻
  Serial.begin(9600);
  pinMode(9, INPUT_PULLUP);//连返回按钮,启用内部上拉电阻
   
}
void loop()
{
  delay(20);
  ReadX();
  delay(20);
  ReadY();
  delay(20);


  if (x < -500) //向左,为了避免判断误差,区间中间不连续,有断接,下同
  { irsend.sendNEC(left1,32);//根据自己遥控器的类型修改sendNEC命令,下同
    delay(200);
  }
  if (x > 500) //向右
  { irsend.sendNEC(right1,32);
    delay(200);
  }
  if ((y < -500)&(x>-450 & x<450)) //向上
  { irsend.sendNEC(up1,32);
    delay(200);
  }

//  if ((y <= 60  & y >= -450)&(x>-450 & x<450)) //不发送指令
//  {
////    delay(200);
//  }
//  if ((y <= 450  & y >= 60)&(x>-450 & x<450)) //不发送指令
//  {
////    delay(200);
//  }

  if ((y > 500)&(x>-450 & x<450)) //向下
  { irsend.sendNEC(down1,32);
    delay(200);
  }
   
  if (!digitalRead(7)) //当按下按钮时,为低电平,此时发送确认代码
    {
         irsend.sendNEC(ok1,32);
         delay(200);
//          Serial.println(ok1);
         
    }


  if (!digitalRead(9)) //当按下按钮时,为低电平,此时发送返回代码
    {
   irsend.sendNEC(return1,32);
    delay(200);
//    Serial.println(return1);
   
  }
  char customKey = customKeypad.getKey();
   
  if (customKey){
   
switch (customKey)
    {
      case 49://1的ASCII码是49,2的是50,一次类推,电视机电源
        irsend.sendNEC(0xFDB04F,32);//
        delay(200);
        break;
      case 50://电视机TV/AV
        irsend.sendNEC(0xFD48B7,32);
        delay(200);
        break;
      case 51://天猫音量-
        irsend.sendNEC(0xF9BA45,32);
        delay(200);
        break;
      case 52://天猫音量+
        irsend.sendNEC(0xF9FF00,32);
        delay(200);
        break;
      case 53: //电视机音量-
        irsend.sendNEC(0xFDC23D,32);
        delay(200);
        break;
      case 54: //电视机音量+
        irsend.sendNEC(0xFD22DD,32);
        delay(200);
        break;
        //以下自己可以根据需要添加
//      case 55://
//        Serial.println("7777777777777777");
//        break;
//      case 56://
//        Serial.println("8888888888888");
//        break;
//      case 57://
//        Serial.println("999999999999");
//        break;
//      case 65: //
//        Serial.println("AAAAAAAAAAA");
//        break;
//      case 66: //
//        Serial.println("BBBBBBBBBBBBBBB");
//        break;
//      case 67: //
//        Serial.println("CCCCCCCCCCCCCC");
//        break;
//      case 68: //
//        Serial.println("DDDDDDDDDDDDD");
//        break;
//        case 69://
//        Serial.println("EEEEEEEEEEEEEE");
//        break;
//      case 70: //
//        Serial.println("FFFFFFFFFFFFFF");
//        break;
//      case 71: //
//        Serial.println("GGGGGGGGGGGGGG");
//        break;
    }



  }



}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2016-6-17 11:17:33 | 显示全部楼层
楼主 你的外壳不会是自己用裁纸刀裁出来的吧?推荐用电磨 加工难度会降低很多。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-6-18 07:16:23 | 显示全部楼层
darkorigin 发表于 2016-6-17 11:17
楼主 你的外壳不会是自己用裁纸刀裁出来的吧?推荐用电磨 加工难度会降低很多。

嫌电磨弄的粉尘多,就用钢锯锯开后,用小刀答题修了修,小洞是用电钻打的眼,然后用小刀修的,第一个产品,要求不高,见笑了
回复 支持 反对

使用道具 举报

发表于 2016-6-18 11:45:13 | 显示全部楼层
不错不错。敢想敢做是很好的说。

有点丑,你可以好好整理下,用CNC加工个面板啥的,就高大上了。
回复 支持 反对

使用道具 举报

发表于 2016-6-19 19:52:44 | 显示全部楼层
楼主
关于端口的选择,有几个键用万用表量着不加负载为低,有几个却为高,选低的那几个不知道为什么不行,而选高的却可以,希望找到这一问题解决方法的老师们告诉一声,谢谢
你能提供一下是什么情况吗,没有看明白,是按键的问题还是端口?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-6-20 06:29:17 | 显示全部楼层
zjz5717 发表于 2016-6-19 19:52
楼主你能提供一下是什么情况吗,没有看明白,是按键的问题还是端口?

总起来说应该是端口的事,我的具体设想是按下时端口表现为低电平,不按(即端口不接任何东西空载)时为高,在试验中发现发送的不是设定的红外值,有时候不按键也自动发送,后来就量了一下各端口的空载电压,发现有编号低(大概是1-5口)的几个为0.5V左右,编号高(大概是6后面的口)的为2.5V左右,我将按键调到6后面的口,到是不自动发送了,但有时候也不是设定的红外值(我就设了两个键,确认和返回,按确认有时候发返回的红外值,反正依然)后来就拉高了一下,一切正常了。但我将线接到1-5口问题又出来了,我估计1-5口用INPUT_PULLUP参数是拉不高的,如果将这几个口通过一个大电阻接到5V人为硬拉高应该可以,就是嫌麻烦没试。我的表达能力一般,不知道这样说你能不能明白。
回复 支持 反对

使用道具 举报

发表于 2016-6-20 10:24:01 | 显示全部楼层
电钻加电磨的头子,可以割、磨、钻、铣 很方便 之前自己做个银戒指还能抛光
DIY玩家必备啊
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-6-20 11:53:11 | 显示全部楼层
darkorigin 发表于 2016-6-20 10:24
电钻加电磨的头子,可以割、磨、钻、铣 很方便 之前自己做个银戒指还能抛光
DIY玩家必备啊

谢谢,这些东西齐全,就是还没想好怎么处理消除加工过程中的粉尘,我想做个吸尘器或者鼓风机之类的东西把粉尘弄走,只是还没有想好安装在阁楼的哪个位置。
回复 支持 反对

使用道具 举报

发表于 2016-6-20 18:57:45 | 显示全部楼层
sendi123456 发表于 2016-6-20 11:53
谢谢,这些东西齐全,就是还没想好怎么处理消除加工过程中的粉尘,我想做个吸尘器或者鼓风机之类的东西把 ...

理论来讲1-5口的针脚是可以使用INPUT_PULLUP的,官方网站的示例使用的是pin2,可能和使用的主板有关系,你用的是nano?(官网用的nano)
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-6-21 07:31:40 | 显示全部楼层
zjz5717 发表于 2016-6-20 18:57
理论来讲1-5口的针脚是可以使用INPUT_PULLUP的,官方网站的示例使用的是pin2,可能和使用的主板有关系,你 ...

我用的就是nano,我想着也是应该可以,不知道为什么就是不行,可能是主板生产商生产的质量问题,没舍得买原版
回复 支持 反对

使用道具 举报

发表于 2016-6-21 18:52:21 | 显示全部楼层
sendi123456 发表于 2016-6-21 07:31
我用的就是nano,我想着也是应该可以,不知道为什么就是不行,可能是主板生产商生产的质量问题,没舍得买 ...

。。。建议你不加载其他程序,单独测试一下pin口的input 的pullup功能
另外做东西还最好买正版,至少质量有保证,还能保修是不是
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-16 03:51 , Processed in 0.040208 second(s), 21 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表