【Raspberry Pi Pico入門 – 応用編】マウスを作ってみる

2023年11月21日Raspberry Pi Pico入門,応用編Arduino,Raspberry Pi Pico

概要

基本編で簡易キーボードを作ったということで、今回はマウスを作ってみます。キーボードに比べるとカーソルの移動が多少ややこしいですが、それ以外はキーボードと大きくは変わりません。

まず初めに決められた位置にカーソルを動かすだけのソフトを作ってみて、内容が何となく理解出来たら解説に載せているジョイスティックを使ったマウスを作ってみてください。

実行環境

IDE:Arduino IDE 2.2.1
MCU:Raspberry Pi Pico

回路

最初のサンプルコードはRaspberry Pi単体で動かしてみます。

コーディング

新しくスケッチを作成し、以下の内容をコピペしてください。

#include <Mouse.h>

void setup() {
  Mouse.begin();
  delay(2000);

  /* マウスを右に移動 */
  Mouse.move(1000, 0, 0);
  delay(1000);

  /* マウスを下に移動 */
  Mouse.move(0, 1000, 0);
  delay(1000);

  /* マウスを左に移動 */
  Mouse.move(-1000, 0, 0);
  delay(1000);

  /* マウスを上に移動 */
  Mouse.move(0, -1000, 0);
  delay(1000);

  /* 下にスクロール */
  Mouse.move(0, 0, -10);
  delay(1000);

  /* 上にスクロール */
  Mouse.move(0, 0, 10);
  delay(1000);
}

void loop() {
}

動作確認

Raspberry Pi PicoをPCに接続した時に、マウスカーソルが右→下→左→上の順に動き、その後下にスクロール、上にスクロールすれば成功です。

解説

Mouseライブラリ

マウス用のライブラリはRaspberry Pi Picoのボード情報に標準でインストールされているので、ライブラリの追加作業は必要ありません。#include <Mouse.h>と記述するだけで使えるようになります。

コードの解説

下のコードを実行することでRaspberry Pi PicoがマウスとしてPCに認識され、マウス機能が使えるようになります。
setup()で最初の方に実行してください。

Mouse.begin();

カーソルの移動はmove()を使います。引数がそれぞれ横方向、縦方向、スクロールの移動量になります。
移動量はカーソルの現在の位置からどれだけ動かすかという量なので、画面の位置を指定して動かすことは出来ません。

Mouse.move(横方向, 縦方向, スクロール);

サンプルコードでは使いませんでしたが、他にも以下のような関数があります。

Mouse.click()実行すると「マウスをクリックした」という信号をPCに送ります。
引数を空欄にすると左クリックとして処理されます。
MOUSE_LEFT:左ボタン(デフォルト)。
MOUSE_RIGHT:右ボタン。
MOUSE_MIDDLE:中ボタン。

【使用例】
Mouse.click(MOUSE_RIGHT);  //右クリック
Mouse.press()クリックと似ているが、違うのはボタンを押したままにすることです。ドラッグを再現したいときに便利です。
引数を空欄にすると左クリックとして処理されます。
MOUSE_LEFT:左ボタン(デフォルト)。
MOUSE_RIGHT:右ボタン。
MOUSE_MIDDLE:中ボタン。

【使用例】
Mouse.press(MOUSE_RIGHT);  //右ボタンを押す
Mouse.release()実行すると「Mouse.press()で押したボタンを離した状態に戻した」という信号をPCに送ります。
引数を空欄にすると左クリックとして処理されます。
MOUSE_LEFT:左ボタン(デフォルト)。
MOUSE_RIGHT:右ボタン。
MOUSE_MIDDLE:中ボタン。

【使用例】
Mouse.release(MOUSE_RIGHT);  //右ボタンを離す

ジョイスティックでマウスを作ってみる

これまでの解説を元にしてジョイスティックでマウスを作ってみます。

回路図

回路図はジョイスティックを試したときと同じものを使います。

コーディング

サンプルコードは↓これです。ジョイスティックのXY座標にGAINを掛けて小さくしたものをMouse.move()に代入しています。R_MAXは何もしていない時にカーソルが微妙に動くのを防ぐため、一定以上傾けないと反応しないようにするための閾値です。GAINはカーソルスピードの調整用パラメータで、大きくすると速く、小さくすると遅くなります。

※moveに入れる値の単位は不明です。画面解像度やマウススピードの設定によって変動していそうな感じなので、実際に動かしながらGAINを微調整してください。

#include <math.h>
#include <Mouse.h>

/* GPIO設定 */
const int STICK_X_PIN = 27;
const int STICK_Y_PIN = 26;
const int STICK_SW_PIN = 22;

/* ジョイスティックのパラメータ */
const int DIV = 10;
const int R_MAX = 50;
const float GAIN_X = 0.005;
const float GAIN_Y = 0.005;

/* その他の変数 */
int x_0 = 0;
int y_0 = 0;

void setup() {
  /* マウス初期設定 */
  Mouse.begin();

  /* GPIO,ADC初期設定 */
  analogReadResolution(12);
  pinMode(STICK_X_PIN, INPUT);
  pinMode(STICK_Y_PIN, INPUT);
  pinMode(STICK_SW_PIN, INPUT_PULLUP);

  /* キャリブレーション */
  int x_sum = 0;
  int y_sum = 0;
  for (int i = 0; i < DIV; i++) {
    x_sum += analogRead(STICK_X_PIN);
    y_sum += analogRead(STICK_Y_PIN);
    delay(50);
  }
  x_0 = x_sum / DIV;
  y_0 = y_sum / DIV;
}

void loop() {
  /* ジョイスティックの傾きを測定 */
  int x_val = analogRead(STICK_X_PIN) - x_0;
  int y_val = analogRead(STICK_Y_PIN) - y_0;
  int r = sqrt((x_val * x_val) + (y_val * y_val));

  /* カーソルの移動 */
  if(r > R_MAX){
    Mouse.move((int)((float)x_val * GAIN_X), (int)((float)y_val * GAIN_Y), 0);
  }

  /* スイッチ */
  if(digitalRead(STICK_SW_PIN) == LOW){
    Mouse.press(MOUSE_LEFT);
    delay(20);
  }else{
    Mouse.release(MOUSE_LEFT);
    delay(20);
  }
}

動作確認

ジョイスティックを倒した方向にカーソルが移動し、スティックを押し込んだ時に左クリックとして反応していれば成功です。

もし変なコードを書き込んでしまってカーソルが暴れだしたときは、一旦Raspberry Pi PicoをPCから外して、BOOTSELボタンを押しながらPCに接続してください。「UF2-Board」という名前で認識されるので書き込み先の再設定をして、修正したコードを書き込みます。