83
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Organization

Arduinoでポケモン剣盾自動化してみた ~自動ワット稼ぎ編~

はじめに

Nintendo Switchから充電ポートがUSB Type-Cになり、専用のプロコントローラーもUSBになったそうで、ArduinoのUSB HID(ヒューマンインターフェースデバイス)機能を持つLeonardoで自動化してみました。

今回は、自動ワット稼ぎで一躍有名になった(なってない)「ポケットモンスター ソード&シールド」を例に進めてみます。

準備するもの

  • PC (自分でPCと呼べるもの)
  • USBケーブル(Type-A - micro)
  • Arduino Leonardo (ATmega32u4チップ搭載)
  • 変換ケーブル(Type-A メス - Type-C オス)

きちんと正規品を買いたかったのですが、お財布が許してくれなかったのでこちらを購入しました。安いですがきちんとしていました。
-Amazon- HiLetgo Leonardo Pro Micro

作業工程

Arduino IDEのインストール

Arduinoの公式サイトに行き、上の SOFTWARE>DOWNLOADS を選択し、 Download the Arduino IDE から自分の環境にあったIDEをダウンロードしてインストール。

Switch操作用ライブラリをダウンロード

今回は、有志の方によって製作されたライブラリを使用します。GitHubの公開ページに行き、clone or download(緑色のプルダウン)からDownkoad ZIPを選択し、ダウンロードして、解凍してください。

解凍したフォルダを置く場所が重要で、ダウンロードしたSwitchControlLibrary-masterディレクトリを、Arduinoがインストールされたディレクトリ(Windowsのデフォルトは C:\Program files(x86)\Arduino) の中にあるlibrariesというディレクトリに移動してください。Arduino IDEはプログラムをコンパイルする際にこのディレクトリを参照してくれます。

Arduino IDEを使う

Arduino IDEはソースコードをコンパイルして実機に転送してくれます。今回使うライブラリと一緒に説明していきます。
まずは最初に使うライブラリの宣言をします。今回用いるライブラリはプロコントローラーと同じ信号をArduinoから送信します。

#include <SwitchControlLibrary.h>

次に各ボタンの動作です。

# Aボタンを押す
SwitchControlLibrary().PressButtonA();
# Aボタンを離す
SwitchControlLibrary().ReleaseButtonA();

このように、ボタンを押す動作と離す動作が別になっているので、これらをペアで使っていきます。対応しているボタンは、

void PressButtonY();
void ReleaseButtonY();
void PressButtonB();
void ReleaseButtonB();
void PressButtonA();
void ReleaseButtonA();
void PressButtonX();
void ReleaseButtonX();
void PressButtonL();
void ReleaseButtonL();
void PressButtonR();
void ReleaseButtonR();
void PressButtonZL();
void ReleaseButtonZL();
void PressButtonZR();
void ReleaseButtonZR();
void PressButtonMinus();
void ReleaseButtonMinus();
void PressButtonPlus();
void ReleaseButtonPlus();
void PressButtonLClick();
void ReleaseButtonLClick();
void PressButtonRClick();
void ReleaseButtonRClick();
void PressButtonHome();
void ReleaseButtonHome();
void PressButtonCapture();
void ReleaseButtonCapture();

です。詳しくはライブラリ内のSwitchControlLibrary.hを読んでください。

次に矢印ですが、スティックではない方向キーは、

MoveHat();

この関数を利用します。上を0として、8分割して、時計回りに数えます。そして中心が8です。例えば、右左 と入力したければ、

MoveHat(2);
MoveHat(6);
MoveHat(8);

となります。最後に真ん中に戻してあげるのを忘れないようにしてくださいね。

自動化

あとはこれらの関数をうまく組み合わせると自動化の出来上がりです。これらの関数をArduinoのloop()に入れてあげることで繰り返し実行することができます。

また、Arduinoの動作はSwitchが認識できる速度より数倍速く動作してしまうので適宜delay()を用いて時間調整をしてあげることが必要です。

そんなこんなでできたコードがこちら。

#include <SwitchControlLibrary.h>

void setup(){
}

void loop() {
  // 開始 みんなで挑戦の直前から。
  SwitchControlLibrary().PressButtonA();
  delay(50);
  SwitchControlLibrary().ReleaseButtonA();
  delay(3000);
  // 募集開始
  SwitchControlLibrary().PressButtonHome();
  delay(50);
  SwitchControlLibrary().ReleaseButtonHome();
  delay(1000);
  SwitchControlLibrary().MoveHat(4); // down
  delay(50);
  SwitchControlLibrary().MoveHat(8); // center
  delay(100);
  SwitchControlLibrary().MoveHat(2); // right
  delay(50);
  SwitchControlLibrary().MoveHat(8); // center
  delay(100);
  SwitchControlLibrary().MoveHat(2); // right
  delay(50);
  SwitchControlLibrary().MoveHat(8); // center
  delay(100);
  SwitchControlLibrary().MoveHat(2); // right
  delay(50);
  SwitchControlLibrary().MoveHat(8); // center
  delay(100);
  SwitchControlLibrary().MoveHat(2); // right
  delay(50);
  SwitchControlLibrary().MoveHat(8); // center
  delay(100);
  SwitchControlLibrary().PressButtonA();
  delay(50);
  SwitchControlLibrary().ReleaseButtonA();
  delay(1500);
  // 設定画面
  SwitchControlLibrary().MoveHat(4); // down
  delay(2000);
  SwitchControlLibrary().MoveHat(8); // center
  delay(50);
  SwitchControlLibrary().MoveHat(2); // right
  delay(50);
  SwitchControlLibrary().MoveHat(8); // center
  delay(50);
  SwitchControlLibrary().MoveHat(4); // down
  delay(50);
  SwitchControlLibrary().MoveHat(8); // center
  delay(50);
  SwitchControlLibrary().MoveHat(4); // down
  delay(50);
  SwitchControlLibrary().MoveHat(8); // center
  delay(50);
  SwitchControlLibrary().MoveHat(4); // down
  delay(50);
  SwitchControlLibrary().MoveHat(8); // center
  delay(50);
  SwitchControlLibrary().MoveHat(4); // down
  delay(50);
  SwitchControlLibrary().MoveHat(8); // center
  delay(50);
  SwitchControlLibrary().PressButtonA();
  delay(50);
  SwitchControlLibrary().ReleaseButtonA();
  delay(500);
  // 時間設定
  SwitchControlLibrary().MoveHat(4); // down
  delay(50);
  SwitchControlLibrary().MoveHat(8); // center
  delay(50);
  SwitchControlLibrary().MoveHat(4); // down
  delay(50);
  SwitchControlLibrary().MoveHat(8); // center
  delay(50);
  SwitchControlLibrary().PressButtonA();
  delay(50);
  SwitchControlLibrary().ReleaseButtonA();
  delay(500);
  // 時間の変更
  SwitchControlLibrary().MoveHat(2); // right
  delay(50);
  SwitchControlLibrary().MoveHat(8); // center
  delay(50);
  SwitchControlLibrary().MoveHat(2); // right
  delay(50);
  SwitchControlLibrary().MoveHat(8); // center
  delay(50);
  SwitchControlLibrary().MoveHat(0); // up
  delay(50);
  SwitchControlLibrary().MoveHat(8); // center
  delay(200);
  SwitchControlLibrary().PressButtonA();
  delay(50);
  SwitchControlLibrary().ReleaseButtonA();
  delay(50);
  SwitchControlLibrary().PressButtonA();
  delay(50);
  SwitchControlLibrary().ReleaseButtonA();
  delay(50);
  SwitchControlLibrary().PressButtonA();
  delay(50);
  SwitchControlLibrary().ReleaseButtonA();
  delay(50);
  SwitchControlLibrary().PressButtonA();
  delay(50);
  SwitchControlLibrary().ReleaseButtonA();
  delay(100);

  SwitchControlLibrary().PressButtonHome();
  delay(50);
  SwitchControlLibrary().ReleaseButtonHome();
  delay(1000);
  SwitchControlLibrary().PressButtonA();
  delay(50);
  SwitchControlLibrary().ReleaseButtonA();
  delay(1000);
  SwitchControlLibrary().MoveHat(4); // down
  delay(50);
  SwitchControlLibrary().MoveHat(8); // center
  delay(500);
  SwitchControlLibrary().PressButtonA();
  delay(50);
  SwitchControlLibrary().ReleaseButtonA();
  delay(1000);
  SwitchControlLibrary().PressButtonA();
  delay(50);
  SwitchControlLibrary().ReleaseButtonA();
  delay(4000);
  SwitchControlLibrary().PressButtonA();
  delay(50);
  SwitchControlLibrary().ReleaseButtonA();
  delay(2000);
  SwitchControlLibrary().PressButtonA();
  delay(50);
  SwitchControlLibrary().ReleaseButtonA();
  delay(1000);
  SwitchControlLibrary().PressButtonA();
  delay(50);
  SwitchControlLibrary().ReleaseButtonA();
  delay(1000);
}

個人の環境で若干変化がある可能性があるのでそこは随時変更してください。

できたら、 Arduino IDE の ツール>ボード から Arduino Leonardo を選択します。

ここからも重要で、SwitchはデバイスのIDが登録外だった場合、信号を受け付けなくなるので、ArduinoのデバイスのIDをSwitchが認識できるものに変えてあげる必要があります。

Arduinoのインストールされたディレクトリから hardware > arduino > avr と進み、boards.txt の285-286行目を、

leonardo.vid.1=0x0f0d
leonardo.pid.1=0x0092

と変更してあげます。

完成したら、Arduino IDE に戻って、左上の矢印からマイコンボードに書き込んで完了です。

完成したArduinoを変換コネクタをつかってSwitchに接続すれば勝手に動いてくれます。

最後に

ライブラリを公開してくださっている方がいたおかげで随分と簡単に実装ができてしまいました。

あとは、画像認識と組み合わせて自動孵化厳選装置も作ってみたいですね。

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
83
Help us understand the problem. What are the problem?