어제 만든 board2(온습도+조도+소리)에 미세먼지 모듈 추가해보기
ㄴ전력 부족으로 아두이노 우노 자체 전원이 안 들어옴
ㄴ현재 와이파이 모듈 전부 사용 중이라 와이파이 연결 불가능
/*
* ============================================================
* BOARD3 — 미세먼지 전용 모듈 (GP2Y1010AU0F)
* Arduino Uno R3 단독 · WiFi 없음 · 시리얼 모니터 출력
* ============================================================
*
* [센서 핀 배열] — 6핀 플랫 케이블 (왼쪽→오른쪽)
* 핀1: LED → 150Ω 저항 → Arduino D3
* 핀2: VCC → Arduino 5V
* 핀3: GND → Arduino GND
* 핀4: OUT → Arduino A0
* 핀5: VCC → Arduino 5V (핀2와 같은 5V)
* 핀6: GND → Arduino GND (핀3와 같은 GND)
*
* [필수 외부 부품]
* - 150Ω 저항 (없으면 220Ω 대체 가능)
* : D3 와 센서 핀1(LED) 사이에 직렬 연결
* : 없으면 LED 핀 과전류로 센서 영구 손상
* - 220μF 전해 콘덴서
* : 센서 VCC(핀2) — GND(핀3) 사이에 병렬 연결
* : + 극을 VCC 쪽에, - 극을 GND 쪽에 연결
* : 없으면 측정값이 튀거나 불안정
*
* [시리얼 출력 예시]
* ==============================
* BOARD3 미세먼지 센서
* ==============================
* [측정] 전압: 0.823 V | 농도: 44.6 μg/m³ | 등급: 보통
* [측정] 전압: 0.761 V | 농도: 32.2 μg/m³ | 등급: 보통
*
* [등급 기준 — WHO / 환경부]
* 좋음 : 0 ~ 30 μg/m³
* 보통 : 31 ~ 80 μg/m³
* 나쁨 : 81 ~ 150 μg/m³
* 매우나쁨: 151 이상 μg/m³
* ============================================================
*/
// ── 핀 정의 ────────────────────────────────────────────────
#define DUST_LED_PIN 3 // 센서 내부 LED 제어 핀 (디지털 출력)
#define DUST_OUT_PIN A1 // 센서 아날로그 전압 출력 핀
// ── 타이밍 상수 (데이터시트 필수 준수, 단위: 마이크로초 μs) ──
// ┌── LED ON ──────────────────┐
// │ 280μs 후 ADC 읽기 │
// │ 40μs 더 기다린 후 LED OFF │
// └─────────────────────────── ┘
// 그 후 9680μs 대기 → 총 1주기 = 10ms
const int SAMPLING_TIME = 280; // LED ON 후 이 시간(μs) 뒤에 ADC 읽기
const int DELTA_TIME = 40; // ADC 읽은 후 추가 대기 (μs)
const int SLEEP_TIME = 9680; // LED OFF 후 다음 사이클까지 대기 (μs)
// ── 보정 상수 ──────────────────────────────────────────────
// 먼지가 전혀 없을 때 센서 출력 전압 (약 0.6V, 환경마다 다를 수 있음)
const float V_NO_DUST = 0.6;
// 전압 → 농도 변환 기울기: 0.5V 증가 = 100 μg/m³ 증가
const float K_FACTOR = 0.5;
// ── 측정 평균 횟수 ─────────────────────────────────────────
// 한 번에 N회 읽어서 평균 → 노이즈(잡음) 줄이기
const int SAMPLE_COUNT = 5;
// ── 출력 주기 ──────────────────────────────────────────────
const unsigned long PRINT_INTERVAL = 1000; // 1000ms = 1초마다 출력
unsigned long lastPrintMs = 0;
// ── 함수 선언 ──────────────────────────────────────────────
float readDustVoltage(); // 센서에서 전압 읽기 (평균)
float voltToDensity(float v); // 전압 → μg/m³ 변환
const char* getDustLevel(float density); // 농도 → 등급 문자열
void printResult(float v, float d); // 시리얼 출력
// ══════════════════════════════════════════════════════════
void setup() {
Serial.begin(9600);
// LED 제어 핀: 출력 모드, 초기값 HIGH (Active LOW → HIGH = LED 꺼짐)
pinMode(DUST_LED_PIN, OUTPUT);
digitalWrite(DUST_LED_PIN, HIGH);
Serial.println(F("=============================="));
Serial.println(F(" BOARD3 미세먼지 센서 "));
Serial.println(F(" GP2Y1010AU0F Serial Only "));
Serial.println(F("=============================="));
Serial.println(F("단위: μg/m³ | 보드레이트: 9600"));
Serial.println(F("------------------------------"));
delay(2000); // 센서 전원 안정화 대기 (2초)
Serial.println(F("[준비] 측정 시작!\n"));
}
// ══════════════════════════════════════════════════════════
// void loop() {
// unsigned long now = millis();
// // 1초마다 측정 및 출력
// if (now - lastPrintMs < PRINT_INTERVAL) return;
// lastPrintMs = now;
// float voltage = readDustVoltage(); // 전압 읽기
// float density = voltToDensity(voltage); // μg/m³ 변환
// printResult(voltage, density); // 시리얼 출력
// }
void loop() {
int raw = analogRead(DUST_OUT_PIN);
float v = raw * (5.0 / 1023.0);
Serial.print("RAW: "); Serial.print(raw);
Serial.print(" V: "); Serial.println(v, 3);
delay(500);
}
// ══════════════════════════════════════════════════════════
// 센서 전압 읽기
// - LED를 규정 타이밍대로 켜고 ADC 값을 읽음
// - SAMPLE_COUNT 회 반복 후 평균 전압 반환
// ══════════════════════════════════════════════════════════
float readDustVoltage() {
long adcSum = 0;
for (int i = 0; i < SAMPLE_COUNT; i++) {
// ① LED 켜기 (Active LOW: LOW 신호 = LED ON)
digitalWrite(DUST_LED_PIN, LOW);
delayMicroseconds(SAMPLING_TIME); // 280μs 대기
// ② 아날로그 값 읽기 (0 ~ 1023)
adcSum += analogRead(DUST_OUT_PIN);
// ③ LED ON 구간 나머지 채우기
delayMicroseconds(DELTA_TIME); // 40μs 추가 대기
// ④ LED 끄기
digitalWrite(DUST_LED_PIN, HIGH);
// ⑤ 다음 사이클까지 대기
delayMicroseconds(SLEEP_TIME); // 9680μs 대기
}
// ADC 평균 → 전압 변환
// Arduino Uno: 10비트 ADC (0~1023), 기준전압 5V
float adcAvg = (float)adcSum / SAMPLE_COUNT;
float voltage = adcAvg * (5.0f / 1023.0f);
return voltage;
}
// ══════════════════════════════════════════════════════════
// 전압 → 먼지 농도 변환 (선형 근사)
// density(μg/m³) = (V - V_no_dust) / K_FACTOR * 100
// 음수 결과는 0으로 처리 (공기가 매우 깨끗한 상태)
// ══════════════════════════════════════════════════════════
float voltToDensity(float v) {
float density = (v - V_NO_DUST) / K_FACTOR * 100.0f;
return (density < 0.0f) ? 0.0f : density;
}
// ══════════════════════════════════════════════════════════
// 농도 → 등급 문자열
// ══════════════════════════════════════════════════════════
const char* getDustLevel(float density) {
if (density <= 30.0f) return "좋음 ";
if (density <= 80.0f) return "보통 ";
if (density <= 150.0f) return "나쁨 ";
return "매우나쁨";
}
// ══════════════════════════════════════════════════════════
// 시리얼 모니터 출력
// 형식: B3, V:0.823, D:44.6, LV:보통
// ══════════════════════════════════════════════════════════
void printResult(float v, float d) {
// 한 줄 포맷 출력 (나중에 Python으로 파싱하기 쉬운 형식)
Serial.print(F("B3,V:"));
Serial.print(v, 3); // 전압 (소수점 3자리)
Serial.print(F(",D:"));
Serial.print(d, 1); // 농도 (소수점 1자리)
Serial.print(F(",LV:"));
Serial.println(getDustLevel(d)); // 등급
}
미세먼지 모듈 고장
GUI -> LCD 모니터 차체에 표시
'로보테크AI' 카테고리의 다른 글
| 융합_로보테크 AI 자율주행 로봇 개발자 과정-26/03/06[발표회1] (0) | 2026.03.06 |
|---|---|
| 융합_로보테크 AI 자율주행 로봇 개발자 과정-26/03/05 (0) | 2026.03.05 |
| 융합_로보테크 AI 자율주행 로봇 개발자 과정-26/03/03 (0) | 2026.03.03 |
| 융합_로보테크 AI 자율주행 로봇 개발자 과정-26/02/27 (0) | 2026.02.27 |
| 융합_로보테크 AI 자율주행 로봇 개발자 과정-26/02/26[조별과제1] (0) | 2026.02.26 |