บทความนี้แนะนำการใช้ Game Pad/Joystick กับบอร์ด Arduino Uno หรือ Arduino Mega เนื่องจากเป็นโมดูลที่ออกแบบเป็น Shield ของบอร์ดทั้ง 2 เมื่อนำมาประกอบจะได้เกมแพดน่ารัก ๆ 1 ชิ้นดังภาพที่ 1 โดยในบทความอธิบายเพิ่มเติมเกี่ยวกับข้อมูลของการเชื่อมต่อระหว่างอุปกรณ์แต่ละชิ้นกับ GPIO พร้อมตัวอย่างการใช้งาน ซึ่งเนื้อหาเกี่ยวกับโมดูลจอยสติกอ่านได้จากบทความก่อนหน้านี้
Joystick Shield
ชิลด์จอยสติกเป็นบอร์ดสำหรับใส่บนบอร์ด Arduino Uno หรือ Arduino Mega ที่เป็นฟอร์มเดียวกัน และได้สภาพของการต่อพ่วงเป็นดังภาพที่ 1 แต่สำหรับคนชอบทำเองอย่างพวกเรา ซึ่งก่อนจะหาซื้อชิลด์ตัวนี้มีได้ทดลองทำเองกับไมโครคอนโทรลเลอร์แบบต่าง ๆ จนได้ผลในระดับที่ใช้งานจริงได้ดังภาพที่ 2,3 และ 4
จากภาพที่ 5 จะพบว่าชิลด์ตัวนี้ประกอบไปด้วยโมดูลจอยสติก กับสวิตช์แบบกดติดปล่อยกับอีก 6 ตัว โดยแต่ละตัวต่อวงจร Pull Up เอาไว้ ซึ่งการเชื่อมต่อของโมดูลและสวิตช์กับขาของ Arduino Uno/Mega เป็นดังภาพที่ 5 หรือตามตารางต่อไปนี้
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 |
ตัวอย่างโปรแกรม
ตัวอย่างโปรแกรมแสดงสถานะของการทำงานของจอยสติกและสถานะของสวิตช์ต่าง ๆ เป็นดังนี้ และตัวอย่างผลลัพธ์เป็นดังภาพที่ 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();
}
กรณีที่ใช้กับบอร์ด ESP32 ดังภาพที่ 7 ต้องเชื่อมต่อจากขั้วจ่อที่เป็นสีเหลืองจากด้านขวามือด้านบนและโค้ดตัวอย่างโปรแกรมเป็นดังนี้
/*
* 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);
}
ตัวอย่างการใช้งานกับบอร์ด ESP32 ที่เชื่อมต่อกับปุ่มต่าง ๆ มีโค้ดการทำงานดังนี้
# 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)
สรุป
จากบทความนี้จะพบว่าชิลด์จอยสติกสามารถใช้งานได้ทันทีโดยไม่ต้องต่อวงจรเพิ่มเติม และขาของ Arduino Uno และ Arduino Mega มีมากพอสำหรับการใช้งาน แต่อย่างไรก็ดี ถ้าต้องการให้แสดงผลด้วยความเร็วและสวยงาม ซึ่งเป็นขีดจำกัดของบอร์ดทั้ง 2 นี้ เนื่องจากปริมาณหน่วยความจำแรมมีไม่มากพอสำหรับทำเทคนิคการสลับบัฟเฟอร์หรือการซ้อนภาพต่าง ๆ ดังนั้น ถ้าสามารถนำภาคจอยสติกนี้เชื่อมต่อกับไมโครคอนโทรลเลอร์ที่ทำหน้าที่แสดงผลและปรมวลผลภาพเข้าด้วยกันได้ ผู้อ่านสามารถสร้างเครื่องเล่นเกมของตนเองขึ้นมาได้โดยไม่ยุ่งยากเลยทีเดียว สุดท้ายนี้ขอให้สนุกกับการเขียนโปรแกรมครับ
ท่านใดอยากพูดคุยสามารถคอมเมนท์ไว้ได้เลยครับ
แหล่งอ้างอิง
(C) 2020-2021, โดย อ.ดนัย เจษฎาฐิติกุล/อ.จารุต บุศราทิจ
ปรับปรุงเมื่อ 2021-07-04, 2021-07-06, 2021-10-12