Gamepad inalámbrico
Introducción
El objetivo de este proyecto es construir un mando de juego inalámbrico para jugar en dispositivos móviles y ordenadores a través de Bluetooth. Para ello, necesitamos utilizar una placa que nos ofrezca conexión Bluetooth. Una opción es utilizar la placa ESP32. Existen diferentes modelos, cualquiera de ellos nos vale.
Materiales comprados
Componente | Precio |
Placa de Arduino WIFI ESP WROOM 32 30 pin 2 uds. | 6,48€ |
Batería USB + cable micro USB. | – |
Caja de botones 56 uds. | 5,20 € |
Joystick 3 uds. | 1,55 € |
Cables de puente sin soldadura (140uds). | 1,60€ |
Total: | 14,83€ |
Materiales utilizados
- Protoboard.
- Placa de Arduino WIFI ESP WROOM 32 30 pin.
- Batería USB + cable micro USB.
- Botón x 4.
- Joystick x 1.
- Cable Dupont x 4.
- Cable de puente sin soldadura x 10.
- Resistencias 5kΩ x 4.
Circuito
Código
#include <Arduino.h>
#include <BleGamepad.h>
//Botones ABXC
#define A_BUTTON 22
#define B_BUTTON 19
#define X_BUTTON 23
#define C_BUTTON 21
#define NUM_BUTTONS 4
/*
* Controles
* {A=1, B=2, C=3, X=4, Y=5, Z=6, L1=7, R1=8, L2=9, R2=10,
* Select=11, Start=12, PS=13, L3=14 , R3=15}
*
*/
int buttonsPins[NUM_BUTTONS] = {X_BUTTON, A_BUTTON, C_BUTTON, B_BUTTON};
// El orden de este array es el que está en buttonPins
int PCGamepadButtons[NUM_BUTTONS] = {4, 1, 3, 2};
// Joystick
#define VRX_JOYSTICK 15
#define VRY_JOYSTICK 4
// Joystick
uint16_t VrxJoystickLecture = 0;
uint16_t VryJoystickLecture = 0;
uint16_t VrxJoystickValue = 0;
uint16_t VryJoystickValue = 0;
typedef enum{ PC } GamepadModes;
GamepadModes gamepadMode = PC;
BleGamepad bleGamepad("Gamepad", "Home");
BleGamepadConfiguration bleGamepadConfig;
void setup() {
delay(1000);
Serial.begin(115200);
// Se pueden quitar las resistencias por INPUT_PULLUP
for(int i = 0; i < NUM_BUTTONS; i++){
pinMode(buttonsPins[i], INPUT);
}
// Configuración básica del gamepad
bleGamepadConfig.setAutoReport(false);
bleGamepadConfig.setControllerType(CONTROLLER_TYPE_GAMEPAD);
bleGamepadConfig.setVid(0xe502);
bleGamepadConfig.setPid(0xabcd);
bleGamepadConfig.setHatSwitchCount(4);
bleGamepad.begin(&bleGamepadConfig);
}
void loop() {
if(bleGamepad.isConnected()){
//Lectura de joysticks
VrxJoystickLecture = analogRead(VRX_JOYSTICK);
VryJoystickLecture = analogRead(VRY_JOYSTICK);
//Valor de joysticks
VrxJoystickValue = map(VrxJoystickLecture, 4095, 0, 0, 32737);
VryJoystickValue = map(VryJoystickLecture, 0, 4095, 0, 32737);
for(int i = 0; i < NUM_BUTTONS; i++){
// Si se han quitado las resistencias, quitar la !
if(!digitalRead(buttonsPins[i])){
bleGamepad.press(PCGamepadButtons[i]);
}
else{
bleGamepad.release(PCGamepadButtons[i]);
}
joysticksHandler(VrxJoystickValue, VryJoystickValue);
}
bleGamepad.sendReport();
}
}
void joysticksHandler(uint16_t leftVrx, uint16_t leftVry){
bleGamepad.setX(VrxJoystickValue);
bleGamepad.setY(VryJoystickValue);
}
Funcionamiento
Después de montar el circuito e implementar el código, para probar el proyecto debemos probar por separado el dispositivo móvil y el ordenador. Para probar en móvil podemos utilizar la aplicación gratuita de Android GamePad Tester (nota: para jugar necesitamos un emulador como Octopus para asignar los botones a la pantalla) y para probar en ordenador podemos probar desde la página: https://hardwaretester.com/gamepad.
Problemas encontrados
No se pueden jugar a todos los juegos capacitados para mando, probablemente debido a que faltan botones que cubran todos los controles.
Por el espacio que ocupan los botones, no se pueden poner dos en línea.
Hola. Excelente proyecto, pero no consigo hacerlo funcionar ni en PC ni en Android. Aunque el PC lo reconoce como conectado, el programa no ejecuta el loop porque » if(bleGamepad.isConnected()» devuelve «false», es decir, el ESP32 no recibe confirmación de estar conectado. Si elimino » if(bleGamepad.isConnected()» el bucle se ejecuta y lee los valores del joystick pero no los transmite al PC.. Si alguien puede ayudarme lo agradecería enormemente. Gracias