Raspberry Pi 3 model B でエアコンをコントロールした話

やったこと

Raspberry Pi 3 model B に赤外線送受信モジュールを繋いで、エアコンのリモコン信号を解析
→ 解析した信号をRasPiから送信できるようにした

使ったもの

  • Raspberry Pi 3 model B
  • ブレッドボードとジャンパーワイヤ数本
  • 抵抗 270Ω
  • 赤外線リモコン受信モジュール(OSRB38C9AA)
  • 赤外線送信LED (OSI5FU5111C-40)

LIRCとの戦い

以前にRasPi2 model B+を使って同じことをした経験があったので、最近発売されたRasPi3でも挑戦してみた。
結論から言うと、RasPi2と同じ方法では実現出来なかった。

RasPi2ではLIRCというモジュールを使い、irrecordやmode2コマンドで信号解析、irsendコマンドによって信号送信ができた。
しかしRasPi3では、irrecord/mode2で信号解析することは出来たものの、irsendでエラーが発生し、信号送信が出来なかった。

参考: Slack経由で家の外からエアコンをon, offできる装置を、Raspberry Piで作ってみた。(しかも御坂美琴ちゃんが応答してくれる)

参考サイトとは、ピンの位置等が少々異なるので注意。

配線
f:id:s4kr4:20160724121555j:plain

lircインストール

$ sudo apt-get install lirc

/boot/config.txtに追記

dtoverlay=lirc-rpi
dtparam=gpio_in_pin=21
dtparam=gpio_out_pin=20

/etc/lirc/hardware.conf

……
LIRCD_ARGS="--uinput"

#Don't start lircmd even if there seems to be a good config file
#START_LIRCMD=false

#Don't start irexec, even if a good config file seems to exist.
#START_IREXEC=false

#Try to load appropriate kernel modules
LOAD_MODULES=true

# Run "lircd --driver=help" for a list of supported drivers.
#DRIVER="UNCONFIGURED"
DRIVER="default"
# usually /dev/lirc0 is the correct setting for systems using udev
DEVICE="/dev/lirc0"
MODULES="lirc_rpi"
……

ここで一度再起動

バイスファイルの確認

$ ls -l /dev/lirc*
crw-rw---- 1 root video 244, 0 Jul 23 21:02 /dev/lirc0

モジュールの確認

$ lsmod | grep lirc
lirc_rpi                6478  0
lirc_dev                8310  1 lirc_rpi
rc_core                16468  1 lirc_dev

信号解析

$ mode2 -d /dev/lirc0 | tee AIRON
space 4898472
pulse 3516
space 1710
pulse 460
space 404
pulse 457
space 1278
pulse 457
space 406
pulse 457
space 405
pulse 458
space 404
pulse 448
space 414
……
^C

$ mode2 -d /dev/lirc0 | tee AIROFF
……
^C

カレントディレクトリに、"AIRON" "AIROFF"というファイルができる。これらを数値のみのデータに変換し、/etc/lirc/lircd.confに書き込む。

# parse_pulse.rb
lines =  File.open(ARGV[0]).readlines
lines_without_first = lines.slice(1..-1)
puts lines_without_first.map{|line|line.split(" ")[1]}.join(" ")
$ ruby parse_pulse.rb AIRON
$ ruby parse_pulse.rb AIROFF

/etc/lirc/lircd.conf

begin remote

  name  aircon
  flags RAW_CODES
  eps            30
  aeps          100

  gap          200000
  toggle_bit_mask 0x0

      begin raw_codes
    name on
# AIR_ONの中身
3483 1748 423 492 370 1307 428 493 370 472 391 491 371 492 369
492 370 493 369 493 375 487 369 493 370 492 369 493 369 1315 422
491 370 493 369 494 367 495 368 493 368 494 368 500 362 1314 420
1368 368 1314 423 495 366 497 367 1319 413 497 366 497 368 442
418 497 365 496 366 496 368 494 366 496 366 496 374 487 367 497
……

    name off
# AIR_OFFの中身
3476 1747 421 468 394 1319 417 466 396 466 395 492 371 466 394
472 392 467 395 467 395 466 395 470 393 467 395 492 371 1338 398
466 395 469 393 469 395 467 394 468 394 470 392 469 393 1321 416
1325 411 1338 401 489 369 494 368 1323 414 468 392 494 369 467
395 468 394 468 394 493 369 467 395 493 370 468 394 492 369 467
……

      end raw_codes

end remote

ここまでは順調で、あとはirsendで信号を送信するだけ……だったのだが、最初に書いた通りここで躓いた。

$ irsend LIST "" ""
irsend: aircon

$ irsend LIST aircon ""
irsend: 0000000000000001 on
irsend: 0000000000000002 off

$ irsend SEND_ONCE aircon on
irsend: command failed: SEND_ONCE aircon on
irsend: hardware does not support sending

$ irsend SEND_ONCE aircon off
irsend: command failed: SEND_ONCE aircon off
irsend: hardware does not support sending

このように、airconコマンドは登録されているものの、実行ができない。

色々とググっていると、こちらで紹介されているように、Raspberry Pi2 model Bではlircが動作しないらしい。これと同じ現象が、RasPi3で起こっているのかもしれない。 記事にはRasPiのファームウェアをアップデートすると動作するかもしれない……とも書かれていたので、早速試してみる。

$ sudo apt-get install rpi-update
$ sudo rpi-update

しかし、RasPi3では、ファームウェアをアップデートしても問題は解決しなかった。

LIRCは諦めよう

もうLIRCではどうにもならなさそうなので、上記ページで紹介されていたプログラムを使って信号解析・送信をすることにした。

GPIO制御用ライブラリのインストール

$ git clone git://git.drogon.net/wiringPi
$ cd wiringPi
$ ./build

バージョン確認

$ gpio -v
gpio version: 2.32
Copyright (c) 2012-2015 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty

Raspberry Pi Details:
  Type: Pi 3, Revision: 02, Memory: 1024MB, Maker: Embest
  * Device tree is enabled.
  * This Raspberry Pi supports user-level GPIO access.
    -> See the man-page for more details
    -> ie. export WIRINGPI_GPIOMEM=1

scanir.c, sendir.cをコピペし、コンパイルする。

$ sudo gcc scanir.c -o scanir -lwiringPi
$ sudo gcc sendir.c -lm -o sendir -lwiringPi

wiringPiで使用するPIN番号を調べる。

$ gpio readall
 +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 |   2 |   8 |   SDA.1 |   IN | 1 |  3 || 4  |   |      | 5V      |     |     |
 |   3 |   9 |   SCL.1 |   IN | 1 |  5 || 6  |   |      | 0v      |     |     |
 |   4 |   7 | GPIO. 7 |   IN | 1 |  7 || 8  | 0 | IN   | TxD     | 15  | 14  |
 |     |     |      0v |      |   |  9 || 10 | 1 | IN   | RxD     | 16  | 15  |
 |  17 |   0 | GPIO. 0 |   IN | 0 | 11 || 12 | 1 | IN   | GPIO. 1 | 1   | 18  |
 |  27 |   2 | GPIO. 2 |   IN | 0 | 13 || 14 |   |      | 0v      |     |     |
 |  22 |   3 | GPIO. 3 |   IN | 0 | 15 || 16 | 0 | IN   | GPIO. 4 | 4   | 23  |
 |     |     |    3.3v |      |   | 17 || 18 | 1 | IN   | GPIO. 5 | 5   | 24  |
 |  10 |  12 |    MOSI |   IN | 0 | 19 || 20 |   |      | 0v      |     |     |
 |   9 |  13 |    MISO |   IN | 0 | 21 || 22 | 0 | IN   | GPIO. 6 | 6   | 25  |
 |  11 |  14 |    SCLK |   IN | 0 | 23 || 24 | 1 | IN   | CE0     | 10  | 8   |
 |     |     |      0v |      |   | 25 || 26 | 1 | IN   | CE1     | 11  | 7   |
 |   0 |  30 |   SDA.0 |   IN | 1 | 27 || 28 | 1 | IN   | SCL.0   | 31  | 1   |
 |   5 |  21 | GPIO.21 |   IN | 0 | 29 || 30 |   |      | 0v      |     |     |
 |   6 |  22 | GPIO.22 |   IN | 1 | 31 || 32 | 0 | IN   | GPIO.26 | 26  | 12  |
 |  13 |  23 | GPIO.23 |   IN | 0 | 33 || 34 |   |      | 0v      |     |     |
 |  19 |  24 | GPIO.24 |   IN | 0 | 35 || 36 | 0 | IN   | GPIO.27 | 27  | 16  |
 |  26 |  25 | GPIO.25 |   IN | 0 | 37 || 38 | 0 | OUT  | GPIO.28 | 28  | 20  |
 |     |     |      0v |      |   | 39 || 40 | 0 | IN   | GPIO.29 | 29  | 21  |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+

Physical欄が実際のPIN番号、wPi欄がwiringPiで使用するPIN番号。
赤外線受信にはGPIO.29、送信にはGPIO.28を使用していたので、プログラムを以下のように使用する。

$ sudo ./scanir air_on.data 29
write file: air_on.data
scaning pin: 29 (wiringpi)
max keep time: 40(ms)
Infrared LED scanning start.
Pressed Ctrl+C, this program will exit.

# ここで受信モジュールに向けてリモコンのONボタンを押下
Scanning has been done.

$ sudo ./scanir air_off.data 29
write file: air_off.data
scaning pin: 29 (wiringpi)
max keep time: 40(ms)
Infrared LED scanning start.
Pressed Ctrl+C, this program will exit.

# ここで受信モジュールに向けてリモコンのOFFボタンを押下
Scanning has been done.

カレントディレクトリに、"air_on.data" "air_off.data"の2つのデータファイルができる。このファイルを、送信用プログラムに渡してやる。

$ sudo ./sendir air_on.data 1 28

これでようやく信号が送信され、無事エアコンのON/OFFができた。