前回の続きです。
前回は人感センサに反応してLEDを付けるようにしていましたが、サーボモータに変更して電灯スイッチのON/OFFを実現します。
一応ですが、こんなものを作らなくても人感センサ付きLED電球もありますよ。(実際一個持ってますが、今の住居では口径が合わないために使う場所がない)
https://my-best.com/4814my-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();
}
//////////////////////////////////////////なかなか角度の調整が難しかったので、トイレを行ったり来たりする羽目に。こういうところはやってみないとわからないですなぁ。




