Zpět na domů

Meteostanice Atmega328 NRF24L01: schémata a kód

Článek rozebírá implementaci meteostanice na Atmega328 s NRF24L01: schématika s balancováním RGB, softwarové filtry blikání, předpověď srážek podle MNK na BMP280, kontrola spojení. Popsány chyby návrhu a optimalizace.

Vytváříme meteostanici: Atmega328 + NRF24L01 + kód
Advertisement 728x90

Meteostanice na Atmega328 s NRF24L01: hardwarová a softwarová realizace

Základní stanice meteostanice je postavena na mikrokontroléru Atmega328 s externím rezonátorem 16 MHz. Napájení je 5 V, pro modul NRF24L01 je zajištěn samostatný stabilizátor AMS1117 na 3,3 V. Schéma zahrnuje RGB podsvícení s vyvážením jasu: rezistor 100 Ω na červený kanál, 200 Ω na zelený a modrý pro kompenzaci fyziologické citlivosti oka a rozdílů v záření krystalů.

Optimalizace napájecích obvodů

V původním schématu byl použit jeden blokovací kondenzátor na napájení a jeden na AREF. To fungovalo, ale porušovalo doporučení: na každý pár VCC-GND je potřeba samostatný kondenzátor 100 nF pro potlačení impulsních rušení MK. Optimálně – tři na napájení plus jeden na AREF. Na sběrnici I²C jsou nadbytečně dvě páry pull-up rezistorů; stačí jeden pár 4,7 kΩ.

Rozložení DPS a zem

Deska je vyrobena ručně fotorezistivní metodou s UV pájecí maskou. Spodní vrstva – souvislý polygon GND, via jsou realizovány pájením drátů. Oddělení analogové a digitální země pro fotorezistor se ukázalo jako zbytečné: senzor je nízkofrekvenční, signál 0,5–4,5 V, rušení milivoltů. Filtr 0,1 µF na vstupu ADC shuntuje vysokofrekvenční rušení a kompenzuje synfázně skoky země.

Google AdInline article slot
  • Fotorezistor vs fotodioda: fotorezistor (kΩ–MΩ) dává voltový signál, je odolný vůči rušení; fotodioda (µA) vyžaduje čistou AGND.
  • Doporučení: společná zem + 0,1 µF na ADC pro fotorezistory.

Oddělení zemí je potřeba pro slaboproudé senzory (termočlánky, piezoelektrické).

Softwarová filtrace blikání

Jas displeje a podsvícení je regulován PWM podle fotorezistoru. Šum ADC a tepelný šum (±3–4 jednotky) způsobují blikání. Napájení problém neodstranilo, použity jsou mediánový filtr 3. řádu a exponenciální.

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

Kombinace filtrů je lepší než průměrování přes 10: odstraňuje špičky bez silného zpoždění reakce.

Google AdInline article slot

Předpověď srážek podle barometru

BMP280 měří tlak každých 10 min, průměrování přes 10 měření. Pole z 6 posledních hodnot je analyzováno metodou nejmenších čtverců pro aproximaci.

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

// MNČ
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);

Koeficient a – sklon, delta – změna za hodinu (Pa). rain od -100 (růst, jasno) do +100 (pokles, déšť).

Kontrola spojení a timeout

Při příjmu paketu od venkovního senzoru se zaznamená lastReceiveTime. Při absenci >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() vynuluje dataIsFresh, displej zobrazí pomlčky.

Atmosférické RGB podsvícení

Barva se mění podle času, napodobuje přírodu: ráno – žlutá, den – modrá, večer – růžová, noc – fialová. Lineární interpolace RGB podle pokroku v intervalu.

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;
}

Fáze zajišťují plynulost bez prudkých skoků.

Kryt a firmware

Kryt: ABS + průhledný PETG, deska podle velikosti displeje. Firmware přes Arduino as ISP na PLS konektorech.

Co je důležité

  • Vyvážení RGB: 100 Ω na červený pro vizuální vyrovnání.
  • Filtry: medián + exponenciální lepší než průměrování proti blikání.
  • MNČ pro tlak: delta ±250 Pa určuje pravděpodobnost deště.
  • Timeout 60 min pro NRF24L01 zabraňuje zobrazení zastaralých dat.
  • Společná zem stačí pro fotorezistor s 0,1 µF.

— Editorial Team

Advertisement 728x90

Číst dál