Zurück zur Startseite

Wetterstation Atmega328 NRF24L01: Schaltpläne und Code

Artikel analysiert Implementierung der Wetterstation auf Atmega328 mit NRF24L01: Schaltungsdesign mit RGB-Balancierung, Software-Flimmerfilter, Niederschlagsvorhersage durch Methode der kleinsten Quadrate auf BMP280, Kommunikationssteuerung. Designfehler und Optimierungen beschrieben.

Erstellen einer Wetterstation: Atmega328 + NRF24L01 + Code
Advertisement 728x90

Wetterstation mit Atmega328 und NRF24L01: Hardware- und Software-Implementierung

Die Basisstation der Wetterstation basiert auf dem Atmega328-Mikrocontroller mit einem externen 16-MHz-Resonator. Die Stromversorgung erfolgt mit 5 V, wobei ein separater AMS1117-3,3-V-Regler für das NRF24L01-Modul verwendet wird. Die Schaltung umfasst eine RGB-Hintergrundbeleuchtung mit Helligkeitsabgleich: ein 100-Ω-Widerstand für den roten Kanal, 200 Ω für grün und blau, um die physiologische Empfindlichkeit des Auges und Unterschiede in der Kristallemission auszugleichen.

Stromversorgungsoptimierung

In der ursprünglichen Schaltung wurde ein Bypass-Kondensator für die Stromversorgung und einer für AREF verwendet. Dies funktionierte, verstieß jedoch gegen Empfehlungen: Jedes VCC-GND-Paar benötigt einen separaten 100-nF-Kondensator, um Impulsrauschen des Mikrocontrollers zu unterdrücken. Optimal sind drei für die Stromversorgung plus einer auf AREF. Auf dem I²C-Bus sind zwei Paare Pull-up-Widerstände überflüssig; ein Paar mit 4,7 kΩ reicht aus.

PCB-Layout und Masseführung

Die Platine wurde per Hand mit der Fotolackmethode und UV-Lötstopplack hergestellt. Die Unterseite ist ein durchgehendes GND-Polygon, Durchkontaktierungen wurden durch Löten von Drähten realisiert. Die Trennung von analoger und digitaler Masse für den Fotowiderstand erwies sich als unnötig: Der Sensor ist niederfrequent, das Signal liegt bei 0,5–4,5 V, das Rauschen im Millivoltbereich. Ein 0,1-µF-Filter am ADC-Eingang leitet hochfrequente Störungen ab und kompensiert Massespitzen im Gleichtakt.

Google AdInline article slot
  • Fotowiderstand vs. Fotodiode: Fotowiderstand (kΩ–MΩ) liefert ein Spannungssignal, robust gegenüber Rauschen; Fotodiode (µA) erfordert saubere AGND.
  • Empfehlung: Gemeinsame Masse + 0,1 µF am ADC für Fotowiderstände.

Massentrennung ist für niederstromsensitive Sensoren (Thermoelemente, Piezo) erforderlich.

Software-Flimmerfilterung

Anzeige und Hintergrundbeleuchtung werden per PWM basierend auf dem Fotowiderstand eingestellt. ADC-Rauschen und thermisches Rauschen (±3–4 Einheiten) verursachen Flimmern. Die Stromversorgung löste das Problem nicht; ein Medianfilter 3. Ordnung und ein exponentieller Filter wurden angewendet.

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

Die Filterkombination ist besser als eine Mittelung über 10 Werte: Sie eliminiert Spitzen ohne signifikante Reaktionsverzögerung.

Google AdInline article slot

Niederschlagsvorhersage per Barometer

BMP280 misst den Druck alle 10 Minuten, gemittelt über 10 Messwerte. Ein Array der letzten 6 Werte wird mit der Methode der kleinsten Quadrate zur Approximation analysiert.

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

// Kleinste Quadrate
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);

Koeffizient a ist die Steigung, delta die Änderung pro Stunde (Pa). rain von -100 (steigend, klar) bis +100 (fallend, Regen).

Kommunikationskontrolle und Timeout

Beim Empfang eines Pakets vom Außensensor wird lastReceiveTime aufgezeichnet. Bei Abwesenheit >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() setzt dataIsFresh auf null, der Bildschirm zeigt Striche an.

Atmosphärische RGB-Hintergrundbeleuchtung

Die Farbe ändert sich im Tagesverlauf, ähnlich der Natur: Morgen – gelb, Tag – blau, Abend – rosa, Nacht – lila. Lineare Interpolation von RGB basierend auf dem Fortschritt innerhalb des Intervalls.

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

Phasen gewährleisten einen sanften Übergang ohne abrupte Sprünge.

Gehäuse und Firmware

Gehäuse: ABS + transparentes PETG, Platine auf Displaygröße zugeschnitten. Firmware via Arduino als ISP an PLS-Anschlüssen.

Wichtige Punkte

  • RGB-Abgleich: 100 Ω auf Rot für visuelle Angleichung.
  • Filter: Median + exponentiell besser als Mittelung gegen Flimmern.
  • Kleinste Quadrate für Druck: Delta ±250 Pa bestimmt Regenwahrscheinlichkeit.
  • 60-min-Timeout für NRF24L01 verhindert Anzeige veralteter Daten.
  • Gemeinsame Masse ausreichend für Fotowiderstand mit 0,1 µF.

— Editorial Team

Advertisement 728x90

Weiterlesen