// --- Pins ---
const int LDR_PIN = A0;
const int PIR_PIN = 2;
const int TRIG_PIN = 3;
const int ECHO_PIN = 4;
const int BTN_PIN = 7;
const int LED_R = 9;
const int LED_Y = 10;
const int LED_G = 11;
const int BUZZ = 6;
// -------- Параметры (разрешено менять) --------
int nightThreshold = 512; // ниже -> считаем "ночь"
int nearDistanceCm = 40; // ближе -> "подошел к зоне"
int blinkPeriodMs = 150; // скорость мигания LED
int alarmToneHz = 2000; // частота тревоги
int alarmBeepDurationMs = 200; // длительность звука в тревоге
// ----------------------------------------------
// monitoring on/off
bool armed = true;
// button edge
int prevBtn = HIGH;
// blink
bool blinkState = false;
unsigned long lastBlinkMs = 0;
// distance
long readDistanceCm() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH, 30000UL); // up to ~5m
if (duration == 0) return -1; // invalid
long cm = duration / 58; // standard conversion
return cm;
}
void setLeds(bool r, bool y, bool g) {
digitalWrite(LED_R, r);
digitalWrite(LED_Y, y);
digitalWrite(LED_G, g);
}
void setup() {
pinMode(LDR_PIN, INPUT);
pinMode(PIR_PIN, INPUT);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(BTN_PIN, INPUT_PULLUP);
pinMode(LED_R, OUTPUT);
pinMode(LED_Y, OUTPUT);
pinMode(LED_G, OUTPUT);
pinMode(BUZZ, OUTPUT);
Serial.begin(9600);
Serial.println("Animal Pen Monitor (PIR + HC-SR04 + LDR)");
}
void loop() {
// --- Button: arm/disarm ---
int btn = digitalRead(BTN_PIN);
if (btn == LOW && prevBtn == HIGH) {
armed = !armed;
delay(150);
}
prevBtn = btn;
// --- Blink tick ---
unsigned long now = millis();
if (now - lastBlinkMs >= (unsigned long)blinkPeriodMs) {
lastBlinkMs = now;
blinkState = !blinkState;
}
// --- Read sensors ---
int lightRaw = analogRead(LDR_PIN);
bool motion = (digitalRead(PIR_PIN) == HIGH);
long distCm = readDistanceCm();
bool night = (lightRaw < nightThreshold);
bool near = (distCm > 0 && distCm <= nearDistanceCm);
// --- Decide state ---
// If disarmed -> all OFF, no buzzer.
// If armed:
// ALARM = night AND (motion OR near)
// WARNING = day AND near
// OK = otherwise
bool alarm = false;
bool warning = false;
if (armed) {
if (night && (motion || near)) alarm = true;
else if (!night && near) warning = true;
}
// --- Output / Indication ---
if (!armed) {
setLeds(false, false, false);
noTone(BUZZ);
} else if (alarm) {
setLeds(blinkState, false, false);
if (blinkState) tone(BUZZ, alarmToneHz, alarmBeepDurationMs);
} else if (warning) {
setLeds(false, blinkState, false);
noTone(BUZZ);
} else {
setLeds(false, false, blinkState);
noTone(BUZZ);
}
// --- Serial diagnostics ---
Serial.print("Light=");
Serial.print(lightRaw);
Serial.print(night ? " (NIGHT)" : " (DAY)");
Serial.print(" Dist=");
Serial.print(distCm);
Serial.print("cm");
Serial.print(near ? " (NEAR)" : " (FAR)");
Serial.print(" Motion=");
Serial.print(motion ? "YES" : "NO");
Serial.print(" Armed=");
Serial.print(armed ? "ON" : "OFF");
Serial.print(" State=");
if (!armed) Serial.println("DISARM");
else if (alarm) Serial.println("ALARM");
else if (warning) Serial.println("WARNING");
else Serial.println("OK");
delay(80);
}