Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Nintendo Switch の Joy-Con で家電を操作する

More than 1 year has passed since last update.

Life is Tech ! Advent Calendar 2018 23日目の記事です。

はじめに

こんにちは、Life is Tech ! メンターのつっちーです。

突然ですが、僕はいま悩んでいることがあります。それは、「リモコンがたくさんあるのをどうにかしたい問題」についてです。

1_cons.JPG

ライトやエアコン、スピーカなどの家電を操作するリモコン。確かに必要ではあるのですが、たくさんの種類のリモコンが机に置いてある状態はイケてないですよね。別のもので代用して1つにまとめることができれば、とってもスマートになるはずです。

Google Homeなどのスマートスピーカを使って声で操作するという方法は最近よく見られるけど、やっぱり物理的なリモコンの操作性は捨てがたい。市販されているスマートリモコンを買って1つにまとめてもいいけど、それなら何か身近なもので代用できるんじゃないか・・・。

そんなことをぐるぐる考えていた僕の目に、ふと映ったものがありました。

2_switch.JPG

3_joycons.JPG

そう、 Nintendo Switch の Joy-Con です。

手に取りやすいサイズと形で、適度な数のボタンも付いています。複数のリモコンのよく使うボタンを1つにまとめるのには十分ではないでしょうか。
なにより、Joy-Conで暖房をつけることなんかができたりしたらすごく楽しそうです。

というわけで、プログラミングと電子工作の力を使って、Joy-Con をリモコン代わりにしてスマートに家電を操作できるようにしていきたいと思います。

概要

Joy-Con と Raspberry Pi を使い、以下のようなシステムを作っていきます。

system.001.jpeg

今回の記事では、部屋のシーリングライトを操作するこちらのリモコンをメインに扱っていきたいと思います。

5_lightcon.JPG

使用したもの

使用したもの 備考
Nintendo Switch Joy-Con (R) 左右(LR)どちらでも大丈夫です。
シーリングライト用リモコン
Raspberry Pi Zero WH OS: Raspbian GNU/Linux 9.6 (stretch)
micro SDカード
赤外線リモコン受信モジュール(OSRB38C9AA)
5mm赤外線LED(940nm OSI5FU5111C-40)
カーボン抵抗1W200Ω
ジャンプワイヤ オスーメス
ミニブレッドボード(BB-601)

注意

ここから電子工作をしていきますが、部品やRaspberry Piはすぐ壊れてしまうため、実際に試す際は配線を間違えないよう注意して作業してください。自己責任でお願いします。

手順

0. Raspberry Pi のセットアップ

ここでは、Raspberry PiへのOSのインストールや初期設定については省略します。セットアップについては以下の記事が参考になるかと思います。

Raspberry Pi Zero(W)のセットアップ

1. Joy-Conのボタン入力を検知する

まずは、Joy-Conのボタン入力を検知する部分を実装していきます。

Joy-ConとRaspberry Piを接続する

実は、 Joy-Con は普通に Bluetooth デバイスとして扱うことができます。なので、マウスやキーボードと同じようにペアリングするだけで簡単に接続することができます。

今回はコマンドライン上でペアリングしていきます。以下のコマンドで bluetoothctl を起動します。

$ sudo bluetoothctl

bluetoothctl の対話環境が起動するので、以下のように scan on と入力し実行します。

[bluetooth]# scan on

デバイスのスキャンが始まったので、Joy-Conのシンクロボタンを長押ししてペアリングモードにします。
すると、スキャンされたデバイスが一覧で表示される中に、以下のようにJoy-Conが出てきます。

[bluetooth]# scan on
Discovery started
・・・
[NEW] Device XX:XX:XX:XX:XX:XX Joy-Con (R)
・・・

この XX:XX:XX:XX:XX:XX (Joy-Conによって異なります)はMACアドレスです。このMACアドレスを使って以下のようにコマンドを入力することでペアリング・接続を行います。

[bluetooth]# pair XX:XX:XX:XX:XX:XX
[bluetooth]# trust XX:XX:XX:XX:XX:XX
[bluetooth]# connect XX:XX:XX:XX:XX:XX

それぞれ succeeded または successful と表示されれば成功です。

余談ですが、MacやWindowsのPCでも接続できます。ゲームコントローラとして使うことができるのはもちろん、プレゼン用のリモコンとして使うことなんかもできます(参考記事:【JavaScript】スイッチのJoy-Conをプレゼンリモコンにするワンライナー)。余談終わり。

pygameを使ったスクリプトを書く

ペアリングができたら、Joy-Conのボタン入力を検知するスクリプトを書いていきます。Pythonのライブラリである pygame を使います。
今回は con.py というファイルを作って以下のようなコードを書きました。

con.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import time
import pygame


def main():
    pygame.init()
    joys = pygame.joystick.Joystick(0)
    joys.init()

    while True:
        events = pygame.event.get()
        for event in events:
            if event.type == pygame.JOYBUTTONDOWN or event.type == pygame.JOYHATMOTION:
                print(event)
        time.sleep(0.1)


if __name__ == '__main__':
    main()

ちょっと解説

まず pygame をimportします。

con.py
import pygame

次に、pygameの初期化、Joystickの取得・初期化を行っています。

con.py
pygame.init()
joys = pygame.joystick.Joystick(0)
joys.init()

以下の部分では、Joy-Con からの入力を events として取得し、それがボタン入力( pygame.JOYBUTTONDOWN )またはスティック入力( pygame.JOYHATMOTION )であればその内容を print しています。

con.py
events = pygame.event.get()
        for event in events:
            if event.type == pygame.JOYBUTTONDOWN or event.type == pygame.JOYHATMOTION:
                print(event)

このスクリプトを実行し、Joy-Conのボタンを押したりスティックを倒したりしてみると、以下のように出力されるはずです。

$ python3 con.py
<Event(10-JoyButtonDown {'joy': 0, 'button': 0})>
<Event(10-JoyButtonDown {'joy': 0, 'button': 1})>
<Event(10-JoyButtonDown {'joy': 0, 'button': 3})>
<Event(10-JoyButtonDown {'joy': 0, 'button': 2})>
<Event(9-JoyHatMotion {'joy': 0, 'hat': 0, 'value': (0, -1)})>
<Event(9-JoyHatMotion {'joy': 0, 'hat': 0, 'value': (0, 0)})>
<Event(9-JoyHatMotion {'joy': 0, 'hat': 0, 'value': (0, 1)})>
<Event(9-JoyHatMotion {'joy': 0, 'hat': 0, 'value': (0, 0)})>
<Event(9-JoyHatMotion {'joy': 0, 'hat': 0, 'value': (0, -1)})>

何度か試していくと、ボタンとidの対応、スティックの向きとvalueの対応が分かってきますね。
終了する場合はcontrol+C を入力します。
これで、Joy-Conの入力が検知できるようになりました。

2. 送信するリモコン信号を取得する

Joy-Con の入力が検知できるようになったので、次はその入力の際にリモコン信号を送信するようにすればいいですね。しかし、そのためにはどんなリモコン信号を送信すればいいのかを知らなければいけません。そこで、リモコンから電化製品に送られる赤外線信号を取得していきます。

赤外線を受信する回路を組む

まずは赤外線を受信する回路を組んでいきます。
赤外線受信モジュールの3本の足を、Raspberry Piのそれぞれ対応するピンとジャンプワイヤーでつなぎます。
今回はinputをgpio18としました。

IMG_9868.JPG

 2018-12-23 20.01.16.png

pigpioで赤外線を受信する

赤外線の送受信をするために、今回は pigpio というライブラリを使っていきます。僕のRaspberry Piにははじめからインストールされていましたが、もしされていないようであれば以下のようにしてインストールします。

$ sudo apt install pigpio python3-pigpio

以下のコマンドでpigpioを起動しておきます。

$ sudo pigpiod

赤外線の送受信に使うスクリプトはpigpioのサイト上で公開されているもの( http://abyz.me.uk/rpi/pigpio/examples.html#Python_irrp_py )をそのまま使うことにします。

以下のコマンドでダウンロードします。 con.py と同じ場所においておきましょう。

$ curl http://abyz.me.uk/rpi/pigpio/code/irrp_py.zip | zcat > irrp.py

以下のようにこのスクリプトを実行すると、赤外線の受信・学習ができます。

$ python3 irrp.py -r -g18 -f codes light:on --no-confirm --post 100

オプションがたくさん付いていますが、それぞれ下の表のような意味を持っています。

オプション 意味
-r recordモード
-g18 gpio18で受信する
-f codes light:on codesというファイルの中にlight:onという名前で出力する
--no-confirm 確認のためにもう一度信号を要求することをしない
--post 100 100msの間赤外線を受信しなかったら信号が終了したとみなす

実行すると以下のように表示されます。

Recording
Press key for 'light:on'

このときにリモコンを赤外線受信モジュールに向けて「全灯」ボタンを押してみると、

Okay

と出力されて実行が終了します。どんな信号が受信されたのか確認してみると、

$ cat codes
{"light:on": [3456, 1653, 415, 1283, 415, 1283, 415, 408, 415, 408, 415, 1283, 415, 408, 415, 408, 415, 408, 415, 1283, 415, 1283, 415, 1283, 415, 408, 415, 1283, 415, 408, 415, 408, 415, 408, 415, 408, 415, 408, 415, 1283, 415, 408, 415, 408, 415, 408, 415, 408, 415, 408, 415, 1283, 415, 408, 415, 408, 415, 408, 415, 1283, 415, 1283, 415, 1283, 415, 1283, 415, 408, 415, 1283, 415, 1283, 415, 1283, 415, 59728, 3456, 1653, 415, 1283, 415, 1283, 415, 408, 415, 408, 415, 1283, 415, 408, 415, 408, 415, 408, 415, 1283, 415, 1283, 415, 1283, 415, 408, 415, 1283, 415, 408, 415, 408, 415, 408, 415, 408, 415, 408, 415, 1283, 415, 408, 415, 408, 415, 408, 415, 408, 415, 408, 415, 1283, 415, 408, 415, 408, 415, 408, 415, 1283, 415, 1283, 415, 1283, 415, 1283, 415, 408, 415, 1283, 415, 1283, 415, 1283, 415, 59728, 3456, 1653, 415, 1283, 415, 1283, 415, 408, 415, 408, 415, 1283, 415, 408, 415, 408, 415, 408, 415, 1283, 415, 1283, 415, 1283, 415, 408, 415, 1283, 415, 408, 415, 408, 415, 408, 415, 408, 415, 408, 415, 1283, 415, 408, 415, 408, 415, 408, 415, 408, 415, 408, 415, 1283, 415, 408, 415, 408, 415, 408, 415, 1283, 415, 1283, 415, 1283, 415, 1283, 415, 408, 415, 1283, 415, 1283, 415, 1283, 415]}

このように出力されています。ここから、同じ手順で light:off といった名前をつけて各ボタンの信号を受信していくと、このファイルにそれぞれの信号が記録されていきます。

これで、送信したい信号を取得することができました。

3. リモコン信号を送信する

それでは、いま取得した信号を送信する準備をしていきます。

赤外線を送信する回路を組む

まずは、赤外線を送信する回路を組んでいきます。
赤外線LEDと抵抗をジャンプワイヤーでつなぎます。
今回はoutputをgpio21としました。

IMG_9876.JPG

 2018-12-23 20.01.37.png

ここまでで回路は完成です。実際の回路はこのような感じになりました。

IMG_9859.JPG

pigpioで赤外線を送信する

赤外線信号の送信は、以下のコマンドで行うことができます。

$ python3 irrp.py -p -g21 -f codes light:on

オプションは以下の意味を持っています。

オプション 意味
-p playbackモード
-g21 gpio21で送信する
-f codes light:on codesというファイルの中にあるlight:onという名前の信号を出力する

実行することで、赤外線信号がLEDから出力され、シーリングライトの灯りがつきます!わーい!

4. Joy-Conの入力で赤外線信号を送信するようにする

最後に、手順1で作成したJoy-Conの入力を検知するPythonスクリプトと連携させていきましょう。
以下のように書き換えます。

con.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import time
import subprocess
import pygame


def main():
    pygame.init()
    joys = pygame.joystick.Joystick(0)
    joys.init()

    while True:
        events = pygame.event.get()
        for event in events:
            if event.type == pygame.JOYBUTTONDOWN and event.button == 0:
                subprocess.run('python3 irrp.py -p -g21 -f codes light:on', shell=True)
                print('Button 0 was pressed.')

        time.sleep(0.1)


if __name__ == '__main__':
    main()

ちょっと解説

irr.py をスクリプト内で実行するために、subprocess をimportします。

con.py
import subprocess

0番目のボタン(=B)が押されたときに、赤外線信号を送信するコマンドを実行するようにします。

con.py
if event.type == pygame.JOYBUTTONDOWN and event.button == 0:
    subprocess.run('python3 irrp.py -p -g21 -f codes light:on', shell=True)

ここまできたら、以下のようにして実行して、Bボタンを押してみましょう。

$ python3 con.py

IMG_9874.JPG

Joy-Conのボタンを押すことで、シーリングライトを点灯させることができました!

おわりに

少しのプログラミングと簡単な電子工作で、Joy-Conをスマートリモコンとして使えるようにすることができました。これを応用すれば、Joy-Conを使って様々なWebサービスを動かすことも簡単にできそうです。逆に、Joy-Conではない他のデバイスをリモコン代わりにすることもできるでしょう。

こういった開発をすることで身の回りの生活が便利になりますし、なによりも楽しいので、これからもいろいろ作っていきたいと思います。

taznica
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away