赤外線リモコン信号を記録して送信する学習リモコンをラズパイゼロでつくる。

自作したNutube / PCM2704 DACで「これがNutubeの音かぁ」と思いながら, エージングしていると, 以前ラズパイ3とBME280ブレイクアウトといっしょにラズパイゼロWを買っていたことを思い出した。

ラズパイ3はいまBME280 / ADRSIRを接続して

この状態で環境測定をしているが, ラズパイゼロはその用途がかぶっているから使い道が見つからずに買ったまま放置していた。

ラズパイゼロを活用して

ラズベリーパイ専用学習リモコン基板 ADRSIRをラズパイ3に取り付けているので自分の必要から作るわけではないのですが, 上のページはなぜかよく見られているようなので, そのページで解析していたリモコン信号を手に入れるデバイスを作ってみようかと思う。
機能がかぶっているデバイスを作るなんて, ソフト屋さんに嫌われている「車輪の再発明」であるが,
自分はソフトウェアの人ではないので関係ありません。

注意

部品は自分の部品箱を探して使えそうなものでやりますので, あくまで実験目的です。
これで良い物ではないと考えてください。
作りたくて部品を集めるなら, 各自きちんと設計してください。

ハードウェア

用意するもの

  • ラズパイゼロW
    (自分はピンヘッダがついていないものでした)
  • 電源アダプタとかUSBケーブルとかケースとかSDカードとか
    (セットで買いました)
  • 赤外線受信モジュール
    (部品箱から出てきたPL-IRM2161-XD1)
  • デカップリングコンデンサ
    (部品箱から出てきた0.1uFのセラコンと100uFの電解コン)
  • ブレッドボードとジャンパワイヤー
  • 赤外線LED
    (部品箱から出てきたLUIR034, これは波長850nmなので今回の応用には不適切な部品。波長950nmの物を使ってください)
  • トランジスタとかFETとか, 赤外線LEDを駆動するデバイス
    (自分は部品箱から出てきたTC4049BPロジックICを使ったけど, 駆動回路は各自設計してください)

回路をブレッドボード上に作る

目的が実験なので雑でいいとはいえ自分でも知性を感じない回路だなんて思う。


赤外線LEDをまさかの「電☆源☆直☆結」とか。
(電流?しらん。真似しない事)

さらに手持ちの赤外線LEDを全部乗せるとか
(電流バランス?しらん 。真似しない事 )

1ゲートのNOTで電流がもの足りないから6ゲート束にするとか,さらにICを2階建てで12ゲートを束にするとか。
“出力電流が大きく”とメーカーが言っているからなんとかなるでしょ(雑)。

TC4049BP/BF 、 TC4050BP/BF は 、 6 回路のバッファで TC4049BP/BF が反転型、TC4050BP/BF が非反転型です。 出力電流が大きく、1 個の TTL を直接駆動できるため、CMOS か ら TTL の接続に有用です。入力は、VDD に無関係に VSS + 18 V ま での電圧を加えることができるため、15 V、10 V 系の CMOS 論理 回路から 5 V 系の CMOS/TTL 論理回路へのレベル変換 IC としても 使用できます。 回路構造は、TC4049BP/BF が 3 段インバータ、TC4050BP/BF が 2 段インバータのため、理想的なスイッチング特性を示します。

TC4049BPデーターシート

この回路は真似しない事を強くおすすめします。

もう一度いいますね
この回路は真似しない事を強くおすすめします。

皆さんはよいドライバーを設計してください。
自分はADRSIRを使うので, これはソフトの動作が確認出来たらいいという割り切りです。

ソフトウェア

ラズパイゼロのSDカードにOSのインストールとWifiの設定を済ましておいてください。
すでに良い記事がWebにあるので, この部分は省略します。

言語の選定

リモコンから送信された 38kHz Duty1/3 で点滅する赤外線リモコン信号を記録して再生が出来るプログラムを作ることが目的。

検索すると似たような物を作っている人がいる。
すでにPythonでプログラムが公開されていたりとか,
LIRC はあきらめましょうとか,
pigpioだとか。
カーネルバージョンがどうだとか。

・ ・ ・ むつかしいな。

することは単純で, 正確な時計(38kHz = 26µs)に同期してピンのH/Lを読み込んだらいいだけ。 (ベアメタルなら)

時計との同期に遅れるとタイミング違反の条件で, OSのタイマ-によって動作するから, 他のプロセスに時間を融通する関係で早ければ早いほどよい言語。

ここで代表的な言語の選定(自分調べ)

Python

Pythonは良い言語だけど, 検索すると出てくる先例でうまく動かないのはおそらくタイミング違反。
Pythonは速度とメモリ使用量の点で脱落。

Elixir

Elixirのアクターモデル

  • すべてのものはアクターである
  • アクターはお互いにメッセージを送りながら動作します

は好きな世界でWebのバックエンドにおいて至高の言語だと考えるが, 速度とメモリ使用量の点で脱落。

PureScript

Purescriptの純粋関数で構成される世界も至高だが, 速度とメモリ使用量の点で脱落。

最速言語(自分にとっての)

選ばれたのはRustでした。

低レベルな制御に「下がる」必要があるプログラマは、お決まりのクラッシュやセキュリティホールのリスクを負わず、 気まぐれなツールチェーンのデリケートな部分を学ぶ必要なくRustで同じことができます。さらにいいことに、 Rustは、スピードとメモリ使用の観点で効率的な信頼性の高いコードへと自然に導くよう設計されています。

まえがき – The Rust Programming Language
https://doc.rust-jp.rs/book/second-edition/

・ ・ ・ 本当ははじめから決めていた。
ハードウェアを直接制御し, OSによる抽象化すら邪魔な領域ですもんね。

ソフトウェアを大別すると

  • アプリケーションソフトウェア
  • システムソフトウェア

とあって, これは典型的な「システムソフトウェア」の領域なので「 システムプログラミング言語 」でないとそもそも無理。

システムプログラミング言語とは、システムプログラミングでよく使用されるプログラミング言語のことである。このような言語は、システムソフトウェアを書くために設計されており、アプリケーションソフトウェアを書く場合とは異なる設計アプローチが求められる。
システムソフトウェアとは、コンピューターのハードウェアの操作・制御のために設計されたコンピューターのソフトウェアであり、アプリケーションソフトウェアを実行するためのプラットフォームを提供する。システムソフトウェアのカテゴリーとしては、オペレーティングシステム、ユーティリティソフトウェア、デバイスドライバ、コンパイラ、リンカなどがある。

システムプログラミング言語
https://ja.wikipedia.org/wiki/システムプログラミング言語

ところで何で比較したかって?
上のページにあるリモコン信号解析アプリケーションは

  • バックエンド
    Elixir / Phoenix
  • フロントエンド
    PureScript / Halogen

だからだよという小ネタをはさんでみた。

RustをラズパイゼロWにインストール

Rustの公式サイト https://www.rust-lang.org/tools/install から

pi@raspberrypi:~/ > curl https://sh.rustup.rs -sSf | sh

これで入りました。

pi@raspberrypi:~/irremocon/ > uname -a
Linux raspberrypi 4.19.57+ #1244 Thu Jul 4 18:42:50 BST 2019 armv6l GNU/Linux
pi@raspberrypi:~/irremocon/ > cargo --version
cargo 1.36.0 (c4fcfb725 2019-05-15)
pi@raspberrypi:~/irremocon/ > rustc --version
rustc 1.36.0 (a53f9df32 2019-07-03)
pi@raspberrypi:~/irremocon/ >

GitHub

GitHubにソース一式をおいておきます。
https://github.com/ak1211/irremocon

ビルド

使うだけの人はリリースビルドでよろしく。
もちろん開発者はデバッグビルドでもよい。
初回はとても待つことになる。0.88秒となっているのはすでにビルドした後だったので。

pi@raspberrypi:~/irremocon/ > cargo build --release
    Finished release [optimized] target(s) in 0.88s
pi@raspberrypi:~/irremocon/ > ls -l target/release      
 合計 5232
 drwxr-xr-x 8 pi pi    4096  8月 13 00:18 build
 drwxr-xr-x 2 pi pi    4096  8月 13 08:12 deps
 drwxr-xr-x 2 pi pi    4096  8月 13 00:18 examples
 drwxr-xr-x 2 pi pi    4096  8月 13 00:18 incremental
 -rwxr-xr-x 2 pi pi 2665516  8月 13 00:30 irrec
 -rw-r--r-- 1 pi pi     108  8月 13 00:30 irrec.d
 -rwxr-xr-x 2 pi pi 2515120  8月 13 08:12 irsend
 -rw-r--r-- 1 pi pi     110  8月 13 00:30 irsend.d
 -rw-r--r-- 1 pi pi      83  8月 13 00:30 libirremocon.d
 -rw-r--r-- 2 pi pi  137282  8月 13 00:29 libirremocon.rlib
 drwxr-xr-x 2 pi pi    4096  8月 13 00:18 native
 pi@raspberrypi:~/irremocon/ >

irrec / irsend ができあがった実行ファイル。
rustはスクリプト言語ではないので, 実行するだけならrustのインストールはいらない。

赤外線リモコン信号の記録

irrecを実行してIRモジュールに手持ちのリモコンを向けてボタンを押すとコードが見られる。
あとはコピーして上のページに貼り付けたら内容が見える。
見えなければ記録に失敗していると思う。
teeを入れているのはついでにファイルに記録するため。

pi@raspberrypi:~/irremocon/ > ./target/release/irrec | tee remocon.ir
 irrec v0.1.0
 This program is display infrared codes.
 <<< Press any key to exit. >>>
 Please press buttons on your remote control.
 7C003C000C002C000C002E000A0010000C000E000C000E000C002C000A0010000C000E000C002C000C002E000C000E000C002E000A0010000A0010000C002C000C002E000C000E000C002C000C002E000C000E000C002C000C0010000A0010000C000E000C000E000C0010000A002E000C000E000C000E000C0010000C002C000C000E000C000E000E000E000C000E000C000E000C000E000E000E000C000E000C002C000C002E000C000E000C000E000C002C000E000E000C000E000C000E000C002E000C002C000C000E000C000E000E000E000C000E000C000E000C000E000E000E000C000E000C000E000C000E000C000E000E002C000C000E000C000E000C002E000C008E02
 bye.
 pi@raspberrypi:~/irremocon/ > ls                                     
 Cargo.lock  Cargo.toml  LICENSE  remocon.ir  src  target
 pi@raspberrypi:~/irremocon/ > cat remocon.ir                         
 7C003C000C002C000C002E000A0010000C000E000C000E000C002C000A0010000C000E000C002C000C002E000C000E000C002E000A0010000A0010000C002C000C002E000C000E000C002C000C002E000C000E000C002C000C0010000A0010000C000E000C000E000C0010000A002E000C000E000C000E000C0010000C002C000C000E000C000E000E000E000C000E000C000E000C000E000E000E000C000E000C002C000C002E000C000E000C000E000C002C000E000E000C000E000C000E000C002E000C002C000C000E000C000E000E000E000C000E000C000E000C000E000E000E000C000E000C000E000C000E000C000E000E002C000C000E000C000E000C002E000C008E02
 pi@raspberrypi:~/irremocon/ >

これは三菱電機扇風機リモコン入/切のコード

赤外線リモコン信号の送信設定

https://docs.golemparts.com/rppal/0.11.3/rppal/pwm/index.html

RPPAL – Raspberry Pi Peripheral Access Library ページによるハードウェアPWMの設定

rootユーザーなら権限問題にならないが, ハードウェアPWMを使うのにsudoするのも使いにくいのでこのように設定を追加します。(バックスラッシュは日本語環境では¥記号に見える。注意)

/boot/config.txt

dtoverlay=pwm

/etc/udev/rules.d/99-com.rules

 SUBSYSTEM=="pwm*", PROGRAM="/bin/sh -c '\ 
    chown -R root:gpio /sys/class/pwm && chmod -R 770 /sys/class/pwm;\ 
    chown -R root:gpio /sys/devices/platform/soc/*.pwm/pwm/pwmchip* &&\ 
    chmod -R 770 /sys/devices/platform/soc/*.pwm/pwm/pwmchip*\ 
'" 

再起動

pi@raspberrypi:~/irremocon/ > sudo reboot

赤外線リモコン信号の送信

扇風機に赤外線LEDを向けて

pi@raspberrypi:~/irremocon/ > ./target/release/irsend < remocon.ir 
irsend v0.1.0
pi@raspberrypi:~/irremocon/ >

扇風機が回り出した。

赤外線LEDの点灯は肉眼で見えないのでカメラを通して見ると かなり強烈な電流が流れているようだ。
バラスト抵抗がないので赤外線LEDに流れる電流を制限する物は電源のインピーダンスとNOTゲートの抵抗のみだからね。
38kHz 1/3duty(点灯, 消灯, 消灯)の繰り返しのパルス点灯だからどうにかなるでしょう。保証はしないけれども。

感想

計画通りに実験が成功したので満足です。
比較していないけれども, Rustの高速性はC/C++に比肩する物と考えています。
PythonでうまくいかないならRustでやってみることをおすすめします。

あと, 自分はADRSIRがあるのでこのハードは使いません。
常用するなら前回の余りがある TTC015B とか TTA008B とかでLED駆動回路作りますし。

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください