아두이노 사운드 센서로 실시간 소음 레벨 모니터링: LED 인디케이터와 LCD 표시
부품 및 소모품
| 부품 |
수량 |
비고 |
| 아두이노 우노 (Arduino UNO) |
1 |
|
| 풀사이즈 브레드보드 |
1 |
|
| 9V 배터리 + 배럴 잭 커넥터 |
각 1 |
휴대용 전원용 (선택) |
| 수-수/수-암 점퍼 와이어 |
1세트 |
|
| 16x2 LCD (I2C 백팩, 0x27 주소) |
1 |
실시간 수치 표시용 |
| 사운드 센서 모듈 KY-038 |
1 |
마이크 내장, 아날로그/디지털 출력 |
| 5mm LED: 노란색 |
2 |
저음량 구간 표시 |
| 5mm LED: 초록색 |
4 |
중간 음량 구간 표시 |
| 5mm LED: 빨간색 |
2 |
고음량 구간 표시 |
| 5mm LED: 흰색 |
4 |
확장 표시용 |
| 5mm LED: 파란색 |
4 |
확장 표시용 |
| 저항 100Ω |
8 |
흰색/파란색 LED용 |
| 저항 220Ω |
4 |
빨간색/노란색 LED용 |
| 저항 330Ω |
4 |
초록색 LED용 |
소프트웨어
프로젝트 소개
스피커에서 나오는 소리 크기를 KY-038 사운드 센서로 실시간 측정해, 음량 레벨에 따라 색상별 LED 바그래프로 시각화하고 LCD에 수치를 표시하는 프로젝트입니다. 호기심과 심심함에서 시작된 작업이지만, 소음 모니터링의 기본 원리를 익히기 좋은 예제입니다.
작동 원리
- KY-038 모듈의 아날로그 출력(AO)을 아두이노 A0 핀으로 읽어 음량 레벨(0~1023) 획득
- 시리얼 모니터로 수집한 데이터를 스프레드시트에 옮겨 정렬, 빈도 높은 구간별 임계값 결정
- 임계값 구간별 LED 그룹 점등:
- 노란색 LED (2개): 저음량 구간 (센서값 ~650~700)
- 초록색 LED (4개): 중간 음량 구간 (~700~720)
- 빨간색 LED (2개): 고음량 구간 (~720~750)
- 흰색/파란색 LED (8개): 확장/피크 표시용
- LCD에 실시간 센서값 표시 (이전 값 잔상 방지 로직 포함)
주요 구현 포인트
- 센서값 잔상 문제 해결: LCD 출력 시 뒤에 공백(
" ")을 출력해 이전 자리수 지움
- 디지털 출력(DO) 활용: 센서 모듈의 내장 콤퍼레이터 출력(DO)을 디지털 핀(D2)으로 읽어 임계값 초과 시에만 LCD 갱신
- 임계값 캘리브레이션: 실제 환경에서 시리얼 모니터로 값 관찰 후 코드 내 임계값 수정 필요
소스 코드
#include "Arduino.h"
#include "LiquidCrystal_PCF8574.h"
#define LCD_ADDRESS 0x27
#define LCD_ROWS 2
#define LCD_COLUMNS 16
#define SCROLL_DELAY 150
#define BACKLIGHT 255
LiquidCrystal_PCF8574 LCDi2C;
// LED 핀 매핑 (브레드보드 순서 = 아두이노 PWM 핀)
int LED1 = 3; int LED2 = 4; int LED3 = 5; int LED4 = 6;
int LED5 = 7; int LED6 = 8; int LED7 = 9; int LED8 = 10;
int soundSensor = 2; // KY-038 DO 핀 → D2
int sensorValue = A0; // KY-038 AO 핀 → A0
boolean LEDStatus = false;
void setup() {
Serial.begin(9600);
LCDi2C.begin(LCD_COLUMNS, LCD_ROWS, LCD_ADDRESS, BACKLIGHT);
pinMode(soundSensor, INPUT);
pinMode(LED1, OUTPUT); pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT); pinMode(LED4, OUTPUT);
pinMode(LED5, OUTPUT); pinMode(LED6, OUTPUT);
pinMode(LED7, OUTPUT); pinMode(LED8, OUTPUT);
}
void loop() {
int sensorValue = analogRead(A0);
int SensorData = digitalRead(soundSensor);
if (SensorData == HIGH) { // 소리 감지됨
if (LEDStatus == false) {
LEDStatus = true;
Serial.println(sensorValue);
// LCD 표시 (잔상 방지용 공백 포함)
LCDi2C.setCursor(0, 0);
LCDi2C.print("SoundLevel Data:");
LCDi2C.setCursor(0, 1);
LCDi2C.print(sensorValue);
LCDi2C.print(" ");
}
// 임계값별 LED 제어 (값은 환경에 맞게 조정 필요)
if (sensorValue >= 750) digitalWrite(LED8, HIGH); else { LEDStatus = false; digitalWrite(LED8, LOW); }
if (sensorValue >= 735) digitalWrite(LED7, HIGH); else { LEDStatus = false; digitalWrite(LED7, LOW); }
if (sensorValue >= 725) digitalWrite(LED6, HIGH); else { LEDStatus = false; digitalWrite(LED6, LOW); }
if (sensorValue >= 720) digitalWrite(LED5, HIGH); else { LEDStatus = false; digitalWrite(LED5, LOW); }
if (sensorValue >= 715) digitalWrite(LED4, HIGH); else { LEDStatus = false; digitalWrite(LED4, LOW); }
if (sensorValue >= 700) digitalWrite(LED3, HIGH); else { LEDStatus = false; digitalWrite(LED3, LOW); }
if (sensorValue >= 675) digitalWrite(LED2, HIGH); else { LEDStatus = false; digitalWrite(LED2, LOW); }
if (sensorValue >= 650) digitalWrite(LED1, HIGH); else { LEDStatus = false; digitalWrite(LED1, LOW); }
}
else {
// 소리 미감지 시 모든 LED 끄기
LEDStatus = false;
for (int i = 1; i <= 8; i++) {
digitalWrite(i + 2, LOW); // D3~D10
}
}
}
회로도
브레드보드 배선도를 끝까지 따라 연결하세요. (첨부 이미지 참조)
보완 및 확장 아이디어
- 임계값을 동적으로 조정하는 오토 캘리브레이션 로직 추가
- 소음 데이터 SD 카드 로깅 또는 IoT 플랫폼 전송
- LED 바그래프를 WS2812B 네오픽셀로 교체해 부드러운 그라데이션 표현
- 소음 기준치 초과 시 알림(부저, 푸시 알림) 기능 추가
- LCD 대신 OLED 디스플레이로 그래프 표시
참고: 본 코드는 작성자의 학습용 프로젝트로, 주석에 "lol" 등 비공식 표현이 포함되어 있습니다. 실제 적용 시 코드 정리와 검증이 필요합니다.