JoyConでLチカしてみた!
この記事は, Muroran Institute of Technology Advent Calendar 2019 - Adventar 18日目の記事です.
はじめに
はてなブログ始めちゃいました!ぷりんです。大学のアドカレを見つけたら後輩に圧をかけられたので自分の誕生日分を担当することにしました。とても遅れちゃってごめんなさいm(__)m。
ぷりんさん残りのマス埋めていいですよ
— 🔥はいばら🔥 (@w_haibara) December 4, 2019
ニンテンドーswitchのJoyConで遊んでみたので紹介します。
120文字を超える文章を書くのは苦手なのですが最後まで読んでくれると嬉しいです。
環境
- Windows10
- Python 3.7
- hidapi モジュール (https://pypi.org/project/hidapi/) 最初はUbuntuで試したのですが、Joyconをhidとして検出出来なかったのでWindowsです。
Joyconの規格
Joyconの通信はNintendo Switch|任天堂にも書かれている通りBluetooth 3.0です。 なのでPython3 からLEDを光らせたり、センサーから入力を取得できそうです。
また、Switchを解析している以下のリポジトリを参考にしました。 https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering
早速通信してみる
入力レポートの設定を参考にシンプルHIDモードで入力を受け取ってみます。
import hid import time VENDOR_ID = 0x057E L_PRODUCT_ID = 0x2006 R_PRODUCT_ID = 0x2007 joycon_device = hid.device() joycon_device.open(VENDOR_ID, R_PRODUCT_ID) joycon_device.write(b'\x01'+b'\x00'+b'\x00\x01\x40\x40\x00\x01\x40\x40'+b'\x03'+b'\x3f') while True: print(joycon_device.read(12))
なんか通信できてそうですね!
Lチカ
subcommand0x30によると、player番号を表してるLEDやHomeボタンも光らせることが出来るので光らせます。 Playerライトは引数の上位ニブルで点滅、下位ニブルで点灯を制御できるそうです。 また、Homeボタンはフェージングとか出来るので楽しいです。詳しくは ここ を読んでください。
def player_light(joycon_device, flush, light): write_output(joycon_device, 0, b'\x01', b'\x30', ((flush << 4) + light).to_bytes(1,byteorder='big')) def home_lamp(joycon_device, cycle_number, pattern, cycle_duration, LED_start_power): argument = ((len(pattern) & 0xf) << 12) + ((cycle_duration & 0xf) << 8)\ + ((LED_start_power & 0xf) << 4) + (cycle_number & 0xf) pattern = (pattern + [[0,0,0] for i in range(15)])[:15] for i in range(7): argument <<= 24 argument += ((pattern[i*2][0] & 0xf)<<20) + ((pattern[i*2+1][0] & 0xf)<<16)\ + ((pattern[i*2][1] & 0xf)<<12) + ((pattern[i*2][2] & 0xf)<<8)\ + ((pattern[i*2+1][1] & 0xf)<<4) + ((pattern[i*2+1][2] & 0xf)<<0) argument <<= 16 argument += ((pattern[14][0] & 0xf)<<12)\ + ((pattern[14][1] & 0xf)<<4)\ + ((pattern[14][2] & 0xf)<<0) write_output(joycon_device, 0, b'\x01', b'\x38',argument.to_bytes(25,byteorder='big')) def write_output(joycon_device, packet_number, command, subcommand, argument): order = (command # 1Byte + packet_number.to_bytes(1,byteorder='big') # 1Byte + b'\x00\x01\x40\x40\x00\x01\x40\x40' # 8Byte + subcommand # 1Byte + argument) # 引数 joycon_device.write(order)
home_lampのpatternは[LED光度,PWMの何か(これを大きくするとゆっくり遷移する),遷移にかける時間]*15です。実際に動かしてみました。
import joycon import time joycon.home_lamp(joycon.get_joyconR(),0x0,[[0xf*(i%2),abs(15-i*2),abs(15-i*2)]for i in range(14)],1,0xf) count = 0 signal = [1,3,7,15,14,12,8,0] while 1: joycon.player_light(joycon.get_joyconR(), 0,signal[count]) count = (count+1) % 8 time.sleep(0.5)
光った!!!!
クリスマスイルミネーション pic.twitter.com/zmuPV1tfWt
— ぷりん🍮 (@nep_pudding3) December 24, 2019
きれいですね!皆さんもJoyconでクリスマスツリーを作ってみてはどうですか?
他の機能
Joyconには他にもHD振動(閃乱カグラの乳を表現した機能)やARカメラ(透視とかできるのかな?)があるのでそれも遊んでみたいです。
最後に
いまプリパラ2期がYoutubeで無料公開されています。ぜひ見てください(唐突なダイマ)
おしまい