홈으로 돌아가기

기상 스테이션 Atmega328 NRF24L01: 회로도 및 코드

Atmega328에 NRF24L01을 사용한 기상 스테이션 구현 분석 기사: RGB 밸런싱 회로 설계, 소프트웨어 플리커 필터, BMP280 최소제곱법 강수 예보, 통신 제어. 설계 오류 및 최적화 설명.

기상 스테이션 제작: Atmega328 + NRF24L01 + 코드
Advertisement 728x90

Atmega328 기반 NRF24L01 날씨 관측소: 하드웨어 및 소프트웨어 구현

날씨 관측소의 베이스 스테이션은 외부 16 MHz 공진기를 사용하는 Atmega328 마이크로컨트롤러로 구축되었습니다. 전원 공급은 5V이며, NRF24L01 모듈을 위해 별도의 AMS1117 3.3V 레귤레이터가 사용됩니다. 회로에는 시각적 민감도와 크리스털 발광 차이를 보상하기 위한 RGB 백라이트 밝기 균형 조정이 포함되어 있습니다: 빨간 채널에 100Ω 저항, 녹색과 파란색 채널에 200Ω 저항을 사용합니다.

전원 공급 최적화

초기 회로에서는 전원용 바이패스 커패시터 하나와 AREF용 커패시터 하나가 사용되었습니다. 이는 작동했지만 권장 사항을 위반했습니다: 각 VCC-GND 쌍은 마이크로컨트롤러 임펄스 노이즈를 억제하기 위해 별도의 100 nF 커패시터가 필요합니다. 최적으로는 전원용 세 개와 AREF용 하나가 적합합니다. I²C 버스에서는 두 쌍의 풀업 저항이 과도하며, 4.7 kΩ 한 쌍으로 충분합니다.

PCB 레이아웃과 접지

보드는 UV 솔더 마스크를 사용한 포토레지스트 방식으로 수작업 제작되었습니다. 하단 레이어는 솔리드 GND 폴리곤이며, 비아는 와이어 납땜으로 구현되었습니다. 포토레지스터를 위한 아날로그와 디지털 접지 분리는 불필요한 것으로 판명되었습니다: 센서는 저주파이며, 신호는 0.5–4.5V, 노이즈는 밀리볼트 수준입니다. ADC 입력의 0.1 µF 필터는 고주파 간섭을 차단하고 공통 모드에서 접지 스파이크를 보상합니다.

Google AdInline article slot
  • 포토레지스터 vs 포토다이오드: 포토레지스터(kΩ–MΩ)는 전압 신호를 제공하며 노이즈에 강합니다; 포토다이오드(µA)는 깨끗한 AGND가 필요합니다.
  • 권장 사항: 포토레지스터의 경우 공통 접지 + ADC에 0.1 µF 필터를 사용하세요.

접지 분리는 저전류 센서(열전쌍, 압전)에 필요합니다.

소프트웨어 플리커 필터링

디스플레이와 백라이트 밝기는 포토레지스터를 기반으로 PWM을 통해 조정됩니다. ADC 노이즈와 열 노이즈(±3–4 단위)로 인해 플리커가 발생합니다. 전원 공급으로는 문제가 해결되지 않아 3차 중앙값 필터와 지수 필터가 적용되었습니다.

int rawValue = analogRead(0);
int filteredValue = med.filter(rawValue);
float smoothValue = expF.filter(filteredValue);
int photoresistor = map(smoothValue, 260, 1023, 0, 255);
photoresistor = constrain(photoresistor, 0, 255);
analogWrite(3, 255 - photoresistor);

필터 조합은 10회 평균보다 우수합니다: 상당한 반응 지연 없이 스파이크를 제거합니다.

Google AdInline article slot

기압계를 통한 강수 예측

BMP280는 10분마다 압력을 측정하며, 10회 측정값을 평균합니다. 최소 자승법을 사용하여 근사화하기 위해 마지막 6개 값의 배열이 분석됩니다.

if (millis() - lasttime > 600000) {
  lasttime = millis();
  PP = pressure();
  for (byte i = 0; i < 5; i++) {
    pres1_array[i] = pres1_array[i + 1];
  }
  pres1_array[5] = PP;
}

// 최소 자승법
for (byte i = 0; i < 6; i++) {
  sumX += time_array[i];
  sumY += (long)pres1_array[i];
  sumX2 += time_array[i] * time_array[i];
  sumXY += (long)time_array[i] * pres1_array[i];
}
a = (long)6 * sumXY - (long)sumX * sumY;
a = (float)a / (6 * sumX2 - sumX * sumX);
delta = a * 6;
rain = map(delta, -250, 250, 100, -100);

계수 a는 기울기이며, delta는 시간당 변화(Pa)입니다. rain은 -100(상승, 맑음)에서 +100(하강, 비) 범위입니다.

통신 제어 및 타임아웃

야외 센서에서 패킷을 수신할 때 lastReceiveTime이 기록됩니다. 60분 이상 없으면:

Google AdInline article slot
if (radio.available()) {
  radio.read(&rxData, sizeof(rxData));
  lastReceiveTime = millis();
  dataIsFresh = true;
}
if (lastReceiveTime > 0 && millis() - lastReceiveTime > 3600000) {
  resetWirelessData();
}

resetWirelessData()dataIsFresh를 0으로 설정하고, 화면에 대시를 표시합니다.

대기 RGB 백라이트

색상은 시간에 따라 변화하며 자연을 모방합니다: 아침 — 노란색, 낮 — 파란색, 저녁 — 분홍색, 밤 — 보라색. 구간 내 진행률을 기반으로 RGB의 선형 보간이 사용됩니다.

float progress = (currentHour - 8 + (float)currentMinute / 60.0) / 3.0;
if (progress < 0.5) {
  float subProgress = progress * 2.0;
  r = 255;
  g = 80 + subProgress * 90;
  b = 0 + subProgress * 50;
} else {
  float subProgress = (progress - 0.5) * 2.0;
  r = 255 - subProgress * 170;
  g = 180 - subProgress * 50;
  b = 60 + subProgress * 195;
}
void day() {
  r = 85; g = 130; b = 255;
}

단계는 급격한 점프 없이 부드러움을 보장합니다.

외함과 펌웨어

외함: ABS + 투명 PETG, 보드는 디스플레이 크기에 맞춤. 펌웨어는 PLS 커넥터를 통해 Arduino as ISP로 업로드됩니다.

핵심 포인트

  • RGB 균형 조정: 시각적 균등화를 위해 빨간색에 100Ω 저항.
  • 필터: 중앙값 + 지수 필터가 플리커 방지에 평균보다 우수.
  • 압력 최소 자승법: delta ±250 Pa가 강수 확률 결정.
  • NRF24L01 60분 타임아웃으로 오래된 데이터 표시 방지.
  • 포토레지스터의 경우 0.1 µF 필터와 공통 접지로 충분.

— Editorial Team

Advertisement 728x90

다음 읽기