ラベル USB mouse の投稿を表示しています。 すべての投稿を表示
ラベル USB mouse の投稿を表示しています。 すべての投稿を表示

2023年4月16日日曜日

Raspberry Pi PicoをUSBマウスとして使う(3/3)(マウスボタンのダブルクリックが使えるようにする)

マウスのダブルクリックが動くようにする

前の投稿で,マウスのダブルクリックができませんでしたが,このサイトで確認したところ,クリックも判定してもらえていないことが分かりました.

改めて,サンプルプログラムで確認しました.

Arduino IDEのメニューをたどると,サンプルプログラムとして[File]→[Examples]→[09.USB]→[Mouse]→[ButtonMouseControl]というのがあります.このサンプルでは,Mouse.press()とMouse.release()だけを使っており,Mouse.click()を使っていないのですが,このプログラムを用いると,このサイトのシングルクリックの判定とダブルクリックの判定がうまくいきました.また,ドラッグの動作もうまく行きました.

そこで,シンプルに,クリックとドラッグの判定をせずに,マウスボタンのdownとupそのものを送出するようにしました.

これが以下のプログラムです.

// move mouse cursor by joystick
// implement left/right button
// 2023/4/16

#include <Mouse.h>

void setup() {
  Serial.begin(9600);
  // joystick
  gpio_init(27);
  gpio_set_dir(27, GPIO_IN); // GP27 in:0(false) out:1(true)
  gpio_init(28);
  gpio_set_dir(28, GPIO_IN); // GP28 in:0(false) out:1(true)
  // button
  gpio_init(16); // right button
  gpio_set_dir(16, GPIO_IN);
  gpio_pull_down(16);
  gpio_init(17); // left button
  gpio_set_dir(17, GPIO_IN);
  gpio_pull_down(17);
  Mouse.begin();
  delay(5000);
}

#define MIN_RAW 3
#define MAX_RAW 1023
#define MIDDLE_RAW ((MAX_RAW - MIN_RAW)/2)

#define MOUSE_DOWN 1
#define MOUSE_UP 0

void loop() {

  //----------------------------------------
  // move
  uint16_t raw_x = analogRead(28); // 3..1023
  int16_t value_x = (raw_x - MIDDLE_RAW)/10; // -50..51
  uint16_t raw_y = analogRead(27); // 3..1023
  int16_t value_y = (raw_y - MIDDLE_RAW)/10; // -50..51

  float dx=0.0;
  float dy=0.0;
  if (value_x > 0) {
    dx = -((float)value_x * value_x / 200.0);
  } else {
    dx = ((float)value_x * value_x / 200.0);
  }
  if (value_y > 0) {
    dy = (float)value_y * value_y / 200.0;
  } else {
    dy = -(float)value_y * value_y / 200.0;
  }
  Mouse.move(dx, dy, 0);

  //----------------------------------------
  // click/drag
  bool left_button_val = gpio_get(17);
  bool right_button_val = gpio_get(16);

  // left button down
  if (left_button_val == MOUSE_DOWN) {
    // if the mouse is not pressed, press it:
    if (!Mouse.isPressed(MOUSE_LEFT)) {
      Mouse.press(MOUSE_LEFT);
    }
  } else {
    // if the mouse is pressed, release it:
    if (Mouse.isPressed(MOUSE_LEFT)) {
      Mouse.release(MOUSE_LEFT);
    }
  }
  // right button down
  if (right_button_val == MOUSE_DOWN) {
    // if the mouse is not pressed, press it:
    if (!Mouse.isPressed(MOUSE_RIGHT)) {
      Mouse.press(MOUSE_RIGHT);
    }
  } else {
    // if the mouse is pressed, release it:
    if (Mouse.isPressed(MOUSE_RIGHT)) {
      Mouse.release(MOUSE_RIGHT);
    }
  }
  delay(10);
}

これでめでたく,USBマウスとして使用することができるようになりました.

2023年4月13日木曜日

Raspberry Pi PicoをUSBマウスとして使う(2/3)(マウスボタンのクリック・ドラッグ)



前回の続きです.

Raspberry Pi PicoをUSBマウスとして使用するにあたって,マウスボタンの実装をします.

まずボタンは物理的にはスイッチとして実装されており,Raspberry Pi PicoではON (down)かOFF (up)かの状態が瞬間ごとに読み取れます.これだけではクリックとドラッグの区別ができませんので,ソフトウェアで実装します.

ソフトウェア

まず,ONかOFFかの読み取りは定期的に行われているので,前回の状態を記憶しておいて,ON→OFFとOFF→ONの状態変化を読み取ります.OFF→ONがボタンのdown,ON→OFFがボタンのupになります.

マウスのイベントとしては,MOUSE_DOWN, MOUSE_UP, MOUSE_CLICKを発出する必要があります.MOUSE_DRAGとMOUSE_CLICKのモードを作成して,MOUSE_DRAGモードの際にはMOUSE_DOWNとMOUSE_UPのイベントを発出します.MOUSE_CLICKモードの際には,マウスボタンを離した瞬間にMOUSE_CLICKイベントを発出することにします.

さらに,MOUSE_DRAGモードとMOUSE_CLICKモードの区別は以下のようにします.downの瞬間にdownしている時間の計測を始めます.初期状態はMOUSE_CLICKにしておいて,ある閾値(ここでは0.5秒)を超えたら,MOUSE_CLICKからMOUSE_DRAGに状態変化すると同時に,ここでMOUSE_DOWNイベントを発出します.

マウスボタンがupされた時点で,現在MOUSE_DRAGモードの場合にはMOUSE_UPイベントを,MOUSE_CLICKモードの場合にMOUSE_CLICKイベントを発出します.

図示すると以下のようになります.

ハードウェア

ハードウェアの製作は以下のようになります.push buttonの片方のピンを3.3Vに接続して,もう片方のピンをGPIOにpull down接続します.今回はGP16とGP17を使いました.

配線全体は以下のようになります.


以下の写真はボタンの部分の配線です.


以下の写真はRaspberry Pi Pico側の配線です.


ダブルクリックについて

ダブルクリックが未実装です.これも時間を測って,時間の閾値を決めてその時間内にマウスボタンがON→OFF→ON→OFFされたらダブルクリックイベントを発出する必要があるみたいです.

もしくは,OSに合わせてハードウェア側でクリックの時間をある程度決めないといけないのかも知れません.

続きはここで.

2023年4月12日水曜日

Raspberry Pi PicoをUSBマウスとして使う(1/3)(マウスカーソルの移動)

Raspberry Pi PicoをArduino IDEから使うと,USBマウスのサンプルソースコードがあります.メニューバーで[File]→[Examples]→[Mouse]→[Circle]のプログラムです.

このプログラムをArduino IDEからRaspberry Pi Picoに書き込み,Raspberry Pi PicoのBOOTSELボタンを押すと,マウスカーソルが円形に一周動きます.macOSのシステム設定でマウスの軌跡の速さを変更すると,この円の半径が変わるので,Raspberry Pi PicoがUSBマウスとして認識されていることが分かります.

ハードウェア

まず,ジョイスティックを使ってマウスカーソルを動かします.ジョイスティックとしてはスイッチサイエンスで購入できるAdafruitの小型アナログジョイスティック小型アナログジョイスティック用ピッチ変換基板をつけた物を,ブレッドボードに挿して用います.

まず,Raspberry Pi Picoのピン配置はこちらにあります.

36pin(3.3V),34pin(GP28),32pin(GP27),28pin(0V)を用います.結線は以下の写真のようにします.全体の写真が以下です.

ジョイスティックのハードウェアは,ただのボリューム(反固定抵抗)で,0Vと+の電圧を与えると,x軸方向とy軸方向の変位に比例した0Vと+の電圧の間の電圧が,x軸方向とy軸方向それぞれに対して出力されます.


次に,Raspberry Pi Pico側の結線の写真が以下です.


最後に,ジョイスティック側の結線の写真が以下です.


ソフトウェア

ジョイスティックの値を読んでシリアルコンソールに表示するプログラムは以下のようになります.

// read joystick and print to serial console
// 2023/4/12

#include <Mouse.h>

void setup() {
  Serial.begin(9600);
  Mouse.begin();
  delay(5000);
}

#define MIN_RAW 3
#define MAX_RAW 1023
#define MIDDLE_RAW ((MAX_RAW - MIN_RAW)/2)

void loop() {
  uint16_t raw_x = analogRead(28); // 3..1023
  int16_t value_x = (raw_x - MIDDLE_RAW)/10; // -50..51
  uint16_t raw_y = analogRead(27); // 3..1023
  int16_t value_y = (raw_y - MIDDLE_RAW)/10; // -50..51

  Serial.print("X raw=");
  Serial.print( raw_x );
  Serial.print(", Value=");
  Serial.print( value_x );

  Serial.print(", Y raw=");
  Serial.print( raw_y );
  Serial.print(", Value=");
  Serial.println( value_y );

  delay(10);
}

次に,ジョイスティックの値を見てマウスカーソルを動かすプログラムは以下のようになります.

// move mouse cursor by joystick
// 2023/4/12

#include <Mouse.h>

void setup() {
  Serial.begin(9600);
  Mouse.begin();
  delay(5000);
}

#define MIN_RAW 3
#define MAX_RAW 1023
#define MIDDLE_RAW ((MAX_RAW - MIN_RAW)/2)

void loop() {
  uint16_t raw_x = analogRead(28); // 3..1023
  int16_t value_x = (raw_x - MIDDLE_RAW)/10; // -50..51
  uint16_t raw_y = analogRead(27); // 3..1023
  int16_t value_y = (raw_y - MIDDLE_RAW)/10; // -50..51

  Serial.print("X raw=");
  Serial.print( raw_x );
  Serial.print(", Value=");
  Serial.print( value_x );

  Serial.print(", Y raw=");
  Serial.print( raw_y );
  Serial.print(", Value=");
  Serial.println( value_y );

  float dx=0.0;
  float dy=0.0;
  if (value_x > 0) {
    dx = -((float)value_x * value_x / 200.0);
  } else {
    dx = ((float)value_x * value_x / 200.0);
  }
  if (value_y > 0) {
    dy = (float)value_y * value_y / 200.0;
  } else {
    dy = -(float)value_y * value_y / 200.0;
  }
  Mouse.move(dx, dy, 0);
  delay(10);
}

マウスボタンの実装

続きはここで.