Arduinoでのアナログジョイスティックの使い方

Arduinoのアナログジョイスティックについてまとめておこうと思う。
秋月電子→http://akizukidenshi.com/catalog/g/gK-10263/

ゲーム機に使われている操作機器なので、簡単にプログラミングすることが出来る。


アナログジョイスティックの回路を作る

上から見た感じはこんな風にしてみた。


これだとどうつないでいるのかわからないので、アナログジョイスティックを外した画像もはっておく。



CN1と書かれたほうが電源のつながっているピン側になる。
10kΩの抵抗を挟んでおくとよい。
ブレッドボードの下側を通るようにつないだので、LCDディスプレイを見やすくなる。
なるべくブレッドボードの端に置いたので、ほかのものをつなぎやすくなる。
ブレッドボードで回路を作るときの参考にしてほしい。

ArduinoIDEのプログラム

//  ------------------------------------------------------------
//  インクルード
//  ------------------------------------------------------------
#include <Wire.h>

#define PIN_AX (A0)
#define PIN_AY (A1)

void setup() {
  Wire.begin();
  lcdInit();
  pinMode(PIN_AX,INPUT);
  pinMode(PIN_AY,INPUT);
  lcdDisp1("Hello");
  delay(1000);
}

void loop() {
  int aj;
  aj=ajoyget();

  if(aj&0x08){
    lcdDisp1("up");
  }
  if(aj&0x04){
    lcdDisp1("down");
  }
  if(aj&0x02){
    lcdDisp1("left");
  }
  if(aj&0x01){
    lcdDisp1("right");
  }

}
//  ------------------------------------------------------------
//  アナログジョイスティック
//  ------------------------------------------------------------
#define analogInit 468
int ajoyget(){
  int ax;
  ax=analogRead(PIN_AX);
  int ay;
  ay=analogRead(PIN_AY);
  int ret;
  ret=0;
  if(ay>(analogInit+100))
    {
    ret|=0x08;
    }
  if(ay<(analogInit-100))
    {
    ret|=0x04;
    }
  if(ax>(analogInit+100))
    {
    ret|=0x02;
    }
  if(ax<(analogInit-100))
    {
    ret|=0x01;
    }
  
  return ret;
}
//  ------------------------------------------------------------
//  アナログジョイスティックここまで
//  ------------------------------------------------------------

//  ------------------------------------------------------------
//  LCD(AQM0802)関係
//  ------------------------------------------------------------
#define LCDA 0x3E           // LCD address
#define CONTRAST 0x20         // for AQM0802@3.3V

//  ----------------------------------------
//  LCDにコマンド送信
//  ----------------------------------------
void lcdCmd(byte cmd) {
  Wire.beginTransmission(LCDA);
  Wire.write((byte)0x00);       // コマンド指定
  Wire.write(cmd);          // コマンド出力
  Wire.endTransmission();       // ストップ

  if( (cmd==0x01) || (cmd==0x02) ) {
    delay(2);             // 2ms待ち
  }
  else {
    delayMicroseconds(30);      // 30us待ち
  }
}

//  ----------------------------------------
//  LCDにデータ送信
//  ----------------------------------------
void lcdData(byte dat) {
  Wire.beginTransmission(LCDA);   // これから...
  Wire.write(0x40);         // データ送るよ
  Wire.write(dat);          // データ
  Wire.endTransmission();       // おしまい
  delayMicroseconds(30);
}

void lcdPut(int x, int y, byte dat){
  lcdLocate( x, y );
  lcdData(dat);
}

void lcdReg(int a, char *str){
  byte H, L;
  byte adr;
  byte dat;
  char *buf;
  
  buf = str;
  if(a == 1){
    adr = 0x40;
  }else if(a == 2){
    adr = 0x48;
  }else if(a == 3){
    adr = 0x50;
  }else if(a == 4){
    adr = 0x58;
  }else if(a == 5){
    adr = 0x60;
  }else if(a == 6){
    adr = 0x68;
  }else if(a == 7){
    adr = 0x70;
  }else if(a == 8){
    adr = 0x78;
  }else {
    adr = 0x40;
  }
  Wire.write(adr);
  Wire.beginTransmission(LCDA);
  for(int i = 0; i < 8; i++){
    H = *buf - '0';
    buf++;
    if(H > 9){
      H = H + '0' - 'a' + 10;
    }
    L = *buf - '0';
    buf++;
    if(L > 9){
      L = L + '0' - 'a' + 10;
    }
    H = H << 4;
    dat = H + L;
    
    Wire.write(dat);
  }
  Wire.endTransmission();
}

//  ----------------------------------------
//  表示位置の指定
//  ----------------------------------------
void lcdLocate(byte col, byte row) {
  byte add = 0x80 + col;        // 1行目+x座標
  if( row>0 ) add += 0x40;      // 2行目に変更
  lcdCmd(add);
}

//  ----------------------------------------
//  初期化
//  ----------------------------------------
void lcdInit() {
  //I2c.begin();            // begin I2C master
  delay(10);
  lcdCmd(0x38);           // 8bit 2line Normal mode
  lcdCmd(0x39);           // 8bit 2line Extend mode
  lcdCmd(0x14);           // OSC 183Hz BIAS 1/5

  // コントラスト設定
  lcdCmd((byte)(0x70 + (CONTRAST & 0x0F))); //下位 4bit
  lcdCmd((byte)(0x5c + (CONTRAST >> 4)));   //上位 2bit
  lcdCmd((byte)0x6b);         // Follwer for 3.3V
  delay(1);

  lcdCmd((byte)0x38);         // Set Normal mode
  lcdCmd((byte)0x0C);         // Display On
  lcdCmd((byte)0x01);         // Clear Display
  delay(1);
}

//  ----------------------------------------
//  全消去関数
//  ----------------------------------------
void lcdClear() {
  lcdCmd(0x01);           // 初期化コマンド出力
  delay(2);
}

//  ----------------------------------------
//  文字列表示関数
//  ----------------------------------------
void lcdPrint( char* cp ) {
  while(*cp!=0x00) {
    lcdData(*cp);
    cp++;
  }
}

//  ----------------------------------------
//  LCDの1行目表示
//  ----------------------------------------
void lcdDisp1( char* cp ) {
  lcdLocate( 0, 0 );
  lcdDisp8( cp );
}

//  ----------------------------------------
//  LCDの2行目表示
//  ----------------------------------------
void lcdDisp2( char* cp ) {
  lcdLocate( 0, 1 );
  lcdDisp8( cp );
}

//  ----------------------------------------
//  8文字表示(普通は使わない)
//  ----------------------------------------
void lcdDisp8( char* cp ) {
  int i;
  for( i=0; i<8; i++ ) {
    if( *cp==0x00 ) break;      // 文字列が終わった
    lcdData( *cp );
    cp++;
  }
  for( ; i<8; i++) {
    lcdData( 0x20 );        // 残りを空白で埋める
    cp++;
  }
}
//  ------------------------------------------------------------
//  LCD(AQM0802)関係ここまで
//  ------------------------------------------------------------

アナログジョイスティックの入力によって、LCDに文字を表示するプログラムを書いてみた。
アナログジョイスティックの上下左右によって数値を返す関数を作ってみた。
関数からきた数値によって、上下左右の判定を行っている。

プログラム上の「analogInit」の数値はシリアルモニタを使って調整してほしい。
調整に使うプログラムはこんな感じ。


#define PIN_AX (A0)
#define PIN_AY (A1)

void setup(){
 Serial.begin(9600);
 delay(1000);
 pinMode(PIN_AX,INPUT);
 pinMode(PIN_AY,INPUT);
}

void loop(){
   int aj;
   aj=analogRead(PIN_AY);
  
   Serial.print(aj);
   Serial.print("\n");
   delay(200);
}

実行結果がこのようになる。




アナログジョイスティックを使った入力は簡単に使うことが出来る。
LCDディスプレイと併用して使うことが多くなると思う。
アナログ入力の主な使い方になる。








コメント

このブログの人気の投稿

STM32CubeIDEに日本語化プラグインを導入する

STM32F401でLチカをする(LED点灯)

STM32F401-Nucleoでシリアル通信をやってみる