2016年9月22日木曜日

今更ですがESP-WROOM-02で赤外線リモコン(174円也)

先日、会社でIoT勉強会を実施しました。

勤務先はガチのソフト開発なのですが、やっぱりIoTへの関心は高く、あっという間に定員に達しました。内容的にはESP-WROOM-02+BME280(気温湿度気圧センサー)+PIRセンサー(人感センサー)+空気質センサー+OLEDという有りがちな組み合わせですが、幸いにも好評のうちに勉強会を終えることができました。


勉強会を開催したい!!という方はLinkedIn経由でくらはしまでご連絡ください。材料費は1人前5000円ぐらいです。団地の集会場やコミュニティセンターでやってみたいです。

で、ここからが本題。勉強会参加者の方から、アフターフォローSNSで「エアコンを制御したい」というお題をいただきましたので、さくっと作ってみました。

■部品■

品名Name秋月PN価格購入数量参考バラ単価使用数
赤外線リモコン受信モジュールOSRB38C9AA(2個入)IR_RECEIVERI-046591001501
5mm赤外線LED OSI5FU5111C−40 (5個入)D1, D2I-032611001202
トランジスタ2SC1815GR 60V150mA (20個入)T1I-008812001101
カーボン抵抗(炭素皮膜抵抗) 1/6W 47Ω (100本入)R3, R4R-16470100112
カーボン抵抗(炭素皮膜抵抗) 1/6W 2.2kΩ (100本入)R1, R2R-16222100112
積層セラミックコンデンサ 47μF16V ±10% 5mmピッチ (10個入)C1P-049177001701

秋月で買うと大量に余りますが、特に抵抗とトランジスタは必ず使うので買ってしまってもいいと思います。コンデンサがわりと高いですが、これは無くてもあんまり変わりませんし、同容量の電解コンデンサなら1本10円ぐらいだと思います。

このうち、抵抗とセラミックコンデンサは極性がありません。つまり、どのピンをどっち側につないでもOKです。が、赤外線受信モジュール、LED、トランジスタ、電解コンデンサには極性があります。電解コンデンサは表面に書いてありますし、LEDは長い方の足がプラス電源側になります。トランジスタは仕様書にECBと書いてありますが、それぞれ、エミッター、コレクタ、ベースの略です。2SC1815の場合は、足を下に向け、平らな面(部品番号などが印字されている面)をこちらに向けて、左からECBの順番です。回路図ではトランジスタの左側がB(ベース)、上(矢印のついてないヤツ)はC(コレクタ)、下(矢印)はE(エミッタ)です。

赤外線受信モジュールIR RECEIVERはモノによって違いますが、今回使ったものは足を下に向け、受光窓をこちらに向けた左から1 OUT、2 GND、3 VCCです。違うモジュールを使った場合には仕様書で確認してみてください。

抵抗値は、2.2kΩ(回路図では2k2と表記)は赤赤赤金、47Ωは黄紫黒金です。最後の金は精度を表すもので金は±5%、銀は±10%です。今回のような用途では5%でも10%でも問題ありません。カラーコードについては、ここのページが見やすいかと思います(特に一番下の表)。

■回路■


会社のブログでは私のホワイトボードへろへろ回路図が晒されてしまったので、汚名返上を願ってEagleで書いてみた。

…ツール使ってもヘロヘロだったorz

あ、4u7じゃなくて47uだった。受信プログラムを走らせていると、リモコン操作していなくてもインバータやLEDランプのノイズを出鱈目な信号として誤認識してしまうので、ノイズ対策としてつけてみたんですが、あんまり違いありませんでした。誤読の場合はメーカー識別コードなどが出鱈目になるので対象となる製品のコードでフィルタリングすれば実用上は問題ないかと思います。

47μFの積層セラミックコンデンサは結構高いので、なしでもええんやで、H田さん。

受信機はIO15、LEDはIO16につないでいますが、これは空いていればどこでもOKですが、ソースのIOポート番号をそれに合わせて変更する必要があります。

同じ回路をArduinoで使う場合には、3v3ではなく5vにつなぎ、R3とR4を75Ωに取り替えてください。

■ライブラリ■

Arduinoの定番IRRemoteをESPで使うとAVR.hでひっかかってしまうので、IRRemoteESP8266を使います。原作者の方、ESP8266へポートしてくださった方に感謝致します。

githubからzip落としてArduino IDEに読み込ませます。

IRRemote/IRRemoteESP8266とも、そのままではバッファが小さくてエアコンのデータを扱うことができません。適当なエディタでIRRemoteESP8266.hを開き、RAWBUFの値を100から400に変更255に変更して保存します。

追記(2017年2月6日):400では動かない、ここは8bitなので255が最大値とのご指摘をいただきました。大変申し訳ありません。ご教示いただきありがとうございました。

…ところで何故私のところでは動いていたのでしょう・・・。

■受信プログラム■

コードを解析してバイナリコードで送るのがスマートなんですけど、面倒くさいのでrawコード(信号のon/off時間をそのままベタに記録したフォーマット。とても長い)を受信します。

なお、エアコンの場合、テレビと違ってリモコン信号が正常に送られているかどうか判断するのが難しいです。設定温度を本体に表示してくれるエアコンは別ですが。なので、私はタイマーのon / offで確認しました。タイマーをセットするとエアコン本体の予約ランプが点灯するので、セット / 解除の信号を送って、ランプの点滅で動作確認しようという寸法です。

何その巨大Lチカ。

他にはフィンの向きを使う(左右に切り替える)のも良いかと思います。なおエアコンの頻繁なon/offは電力消費にもエアコン本体の寿命にも悪影響を与えるので、ご注意を。

仕事部屋は古いFujitsuエアコン、IRRemoteのサンプルを改造して、以下のような出力を得ました。Panasonicとか48bitsとか出てますが気にしないように。

26度、風量自動、1時間タイマーON:
8083F
Decoded PANASONIC - Address: 28C6 Value: 8083F (48 bits)

Raw (244): 0xCE4,0x672,0x1C2,0x190,0x1C2,0x190,0x1C2,0x4E2,0x1C2,0x190,0x1C2,0x4E2,0x1C2,0x190,0x1C2,0x1C2,0x1C2,0x190,0x1C2,0x4E2,0x1C2,0x4E2,0x1C2,0x1C2,0x1C2,0x190,0x1C2,0x1C2,0x1C2,0x4E2,0x1C2,0x4E2,0x1C2,0x190,0x1C2,0x1C2,0x190,0x1C2,0x1C2,0x190,0x1C2,0x1C2,0x190,0x1C2,0x1C2,0x190,0x1C2,0x1C2,0x190,0x1F4,0x190,0x190,0x190,0x1C2,0x190,0x1C2,0x1C2,0x1C2,0x190,0x4E2,0x1C2,0x190,0x1C2,0x190,0x1C2,0x1C2,0x1C2,0x1C2,0x190,0x1C2,0x190,0x1C2,0x1C2,0x1C2,0x190,0x4E2,0x1C2,0x1C2,0x190,0x190,0x1C2,0x190,0x1C2,0x1C2,0x190,0x1C2,0x1C2,0x4E2,0x1C2,0x4E2,0x1C2,0x4E2,0x1C2,0x4E2,0x1C2,0x4E2,0x1C2,0x4E2,0x1C2,0x190,0x190,0x1F4,0x190,0x190,0x1C2,0x4E2,0x1C2,0x190,0x1C2,0x190,0x190,0x1C2,0x1C2,0x1C2,0x190,0x1C2,0x1C2,0x190,0x1C2,0x190,0x190,0x1C2,0x1C2,0x4E2,0x1C2,0x4E2,0x1C2,0x1C2,0x190,0x1C2,0x1C2,0x190,0x1C2,0x1C2,0x190,0x190,0x1C2,0x190,0x1C2,0x1C2,0x190,0x4E2,0x1C2,0x1C2,0x190,0x4E2,0x1C2,0x4E2,0x1C2,0x190,0x190,0x1F4,0x190,0x1C2,0x1C2,0x4E2,0x1C2,0x190,0x1C2,0x190,0x190,0x1C2,0x1C2,0x190,0x1C2,0x1C2,0x1C2,0x190,0x1C2,0x190,0x190,0x1C2,0x190,0x1C2,0x1C2,0x190,0x190,0x1C2,0x1C2,0x1C2,0x190,0x190,0x190,0x4E2,0x1C2,0x4E2,0x1C2,0x4E2,0x1C2,0x4E2,0x1C2,0x190,0x190,0x1C2,0x1C2,0x190,0x1C2,0x1C2,0x190,0x190,0x1C2,0x4E2,0x1C2,0x190,0x1C2,0x190,0x190,0x1C2,0x190,0x190,0x1C2,0x190,0x1C2,0x190,0x1C2,0x190,0x1C2,0x190,0x190,0x1C2,0x190,0x190,0x190,0x1C2,0x190,0x1C2,0x1C2,0x4E2,0x1C2,0x4E2,0x1C2,0x1C2,0x190,0x4E2,0x1C2,0x4E2,0x1C2,0x190,0x190,0x4E2,0x1C2,0x4E2,0x190,

26度、風量自動、タイマー解除:
8083F
Decoded PANASONIC - Address: 28C6 Value: 8083F (48 bits)
Raw (244): 0xCE4,0x672,0x1C2,0x190,0x1C2,0x1C2,0x1C2,0x4E2,0x1C2,0x1C2,0x1C2,0x4E2,0x1C2,0x1C2,0x1C2,0x190,0x1C2,0x1C2,0x190,0x4E2,0x1C2,0x4E2,0x1C2,0x190,0x1C2,0x190,0x1C2,0x1C2,0x1C2,0x4E2,0x1C2,0x4E2,0x1C2,0x1C2,0x190,0x190,0x1C2,0x190,0x1C2,0x1C2,0x190,0x190,0x1C2,0x190,0x1C2,0x1C2,0x190,0x190,0x1C2,0x190,0x1C2,0x1C2,0x1C2,0x190,0x1C2,0x190,0x1C2,0x1C2,0x190,0x4E2,0x1C2,0x1C2,0x190,0x190,0x1C2,0x190,0x190,0x1C2,0x1C2,0x190,0x1C2,0x1C2,0x1C2,0x190,0x1C2,0x4E2,0x1C2,0x1C2,0x190,0x190,0x1C2,0x1C2,0x1C2,0x190,0x1C2,0x190,0x1C2,0x4B0,0x1C2,0x4E2,0x1C2,0x4E2,0x1C2,0x4B0,0x1C2,0x4E2,0x1C2,0x4E2,0x1C2,0x190,0x1C2,0x190,0x1C2,0x1C2,0x190,0x4E2,0x1C2,0x1C2,0x190,0x190,0x1C2,0x190,0x1C2,0x190,0x1C2,0x190,0x1C2,0x1C2,0x190,0x1C2,0x1C2,0x190,0x1C2,0x4E2,0x1C2,0x4E2,0x1C2,0x1C2,0x1C2,0x190,0x1C2,0x190,0x190,0x1C2,0x1C2,0x1C2,0x190,0x1C2,0x190,0x1C2,0x1C2,0x4E2,0x1C2,0x190,0x1C2,0x4E2,0x1C2,0x4E2,0x1C2,0x1C2,0x1C2,0x190,0x1C2,0x1C2,0x190,0x190,0x1C2,0x190,0x1C2,0x1C2,0x190,0x190,0x1C2,0x190,0x1C2,0x1C2,0x190,0x1C2,0x1C2,0x190,0x1C2,0x190,0x190,0x1C2,0x1C2,0x190,0x190,0x1C2,0x190,0x1C2,0x190,0x190,0x190,0x1C2,0x1C2,0x190,0x1C2,0x190,0x1C2,0x190,0x1C2,0x190,0x190,0x1C2,0x190,0x1C2,0x1C2,0x190,0x190,0x1C2,0x1C2,0x190,0x1C2,0x190,0x190,0x1C2,0x1C2,0x190,0x1C2,0x190,0x1C2,0x190,0x190,0x1C2,0x1C2,0x190,0x190,0x1C2,0x1C2,0x190,0x1C2,0x190,0x1C2,0x1C2,0x1C2,0x190,0x1C2,0x4E2,0x1C2,0x4E2,0x1C2,0x4E2,0x1C2,0x4E2,0x1C2,0x190,0x190,0x4E2,0x1C2,0x190,0x1C2,0x1C2,0x190,

長いっすねー。ソースは短いっす。


■送信プログラム■

受信プログラムからシリアルに吐き出されたraw列をコピペして、5秒ごとに送信受信を繰り返すプログラムです。これも元は附属のサンプルを書き換えました。

動きます。動きますが、赤外線LEDの指向性がかなり強いので、向きをちゃんと合わせないと反応してくれません。気をつけてください。

こっちもソース短いです。

5 件のコメント:

  1. こん**は
    エアコンを コントロールしたく、記事にあるように IRremoteESP8266.h の当該箇所204行目を400に書き換えてみたのですが、うまく動いてくれません。

    // Some useful constants
    #define USECPERTICK 50 // microseconds per clock interrupt tick
    #define RAWBUF 400 // Length of raw duration buffer

    // Marks tend to be 100us too long, and spaces 100us too short

    以下には結果ですが、長いので冒頭だけ抜粋いたします。

    100 の場合
    F20D03FC (32 bits)
    Raw (100): 0x1130,0x1162,0x226,
    0x672,0x226,
    0x672,0x226,
    0x672,0x226,
    0x672,0x226,0x258,0x226,0x258,0x1F4,
    0x672,0x226,0x258,0x226,0x258,0x1F4,0x258,0x226,0x258,0x226,0x258,0x226,
    0x672,0x226,

    400 の場合
    Unknown encoding: 11B72AB8 (32 bits)
    Raw (40): 0x226,0x258,0x226,
    0x672,0x258,
    0x672,0x226,0x258,0x1F4,0x258,0x258,0x226,0x226,0x258,0x226,0x258,0x226,0x258,0x226,0x258,0x258,0x226,0x258,0x226,0x226,
    0x672,0x226,
    0x672,0x226,
    0x672,0x226,0x258,0x226,0x258,0x226,
    0x672,0x258,0x226,0x226,

    100は冒頭のみ、400は全部ですが、長さが短くなりました。
    かつ、信号が途中からしか認識されていないようです。
    ま、そもそもエアコンの信号は100でも途中で切れてるんですが…。

    ちなみに書き換え前の100の状態では、照明の制御が正常に行えている状態です。
    記事の書き換えの部分だけで動作がおかしくなっているようですので、
    どこか書き換えの場所が間違っているのでしょうか?

    返信削除
  2. コメントありがとうございます。

    実験に使った回路をばらしてしまったので、組み立て直して追試してみますね。ちょっとお時間ください。

    ただ、エアコンによってコードの長さや構成が違っているので、再現できないかもしれません。その点ご了承いただければ幸いです。

    返信削除
  3. お手数お掛けするようですみません。
    よろしくお願いします。

    ところで、よく見たら8080asmから、なんですね。
    その昔、TK80やL-kit16を欲しがってた頃を思い出しました。
    z80asmと書いてあればきっと最初に買った8001を思い出したんでしょうが、なにせ8080asmですからね。

    返信削除
  4. こん**は
    質問の件でしたが、自己解決しました。
    結局RAWBUFの値は1バイトで読んでいるらしく、255が最大値のようです。
    300、200、250、255、256、とテストし、256以上だと質問したような状態になりました。
    おさわがせしました。

    返信削除
  5. 大変申し訳ありません、記事を訂正致しました。

    私のところでは何で動いていたのかという謎が残りますがorz

    TK-80は私の初めてのマイコンでした。うーん、ASMだったらbyte長を間違えるなどというヘマはしなかったと思・・・いたいですw

    ご指摘ありがとうございました。今後ともどうぞよろしくお願いいたします。

    返信削除