This article is a guideline on using GamePad/Joystick with Arduino Uno or Arduino Mega because it is a module designed as a shield of both boards. When assembled, you will get 1 cute gamepad as shown in Figure 1. The article explains more about the information of the connection between each device and the GPIO with examples of use. The content about the joystick module can be read from the previous article.
Joystick Shield
The joystick shield is a board that can be put on the Arduino Uno or Arduino Mega of the same form. The condition of the tow is as shown in Figure 1, but for people who like to do it themselves, before buying this shield, we have tried doing it ourselves with different types of microcontrollers until it works at a practical level as shown in Figures 2,3 and 4.
From Figure 5, you can see that this shield consists of a joystick module with 6 push-and-release switches, each with a pull-up circuit. The connection of the module and the switch with the pins of Arduino Uno/Mega is as shown in Figure 5 or the following table.
JoyStick Sheild | Arduino Uno/Arduino Mega GPIO |
---|---|
VrX | A0 |
VrY | A1 |
Joystick SW | D8 |
sw เล็กซ้าย | D7 |
sw เล็กขวา | D6 |
sw ฟ้าซ้าย | D5 |
sw ฟ้าขวา | D3 |
sw เหลืองบน | D2 |
sw เหลืองล่าง | D4 |
Example Code
An example code showing the status of the joystick operation and the status of various switches is as follows, and the result is shown in Figure 6.
/****************************************************************
Joypad Shield
by JarutEx (https://www.jarutex.com)
****************************************************************/
#define VR_X 0
#define VR_Y 1
#define VR_SW 8
#define SW_SELECT 7 // Select
#define SW_START 6 // Start
#define SW_X 5 // blue left
#define SW_Y 2 // yellow top
#define SW_A 4 // yellow bottom
#define SW_B 3 // blue right
#define NUM_SWITCHES 7
uint8_t swPins[NUM_SWITCHES] = {VR_SW, SW_SELECT, SW_START, SW_X, SW_Y, SW_A, SW_B};
uint8_t swStatus[NUM_SWITCHES] = {0, 0, 0, 0, 0, 0, 0}; // 1-pressed, 0-released
uint16_t joy[2] = {0, 0}; // x,y
void doInput() {
joy[0] = analogRead(0);
joy[1] = analogRead(1);
for (int i = 0; i < NUM_SWITCHES; i++) {
swStatus[i] = ((digitalRead(swPins[i])) ? (0) : (1));
}
}
void doShowInfo() {
Serial.print("X: ");
Serial.print(joy[0]);
Serial.print(" Y: ");
Serial.print(joy[1]);
Serial.print(" Sw: ");
for (int i = 0; i < NUM_SWITCHES; i++) {
Serial.print(swStatus[i]);
if (i < (NUM_SWITCHES - 1)) {
Serial.print(":");
}
}
Serial.println();
}
void setup() {
Serial.begin(115200);
for (int i = 0; i < NUM_SWITCHES; i++) {
pinMode( swPins[i], INPUT );
digitalWrite( swPins[i], HIGH );
}
}
void loop() {
doInput();
doShowInfo();
}
In the case of using it with ESP32 as shown in Figure 7, it must be connected from the yellow pin from the top-right side and the sample code is as follows.
/*
* esp32oled + GamePad
* (C) 2021, JarutEx (https://www.jarutex.com)
* 2021-07-06
*/
#include <Arduino.h>
#define PIN_VR_X 36
#define PIN_VR_Y 39
#define PIN_SW_A 2
#define PIN_SW_B 14
#define PIN_SW_C 13
#define PIN_SW_D 15
#define PIN_SW_E 16
#define PIN_SW_F 26
#define MAX_SW 6
uint8_t swPins[MAX_SW] = {PIN_SW_A,PIN_SW_B,PIN_SW_C,PIN_SW_D,PIN_SW_E,PIN_SW_F};
uint8_t swValues[MAX_SW];
uint8_t vrPins[2] = {PIN_VR_X, PIN_VR_Y};
uint16_t vrValues[2];
void setup() {
for (int i=0; i<MAX_SW; i++) {
pinMode( swPins[i], INPUT_PULLUP );
swValues[i] = 1;
}
Serial.begin(9600);
}
void doUpdate() {
for (int i=0; i<MAX_SW; i++) {
swValues[i] = digitalRead( swPins[i] );
}
vrValues[0] = analogRead( vrPins[0] );
vrValues[1] = analogRead( vrPins[1] );
}
void doShow() {
Serial.print(vrValues[0]);
Serial.print(",");
Serial.print(vrValues[1]);
Serial.print(":");
for (int i=0; i<MAX_SW; i++) {
Serial.print(swValues[i]);
if (i<(MAX_SW-1)) {
Serial.print("/");
}
}
Serial.println();
}
void loop() {
doUpdate();
doShow();
delay(250);
}
An example of use with an ESP32 connected to various buttons, there is a code as follows.
# Joystick module + ESP32 + MicroPython
# By JarutEx (https://www.jarutex.com)
from machine import Pin, ADC
import time
import machine as mc
import gc
gc.collect()
gc.enable()
mc.freq(240000000)
vrx = ADC(Pin(36, Pin.IN))
vrx.atten(ADC.ATTN_11DB) #Full range: 3.3v
vry = ADC(Pin(39, Pin.IN))
vry.atten(ADC.ATTN_11DB) #Full range: 3.3v
swPins = [
Pin(2, Pin.IN, Pin.PULL_UP), # A
Pin(14, Pin.IN, Pin.PULL_UP), # B
Pin(13, Pin.IN, Pin.PULL_UP), # C
Pin(15, Pin.IN, Pin.PULL_UP), # D
Pin(16, Pin.IN, Pin.PULL_UP), # E
Pin(26, Pin.IN, Pin.PULL_UP) #f
]
vrxValue = 0
vryValue = 0
swValue = [1,1,1,1,1,1]
def doUpdate():
global vrxValue, vryValue, swValue
vrxValue = vrx.read()
vryValue = vry.read()
for i in range(6):
swValue[i] = swPins[i].value()
def doShow():
print("({},{}):A{}/B{}/C{}/D{}/E{}/F{}".format(
vrxValue,vryValue,
swValue[0],swValue[1],swValue[2],
swValue[3],swValue[4],swValue[5]))
while True:
doUpdate()
doShow()
time.sleep_ms(200)
Conclusion
From this article, you will find that the joystick shield can be used immediately without additional circuitry, and the pins of Arduino Uno and Arduino Mega are enough for use. However, if you want to display with speed and beauty which is the limit of these boards because the amount of RAM is not enough for the buffer switching technique or various overlays, so if you can bring this joystick sector to connect to the microcontroller that responsible for display and process together. Readers can create their game consoles without any hassle. Finally, have fun with programming.
If you want to discuss or talk with us, feel free to comments below!!
Reference
(C) 2020-2021, By Jarut Busarathid and Danai Jedsadathitikul
Updated 2021-10-17