RN-42 Bluetoothモジュールの使い方3


Pocket

「RN-42Bluetoothモジュールの使い方2」の続きです。

最後にタブレットからPCのマウス、キーボードを遠隔操作してみたいと思います。

タブレットとRN42モジュールとはSPP通信を行い、タブレットからユーザ操作(スライドやタップなど)を送信して、PC側で信号の解読&マウス、キーボード操作を行います。
タブレット側には
・マウスモード
・キーボードモード
・ゲームパッドモード
を作って、それぞれ操作する対象を切り替えられるようにしたいと思います。

 

システム構成

ざっくりしたシステム構成です。

システム構成

PC側のプログラムはPythonで記述しています。使用するライブラリは下記の通りです。

  • Pyserial2.7 : シリアル通信をするために使用しています。
  • ctypes1.0.2 : PythonからCで書かれたライブラリを呼び出すことができます。マウスやキーボード操作のために、WindowsのDLLを呼び出すのに使用しています。
  • Guippy0.1.1 : WinwosGUIを簡単に操作するためのライブラリ。ctypesのラッパー。

 

通信仕様

Bluetooth SPP通信でやり取りするメッセージ仕様です。
とりあえず使いそうな操作を適当に決めてしまいます^^;

Mode 操作 message 補足
マウス マウス移動 ‘M’ (x) (y) x=X軸の移動量(2byte), y=Y軸の移動量(2byte)
右クリック ‘R’
左クリック ‘L’
ホイール ‘O’ (d) d=まわした量(手前<0, 奥>0)
右ドラッグ ‘I’ ドラッグ状態にする
左ドラッグ ‘U’ ドラッグ状態にする
ドロップ ‘J’ 左右のドラッグ状態を解除
ゲームパッド パッド操作 ‘G’ (a) (b) ボタン操作 1=On, 0=Off
a(1byte):
 **000000 = 未使用
 00*00000 = Start
 000*0000 = Esc
 0000*000 = 上
 00000*00 = 下
 000000*0 = 左
 0000000* = 右
b(1byte):
 *0000000 = コンボ1
 0*000000 = パンチ1
 00*00000 = パンチ2
 000*0000 = パンチ3
 0000*000 = コンボ2
 00000*00 = キック1
 000000*0 = キック2
 0000000* = キック3
キーボード *未実装* *未実装* 時間の関係上、キーボードモードは未実装。

ゲームパッドモードは完全にストリートファイターV専用仕様にしてます。
キーボードモードは今回は未実装です・・・手抜きかな?

 

クライアントプログラムの実装

Bluetooth通信部分は、「RN-42Bluetoothモジュールの使い方2」と同じです。

後は、UI部分を実装するだけ。超簡単(適当)なので割愛。gitHub見てね。

今回送信するメッセージは最大でも5byteなので、最大送信時間は40/115200=0.00034s。
クライアント側で4mm以下で連続送信しないようにしてあげれば問題なさそうです。

 

サーバプログラムの実装

こちらもpyserialとguippy使うと簡単に作れました。

# -*- coding: utf-8 -*-

import serial
import struct
import guippy
import time

ser = serial.Serial(3, 115200)
print ser.name
gp = guippy.Guippy()

isDragLeft = False
isDragRight = False

old_key = 0x0000

while True:
	cmd = ser.read()
	print cmd
	
	old_time = time.clock()
	if cmd == 'M':
		x,y = struct.unpack('hh', ser.read(4))
		gp.jump(x,y,True,False)
		print x,y
	elif cmd == 'R':
		gp.click(guippy.mouse.RIGHT)
	elif cmd == 'L':
		gp.click(guippy.mouse.LEFT)
	elif cmd == 'O':
		n, = struct.unpack('b', ser.read())
		gp.wheel(n)
		print n
	elif cmd == 'U':
		isDragLeft = True
		gp.drag(guippy.mouse.LEFT)
	elif cmd == 'I':
		isDragRight = True
		gp.drag(guippy.mouse.RIGHT)
	elif cmd == 'J':
		if isDragLeft: gp.drop(guippy.mouse.LEFT)
		if isDragRight: gp.drop(guippy.mouse.RIGHT)
	elif cmd == 'G':
		key, = struct.unpack('h', ser.read(2))
		print key
		
		if old_key - key <> 0:
			if key&0x2000 > 0: #START
				gp.enter()
			if key&0x1000 > 0: #ESC
				gp.escape()
			if key&0x0800 > 0: #UP
				gp.push(38)
			else:
				gp.release(38)
			if key&0x0400 > 0: #DOWN
				gp.push(40)
			else:
				gp.release(40)
			if key&0x0200 > 0: #LEFT
				gp.push(37)
			else:
				gp.release(37)
			if key&0x0100 > 0: #RIGHT
				gp.push(39)
			else:
				gp.release(39)
			if key&0x0080 > 0: #Combo1
				gp.punch('o')
				gp.push(39)
				gp.release(39)
				gp.push(40)
				gp.release(40)
				gp.push(39)
				gp.release(39)
				gp.punch('u')

				gp.push(40)
				gp.push(39)
				gp.release(40)
				gp.release(39)
				gp.push(40)
				gp.push(39)
				gp.release(40)
				gp.release(39)
				gp.punch('o')

			if key&0x0040 > 0: #P1
				gp.push(85)
			else:
				gp.release(85)
			if key&0x0020 > 0: #P2
				gp.push(73)
			else:
				gp.release(73)
			if key&0x0010 > 0: #P3
				gp.push(79)
			else:
				gp.release(79)
			if key&0x0008 > 0: #Combo2
				gp.push(40)
				gp.push(39)
				gp.release(40)
				gp.push(79)
				gp.release(39)

			if key&0x0004 > 0: #K1
				gp.push(74)
			else:
				gp.release(74)
			if key&0x0002 > 0: #K2
				gp.push(75)
			else:
				gp.release(75)
			if key&0x0001 > 0: #K3
				gp.push(76)
			else:
				gp.release(76)
			old_key = key

	elif cmd == 'E':
		break

	new_time = time.clock()
	elapsed = new_time - old_time
	print elapsed
	old_time = new_time

ser.close()

一番苦労したのは68-86行目、100-105行目のコンボのところですね(笑

あと、ゲームパッドモードの操作は結局キーボード操作(ゲーム側でUは弱パンチとかに設定している)にしているんですが・・・
Guippyのキーボード操作(push,releaseなど)が処理完了までに200msぐらいかかかるようで、格闘ゲームにはまったく使えなかったという。
#かろうじて波動拳、昇竜拳コマンドはいけました

 

動かしてみたよ

さっそく動かしてみました。

やったー!動いた!

・・・まぁ、あまり実用的ではないですが。

 

あとがき

3回にわたってRN42 Bluetoothモジュールの使い方を書いてみました。
基本的な使い方は理解できたかなと思います。

サンプルで作ったプログラムは、あまり実用的ではないですが、スマホをリモコン代わりに使えるようにしたら、もっと実用的にできるかなとも思いました。
例えば、ボタンひとつで、
・メーラーを立ち上げ自動読み上げ
・YouTubeを開いてプレイリストを自動再生
・PCのシャットダウン
とかは、簡単に実装できそうです。

今回のサンプルプログラムは下記においておきますね。
https://github.com/workpiles/BtSample
では。

 
 

Leave a Comment

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