俺の報告

RoomClipを運営するエンジニアの日報(多分)です。

Arduinoでエアコンのリモコンを再現す。 - 日報 #150

梅雨入りしたそうですが、
日々暑いです。
今日はもう疲れたので、趣味のお話。

弊社オフィスはペッカペカで至極快適なのですが、
1個だけ不満がございます。
タイトルですこし触れましたが、、、
弊社は合計4つほどエアコンがあるのですが、
リモコンが1つしかないのです。
コレではいけません。

ということで、自作しましょう。

発想としては、PICだかなんだかのマイコンを通して、
赤外線受光器でもってリモコンの信号を解析して、
赤外線LEDにその通りの動作をさせればよいわけです。

受光器からの信号解析のためにシリアル通信が必要になるので、
ここはUSBインターフェースを使いやすい18F14K50を使います。
この神サイトがあるかぎり、なんだってできそうです。

ですが、
解析してテストするまでならもっと簡単にやりたいものです。
てことで、みんなだいすきArduinoを使いましょう。

macArduinoが初めてだったのですが、
IDEは$3程度で手に入るようです。
http://www.arduino.cc/en/Main/Software

そいで、赤外線受光器は手元にあったOSRB38C9AA(100円なり)をつかい、
LEDはまぁ、そのへんの適当な奴をつかいます。
型番とか忘れた知らん。

あぁなんか書き出して面倒臭くなってきた。
要は赤外線受光器に向けてリモコンの電源ボタンとかを押して、
その点滅情報をマイクロ秒で取得して、
そのままLEDを光らせればよいわけですよ。

あとは赤外線リモコンの仕様ですが、
このへんを参考にすれば、フレームとかデータとかの仕切りがわかります。
ってか、ぶっちゃけ解析は面倒なんであんまいらんくて、
「ON、OFF」だけできりゃいいので、その情報をそのままプログラムに書き込んじゃいます。

さて、面倒な読み取りスクリプトですが、
色んなサンプルがありますが、僕はこうしましたってのを後ろにくっつけておきます。
だいたい下記のような感じですごーーい簡単にとりあえずリモコン動作は確認できました。

f:id:tom_rc:20150609212257j:plain

さて、続いてはこれをPICで組んで、
あとはかっこいいボタンでもつけてやればいいですね。
楽しみです。

#define DETECTOR_PIN 7
#define SERIAL_BPS 57600

// Button Interval 1sec
#define INTERVAL 1000000 // usec

// NEC 562, AEHA 350-500 (425)
#define FRAME_SEC 500 // usec

// 1: state process, 2: frame count
#define DATA_MODE 1

// 0: debugging, 1: data only
#define STDOUT_MODE 1

// Separator
#define SEPARATOR ","

unsigned long interval_start = 0;
unsigned long window_start = 0;
unsigned long state_start = 0;
int frame_cnt = 0;
int state = HIGH;

void setup() {
  // set pinMode
  pinMode(DETECTOR_PIN, INPUT);

  // put your setup code here, to run once:
  Serial.begin(SERIAL_BPS);
  Serial.println("Start!");
}

void loop() {
    if (digitalRead(DETECTOR_PIN) == LOW) {
      interval_start = micros();
      window_start = interval_start;
      state_start = interval_start;
      state = LOW;

      Serial.println("Catch the signal.");

      while ((micros() - interval_start) <= INTERVAL) {
        if (state != digitalRead(DETECTOR_PIN)) {
          if (STDOUT_MODE == 0) {
            if (state) {
              Serial.print("OFF: ");
            } else {
              Serial.print("ON: ");
            }
          }

          /*
          // total process time
          Serial.print("Total Process Time: ");
          Serial.println(micros() - interval_start);
          // window process time
          Serial.print("Window Process Time: ");
          Serial.println(micros() - window_start);
          */

          if (DATA_MODE == 2) {
            // frame count
            if (STDOUT_MODE == 0) {
              Serial.print("Frame count: ");
            }
            Serial.print(frame_cnt);
          }

          if (DATA_MODE == 1) {
            // state process time
            if (STDOUT_MODE == 0) {
              Serial.print("State Process Time: ");
            }
            Serial.print(micros() - state_start);
          }

          // separate
          Serial.print(SEPARATOR);

          // init frame state
          window_start = micros();
          state_start = window_start;
          frame_cnt = 0;
          state = !state;
        }
        if (micros() - window_start >= FRAME_SEC) {
          window_start = micros();
          frame_cnt = 0;
        } else {
          frame_cnt++;
        }
      }
      Serial.println("\nEnd the signal.");
    }
}