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.
- 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.
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:
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
Noch keine Kommentare.