Program Resource

開発者向け各種コード、アルゴリズム、リソース情報ライブラリ もしくはねふぁの覚え書き

前回はBluetoothキーボードライブラリを使ってM5StackをBluetoothキーボード化してみた。今回は同じ開発者が提供しているBluetoothマウスライブラリを使って、Bluetoothマウス化してみる。

https://github.com/T-vK/ESP32-BLE-Mouse

Zip形式でライブラリを追加しておく。

マウスの操作方法はジョイスティックを使う等色々考えられるが、今回はMPU9250のジャイロセンサーを使用する。I2C接続で繋いでおく。

M5Stackの種類によってはジャイロセンサー内蔵タイプもあるので、そういったモデルであれば完全にM5Stack単体で済む。M5Stackの種類については下記サイトが分かり易くまとめられている。

スケッチは以下の通り。持ち方を考えて、M5Stackを上下逆にしている。ボタンCは左クリック、ボタンAは右クリック、ボタンBを押しながら傾けるとスクロールにしている。ジャイロセンサーもライブラリで簡単に使えるので、スケッチもこれだけで済む。

#define M5STACK_MPU9250
#include <M5Stack.h>
#include <BleMouse.h>

#define GYRO_CHECK_INTERVAL		10
#define GYRO_CHECK_INTERVAL_WHEEL	30

BleMouse bleMouse("M5 GyroMouse");
bool blestate = false;
bool wheelmode = false;
int gyrointerval = GYRO_CHECK_INTERVAL;
signed char mousex, mousey, mwheel;
int ipitch, iroll, iyaw;
float pitch, roll, yaw;
char chbuff[32];
unsigned long current_millis, last_millis = 0;

void showstate(char *txt) {
	M5.Lcd.setCursor(0, 120);
	M5.Lcd.fillRect(0, 120, 320, 20, BLACK);
	M5.Lcd.printf(txt);
}

void showgyro(char *txt) {
	M5.Lcd.setCursor(0, 140);
	M5.Lcd.printf(txt);
}

void setup() {
	M5.begin();
	M5.Power.begin();
	bleMouse.begin();

	M5.Lcd.clear(BLACK);
	M5.Lcd.setRotation(3);
	M5.Lcd.setTextSize(2);
	M5.Lcd.println("Gyro Mouse");
	M5.Lcd.println("C: Left");
	M5.Lcd.println("B: Wheel (Hold)");
	M5.Lcd.println("A: Right");
	showstate("Disconnected");

	M5.IMU.Init();
}

void loop() {
	M5.update();

	current_millis = millis();

	if (bleMouse.isConnected()) {
		if (!blestate) {
			blestate = true;
			showstate("Connected");
		}

		if (current_millis - last_millis > gyrointerval) {
			M5.IMU.getAhrsData(&pitch, &roll, &yaw);
			sprintf(chbuff, "%.1f %.1f %.1f           ", pitch, roll, yaw);
			ipitch = (int)pitch;
			iroll = (int)roll;
			iyaw = (int)yaw;
			showgyro(chbuff);
			if (wheelmode) {
				mousex = 0;
				mousey = 0;
				if (abs(ipitch) >= 10)
					mwheel = (signed char)(ipitch / 10);
			} else {
				mousex = (signed char)((iroll < 0 ? min(0, iroll + 10) : max(0, iroll - 10)) / 10);
				mousey = -1 * (signed char)((ipitch < 0 ? min(0, ipitch + 10) : max(0, ipitch - 10)) / 10);
				mwheel = 0;
			}
			bleMouse.move(mousex, mousey, mwheel);
			last_millis = current_millis;
		}

		if (M5.BtnA.wasPressed()) {
			bleMouse.press(MOUSE_RIGHT);
		} else if (M5.BtnA.wasReleased()) {
			bleMouse.release(MOUSE_RIGHT);
		} else if (M5.BtnB.wasPressed()) {
			wheelmode = true;
			gyrointerval = GYRO_CHECK_INTERVAL_WHEEL;
		} else if (M5.BtnB.wasReleased()) {
			wheelmode = false;
			gyrointerval = GYRO_CHECK_INTERVAL;
		} else if (M5.BtnC.wasPressed()) {
			bleMouse.press(MOUSE_LEFT);
		} else if (M5.BtnC.wasReleased()) {
			bleMouse.release(MOUSE_LEFT);
		}
	} else {
		if (blestate) {
			blestate = false;
			showstate("Disconnected");
		}
	}
}

PCとペアリングして操作した様子を動画に撮ってみた。GPD MicroPCとペアリングしようとしてみたが、なぜかこちらは上手くペアリングできなかった。

Print Friendly, PDF & Email

This post is also available in: 英語

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


*

CAPTCHA