●動作概要
・90cm以内に物体を検知したらライトを点灯
・検知されなくなったら5秒後に消灯
●プログラムコード
/* HC-SR04モジュール設定 */
#define SONIC_TRIG 7
#define SONIC_ECHO 6
/* リレースイッチピン */
#define SWITCH_PIN 4
/* 消灯用タイマー */
unsigned long gElapsedTime;
/* 照明ステータス */
int gLightStatus = LOW;
/* 消灯までの時間 */
int gLightOffWaitSec = 5;
/* 検出境界値(cm) */
int gBorder = 20;
/*
* 初期処理:超音波距離測定
*/
void initUltraSonic() {
pinMode(SONIC_TRIG, OUTPUT);
pinMode(SONIC_ECHO, INPUT);
}
/*
* 超音波距離測定
* 音速331.5 + 0.6 * 温度:1cm当たりの音波の時間(マイクロ秒)
* 343.5:29.11@室温20度
* 30.40@調整後
* 測定可能距離:2cm〜400cm
* 失敗時:0
*/
double measureUltraSonic() {
// Trigに10マイクロ秒 HIGH出力
digitalWrite(SONIC_TRIG, LOW);
delayMicroseconds(2);
digitalWrite(SONIC_TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(SONIC_TRIG, LOW);
// EchoがHIGHからLOWになる時間(マイクロ秒)を取得
// TIMEOUT : 測定距離 × 往復 × 1cm当たりの音波の時間(マイクロ秒) + Trigの時間
// 24720μ : 400cm * 2 * 30.4 + 400
double duration = pulseIn(SONIC_ECHO, HIGH, 24720);
// 往復時間と音速から距離算出
// 距離 = 時間 / 2 * 30.4
return duration / 60.8;
}
/*
* 距離測定
*/
double measureRange() {
double wk_range = 0, wk;
int count = 0;
for(int i = 0; i < 10; i++) {
if (i > 0) delay(60); // MaxRepeat 60ms
wk = measureUltraSonic();
if (wk) {
wk_range += wk;
count++;
if (count > 1) break;
}
}
if (count == 0) {
return 0;
}
return wk_range / count;
}
/*
* 範囲内に物体があるか判定する
* -1:測定失敗
* 0:物体なし
* 1:物体あり
*/
int checkDetect() {
double wk_range = measureRange();
if (!wk_range) {
// 測定失敗
Serial.println(F(" 測定失敗"));
return -1;
}
Serial.print(wk_range);
Serial.println(F(" cm"));
if (wk_range > gBorder) {
// 範囲外
return 0;
} else {
// 範囲内あり
return 1;
}
}
/*
* ステータス更新
* 点灯、消灯の制御を行う
*/
void updateStatus(int nowStatus) {
if (nowStatus == HIGH) {
// HIGHの場合、タイマー更新
gElapsedTime = millis();
} else {
// LOWの場合、消灯までの時間が経過するまで待つ
if (millis() - gElapsedTime < gLightOffWaitSec * 1000) {
return;
}
}
if (gLightStatus == nowStatus) {
return;
} else {
gLightStatus = nowStatus;
}
digitalWrite(SWITCH_PIN, gLightStatus);
Serial.print("LIGHT --> ");
Serial.println(gLightStatus ? "ON" : "OFF");
}
// =======================================================
// メイン処理
// =======================================================
void setup() {
// リレースイッチピン設定
pinMode(SWITCH_PIN, OUTPUT);
// 距離測定初期化
initUltraSonic();
// タイマー初期化
gElapsedTime = millis();
Serial.begin(115200);
}
void loop() {
int checkStatus = LOW;
switch(checkDetect()) {
case 1: // 検知あり
checkStatus = HIGH;
break;
case 0: // 検知なし
checkStatus = LOW;
break;
default: // 測定失敗
delay(100);
return;
}
// ステータス更新
updateStatus(checkStatus);
delay(100);
}
●今後の予定
・消灯までの時間と検出の境界値を実行時に変えれるようにする
・省電力化

0 件のコメント:
コメントを投稿