【Arduino】Arduino Nano(互換機)+人感センサ+サーボモータでトイレを灯す

前回の続きです。

engetu21.hatenablog.com

前回は人感センサに反応してLEDを付けるようにしていましたが、サーボモータに変更して電灯スイッチのON/OFFを実現します。

一応ですが、こんなものを作らなくても人感センサ付きLED電球もありますよ。(実際一個持ってますが、今の住居では口径が合わないために使う場所がない)
my-best.com

1.構成と回路図

構成図はこんな感じ。
f:id:engetu21:20190522234215p:plain

Arduinoの信号ピンはD12を使います。
サーボモータはSG-90。
こいついつもこれ使ってんなって感じですが、なんせ5個セットで買ってるからね。
akizukidenshi.com


回路図はこんな感じ。信号線はわかりやすいように青色、+線は赤、ー(マイナス)線は黒にしてみました。
f:id:engetu21:20190522231049p:plain

2.プログラム

前回からの変更点として、サーボモータを動かす関数を新たに設けてます。あと、setup()内の「// 無条件で初回は点灯」の部分は、変数間違えてたのでそこも修正して、検知は1秒⇒0.5秒間隔に変更。
サーボモータ用の12ピンは定数にすべきだったけど、まぁいいや。
大体これで動きます。

#include <Servo.h>  //サーボモーター用ライブラリを読み込み

#define LED_PIN 3
#define PIR_PIN 8

int sonzai = 0;        // 存在フラグ
int tentouzumi = 0;    // 点灯フラグ
double count = 0;       // 秒数カウンター

//////////// サーボモータ設定 /////////////
Servo myservo; //サーボ用のオブジェクトを作成
int val; //サーボの角度を格納するための変数
//////////////////////////////////////////

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_PIN, OUTPUT);
  pinMode(PIR_PIN, INPUT_PULLUP);
  //Serial.begin(9600); 

  //tentouzumi = 1;      // 無条件で初回は点灯
  sonzai = 1;
}

// the loop function runs over and over again forever
void loop() {
  
  delay(500);         // 0.5秒間スリープ
  count = count + 0.5;   // カウントアップ
  analogWrite(LED_PIN, 0);

  // 30秒後に判定
  if (count == 30){
    
    count = 0;                // カウンターリセット
    //Serial.println("30秒目の判定!");
    //Serial.println(sonzai);
    //Serial.println(tentouzumi);
  
    // 点灯しており、かつ誰も居ない時
    if (tentouzumi == 1 && sonzai == 0){

      // 明かりを消す
      servoSwitchOff();

      tentouzumi = 0;  // 点灯済みフラグをクリア
    }
    
    sonzai = 0;        // 存在フラグをクリア
    
  }
  
  //0.5秒ごとに判定
  if (count < 30){
    //Serial.println(count);
    //Serial.println(sonzai);
    //Serial.println(tentouzumi);

    // 点灯しておらず、かつ誰か居る時
    if (tentouzumi == 0 && sonzai == 1){

      // 明かりを付ける
      servoSwitchOn();

      tentouzumi = 1;     // 点灯済みフラグをONに
      count = 0;          // カウンタリセット

    }

  }
  
  // センサに反応があった場合(誰か居る場合)
  if (digitalRead(PIR_PIN) == HIGH){
      sonzai = 1;         // 存在フラグをONに
      analogWrite(LED_PIN, 20);
  }
}

//////////// サーボモータ動作 /////////////
void servoSwitchOn() {
        myservo.attach(12); //デジタル12番ピンをサーボの角度命令出力ピンとして設定

        val = 0;

        // サーボモータ実行
        for(int i=90; i<=130; i++){
          val = i;
          myservo.write(val);
          delay(15);
        }
        for(int i=130; i>=90; i--){
          val = i;
          myservo.write(val);
          delay(15);
        }
        myservo.detach();
}

void servoSwitchOff() {
        myservo.attach(12); //デジタル12番ピンをサーボの角度命令出力ピンとして設定

        val = 0;

        // サーボモータ実行
        for(int i=90; i>=70; i--){
          val = i;
          myservo.write(val);
          delay(15);
        }
        for(int i=70; i<=90; i++){
          val = i;
          myservo.write(val);
          delay(15);
        }
        myservo.detach();
}
//////////////////////////////////////////

なかなか角度の調整が難しかったので、トイレを行ったり来たりする羽目に。こういうところはやってみないとわからないですなぁ。

3.設置

追加したサーボモータは両面テープでスイッチの下にくっつける。
サーボモータのプロペラ(?)はスイッチの大きさに合わせて削りました。
f:id:engetu21:20190522231446j:plain

Aruduino Nanoを入れた箱。自作。ワイシャツ買ったので、それに入っている型崩れ防止用の厚紙がいい感じに余ってたので、ノリで組み合わせて紙テープを張りました。意外とよくできてる。蓋も作ってます。
f:id:engetu21:20190522231405j:plain

検知すると光ります。
f:id:engetu21:20190522231412j:plain

実際には箱の中に設置した青色LEDの光が投下されてるだけです。
f:id:engetu21:20190522231744j:plain

蓋取った時の箱の中身。箱の下に穴をあけてUSBケーブルを通してます。
f:id:engetu21:20190522231427j:plain