// --------------------------------------------------------------------------------
/*

07 人體偵測防盗感應器 LED + Buzzer (挑戰的答案)

[學習重點]

1. 認識 PIR Motion Sensor 人體紅外線感應器
2. 認識 Buzzer 蜂嗚器

[挑戰]

- 加入一個 Reset 按鈕開關
- 當觸發警報後需要按 Reset 按鈕才能關閉警報


Created by Jason on 7 Aug 2022.

*/
// --------------------------------------------------------------------------------

int ledPin = 9; // 定義 ledPin 變數並設定適合的 Pin 號
int buzzPin = 10; // 定義 buzzPin 變數並設定適合的 Pin 號
int buttonPin = 7; // 定義 buttonPin 變數並設定適合的 Pin 號
int buttonState; // 外置 Reset 按鈕的狀態 (HIGH / LOW)
int pirPin = 4; // 定義接收開關狀態的 Pin 號
int pirState; // 開關的狀態 (HIGH / LOW)
int alarmState = -1; // 警報的狀態

void setup() {
  pinMode(ledPin, OUTPUT); // 設定 ledPin 為輸出模式
  pinMode(buzzPin, OUTPUT); // 設定 buzzPin 為輸出模式
  pinMode(buttonPin, INPUT); // 設定 buttonPin 為輸入模式
  pinMode(pirPin, INPUT); // 設定 pirPin 為輸入模式
}

void loop() {
  buttonState = digitalRead(buttonPin); // 讀取開關的狀態 (LOW / HIGH)
  pirState = digitalRead(pirPin); // 讀取開關的狀態 (LOW / HIGH)

  // 檢查 PIR 狀態,開關接觸的話發出警報
  if (pirState == HIGH) {
    alarmState = 1;
  }

  // 檢查外置 Reset 按鈕狀態,開關接觸的話取消警報
  if (buttonState == HIGH) {
    alarmState = -1;
  }

  // 檢查開關狀態,開關接觸的話發出警報
  if (alarmState > 0 ) {
    digitalWrite(ledPin, HIGH); // ledPin 輸出高電位
    // 透過 Buzzer 發出警報聲
    for(int i = 0; i < 255; i = i + 5) {
      analogWrite(buzzPin, i);
      delay(5);
    }
    for(int i = 255; i > 0; i = i - 5) {
      analogWrite(buzzPin, i);
      delay(5);
    }
  } else {
    digitalWrite(ledPin, LOW); // ledPin 輸出低電位
  }

	delay(100); // 延時 0.1 秒
}