Arduino Pro Micro 实现游戏手柄Joysticks

概述

国内网络上关于手柄制作的资料感觉特别的少,最近参加华东交通大学校电赛,其中一个题目是运用单片机制作游戏手柄,所以我打算用atmega32u4单片机运用arduino的ide来实现这些功能。下面的参考链接是我能找到的最符合要求的项目,但是这其中有很多的问题,我先把实现的流程和大家说,出现的问题我留在文章末尾。

参考链接

实现过程

用到的元件:

Arduino Pro Micro * 1
5个引脚的PS2游戏手柄 * 2
轻触按键 * 16
5mm绿色LED * 1
5mm蓝色LED * 1
220Ω电阻 * 2

Arduino IDE的配置

点击Tools > the Board selection tab > Boards Manager.

project-image

找到SparkFun AVR Boards package并下载

请添加图片描述

选择Sparkfun Pro Micro

project-image

在arduino官网下载Keypad库并安装

https://www.arduino.cc/reference/en/libraries/keypad/

引脚连接方式:

//                                左摇杆
// A0  --------------------------- VRX
// A1  --------------------------- VRY
// D14 --------------------------- SW
// 5V  --------------------------- 5V
// GND --------------------------- GND
//                                右摇杆
// A2  --------------------------- VRX
// A3  --------------------------- VRY
// D16 --------------------------- SW
// 5V  --------------------------- 5V
// GND --------------------------- GND
//                                4X4矩阵键盘
// D2  --------------------------- C1
// D3  --------------------------- C2
// D4  --------------------------- C3
// D5  --------------------------- C4
// D6  --------------------------- R1
// D7  --------------------------- R2
// D8  --------------------------- R3
// D9  --------------------------- R4
//                                字符键盘指示灯
// D15 --------------------------- +
//                                数字键盘指示灯
// D10 --------------------------- +

矩阵键盘的连接方式

请添加图片描述

实现的代码

#include <Keypad.h>
#include "Keyboard.h"
#include "Mouse.h"

const byte ROWS = 4; // four rows
const byte COLS = 4; // four columns

// Define the symbols on the buttons of the keypads.
char letterKeys[ROWS][COLS] = {
  {'e','a','r','i'},
  {'o','t','n','s'},
  {'p','m','h','w'},
  {'l','c','u','d'}
};

char numberKeys[ROWS][COLS] = {
  {'1','2','3','+'},
  {'4','5','6','-'},
  {'#','0','*','%'},
  {'7','8','9','/'}

};

byte rowPins[ROWS] = {6, 7, 8, 9}; // Connect to the row pinouts of the keypad.
byte colPins[COLS] = {2, 3, 4, 5}; // Connect to the column pinouts of the keypad.

// Initialize an instance of class NewKeypad for each keypad setting - letter and number.
Keypad letterKeypad = Keypad( makeKeymap(letterKeys), rowPins, colPins, ROWS, COLS);
Keypad numberKeypad = Keypad( makeKeymap(numberKeys), rowPins, colPins, ROWS, COLS);

// Define pinouts of joysticks.
#define VRX_L A0
#define VRY_L A1
#define SW_L 14
#define VRX_R A2
#define VRY_R A3
#define SW_R 16

// Define keypad LED pins:
#define let_LED 15
#define num_LED 10

// Define dynamic keypad options - letter and number.
volatile boolean letter = true;
volatile boolean number = false; 

// Define the data holders:
int joystick_left_x, joystick_left_y, joystick_left_button, joystick_right_x, joystick_right_y, joystick_right_button;

void setup() {
  Serial.begin(9600);

  // Initialize mouse and keyboard control:
  Mouse.begin();
  Keyboard.begin();

  // Joystick button settings:
  pinMode(SW_L, INPUT);
  digitalWrite(SW_L, HIGH);
  pinMode(SW_R, INPUT);
  digitalWrite(SW_R, HIGH);

  // Keypad LEDs:
  pinMode(let_LED, OUTPUT);
  digitalWrite(let_LED, HIGH);
  pinMode(num_LED, OUTPUT);
  digitalWrite(num_LED, LOW);
}

void loop() {
  // Read joystick positions:
  read_joysticks();

  // Mouse:
  mouse_controls();

  // Keyboard:
  keyboard_controls();

}

void read_joysticks(){
  joystick_left_x = analogRead(VRX_L); 
  joystick_left_y = analogRead(VRY_L);
  joystick_left_button = digitalRead(SW_L);
  
  joystick_right_x = analogRead(VRX_R); 
  joystick_right_y = analogRead(VRY_R);  
  joystick_right_button = digitalRead(SW_R);

  /*
  Serial.print(joystick_right_x);
  Serial.print("\t");
  Serial.print(joystick_right_y);
  Serial.print("\t\t");
  Serial.print(joystick_right_button);
  Serial.print("\n\n");
  */
}

void mouse_controls(){
  // Move mouse according to the left joystick movements.
  if(joystick_left_y > 700)  Mouse.move(0, -15); // UP
  if(joystick_left_y < 300)  Mouse.move(0, 15);  // DOWN
  if(joystick_left_x > 700)  Mouse.move(-15, 0); // LEFT
  if(joystick_left_x < 300)  Mouse.move(15, 0);  // RIGHT
  if(joystick_left_button == 0) Mouse.click(MOUSE_LEFT); // LEFT CLICK
  if(joystick_right_button == 0) Mouse.click(MOUSE_RIGHT); // RIGHT CLICK
  delay(100);
}

void keyboard_controls(){
  // Change keypad settings (letter or number) and press modifier keys according to the right joystick movements.
  if(joystick_right_y > 700){ Keyboard.press(KEY_RETURN); delay(100); Keyboard.releaseAll(); }    // RETURN
  if(joystick_right_y < 300){ Keyboard.press(KEY_BACKSPACE); delay(100); Keyboard.releaseAll(); } // BACKSPACE
  if(joystick_right_x > 700){ letter = true; number = false; digitalWrite(let_LED, HIGH); digitalWrite(num_LED, LOW); } // Letter Keypad
  if(joystick_right_x < 300){ letter = false; number = true; digitalWrite(let_LED, LOW); digitalWrite(num_LED, HIGH); } // Number Keypad
  
  // Get the custom key depending on the selected keypad type - letter or number.
  char customKey;
  if(letter == true) customKey = letterKeypad.getKey();
  if(number == true) customKey = numberKeypad.getKey();
  
  // Write the custom key.
  if (customKey){
    Keyboard.write(customKey);
  }
}

存在的问题

如果你只是跟着上面的步骤去制作的话,你会发现根本大不了游戏,因为键盘没有接地,单片机无法扫描,代码的倒数第九行的getkey()只会触发一次。但是启用引脚的pull up功能,然后把按键独立接地,这些功能就可以实现了,经过我几个夜晚的调试,最终完成了以下代码:

#include <Key.h>
#include <Keypad.h>

#include <Mouse.h>

#include <Keyboard.h>

#define VRX_L A0
#define VRY_L A1
#define SW_L 14
#define VRX_R A2
#define VRY_R A3
#define SW_R 16


#define let_LED 15
#define num_LED 10

char KeyboardNum[8] = {0};

char KeyboardNum_1[8] = {  
  'q',
  'w',
  'e', 
  'r',
  'a',  
  's',
  'd',
  ' ',
  };

char KeyboardNum_2[8] = {  
  'y',
  'u',
  'i', 
  'o',
  'h',  
  'j',
  'k',
  'l',
  };
  
int joystick_left_x, joystick_left_y, joystick_left_button, joystick_right_x, joystick_right_y, joystick_right_button;

void setup() {
  Serial.begin(9600);

  Mouse.begin();
  Keyboard.begin();

  // Joystick button settings:
  pinMode(SW_L, INPUT);
  digitalWrite(SW_L, HIGH);
  pinMode(SW_R, INPUT);
  digitalWrite(SW_R, HIGH);

  // Keypad LEDs:
  pinMode(let_LED, OUTPUT);
  digitalWrite(let_LED, HIGH);
  pinMode(num_LED, OUTPUT);
  digitalWrite(num_LED, LOW);

  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
}

void loop() {
  // joystick positions:
  read_joysticks();

  // Mouse:
  mouse_controls();

  // Keyboard:
  keyboard_controls();

}

void read_joysticks(){
  joystick_left_x = analogRead(VRX_L); 
  joystick_left_y = analogRead(VRY_L);
  joystick_left_button = digitalRead(SW_L);
  
  joystick_right_x = analogRead(VRX_R); 
  joystick_right_y = analogRead(VRY_R);  
  joystick_right_button = digitalRead(SW_R);

  /*
  Serial.print(joystick_right_x);
  Serial.print("\t");
  Serial.print(joystick_right_y);
  Serial.print("\t\t");
  Serial.print(joystick_right_button);
  Serial.print("\n\n");
  */
}

void mouse_controls(){
  if(joystick_left_y > 700)  Mouse.move(-15,0); // UP
  if(joystick_left_y < 300)  Mouse.move(15,0);  // DOWN
  if(joystick_left_x > 700)  Mouse.move(0,15); // LEFT
  if(joystick_left_x < 300)  Mouse.move(0,-15);  // RIGHT
  if(joystick_left_button == 0) Mouse.click(MOUSE_LEFT); // LEFT CLICK
  if(joystick_right_button == 0) Mouse.click(MOUSE_RIGHT); // RIGHT CLICK
}

void keyboard_controls(){
  if(joystick_right_y > 700){ Keyboard.press(KEY_RETURN); delay(100); Keyboard.releaseAll(); }    // RETURN
  if(joystick_right_y < 300){ Keyboard.press(KEY_BACKSPACE); delay(100); Keyboard.releaseAll(); } // BACKSPACE
  if(joystick_right_x > 700){  
    digitalWrite(let_LED, HIGH); 
    digitalWrite(num_LED, LOW); 
     for(int i=0;i<8;i++)
     KeyboardNum[i] = KeyboardNum_1[i] ;
  } // Letter Keypad  
  if(joystick_right_x < 300){ 
    digitalWrite(let_LED, LOW); 
    digitalWrite(num_LED, HIGH); 
    for(int i=0;i<8;i++)
     KeyboardNum[i] = KeyboardNum_2[i] ;
  } // Number Keypad
  
  if(digitalRead(2) == LOW) {Keyboard.press(KeyboardNum[0]);}
  if(digitalRead(2)==HIGH){Keyboard.release(KeyboardNum[0]);} 
  if(digitalRead(3) == LOW) {Keyboard.press(KeyboardNum[1]);}
  if(digitalRead(3)==HIGH){Keyboard.release(KeyboardNum[1]);}
  if(digitalRead(4) == LOW) {Keyboard.press(KeyboardNum[2]);}
  if(digitalRead(4)==HIGH){Keyboard.release(KeyboardNum[2]);}
  if(digitalRead(5) == LOW) {Keyboard.press(KeyboardNum[3]);}
  if(digitalRead(5)==HIGH){Keyboard.release(KeyboardNum[3]);}
  if(digitalRead(6) == LOW) {Keyboard.press(KeyboardNum[4]);}
  if(digitalRead(6)==HIGH){Keyboard.release(KeyboardNum[4]);}
  if(digitalRead(7) == LOW) {Keyboard.press(KeyboardNum[5]);}
  if(digitalRead(7)==HIGH){Keyboard.release(KeyboardNum[5]);}
  if(digitalRead(8) == LOW) {Keyboard.press(KeyboardNum[6]);}
  if(digitalRead(8)==HIGH){Keyboard.release(KeyboardNum[6]);}
  if(digitalRead(9) == LOW) {Keyboard.press(KeyboardNum[7]);}
  if(digitalRead(9)==HIGH){Keyboard.release(KeyboardNum[7]);}
}

使用以上代码时,按键相对独立,8个按键分别由8个引脚控制。

成品图:

请添加图片描述

Arduino Pro Mini是一款小型的Arduino开发板,它可以用来制作游戏手柄。根据引用\[1\]中的参考链接,制作Arduino Pro Mini手柄的过程需要以下元件:Arduino Pro Micro、PS2游戏手柄、轻触按键、LED灯和电阻。你可以使用Arduino IDE来配置Arduino Pro Mini开发板。 根据引用\[2\]中的参考链接,国内关于手柄制作的资料相对较少。但是你可以参考华东交通大学校电赛的相关项目,使用atmega32u4单片机Arduino IDE来实现手柄功能。在参考链接中可能会遇到一些问题,你可以在文章末尾找到解决方法。 如果你已经拿到了Arduino Pro Mini手柄,并且正确安装了Arduino Pro Micro开发板驱动,你可以将手柄连接到电脑。在设备管理器中,你应该能够看到Arduino Pro Micro开发板的显示。这意味着手柄已经成功连接到电脑,并且可以使用其中的按键和摇杆功能来畅玩大部分游戏。\[3\] #### 引用[.reference_title] - *1* *2* [Arduino Pro Micro 实现游戏手柄Joysticks](https://blog.csdn.net/weixin_50459779/article/details/121319822)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [基于Arduino Pro Micro游戏手柄制作](https://blog.csdn.net/mcu_fang/article/details/128614994)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值