Jumat, 24 Oktober 2014

Interface Joystick PS 2 berbasis Mikrokontroller AVR dan compiler Codevision AVR

Bissmilahirrohmanirrohim..,

Hhmm.., dah lama gak posting jadi rada kaku..., hohohooo..,

     Sekarang saya akan mencoba untuk share kepada teman-teman cara interface joystick PS2 dengan mikrokontroler AVR dan program yang digunakan bahasa C compiler Codevision AVR yang di aplikasikan pada robot beroda. Joystick PS2 ada 2 tipe yang Wire / kabel dan Wireless tanpa kabel, pada ajang KRAI penggunaan joystick ini sangat familiar karena mudah penggunaan'y dan simple. Interface Joystick PS dengan Mikrokontroler AVR ini menggunakan komunikasi SPI (Serial Peripheral Interface) atau yg dikenal dengan 3 kabel, tapi disini saya tidak akan bahas detail tentang SPI (ask google), 

Ok langsung aja, 
1. Kita lihat Pin Konfigurasi dari Joystick PS 2

Gambar 1. Pin konfigurasi Joystick PS2

     Dari gambar diatas bisa kita lihat joystick PS memiliki 9 pin dengan warna yang berbeda. akan tetapi ada beberapa joystick(tipe kabel/wire) di pasaran yang hanya memiliki 8 pin. Dari 9 atau 8 pin tersebut yang hanya digunakan hanya 6 pin / warna dengan mengabaikan tegangan motor(Getar) pada joystick. 6 warna kabel tersebut yaitu (Brown = data), (Orange = Command), (Black = Ground), (Red = Power), (Yellow = Attention), dan (Blue = Clock). Hati-hati terhadap warna Orange dan Kuning karena hampir sama jika terbalik maka joystick tidak akan bisa digunakan.

2. Rangkaian Joystick PS2 dengan Mikrokontroler.


Gambar 2. Rangkaian joystick PS2 dengan Mikrokontroler

    Dari rangkaian diatas joystick PS2 dengan mikrokontroler cukup sederhana hanya 4 pin yaitu Mosi, Miso, SCK, dan Pin bebas. Untuk pin SCK, MOSI, PB4(bebas) diberi resistor 220 ohm sebagai pengaman, sedangkan resistor 4k7 ohm pada MISO sebagai Pull-up. Pin SCK dihubungkan ke kabel joystick warna biru, PB4 (pin bebas) dihubungkan ke kabel joystick warna kuning, Pin MOSI dihubungkan ke kabel joystick warna orange, dan Mosi dihubungkan ke kabel joysick warna Coklat dan diberi pull-up.Sedangkan untuk power joystick diberi tegangan 5 V (merah) dan ground (hitam).

3. Pertukaran data joystick dengan mikrokontroler


     Pertukaran data joystick dengan uC terlihat pada tabel 1 dan 2. Untuk mengawali komunikasi dengan joystick, mikrokontroler mengirim Byte pertama berupa perintah 0x0, kemudian Byte kedua dengan perintah 0x42 (baca data) sekaligus menerima tipe joystick (0x41 [65] untuk digital, dan 0x73 [115] untuk analog) dari kontroler joystick. Byte ketiga dan seterusnya uC menerima data dari kontroler joystick berturut-turut 0x5A (ready), data digital 1, dan data digital 2. Data digital ini bersifat Aktif LOW (0). jadi jika tidak ada tombol di tekan akan diterima data 0xFF (0b11111111). 
misal jika kita menekan / mengaktifkan tombol R2 maka potongan coding'y :

 if (byte5==0b11111101).    // Tombol R2 di baris byte 5 dengan kolom bit 1 aktifkan low. (liat tabel 1)
{       
         lcd_clear();
         lcd_gotoxy(0,1);         
         lcd_puts("R2");
         delay_ms(100);       
 } 

    Jika joystick dalam kondisi analog maka komunikasi dilanjutkan dengan data analog 1, data analog 2, data analog 3, data analog 4. dimana saat kondisi netral berupa data 0x7F (127) dengan nilai minimal 0 dan nilai maksimal 0xFF(255). saat operasi digital, byte 6 - 9 selalu memberikan data 0xFF. 
misal jika kita ingin mengaktifkan analog kanan - sumbu x. maka potongan coding'y :

 if ( (ID == 115) && (byte6 == 0b00000000) || (byte6 == 0b11111111) ) // mode analog diaktifkan(115)  {        
      itoa(byte6, analog6);           // byte 6 == 0b11111111  analog kanan - sumbu x di aktifkan, dsb.
      lcd_clear();
      lcd_gotoxy(0,1);
      lcd_puts(analog 6);
      lcd_gotoxy(0,5);                      
      lcd_puts(" analog ON");          
      delay_ms(100);
}

dari tabel diatas berikut prosedur untuk membaca data dari joystick :
void baca_data()
{        
        PORTB.4 = 0;       
        spi(0x01);    
        ID = spi(0x42);
        SS = spi(0);
        byte4 = spi(0);
        byte5 = spi(0);
        byte6 = spi(0);
        byte7 = spi(0);
        byte8 = spi(0);
        byte9 = spi(0);
        PORTB.4 = 1;
}

    Portb.4 sebagai psxattn pada kodisi iddle / awal berlogika high (1), untuk mengaktifkan maka diberi logika low (0), kemudian terjadi pertukaran data seperti yg di jelaskan diatas. komunikasi di akhiri dengan memberi Portb.4 logika high (1) kembali.

     Sebenernya saya punya banyak contoh coding'y yang di dapat dr om google, ataupun program yang saya buat sendiri. 
berikut salah satu full program interface joystick menggunakan mikrokontroler avr atmega8.


Chip type                                : ATmega8
Program type                           : Application
AVR Core Clock frequency   : 8.000000 MHz
Memory model                       : Small
External RAM size                 : 0
Data Stack size                       : 256
*****************************************************/


#include <mega8.h>
#include <stdlib.h>
// Alphanumeric LCD Module functions
#include <alcd.h>

// SPI functions
#include <spi.h>
#include <delay.h>
// Declare your global variables here
unsigned char spi(unsigned char data);

void main(void)
{
// Declare your local variables here
unsigned char byte4, byte5, byte6, byte7, byte8, byte9;
unsigned char ID, SS;
unsigned char *analog;
unsigned char *analog6;
unsigned char *analog7;
unsigned char *analog8;
unsigned char *analog9; 

// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=Out Func4=In Func3=Out Func2=Out Func1=In Func0=In
// State7=T State6=T State5=0 State4=T State3=0 State2=0 State1=T State0=T
PORTB=0x04;
DDRB=0x2C;
// SPI initialization
// SPI Type: Master
// SPI Clock Rate: 62.500 kHz
// SPI Clock Phase: Cycle Half
// SPI Clock Polarity: High
// SPI Data Order: LSB First
SPCR=0x7F;
SPSR=0x00;

// Alphanumeric LCD initialization
// Connections specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTC Bit 0
// RD - PORTC Bit 1
// EN - PORTC Bit 2
// D4 - PORTC Bit 3
// D5 - PORTC Bit 4
// D6 - PORTC Bit 5
// D7 - PORTB Bit 0
// Characters/line: 8
lcd_init(16);

while (1)
{
      // Place your code here
        lcd_clear();
        PORTB.2 = 0;
        spi(0x01);    
        ID = spi(0x42);
        SS = spi(0);
        byte4 = spi(0);
        byte5 = spi(0);
        byte6 = spi(0);
        byte7 = spi(0);
        byte8 = spi(0);
        byte9 = spi(0);
        PORTB.2 = 1;
     
      lcd_clear();
      itoa(ID, analog);
      lcd_gotoxy(0,0);
      lcd_puts(analog);
     
      if (ID == 65)
      {
       lcd_gotoxy(5,0);
       lcd_puts("analog off");
       delay_ms(500);
      }
     
      else if (ID == 115)
      {
       lcd_gotoxy(5,0);
       lcd_puts("analog on");
       delay_ms(500);
      }

       lcd_clear();     
       if (byte4 == 0b01111111)
        {
         lcd_clear();
         lcd_gotoxy(0,1);
        lcd_puts("left");
        delay_ms(700);
        }     
       
       else if (byte4 == 0b10111111)
        {
        lcd_clear();
         lcd_gotoxy(0,1);
        lcd_puts("down");
         delay_ms(700);
        }
       
       else if (byte4 == 0b11011111)
       {
         lcd_clear();
         lcd_gotoxy(0,1);
         lcd_puts("right");
         delay_ms(700);
        }
       
       else if (byte4 == 0b11101111)
       {
         lcd_clear();
         lcd_gotoxy(0,1);
        lcd_puts("up");
         delay_ms(700);
        }               
      
       else if (byte4 == 0b11110111)
       {
         lcd_clear();
         lcd_gotoxy(0,1);
         lcd_puts("start");
         delay_ms(700);
        }                 
                 
       else if (byte4 == 0b11111110)
       {
         lcd_clear();
         lcd_gotoxy(0,1);
         lcd_puts("select");
         delay_ms(700);
       }
       
       else if (byte5 == 0b01111111)
       {
        lcd_clear();
        lcd_gotoxy(0,1);
        lcd_puts("kotak");
        delay_ms(700);
       }

       else if (byte5 == 0b10111111)
       {
         lcd_clear();
         lcd_gotoxy(0,1);
         lcd_puts("X");
         delay_ms(700);
       }
        
       else if (byte5 == 0b11011111)
       {
         lcd_clear();
         lcd_gotoxy(0,1);
         lcd_puts("bulat");
         delay_ms(700);
       }
       
       else if (byte5 == 0b11101111)
       {
         lcd_clear();
         lcd_gotoxy(0,1);
         lcd_puts("segitiga");
         delay_ms(700);
       }               
      
       else if (byte5 == 0b11110111)
       {
         lcd_clear();
         lcd_gotoxy(0,1);
         lcd_puts("R1");
         delay_ms(700);
       } 
       
       else if (byte5 == 0b11111011)
       {
         lcd_clear();
         lcd_gotoxy(0,1);
         lcd_puts("L1");
         delay_ms(700);
       }
      
       else if (byte5 == 0b11111101)
       {
         lcd_clear();
         lcd_gotoxy(0,1);
         lcd_puts("R2");
         delay_ms(700);
       } 
      
       else if (byte5 == 0b11111110)
       {
         lcd_clear();
         lcd_gotoxy(0,1);
         lcd_puts("L2");
         delay_ms(700);       
       }
                      
      else if ( (ID == 115) && (byte6 == 0b00000000) || (byte6 == 0b11111111) )
      {itoa(byte6, analog6);
      lcd_clear();
      lcd_gotoxy(0,1);
      lcd_puts(analog6);
      lcd_gotoxy(0,5);
      lcd_puts(" analog ON");          
      delay_ms(700);}
     
      else if ( (ID == 115) && (byte7 == 0b00000000) || (byte7 == 0b11111111) )  
      {itoa(byte7, analog7);
      lcd_clear();
      lcd_gotoxy(0,1);
      lcd_puts(analog7);
      lcd_gotoxy(0,5);
      lcd_puts(" analog ON");
      delay_ms(700);}
      
      else if ((ID == 115) && (byte8 == 0b00000000) || (byte8 == 0b11111111) )
      {itoa(byte8, analog8);
      lcd_clear();
      lcd_gotoxy(0,1);
      lcd_puts(analog8);
      lcd_gotoxy(0,5);
      lcd_puts(" analog ON");
      delay_ms(700);}
     
      else if ((ID == 115) && (byte9 == 0b00000000) || (byte9 == 0b11111111) )
      {itoa(byte9, analog9);
      lcd_clear();
      lcd_gotoxy(0,1);
      lcd_puts(analog9);
      lcd_gotoxy(0,5);
      lcd_puts(" analog ON");
      delay_ms(700);}
     
      lcd_clear();            
}
}

    Jika teman-teman perlu refrensi coding joystick PS dengan mikrokontroler menggunakan bahasa C codevision avr bisa download disini, atau program robot saya yang menggunakan joystick silahkan download disana.

Refrensi:

Berikut adalah video interface Joystick PS dengan mikrokontoler AVR yang diaplikasikan untuk menggerakan Robot beroda.