3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

M5StackでDS4のタッチパッド入力を認識する

Last updated at Posted at 2024-03-30

コードまで載せている記事はなかったので作ってみました!
既にM5StackとDS4をBluetooth接続できている方向けの記事です。
接続方法は他の記事で詳しく解説されているのでそこを見ていただきたいです。

コード

早速コードを載せます

title
#include <PS4Controller.h>

String byteToBinary(uint8_t byte) {
  String byteString(byte, BIN);

  for (int i = byteString.length(); i < 8; i++) {
    byteString = '0' + byteString;
  }

  return byteString;
}

char x_char[13];
char y_char[13];
int x_int;
int y_int;

void showTouchPad(){
  strcpy(x_char,"000000000000");
  strcpy(y_char,"000000000000");
  x_int = 0;
  y_int = 0;

  for(int i = 0;i<8;i++){
    if(byteToBinary(PS4.LatestPacket()[50]).charAt(i)== '1'){
      y_char[i] = '1';
    }
    if(byteToBinary(PS4.LatestPacket()[48]).charAt(i)== '1'){
      x_char[i+4] = '1';
    }
  }
  for(int i = 0;i<4;i++){
    if(byteToBinary(PS4.LatestPacket()[49]).charAt(i)== '1'){
      y_char[i+8] = '1';
    }
    if(byteToBinary(PS4.LatestPacket()[49]).charAt(i+4)== '1'){
      x_char[i] = '1';
    }
  }

  for(int i = 0;i<12;i++){//10進数に変換
    if(x_char[i]=='1'){
      x_int += pow(2,11-i);
    }
    if(y_char[i]=='1'){
      y_int += pow(2,11-i);
    }
  }
  Serial.printf("x: %d\n",x_int);
  Serial.printf("y: %d\n",y_int);
  Serial.println();

}

void setup() {
  Serial.begin(115200);
  PS4.begin("0A:1B:2C:3D:4E:5F");
  Serial.println("Ready.");
}

void loop() {
  if(PS4.isConnected()){

    delay(255);//255未満はきつい(DS4が接続した瞬間に情報を受け取ろうとすると止まっちゃうっぽい)
    
    showTouchPad();
    
  }
}

コードの概要

DS4のあらゆる情報がPS4.LatestPacket[]で送られてきます。
そのうち[50],[49],[48]がタッチパッドの触れられている座標に関する情報を持っていますのでそこだけ引き出しています。

うまく行けば
x: 938
y:344

x: 800
y: 400
のように出力されます。

二本指でも認識できます

https://x.com/Syake0_/status/1774051875509436533/video/1
↑動画をTwitterにあげてます。
[52]~[54]が二本目の指の座標を表しているので同様にその座標を取得できる
ついでにLCDも使ってわかりやすくしてみました。

#include <PS4Controller.h>
#include <M5Stack.h>

String byteToBinary(uint8_t byte){
  String byteString(byte, BIN);

  for (int i = byteString.length(); i < 8; i++) {
    byteString = '0' + byteString;
  }

  return byteString;
}

char x1_char[13];
char y1_char[13];
int x1_int;
int y1_int;
char x2_char[13];
char y2_char[13];
int x2_int;
int y2_int;

void getTouchPad(){
  strcpy(x1_char,"000000000000");
  strcpy(y1_char,"000000000000");
  x1_int = 0;
  y1_int = 0;
  strcpy(x2_char,"000000000000");
  strcpy(y2_char,"000000000000");
  x2_int = 0;
  y2_int = 0;

  for(int i = 0;i<8;i++){
    if(byteToBinary(PS4.LatestPacket()[50]).charAt(i)== '1'){
      y1_char[i] = '1';
    }
    if(byteToBinary(PS4.LatestPacket()[48]).charAt(i)== '1'){
      x1_char[i+4] = '1';
    }
    if(byteToBinary(PS4.LatestPacket()[54]).charAt(i)== '1'){
      y2_char[i] = '1';
    }
    if(byteToBinary(PS4.LatestPacket()[52]).charAt(i)== '1'){
      x2_char[i+4] = '1';
    }
  }
  for(int i = 0;i<4;i++){
    if(byteToBinary(PS4.LatestPacket()[49]).charAt(i)== '1'){
      y1_char[i+8] = '1';
    }
    if(byteToBinary(PS4.LatestPacket()[49]).charAt(i+4)== '1'){
      x1_char[i] = '1';
    }
    if(byteToBinary(PS4.LatestPacket()[53]).charAt(i)== '1'){
      y2_char[i+8] = '1';
    }
    if(byteToBinary(PS4.LatestPacket()[53]).charAt(i+4)== '1'){
      x2_char[i] = '1';
    }
  }

  for(int i = 0;i<12;i++){//10進数に変換
    if(x1_char[i]=='1'){
      x1_int += pow(2,11-i);//0~1919
    }
    if(y1_char[i]=='1'){
      y1_int += pow(2,11-i);//0~941
    }
    if(x2_char[i]=='1'){
      x2_int += pow(2,11-i);//0~1919
    }
    if(y2_char[i]=='1'){
      y2_int += pow(2,11-i);//0~941
    }
  }
  Serial.printf("x1: %d\n",x1_int);
  Serial.printf("y1: %d\n",y1_int);
  Serial.printf("x2: %d\n",x2_int);
  Serial.printf("y2: %d\n",y2_int);
  Serial.println();
}

void Lcd(){//0~320,0~240
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.drawCircle(x1_int/(1919/360),y1_int/(941/240),10,YELLOW);
  M5.Lcd.drawCircle(x2_int/(1919/360),y2_int/(941/240),10,RED);
}

void setup() {
  Serial.begin(115200);
  PS4.begin("0A:1B:2C:3D:4E:5F");
  Serial.println("Ready.");
  M5.begin();
  M5.Power.begin();
}

void loop() {
  if(PS4.isConnected()){
    delay(255);//255未満はきつい(DS4が接続した瞬間に情報を受け取ろうとすると止まっちゃうっぽい)
    while(1){
      getTouchPad();
      Lcd();
      delay(10);
    }
  }
}

参考にさせていただいた記事

Qiita:M5StackにPS4コントローラをBluetooth接続

Qiita:ESP32でDualShock4のIMUを使う

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?