LoginSignup
11
15

More than 3 years have passed since last update.

お家の照明をリモコンで操作できるようにしよう

Last updated at Posted at 2016-07-03
1 / 29

寝る前に電気を消すのは面倒ですね、立ち上がりたくないですね。面倒くさい!

我が家では悲しいことにリモコンで操作できる系のシーリングライトが取り付けできない感じのお部屋です。


リモコンでスイッチを操作できる仕組みを作りましょう!

Artboard 1.png


材料

ちょうど壊れてしまったディスプレイに付いていた、使い道のなくなったリモコン(RU-DM114)があったのでこれを使います。


サーボモーターを動かす


サーボモーターにはそれぞれ5V、GND、5番PINを接続

fj_ブレッドボード.png


#include<Servo.h>
#define SERVO_PIN 5

Servo servo;

void setup(){
    servo.attach(SERVO_PIN);
}

void loop() {
  servo.write(0);
  delay(500);
  servo.write(100);  
  delay(500);
}

image


赤外線を受信する


fj_ブレッドボード_2.png


#define READ_PIN 7
#define LOW_STATE 0
#define HIGH_STATE 1

void setup(){
  Serial.begin(9600);
  pinMode(READ_PIN, INPUT);
}

int waitHigh() {
  unsigned long start = micros();
  while (digitalRead(READ_PIN) == HIGH) {
    if (micros() - start > 5000000) {
      return 1;
    }
  }
  return 0;
}

unsigned long now = micros();
unsigned long lastStateChangedMicros = micros();
int state = HIGH_STATE;

void loop() {
  if (state == LOW_STATE) {
    while (digitalRead(IR_READ_PIN) == LOW);
  } else {
    int ret = waitHigh();
    if (ret == 1) {
      Serial.print("\n");
      return;
    }
  }

  now = micros();
  Serial.print((now - lastStateChangedMicros) / 10, DEC);
  Serial.print(",");
  lastStateChangedMicros = now;
  if (state == HIGH_STATE) {
    state = LOW_STATE;
  } else {
    state = HIGH_STATE;
  }
}

image

赤外線センサーが反応したらLEDが光るようにしています。


受信した赤外線を識別する


このままではすべての赤外線に反応してしまうため、テレビのリモコンでもエアコンのリモコンでもセンサーが反応してしまいます。
対応させるリモコンの電源ボタンの信号にのみに反応させるため、受信したときの信号を調べます。


電源ボタンの赤外線を受信するとシリアルモニタでこんな感じの数値の羅列が取得できました。

2028,803,384,54,46,56,44,60,136,59,40,60,41,60,135,60,136,59,135,60,384,59,136,59,136,59,41,56,43,60,41,59,41,60,41,59,40,59,2026,803,387,54,46,59,41,59,136,59,41,59,41,59,136,59,136,60,135,60,384,59,136,59,136,60,40,60,41,57,44,59,41,59,40,58,43,59,2026,803,387,56,44,59,41,59,136,56,44,59,41,59,136,59,136,59,135,60,384,59,136,59,136,59,41,60,41,59,41,60,41,59,41,59,40,59,2026,803,387,54,46,59,41,60,136,59,41,59,41,59,136,56,138,60,134,57,387,59,136,60,136,59,41,60,41,59,41,60,41,59,41,59,40,60,2026,805,384,54,46,60,41,59,136,59,41,59,41,59,136,59,136,59,135,60,384,57,138,59,136,59,41,60,41,59,41,59,41,60,42,58,40,60

アナログなので数値は多少前後しますが、
よく観察すると、2026,803,384,54,・・・というパターンが何度もでてくるのが観測できます。


これをパターン毎に分解して、Excelに突っ込みます。

スクリーンショット 2016-07-04 3.08.28.png

MODE関数で最頻値が取得できますので、この値が電源ボタンの信号だと推測できます。


この2つをくっ付けて完成!


問題いろいろ


問題その1 あまり赤外線を検知しない


完全な信号はなかなか来ないので、数値の揺らぎはある程度許容する

if (abs(value - pattern[number]) < 10) {
  // OK
}

問題その2 サーボモーターがうるさい


待機音がうるさいので

普段はdetachしておく

servo.detach(SERVO_PIN);
servo.attach(SERVO_PIN);

雑ですが最終的にこんなコードになりました

#include<Servo.h>

#define IR_READ_PIN 7
#define SERVO_PIN 5
#define LOW_STATE 0
#define HIGH_STATE 1

Servo servo;

void setup(){
  Serial.begin(9600);
  pinMode(IR_READ_PIN, INPUT);
}

int waitHigh() {
  unsigned long start = micros();
  while (digitalRead(IR_READ_PIN) == HIGH) {
    if (micros() - start > 5000000) {
      return 1;
    }
  }
  return 0;
}

unsigned long now = micros();
unsigned long lastStateChangedMicros = micros();
int state = HIGH_STATE;
int number = 0;
int pattern[38] = {2026, 805,384,54,46,59,41,59,136,59,41,59,41,59,136,59,136,59,135,60,384,59,136,59,136,59,41,60,41,59,41,59,41,59,41,59,40,60};

void loop() {
  if (state == LOW_STATE) {
    while (digitalRead(IR_READ_PIN) == LOW);
  } else {
    if (1 == waitHigh()) {
      if (servo.attached()) {
        servo.detach();
      }

      Serial.println("off");
      return;
    }
  }

  now = micros();

  long value = (now - lastStateChangedMicros) / 10;
  Serial.print(value);
  Serial.print(", ");

  number++;
  if (value > 2000 || number >= 38) {
    number = 0;
  } else {
    if (abs(value - pattern[number]) > 10) {
      number = 0;
    }
    if (number == 38) {
      push();
      number = 0;
    }
  }

  if (state == HIGH_STATE) {
    state = LOW_STATE;
  } else {
    state = HIGH_STATE;
  }

  lastStateChangedMicros = now;
}

void push() {
  Serial.println("");
  Serial.println("push!");

  if (!servo.attached()) {
    servo.attach(SERVO_PIN);
    delay(5000);
  }

  servo.write(170);
  delay(1000);
  servo.write(90);  
  delay(500);
}

問題その3 どうやって固定しよう・・・


ダンボールとビニタイで固定した

IMG_0245.jpg


とりあえずできた!

image


good night 🌙


こうやって人類は退化していくのでした。💤


参考

11
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
15