back to top

Arduino ile Kablosuz Gamepad Yapalım

Hepimiz bilgisayarlarımızda oyun oynamayı severiz heralde 🙂 . Ama bazen de koskoca kanepe dururken bilgisayarın başında sandalye yada koltukta oturmak istemeyiz. Çözüm: kablosuz gamepad. Herhangi bir teknoloji marketine gittiğimizde elbette bir çok markaya ait çeşitli ürünler bulabiliriz fakat neden kendimiz yapmayalım?

Bu projede ihtiyacımız olan malzemeler şunlar:

Ürünlerin tamamını tek seferde satın almak isterseniz bu linki kullanabilirsiniz. (NOT: Stokta olmayan ürünler sepete eklenmemektedir, lütfen buradaki liste ile karşılaştırarak kontrol ediniz.)

Bu projemizi kısaca şu şekilde özetleyebiliriz: İki adet Arduino’yu HC05 bluetooth modülleri kullanarak haberleştiriyoruz. Bir Arduino üzerinde joystick shield bulunuyor ve bu Arduino’yu gamepad olarak kullanıyoruz. Kart üzerindeki analog joystick ve butonların değerleri okunarak, bilgisayarımıza bağlı olan diğer Arduino’ya gönderiliyor. Bu Arduino’da kendisini bilgisayarımıza gamepad olarak tanıttığından, gelen sensör bilgisine göre joystick ve buton hareketleri bilgisayarımıza bildiriliyor.

Malzeme listesinde (*) ile belirttiğim Arduino modelleri üzerinde ATmega 32u4 mikrokontrolcü bulunmakta. Bu mikrokontrolcü, bilgisayara USB üzerinden bağlandığında yanlızca seri port olarak değil; kendisini klavye, fare veya joystick olarak tanıtabilme özelliğine sahip. Arduino UNO veya MEGA gibi kartlardaki işlemciler malesef bu özelliğe sahip değiller.

HC05 Bluetooth Modülünü Master-Slave Olarak Ayarlamak:

Projemizde kablosuz haberleşme için HC05 bluetooth modüllerini kullanacağız. Bu modüller, fabrika çıkışında slave olarak ayarlanmış bir şekilde gelmektedir. Biz bu projede bir modülün master olarak çalışmasını ve doğrudan diğer kullandığımız modül ile haberleşmesini istiyoruz. Bu yüzden her iki modülü de konfigüre etmemiz gerekli.

İlk olarak modüllerden slave modunda çalışacak olanın şifresini, MAC adresini ve baud rate’ini değiştirmemiz gerekli. Konfigürasyon için bir USB-Seri dönüştürü kartı kullanabilir veya Arduino UNO’nuza boş bir kod yükleyip (yanlızca void setup(){} ve void loop(){} fonksiyonlarını yazmanız yeterlidir) aşağıdaki şekildeki gibi bağlantı yapabilirsiniz:

hc05_config_bb

Arduino IDE’yi açıyoruz, doğru COM portunu seçiyor ve seri port ekranını açarak aşağıdaki gibi ayarlıyoruz:

serial_monitor_1

HC05 modülümüzü konfigürasyon moduna sokabilmek için, 5V bağlantısını en sonra bırakıp, modül üzerindeki butona basılı tutarak güç bağlantısını yapmalısınız. Eğer modül üzerindeki LED 2 sn süre açık kalıp 2 sn kapalı kalıyorsa, modül konfigürasyon moduna başarılı bir şekilde girmiş demektir. Seri port ekranından AT komutunu veriyoruz, OK cevabı geliyorsa bağlantımızda herhangi bir sorun yok demektir.

Öncelikle slave modunda çalışacak olan modülün MAC adresini öğrenmemiz gerekiyor. Bunun için AT+ADDR komutunu veriyoruz. Modülün bize cevap olarak MAC adresini veriyor (örneğin +ADDR:2015:7:206807). Bu adresi kenara not ediyoruz, çünkü master modülümüzü yalnızca bu adresli slave modüle bağlanacak şekilde ayarlayacağız. Slave modül için sırasıyla

AT+ROLE=0

AT+UART=115200,0,0

AT+PSWD=1234

komutlarını vererek, modülü slave modunda ve 115200 baud rate’e ve bağlantı şifresini 1234 olacak şekilde ayarlıyoruz. Şifreyi istediğiniz gibi değiştirebilirsiniz, fakat master modül ile bu şifre aynı olmalıdır.

Slave modülümüzü ayarladıktan sonra, sıra master modülün ayarlarına geldi. Diğer HC05 modülümüzü aynı şekilde bağlıyoruz ve sırasıyla şu komutları veriyoruz:

AT+ROLE:1

AT+UART=115200,0,0

AT+BIND=2015,72,06807 (bir önceki bölümde not ettiğiniz slave modülünüzün MAC adresi olarak değiştirmelisiniz)

AT+CMODE=0

AT+PSWD=1234 (slave modülünüzün şifresi ile aynı olmalıdır)

Bu aşamaları tamamladıysanız artık Arduino’larımızı programlamaya başlayabiliriz demektir. Master olarak ayarlanmış HC05 modülü üzerindeki LED, bağlantı sağlandığında yaklaşık olarak 3 saniyede 2 defa yanıp sönecektir. HC05 modüllerinin konfigürasyonu ile ilgili sıkıntı yaşıyorsanız, detaylı anlatıma sahip HC05 ve HC06 Bluetooth Seri Modülleri Kullanımı yazısından faydalanabilirsiniz.

Arduino ile Joystick Shield Kullanımı:

450xN

Arduino UNO’muzun üzerine joystick shield’ı takarak bir gamepad oluşturacağız. Bağlantılar şu şekilde:

  • Analog X ekseni -> A0
  • Analog Y ekseni -> A1
  • Buton A ->D2
  • Buton B -> D3
  • Buton C -> D4
  • Buton D -> D5
  • Buton E -> D6
  • Buton F -> D7
  • Joystick Buton -> D8

Bu pinlerin değerlerini okuyup, seri port üzerinden belirli bir formatta gönderim yapmamız gerekiyor. Bilginin geldiğini göstermek için ilk önce $ karakteri gönderiliyor, daha sonra sırası ile X ekseni, Y ekseni, A, B, C, D, E, F ve son olarak joystick butonunun değerleri bildiriliyor. Tek bir okumada gelen bilginin bittiğini göstermek için ise # karakteri kullanılıyor. Bu işlem her 50 ms’de bir defa gerçekleşiyor:

#define joy_x A0
#define joy_y A1
#define btn_a 2
#define btn_b 3
#define btn_c 4
#define btn_d 5
#define btn_e 6
#define btn_f 7
#define joy_btn 8

void setup()
{
  for (int i = 2; i >= 8; i++)
  {
    pinMode(i, INPUT);
  }
  Serial.begin(115200);
}

void loop()
{
  Serial.print('

Shield'ımızın düzgün çalışıp çalışmadığını, kodun sondan iki önceki Serial.print('#'); satırını Serial.println('#'); olarak değiştirerek deneyebiliriz. Böylelikle seri port ekranında gelen değerleri daha kolay bir şekilde okumuş oluruz:

serial_monitor_debug

Bu şekilde değerler görüyosak ve butonlara ve analog joystick'e müdahale ettiğimizde değişmelerde bir problem yoksa kodumuz doğru çalışıyor demektir. Kodumuz doğru çalışıyor ise, joystick shield üzerinde "Bluetooth" yazan sokete bağlantı pinlerine dikkat ederek HC05 modülümüzü bağlıyoruz.

shield_bt

Not: Eğer deneme için kodun son satırını Serial.println('#); olarak değiştirdiyseniz, eski haline getirmeyi unutmayınız. Aksi takdirde bir sonraki aşamada kodunuz çalışmayacaktır. Ayrıca gamepad olarak kullandığımız karta HC05 modülü takılı iken yükleme gerçekleştiremiyoruz, kod yükleyeceğimiz zaman modülü çıkartmamız gerekli.

Arduino Leonardo'nun Joystick Olarak Programlanması:

Yazının başında da belirttiğim gibi, Arduino Leonardo ve Micro kartları sahip oldukları ATmega32u4 mikrokontrolcü sayesinde bilgisayara kendilerini klavye, mouse veya joystick gibi çevre birimleri olarak tanıtabilmektedir. Joystick olarak kullanımı için bu adresteki kütüphaneyi indirip C:\Program Files (x86)\Arduino\libraries veya C:\Program Files\Arduino\libraries klasörü altına kopyalamamız gereklidir (Arduino IDE klasörü, bilgisayarınızda 32-bit işletim sistemi yüklü ise Program Files, 64-bit işletim sistemi yüklü ise Program Files (x86) altında yer alır).

HC05 modülümüzü Arduino Leonardo'muza aşağıdaki şemaya göre bağlıyoruz:

hc05_leo_bb

Kütüphaneyi de yükledikten sonra Arduino Leonardo'muzu bilgisayarımıza bağlayarak aşağıdaki kodu yüklüyoruz:

#include <Joystick.h>

int pos_x = 0;
int pos_y = 0;
int a_btn = 0;
int b_btn = 0;
int c_btn = 0;
int d_btn = 0;
int e_btn = 0;
int f_btn = 0;
int joy_btn = 0;

void setup()
{
  Serial.begin(115200); //USB-CDC
  Serial1.begin(115200); //TTL Serial
  Joystick.begin();
  while(!Serial1){}
}

void loop()
{
  readValues();
  Joystick.setXAxis(pos_x);
  Joystick.setYAxis(pos_y);
  Joystick.setButton(0, !a_btn);
  Joystick.setButton(1, !b_btn);
  Joystick.setButton(2, !c_btn);
  Joystick.setButton(3, !d_btn);
  Joystick.setButton(4, !e_btn);
  Joystick.setButton(5, !f_btn);
  Joystick.setButton(6, !joy_btn);
  
  Serial.print(pos_x);
  Serial.print(",");
  Serial.print(pos_y);
  Serial.print(",");
  Serial.print(a_btn);
  Serial.print(",");
  Serial.print(b_btn);
  Serial.print(",");
  Serial.print(c_btn);
  Serial.print(",");
  Serial.print(d_btn);
  Serial.print(",");
  Serial.print(e_btn);
  Serial.print(",");
  Serial.print(f_btn);
  Serial.print(",");
  Serial.println(joy_btn);
  
}

void readValues()
{
  String readout = Serial1.readStringUntil('#');
  String joy_x = readout.substring(1, 5);
  pos_x = joy_x.toInt();
  pos_x = map(pos_x, 0, 1023, -127, 127);
  String joy_y = readout.substring(6, 10);
  pos_y = joy_y.toInt();
  pos_y = map(pos_y, 0, 1023, 127, -127);
  String btn_a = readout.substring(11, 13);
  a_btn = btn_a.toInt();
  String btn_b = readout.substring(13, 15);
  b_btn = btn_b.toInt();
  String btn_c = readout.substring(15, 17);
  c_btn = btn_c.toInt();
  String btn_d = readout.substring(17, 19);
  d_btn = btn_d.toInt();
  String btn_e = readout.substring(19, 21);
  e_btn = btn_e.toInt();
  String btn_f = readout.substring(21, 23);
  f_btn = btn_f.toInt();
  String btn_joy = readout.substring(23, 25);
  joy_btn = btn_joy.toInt();
}

Buradaki kod, Arduino UNO + Joystick Shield kullanarak yaptığımız gamepad'imizden HC05 bluetooth modülü aracılığıyla gelen analog joystick ve buton bilgisini, bilgisayarımıza bir joystick'in hareketi şeklinde gönderiyor.

Kod yüklendikten sonra, bilgisayarımızda Denetim Masası'nı açarak "Aygıtlar ve yazıcıları görüntüle"ye tıklıyoruz. Burada Arduino Leonardo isimli bir gamepad cihazı görünecektir:

control_panel

Arduino Leonardo'ya sağ tıklayarak "Oyun kumandası ayarları"nı seçtiğimizde ise gamepad'imizin doğru çalışıp çalışmadığını kontrol edebiliriz.

game_controllers

Yaptığımız bu gamepad, dizilimi itibari ile bana eski Nintendo oyunlarını hatırlatıyor. Retro oyunları çok sevdiğimden, bu gamepad ile ilk oynadığım oyun Super Mario oldu 🙂

fceux_mario

Sizler de yaptığınız projeleri sosyal medya hesaplarınızdan #ÜretmektenKorkma etiketi ile paylaşabilir, oynadığınız oyunları yorumlar kısmına yazabilirsiniz. Bir sonraki projede görüşmek üzere. İyi eğlenceler!

);
if (analogRead(joy_x) < 1000) Serial.print("0");
if (analogRead(joy_x) < 100) Serial.print("0");
if (analogRead(joy_x) < 10) Serial.print("0");
Serial.print(analogRead(joy_x));
Serial.print(',');
if (analogRead(joy_y) < 1000) Serial.print("0");
if (analogRead(joy_y) < 100) Serial.print("0");
if (analogRead(joy_y) < 10) Serial.print("0");
Serial.print(analogRead(joy_y));
Serial.print(',');
Serial.print(digitalRead(btn_a));
Serial.print(',');
Serial.print(digitalRead(btn_b));
Serial.print(',');
Serial.print(digitalRead(btn_c));
Serial.print(',');
Serial.print(digitalRead(btn_d));
Serial.print(',');
Serial.print(digitalRead(btn_e));
Serial.print(',');
Serial.print(digitalRead(btn_f));
Serial.print(',');
Serial.print(digitalRead(joy_btn));
Serial.print('#');
delay(50);
}
Shield’ımızın düzgün çalışıp çalışmadığını, kodun sondan iki önceki Serial.print(‘#’); satırını Serial.println(‘#’); olarak değiştirerek deneyebiliriz. Böylelikle seri port ekranında gelen değerleri daha kolay bir şekilde okumuş oluruz:

serial_monitor_debug

Bu şekilde değerler görüyosak ve butonlara ve analog joystick’e müdahale ettiğimizde değişmelerde bir problem yoksa kodumuz doğru çalışıyor demektir. Kodumuz doğru çalışıyor ise, joystick shield üzerinde “Bluetooth” yazan sokete bağlantı pinlerine dikkat ederek HC05 modülümüzü bağlıyoruz.

shield_bt

Not: Eğer deneme için kodun son satırını Serial.println(‘#); olarak değiştirdiyseniz, eski haline getirmeyi unutmayınız. Aksi takdirde bir sonraki aşamada kodunuz çalışmayacaktır. Ayrıca gamepad olarak kullandığımız karta HC05 modülü takılı iken yükleme gerçekleştiremiyoruz, kod yükleyeceğimiz zaman modülü çıkartmamız gerekli.

Arduino Leonardo’nun Joystick Olarak Programlanması:

Yazının başında da belirttiğim gibi, Arduino Leonardo ve Micro kartları sahip oldukları ATmega32u4 mikrokontrolcü sayesinde bilgisayara kendilerini klavye, mouse veya joystick gibi çevre birimleri olarak tanıtabilmektedir. Joystick olarak kullanımı için bu adresteki kütüphaneyi indirip C:\Program Files (x86)\Arduino\libraries veya C:\Program Files\Arduino\libraries klasörü altına kopyalamamız gereklidir (Arduino IDE klasörü, bilgisayarınızda 32-bit işletim sistemi yüklü ise Program Files, 64-bit işletim sistemi yüklü ise Program Files (x86) altında yer alır).

HC05 modülümüzü Arduino Leonardo’muza aşağıdaki şemaya göre bağlıyoruz:

hc05_leo_bb

Kütüphaneyi de yükledikten sonra Arduino Leonardo’muzu bilgisayarımıza bağlayarak aşağıdaki kodu yüklüyoruz:


Buradaki kod, Arduino UNO + Joystick Shield kullanarak yaptığımız gamepad’imizden HC05 bluetooth modülü aracılığıyla gelen analog joystick ve buton bilgisini, bilgisayarımıza bir joystick’in hareketi şeklinde gönderiyor.

Kod yüklendikten sonra, bilgisayarımızda Denetim Masası‘nı açarak “Aygıtlar ve yazıcıları görüntüle”ye tıklıyoruz. Burada Arduino Leonardo isimli bir gamepad cihazı görünecektir:

control_panel

Arduino Leonardo’ya sağ tıklayarak “Oyun kumandası ayarları”nı seçtiğimizde ise gamepad’imizin doğru çalışıp çalışmadığını kontrol edebiliriz.

game_controllers

Yaptığımız bu gamepad, dizilimi itibari ile bana eski Nintendo oyunlarını hatırlatıyor. Retro oyunları çok sevdiğimden, bu gamepad ile ilk oynadığım oyun Super Mario oldu 🙂

fceux_mario

Sizler de yaptığınız projeleri sosyal medya hesaplarınızdan #ÜretmektenKorkma etiketi ile paylaşabilir, oynadığınız oyunları yorumlar kısmına yazabilirsiniz. Bir sonraki projede görüşmek üzere. İyi eğlenceler!

Son Çıkan Yazılar

42 YORUMLAR

  1. Readout, strimg ve substring, to int nedir ? Ve benim takildiğim kisim değerleri okumak değil benim zorlandığım bir joystick değerini ikiyebölüp iki farklı motora yönlendirmek kumandada ileriye basıp arkadaki iki motora değer yazdırmak mesela

  2. Merhaba arduino leonardo ya kodları yüklüyorum pc ye joystick olarak tanıtıyorum ama ne yaparsam yapayım joystick ve buton hareketlerini alamıyorum yani hiç tepki yok

    • Kablosuz bağlantının sorunsuz gerçekleştiğinden emin misiniz? Arduino Leonardo bilgisayarınıza bağlı iken seri monitörü açarak butonların değerlerinin doğru gelip gelmediğini kontrol edebilirsiniz.

    • PS3 kontrolcüsünü doğrudan Bluetooth ile bilgisayarınıza bağlayabilirsiniz 🙂 Ya da kendi devrenizi yapmak isterseniz kontrolcünün içerisindeki joystick potansları ve butonları teker teker Arduino’ya da bağlayabilirsiniz.

    • Alıcı tarafında USB HID özelliği bulunmadığı için malesef Arduino Nano kullanamazsınız. Verici (gamepad) tarafında ise sorunsuzca kullanabilirsiniz.

  3. Merhabalar
    ben ardiuno leonardoya kodları yüklediğim esnada şu şekide bir hata alıyorum. Yardımlarınızı bekliyorum.

    :\Users\KORAY\AppData\Local\Temp\arduino_modified_sketch_839397\sketch_apr14a.ino: In function ‘void setup()’:
    sketch_apr14a:17: error: ‘Joystick’ was not declared in this scope
    Joystick.begin()
    C:\Users\KORAY\AppData\Local\Temp\arduino_modified_sketch_839397\sketch_apr14a.ino: In function ‘void loop()’:
    sketch_apr14a:24: error: ‘Joystick’ was not declared in this scope
    Joystick.setXAxis(pos_x);
    exit status 1
    ‘Joystick’ was not declared in this scope
    C:\Program Files\Arduino\libraries\rfid-master içerisinde geçersiz kütüphane bulundu: C:\Program Files\Arduino\libraries\rfid-master

    kütüphaneyi yüklerken C:\Program Files (x86)\Arduino\libraries klasörüne yalnızca indirdiğim kütüphanedeki joystick klasörünü yüklüyoruz doğru mudur arkadaşlar?

    • Tek tırnak işaretlerinizden kaynaklı olabilir. Klavyenizde Shift + 2 (nümerik klavyeden değil, üst sıradakinden) ile yazacağınız tırnak işaretini kullanmanız gereklidir.

  4. Arduino UNO R3 Klon aldım buton box için fakat bana gelen hatada joistck yapamazdin deniyor simhub programinda bunun için çözümü verebilirmisiniz ?

    • Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD,
      1, 0, // Button Count, Hat Switch Count
      true, true, false, // X and Y, but no Z Axis
      false, false, false, // No Rx, Ry, or Rz
      false, false, // No rudder or throttle
      false, false, false); // No accelerator, brake, or steering

      kütüphanenin altına bunu eklersen o hatayı vermez
      ben denedim oldu

  5. #include

    int pos_x = 0;
    int pos_y = 0;
    int a_btn = 0;
    int b_btn = 0;
    int c_btn = 0;
    int d_btn = 0;
    int e_btn = 0;
    int f_btn = 0;
    int joy_btn = 0;

    void setup()
    {
    Serial.begin(115200); //USB-CDC
    Serial1.begin(115200); //TTL Serial
    Joystick.begin();
    while(!Serial1){}
    }

    void loop()
    {
    readValues();
    Joystick.setXAxis(pos_x);
    Joystick.setYAxis(pos_y);
    Joystick.setButton(0, !a_btn);
    Joystick.setButton(1, !b_btn);
    Joystick.setButton(2, !c_btn);
    Joystick.setButton(3, !d_btn);
    Joystick.setButton(4, !e_btn);
    Joystick.setButton(5, !f_btn);
    Joystick.setButton(6, !joy_btn);

    Serial.print(pos_x);
    Serial.print(“,”);
    Serial.print(pos_y);
    Serial.print(“,”);
    Serial.print(a_btn);
    Serial.print(“,”);
    Serial.print(b_btn);
    Serial.print(“,”);
    Serial.print(c_btn);
    Serial.print(“,”);
    Serial.print(d_btn);
    Serial.print(“,”);
    Serial.print(e_btn);
    Serial.print(“,”);
    Serial.print(f_btn);
    Serial.print(“,”);
    Serial.println(joy_btn);

    }

    void readValues()
    {
    String readout = Serial1.readStringUntil(‘#’);
    String joy_x = readout.substring(1, 5);
    pos_x = joy_x.toInt();
    pos_x = map(pos_x, 0, 1023, -127, 127);
    String joy_y = readout.substring(6, 10);
    pos_y = joy_y.toInt();
    pos_y = map(pos_y, 0, 1023, 127, -127);
    String btn_a = readout.substring(11, 13);
    a_btn = btn_a.toInt();
    String btn_b = readout.substring(13, 15);
    b_btn = btn_b.toInt();
    String btn_c = readout.substring(15, 17);
    c_btn = btn_c.toInt();
    String btn_d = readout.substring(17, 19);
    d_btn = btn_d.toInt();
    String btn_e = readout.substring(19, 21);
    e_btn = btn_e.toInt();
    String btn_f = readout.substring(21, 23);
    f_btn = btn_f.toInt();
    String btn_joy = readout.substring(23, 25);
    joy_btn = btn_joy.toInt();
    }

    buradada hata alıyorum

  6. Joystick.setXAxis(pos_x);
    Joystick.setYAxis(pos_y);
    Joystick.setButton(0, !a_btn);
    Joystick.setButton(1, !b_btn);
    Joystick.setButton(2, !c_btn);
    Joystick.setButton(3, !d_btn);
    Joystick.setButton(4, !e_btn);
    Joystick.setButton(5, !f_btn);
    Joystick.setButton(6, !joy_btn);

    burada hata aldım

  7. Arduino:1.8.13 (Windows 10), Kart:”Arduino Leonardo”

    C:\Users\vefak\AppData\Local\Temp\arduino_modified_sketch_487000\sketch_mar31c.ino: In function ‘void setup()’:

    sketch_mar31c:18:3: error: ‘Joystick’ was not declared in this scope

    Joystick.begin();

    ^~~~~~~~

    C:\Users\vefak\AppData\Local\Temp\arduino_modified_sketch_487000\sketch_mar31c.ino:18:3: note: suggested alternative: ‘Joystick_’

    Joystick.begin();

    ^~~~~~~~

    Joystick_

    C:\Users\vefak\AppData\Local\Temp\arduino_modified_sketch_487000\sketch_mar31c.ino: In function ‘void loop()’:

    sketch_mar31c:25:3: error: ‘Joystick’ was not declared in this scope

    Joystick.setXAxis(pos_x);

    ^~~~~~~~

    C:\Users\vefak\AppData\Local\Temp\arduino_modified_sketch_487000\sketch_mar31c.ino:25:3: note: suggested alternative: ‘Joystick_’

    Joystick.setXAxis(pos_x);

    ^~~~~~~~

    Joystick_

    exit status 1

    ‘Joystick’ was not declared in this scope

    This report would have more information with
    “Show verbose output during compilation”
    option enabled in File -> Preferences.

    hatam bu

CEVAP VER

Lütfen yorumunuzu giriniz!
Lütfen isminizi buraya giriniz