Powrót do strony głównej

Stacja meteorologiczna Atmega328 NRF24L01: schematy i kod

Artykuł analizuje realizację stacji meteorologicznej na Atmega328 z NRF24L01: schematyka z balansowaniem RGB, programowe filtry migotania, prognoza opadów wg metody najmniejszych kwadratów na BMP280, kontrola komunikacji. Opisane błędy projektowania i optymalizacji.

Tworzymy stację meteorologiczną: Atmega328 + NRF24L01 + kod
Advertisement 728x90

Stacja meteorologiczna na Atmega328 z NRF24L01: realizacja sprzętowa i programowa

Stacja bazowa zbudowana jest na mikrokontrolerze Atmega328 z zewnętrznym rezonatorem 16 MHz. Zasilanie 5 V, dla modułu NRF24L01 przewidziano osobny stabilizator AMS1117 na 3,3 V. Schemat obejmuje podświetlenie RGB z balansowaniem jasności: rezystor 100 Ω na kanał czerwony, 200 Ω na zielony i niebieski dla kompensacji fizjologicznej wrażliwości oka i różnic w emisji kryształów.

Optymalizacja obwodów zasilania

W pierwotnym schemacie użyto jednego kondensatora blokującego na zasilanie i jednego na AREF. Działało to, ale naruszało zalecenia: na każdą parę VCC-GND wymagany jest osobny kondensator 100 nF do tłumienia impulsowych zakłóceń MK. Optymalnie — trzy na zasilanie plus jeden na AREF. Na szynie I²C nadmiarowo dwie pary rezystorów podciągających; wystarczy jedna para 4,7 kΩ.

Rozmieszczenie ścieżek i masa

Płytka wykonana ręcznie metodą fotorezystywną z maską lutowniczą UV. Dolna warstwa — pełny poligon GND, via zrealizowane lutowaniem przewodów. Rozdzielenie masy analogowej i cyfrowej dla fotorezystora okazało się zbędne: czujnik niskoczęstotliwościowy, sygnał 0,5–4,5 V, zakłócenia miliwoltowe. Filtr 0,1 µF na wejściu ADC bocznikuje wysokoczęstotliwościowe zakłócenia i kompensuje synfazowo skoki masy.

Google AdInline article slot
  • Fotorezystor vs fotodioda: fotorezystor (kΩ–MΩ) daje sygnał napięciowy, odporny na zakłócenia; fotodioda (µA) wymaga czystej AGND.
  • Rekomendacja: wspólna masa + 0,1 µF na ADC dla fotorezystorów.

Rozdzielenie mas potrzebne dla słaboprądowych czujników (termopary, piezoelektryczne).

Programowa filtracja migotania

Jasność wyświetlacza i podświetlenia regulowana PWM według fotorezystora. Szum ADC i szum termiczny (±3–4 jednostki) powodują migotanie. Zasilanie nie rozwiązało problemu, zastosowano filtr medianowy 3. rzędu i wykładniczy.

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

Kombinacja filtrów lepsza od uśredniania po 10: eliminuje skoki bez dużego opóźnienia reakcji.

Google AdInline article slot

Prognoza opadów na podstawie barometru

BMP280 mierzy ciśnienie co 10 min, uśrednianie po 10 pomiarach. Tablica z 6 ostatnich wartości analizowana metodą najmniejszych kwadratów do aproksymacji.

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

// MNK
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);

Współczynnik a — nachylenie, delta — zmiana na godzinę (Pa). rain od -100 (wzrost, bezchmurnie) do +100 (spadek, deszcz).

Kontrola łączności i timeout

Przy odbiorze pakietu z czujnika zewnętrznego zapisywany jest lastReceiveTime. Przy braku >60 min:

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

resetWirelessData() zeruje dataIsFresh, wyświetlacz pokazuje myślniki.

Atmosferyczne podświetlenie RGB

Kolor zmienia się w czasie, naśladując naturę: rano — żółty, dzień — niebieski, wieczór — różowy, noc — fioletowy. Liniowa interpolacja RGB według postępu w przedziale.

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 dayy() {
  r = 85; g = 130; b = 255;
}

Fazy zapewniają płynność bez gwałtownych skoków.

Obudowa i oprogramowanie

Obudowa: ABS + przezroczysty PETG, płytka dopasowana do rozmiaru wyświetlacza. Oprogramowanie przez Arduino as ISP na złączach PLS.

Co jest ważne

  • Balansowanie RGB: 100 Ω na czerwony dla wizualnego wyrównania.
  • Filtry: mediana + wykładniczy lepsze od uśredniania przeciw migotaniu.
  • MNK dla ciśnienia: delta ±250 Pa określa prawdopodobieństwo deszczu.
  • Timeout 60 min dla NRF24L01 zapobiega pokazywaniu przestarzałych danych.
  • Wspólna masa wystarczająca dla fotorezystora z 0,1 µF.

— Editorial Team

Advertisement 728x90

Czytaj dalej