/* * [2차시] 화장실 인체감지등 (네오픽셀 링 + 가변저항 밝기 조절) * * 준비: 스케치 > 라이브러리 포함 > 라이브러리 관리 > "Adafruit NeoPixel" 설치 * * 배선 (우노 5V는 2개뿐이라 브레드보드 +,- 레일로 나눠 씁니다) * 우노 5V -> 브레드보드 + 레일 우노 GND -> 브레드보드 - 레일 * PIR VCC -> + 레일, GND -> - 레일, OUT -> D2 * 네오픽셀 빨강 -> + 레일, 검정 -> - 레일, 초록(DI) -> D6 (★ DI 쪽! DO 아님) * 가변저항 VCC -> + 레일, GND -> - 레일, OUT -> A0 * * 동작 * 움직임 감지 -> LED 켜짐 -> 마지막 움직임 후 30초 지나면 꺼짐 * 손잡이(가변저항)를 돌리면 밝기가 실시간으로 바뀜 * 시리얼 모니터(9600)에 남은 시간과 밝기가 1초마다 표시됨 * * ★ 바꿔 볼 숫자 ★ * HOLD_MS : 유지 시간. 30000 = 30초, 60000 = 1분, 120000 = 2분 * BRIGHT_MAX : 손잡이 최대 밝기 (120 넘기지 마세요 - 전류가 커져 리셋될 수 있음) * COLOR_R/G/B : 색 (255,255,200 = 따뜻한 흰색 / 255,120,0 = 주황 / 0,0,255 = 파랑) */ #include const int PIR_PIN = 2; const int LED_PIN = 6; const int POT_PIN = A0; const int LED_COUNT = 8; const unsigned long HOLD_MS = 30000; // ★ 유지 시간 (30초) const int BRIGHT_MIN = 5; // 손잡이 최소 밝기 const int BRIGHT_MAX = 120; // ★ 손잡이 최대 밝기 const int COLOR_R = 255, COLOR_G = 255, COLOR_B = 200; // ★ 색 Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); unsigned long lastMotion = 0; // 마지막으로 움직임을 본 시각 unsigned long lastPrint = 0; // 마지막으로 시리얼에 찍은 시각 bool lightOn = false; // 지금 LED가 켜져 있나? int brightness = 80; // 현재 밝기 // 현재 상태(켜짐/꺼짐, 밝기)를 링에 반영 void applyLight() { if (lightOn) { strip.setBrightness(brightness); strip.fill(strip.Color(COLOR_R, COLOR_G, COLOR_B)); // 전체를 지정 색으로 } else { strip.clear(); // 전체 끄기 } strip.show(); // 실제로 반영 } void setup() { pinMode(PIR_PIN, INPUT); strip.begin(); applyLight(); // 시작할 땐 꺼 두기 Serial.begin(9600); Serial.println("PIR warming up 5s"); delay(5000); Serial.println("ready"); } void loop() { // 1) 손잡이 위치(0~1023) -> 밝기. 값이 조금 이상 바뀔 때만 다시 그림 (떨림 방지) int newBright = map(analogRead(POT_PIN), 0, 1023, BRIGHT_MIN, BRIGHT_MAX); if (abs(newBright - brightness) >= 3) { brightness = newBright; if (lightOn) applyLight(); } // 2) 움직임이 있으면 "지금 시각"을 기억하고 LED 켜기 if (digitalRead(PIR_PIN) == HIGH) { lastMotion = millis(); if (!lightOn) { lightOn = true; applyLight(); Serial.println("LED ON"); } } // 3) 켜져 있을 때: 시간 다 되면 끄고, 아니면 1초마다 남은 시간 표시 if (lightOn) { unsigned long elapsed = millis() - lastMotion; if (elapsed >= HOLD_MS) { lightOn = false; applyLight(); Serial.println("LED OFF"); } else if (millis() - lastPrint >= 1000) { Serial.print("remain "); Serial.print((HOLD_MS - elapsed + 999) / 1000); Serial.print(" s brightness "); Serial.println(brightness); lastPrint = millis(); } } delay(50); }