아두이노 프로젝트 · 1차시

화장실에 들어가면
저절로 켜지는 전등

PIR 센서로 만드는 화장실 인체감지등
아두이노 기반 자동 조명 제어

모아로보틱스← → 키로 넘기기
도입 5분
1차시 · 도입

밤에 화장실 갈 때 불은 누가 켜나요?

  • 어둠 속에서 스위치를 더듬어 찾는다
  • 나올 때 불을 안 끄고 나온다
  • 손을 다 씻지 않은 채 스위치를 만진다

오늘의 결론

사람이 들어오면 알아서 켜지고,
나가면 알아서 꺼지는 전등을
2번의 수업 동안 직접 만듭니다.

완성품은 집 화장실에 실제로 달아 씁니다.

이번 시간 목표 — PIR 센서가 움직임을 어떻게 알아내는지 이해하고, 아두이노로 그 신호를 직접 읽어 봅니다.
이론 15분
1차시 · 이론 ①

아두이노는 "판단하는 작은 컴퓨터"

입력센서 · 버튼
판단아두이노 (우리가 쓴 코드)
출력LED · 모터 · 소리
  • 5V / GND — 부품에 전기를 주는 핀 (+와 −)
  • D2, D6 … — 디지털 핀. 1(HIGH) 또는 0(LOW)만 다룸
  • A0 … — 아날로그 핀. 0~1023 사이 값을 읽음
  • USB — 코드를 넣고, 전원도 주고, 대화도 함

오늘 쓸 핀

5V센서 전원
GND센서 접지
D2센서 신호 읽기
D13보드에 붙은 L LED
이론 15분
1차시 · 이론 ②

PIR 센서는 "열의 움직임"을 본다

  • 사람 몸은 적외선(열)을 내보낸다
  • 센서 안에는 열을 느끼는 판이 2개 있다
  • 하얀 돔(렌즈)이 시야를 여러 조각으로 나눈다
  • 사람이 지나가면 두 판의 차이가 생김 → 1(HIGH)
  • 가만히 서 있으면 차이가 없음 → 0(LOW)
그래서 PIR은 "사람이 있다"가 아니라 "사람이 움직였다"를 알려 줍니다. 가만히 있으면 꺼지는 이유!
감지판 A · B 움직이면 A와 B가 다르게 느낀다 → 1
이론 15분
1차시 · 이론 ③

코드는 딱 두 덩어리로 되어 있다

const int PIR_PIN = 2;      // 센서를 꽂은 핀

void setup() {            // 켜질 때 한 번
  pinMode(PIR_PIN, INPUT);
  Serial.begin(9600);      // 컴퓨터와 대화 시작
}

void loop() {             // 그 뒤로 계속 반복
  int state = digitalRead(PIR_PIN);  // 1 or 0
  Serial.println(state);   // 화면에 보여 주기
  delay(50);               // 0.05초 쉬기
}
  • setup() — 전원이 켜질 때 한 번만. 핀 역할 정하기, 대화 시작
  • loop() — 그 뒤로 무한 반복. 읽고 → 판단하고 → 내보내기
  • digitalRead(핀) — 그 핀이 1인지 0인지 읽는다
  • Serial.println() — 컴퓨터 화면(시리얼 모니터)에 글자 출력
  • delay(ms) — 밀리초(1/1000초) 단위로 쉬기
실습 ①
1차시 · 실습 ① PIR 연결하기

선 3개만 꽂으면 됩니다

PIR 핀점퍼선아두이노
VCC주황5V
OUT빨강D2
GND갈색GND
센서 기판 아래 핀 순서는 왼쪽부터 GND · OUT · VCC. 렌즈 안쪽에 글씨가 작게 적혀 있으니 꼭 확인. 암–수(F–M) 점퍼선을 씁니다.
Arduino UNO 5VGND D2 PIR HC-SR501 GNDOUTVCC
실습 ①
1차시 · 실습 ① 코드 넣고 확인하기

업로드 → 시리얼 모니터 → 손 흔들기

  1. 아두이노 IDE에서 01_pir_basic.ino 열기
  2. 도구 › 보드 › Arduino Uno
  3. 도구 › 포트 › COM○ (또는 usbserial) 선택
  4. 업로드 버튼 클릭, "업로드 완료" 확인
  5. 오른쪽 위 돋보기 아이콘 → 시리얼 모니터, 9600 선택
  6. 10초 카운트다운 후 손 흔들기 → 1, 멈추면 0

이럴 땐

  • 포트가 안 보임 → USB 다시 꽂기, CH340 드라이버
  • 모니터를 열자 카운트가 처음부터 → 정상. 모니터를 열면 보드가 다시 시작됨
  • 글자가 깨짐 → 9600으로 되어 있는지
  • 처음 30초쯤 1/0이 제멋대로 → 센서가 안정되는 중, 조금만 기다리기
실습 ②
1차시 · 실습 ② 센서 성능 실험

어디까지 보고, 얼마나 오래 켜져 있을까?

실험방법기록
감지 거리1 m씩 물러나며 손 흔들기___ m까지
감지 각도센서 옆쪽에서 접근좌 ___° 우 ___°
느린 움직임천천히 걷기 vs 빨리느릴 때 감지 ○/×
유지 시간1이 된 뒤 몇 초 만에 0으로___ 초

센서 뒷면의 주황 손잡이 2개

  • Sx(감도) — 시계 방향으로 돌리면 더 멀리까지
  • Tx(유지시간) — 시계 방향으로 돌리면 더 오래 1 유지
유지 시간은 다음 시간에 코드로 30초로 고정할 거라, Tx는 가장 짧게(반시계 끝) 돌려 두세요. 코드가 시간을 정확히 셀 수 있게.
정리
1차시 · 정리

오늘 확인한 것

  • 아두이노 = 입력 → 판단 → 출력
  • PIR은 열의 움직임을 1/0으로 알려 준다
  • setup()은 한 번, loop()는 계속
  • digitalRead로 센서를 읽고 Serial로 보여 줬다

다음 시간

진짜 조명(네오픽셀 링)을 붙이고,
움직임이 멈추면 30초 뒤 저절로 꺼지게,
손잡이로 밝기를 조절하게 만듭니다.

부품은 오늘 배선 그대로 두고 보관하세요.

아두이노 프로젝트 · 2차시

움직임을 빛으로 —
자동 전등 완성하기

네오픽셀 링 · 30초 자동 꺼짐 · 손잡이로 밝기 조절

모아로보틱스← → 키로 넘기기
도입 5분
2차시 · 도입

지난 시간 센서는 이렇게 말했죠

움직임 있음 → 1
움직임 없음 → 0

하지만 실제 전등이 센서 값을 그대로 따라 하면?
화장실에 앉아 가만히 있는 순간 불이 꺼집니다.

그래서 오늘 만들 규칙

  • 움직임을 보면 즉시 켠다
  • 마지막 움직임부터 30초를 센다
  • 그동안 또 움직이면 다시 30초
  • 30초를 넘기면 끈다
  • 밝기는 손잡이로 그때그때 조절
이론 15분
2차시 · 이론 ①

네오픽셀 — 선 하나로 LED 8개 조종

  • LED 하나하나에 작은 제어 칩이 들어 있다
  • 데이터 선 1개(DI)로 "몇 번째를 무슨 색, 얼마나 밝게"를 명령
  • 전원은 5V에서 직접 받는다 → 아두이노 핀은 명령만
  • 선이 3개: 빨강(5V) · 검정(GND) · 초록(DI)
  • 밝기를 올리면 전류가 커진다 → USB 한계 때문에 최대 120
0123 4567 WS2812B 8구 링 DI ← 여기로 명령
이론 15분
2차시 · 이론 ②

IoT 기기의 뼈대는 항상 같다

PIR 센서입력 · D2
아두이노규칙: 감지 → ON, 30초 → OFF
네오픽셀출력 · D6
꺼짐 센서만 지켜보는 중 켜짐 마지막 움직임 후 시간 세는 중 움직임 감지 (1) 30초 동안 움직임 없음 또 움직임 → 30초 다시
이론 15분
2차시 · 이론 ③

30초는 어떻게 셀까? — millis()

// millis() = 켜진 뒤 지난 시간 (밀리초)

if (digitalRead(PIR_PIN) == HIGH) {
  lastMotion = millis();   // 지금 시각 기억
  lightOn = true;
}

if (millis() - lastMotion >= 30000) {
  lightOn = false;         // 30초 지났으면 끔
}
  • delay(30000)을 쓰면? 30초 동안 아무것도 못 읽음. 그사이 움직여도 모른다
  • 대신 시계를 본다: 마지막 움직임 시각을 적어 두고, 지금 시각과 빼서 30초가 넘었는지 확인
  • 움직임이 또 오면 시각을 다시 적음 → 30초가 자동으로 연장
스톱워치 비유 — 사람이 움직일 때마다 리셋 버튼을 누르고, 30초가 다 차면 불이 꺼지는 것.
이론 15분
2차시 · 이론 ④

손잡이 → 숫자 → 밝기

가변저항손잡이 돌리기
A00 ~ 1023
map()5 ~ 120
밝기
int raw = analogRead(A0);              // 0~1023
int b = map(raw, 0, 1023, 5, 120);  // 5~120
strip.setBrightness(b);
  • 디지털 핀은 1/0뿐, 아날로그 핀(A0)0~1023 단계
  • 가변저항은 돌리는 만큼 전압이 변하는 부품
  • map(값, 원래 최소, 원래 최대, 새 최소, 새 최대) — 범위를 다른 범위로 바꿔 주는 함수
  • 손잡이가 반대로 움직이면 map(raw, 1023, 0, …)
실습 ③
2차시 · 실습 ③ 전체 배선

브레드보드 없이, 우노 헤더에 바로 꽂기

부품우노 핀
네오픽셀빨강5V
검정GND
초록 (DI)D6
PIR주황 (VCC)5V (두 번째)
갈색 (GND)GND
빨강 (OUT)D2
가변저항초록 (VCC)5V 여분 핀
노랑 (GND)GND 여분 핀
파랑 (OUT)A0
UNO 헤더 핀 D6D2A05V5VGNDGND여분 5V여분 GND 네오픽셀 PIR1차시 그대로 가변저항
실습 ③
2차시 · 실습 ③ 순서대로

USB는 맨 마지막에 꽂습니다

  1. 네오픽셀 빨강 → 5V, 검정 → GND, 초록(DI) → D6
  2. PIR은 1차시 그대로: 주황(VCC) → 두 번째 5V, 갈색(GND) → GND, 빨강(OUT) → D2
  3. 가변저항 초록(VCC) → 여분 5V, 노랑(GND) → 여분 GND
  4. 가변저항 파랑(OUT) → A0
  5. 선생님 점검 후 USB 연결
  6. 02_auto_light.ino 업로드 → 5초 뒤 손 흔들기

라이브러리 먼저

스케치 › 라이브러리 포함 › 라이브러리 관리
Adafruit NeoPixel 검색 → 설치

링의 선이 DI(입력) 쪽에 붙어 있는지 확인. DO 쪽이면 아무것도 안 켜집니다. 켜지는 순간 보드가 꺼졌다 켜지면 밝기 손잡이를 낮추세요.
실습 ③
2차시 · 코드 2 핵심

loop()에서 하는 일 세 가지

// 1) 손잡이 → 밝기
int nb = map(analogRead(POT_PIN), 0,1023, 5,120);
if (abs(nb - brightness) >= 3) { brightness = nb; ... }

// 2) 움직임 → 시각 기억 + 켜기
if (digitalRead(PIR_PIN) == HIGH) {
  lastMotion = millis();
  if (!lightOn) { lightOn = true; applyLight(); }
}

// 3) 30초 지났으면 끄기
if (lightOn && millis() - lastMotion >= HOLD_MS) {
  lightOn = false; applyLight();
}

바꿔 볼 숫자

HOLD_MS유지 시간. 30000 = 30초
BRIGHT_MAX손잡이 최대 밝기 (≤120)
COLOR_R/G/B색. 255,255,200 = 따뜻한 흰색

시리얼 모니터(9600)를 열면 1초마다
remain 25 s brightness 64 처럼 보입니다.

실습 ④
2차시 · 실습 ④ 내 화장실에 맞추기

숫자를 바꿔 보고, 직접 느껴 보기

유지 시간 비교

HOLD_MS느낌
5000앉아 있으면 금방 꺼짐 — 불편
30000보통 화장실 사용에 적당
120000편하지만 나간 뒤에도 오래 켜짐 — 전기 낭비

편의 ↔ 절전, 우리 집엔 몇 초가 맞을까?

색과 밝기

  • 255,255,200 따뜻한 흰색
  • 255,120,0 주황 — 잠 깨지 않게
  • 0,0,255 파랑

밝기는 손잡이로 눈부시지 않은 지점을 찾고, 그 위치를 그대로 둔 채 설치.

센서 위치

문 쪽? 변기 쪽? 높이는? — 1차시 감지 각도 실험 결과를 떠올려 보세요.

정리
2차시 · 완성 체크

이 다섯 개가 되면 완성

  • 손 흔들면 링이 켜진다
  • 가만히 30초 후 저절로 꺼진다
  • 중간에 움직이면 30초가 다시 시작된다
  • 손잡이를 돌리면 밝기가 바뀐다
  • PC 없이 USB 충전기만 꽂아도 똑같이 동작한다

더 해 보고 싶다면

  • 남은 시간을 링으로 — 시간이 갈수록 LED 8 → 1개로
  • 서서히 밝아지기 — for문으로 밝기 0 → 현재값
  • 택트 스위치로 자동 / 항상 켜짐 / 꺼짐 모드
  • 조도 센서를 더해 낮에는 안 켜지게
정리
2차시 · 안 될 때

이럴 땐 여기부터

증상원인해결
링이 전혀 안 켜짐DO 쪽에 선 연결 / D6 아님 / 라이브러리 없음DI 확인, 핀 번호, Adafruit NeoPixel 설치
켜지자마자 보드가 꺼졌다 켜짐밝기 과다 → 전류 초과손잡이 낮추기, BRIGHT_MAX 줄이기
계속 켜져 있음PIR Tx 손잡이가 길게 / 가까이서 계속 감지Tx 반시계 끝, 센서 방향 바꾸기
카운트다운이 중간에 처음으로시리얼 모니터 열 때 자동 리셋정상. 기다리면 됨
손잡이 방향이 반대map() 범위 방향map(raw, 1023, 0, …)
포트가 안 보임USB 접촉 / 드라이버다시 꽂기, CH340 드라이버
2차시 · 정리

두 시간 동안 만든 것

1 → 💡

센서의 1과 0을
규칙(30초, 밝기)을 거쳐
진짜 빛으로 바꿨습니다.

집에 가져가서

  • 반투명 수납박스에 넣고 PIR 렌즈 자리를 뚫기
  • USB 충전기(5V)에 꽂아 화장실에 설치
  • 일주일 써 보고 유지 시간·밝기를 다시 정하기

입력 → 판단 → 출력. 이 뼈대는 스마트홈 기기 대부분이 똑같습니다.

모아로보틱스