【Arduino】Arduino Nano(互換機)+人感センサ+サーボモータでトイレを灯す
前回の続きです。
前回は人感センサに反応してLEDを付けるようにしていましたが、サーボモータに変更して電灯スイッチのON/OFFを実現します。
一応ですが、こんなものを作らなくても人感センサ付きLED電球もありますよ。(実際一個持ってますが、今の住居では口径が合わないために使う場所がない)
my-best.com
1.構成と回路図
構成図はこんな感じ。
Arduinoの信号ピンはD12を使います。
サーボモータはSG-90。
こいついつもこれ使ってんなって感じですが、なんせ5個セットで買ってるからね。
akizukidenshi.com
回路図はこんな感じ。信号線はわかりやすいように青色、+線は赤、ー(マイナス)線は黒にしてみました。
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(); } //////////////////////////////////////////
なかなか角度の調整が難しかったので、トイレを行ったり来たりする羽目に。こういうところはやってみないとわからないですなぁ。