Fortgeschrittener Kippwannen-Regenmesser mit Arduino-Integration
Komponenten & Zubehör
| Bauteil | Anzahl | Hinweise |
|---|---|---|
| Arduino Nano R3 | 1 | Steuerung, Logging, Display |
| Tiny RTC I2C DS1307 (oder DS3231) | 1 | Echtzeituhr mit Backup-Batterie |
| SD-Karten-Modul (LC Studio) | 1 | Datenlogging (CSV) |
| LCD 16×2 (Weiß auf Blau, I2C oder 3-Draht) | 1 | Hier per 74HC595 Shift-Register (3 Pins) |
| 74HC595 Shift-Register | 1 | Seriell-Parallel für LCD |
| Reed-Kontakt (NO) + Magnet (7×7 mm) | je 1 | Kippwannen-Erkennung |
| Taster (PCB) + Potentiometer 10 kΩ (Kontrast) | je 1 | Menünavigation & LCD-Kontrast |
| Widerstände: 1 kΩ (×2), 330 Ω (×2) | Set | Pull-ups, LED-Vorwiderstände |
| Keramik-Kondensator 100 nF | 1 | Entstörung |
| 7–12 V Netzteil (Hutschiene/Stecker) | 1 | Innen-Einheit |
| Lochrasterplatine 5×10 cm (2×) | 2 | Hauptplatine & Frontplatine |
| 3D-gedruckte Teile (PETG) | Set | Außen: Basis, Deckel, Trichter, Filter, Kippwanne, Unterbau. Innen: Gehäuse, Front, Spacer. |
Werkzeuge
- 3D-Drucker (PETG, 30 % Infill, Filter: keine Horizontal-Schalen → porös)
- Lötkolben, Bohrer (3 mm, 1/8″, 1/4″), Schraubendreher
- Schrauben: M3×6, M3×10, M3×15, 1/4-20 Sechskant
Funktionsprinzip
Der Kippwannen-Regenmesser (Tipping Bucket) entspricht dem meteorologischen Standard. Regenwasser wird über einen Trichter in eine wippende Wanne (wie eine Wippe) geleitet. Jede Kammer fasst ca. 2 ml. Beim Kippen schließt ein Magnet an der Wanne kurz einen Reed-Kontakt → Hardware-Interrupt am Arduino.
Berechnung: Auffangfläche = 16,605 in² (ca. 107 cm²). 1 Kipp = 2 ml = 0,122 in³ → Niederschlag = 0,122 / 16,605 = 0,00735 Zoll (0,187 mm) pro Kipp. Im Code als conversion_factor = 0.00854 Zoll (kalibriert).
Aufbau-Schritte (Kurzfassung)
- 3D-Druck: Alle Teile in PETG (UV- & temperaturbeständig). Filter ohne Top/Bottom-Layer (porös).
- Frontplatine: LCD trocken einpassen, Bohrungen für Montagelöcher in Lochraster übertragen. 74HC595, Taster, Widerstände bestücken, Verdrahtung laut Schema.
- LCD montieren: Mit gedruckten Distanzhaltern (Spacer) über dem IC befestigen (M3×15).
- Hauptplatine: Arduino Nano (Pin D12 → Loch R27), Kondensator, Widerstände, Verdrahtung. Dann SD- & RTC-Modul einlöten.
- Innen-Gehäuse: Kabeldurchführungen bohren, Hauptplatine einschieben (2× M3×6), Frontplatine anschrauben, Taster durch Frontabdeckung.
- Außen-Einheit: Reed-Kontakt an Unterbau (Kabelbinder). Magnet an Kippwanne. Wanne auf Messingrohr (1/8″, ca. 5 cm) als Achse → leichtgängig! 1/8″ Unterlegscheibe außen. Basis an Aluwinkel (1/4-20 Schrauben von innen). Unterbau an Gehäuseboden (M3×10).
- Trichter & Filter: Trichter einsetzen. Vogelschutz: 24 Stück 2″ verzinkter Draht (erhitzt in Kunststoff drücken). Filter in Trichter einlegen (regelmäßig reinigen).
- Aufstellung: Außenwaage in beide Richtungen nivellieren. Kabel zur Inneneinheit verlegen.
- Inbetriebnahme: RTC-Zeit setzen (eigenes Sketch), Hauptprogramm flashen, SD-Karte einlegen. Test: Reed-Kontakt kurzschließen → Zähler steigt. SD-Karte prüfen (Text.txt mit Zeitstempeln).
- Kalibrierung (optional): 1 Tasse (236,6 ml = 14,44 in³) sehr langsam eingießen → Anzeige soll 0,87″ (22,1 mm) zeigen.
conversion_factoranpassen.
Display & Menü
Ein Taster schaltet durch 4 Anzeigemodi (Entprellung 300 ms, Hintergrundbeleuchtung 30 s nach Tastendruck):
- Aktuelle Stunde (seit letzter vollen Stunde)
- Vorherige Stunde
- Aktueller Tag (seit Mitternacht)
- Vorheriger Tag
Hintergrundbeleuchtung schaltet sich nach 30 s Inaktivität aus.
Datenlogging (SD-Karte)
Jeder Kipp-Ereignis wird sofort mit Zeitstempel (JJJJ/MM/TT HH:MM:SS) und Niederschlagsmenge in test.txt geschrieben. Format:
Event 2021/12/24 14:32:15 0.00854
Event 2021/12/24 14:35:02 0.00854
...
Datei kann in Excel/Calc importiert → Diagramme, Statistiken.
Arduino-Code (Zwei Sketches)
1. RTC-Zeit einstellen (einmalig)
#include <Wire.h>
#define DS1307_I2C_ADDRESS 0x68
byte decToBcd(byte v) { return (v/10*16)+(v%10); }
void setDateDs1307() {
byte second=0, minute=11, hour=12, dayOfWeek=5, dayOfMonth=24, month=7, year=20;
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0); Wire.write(decToBcd(second)); Wire.write(decToBcd(minute));
Wire.write(decToBcd(hour)); Wire.write(decToBcd(dayOfWeek));
Wire.write(decToBcd(dayOfMonth)); Wire.write(decToBcd(month)); Wire.write(decToBcd(year));
Wire.endTransmission();
}
void setup() { Wire.begin(); Serial.begin(19200); setDateDs1307(); }
void loop() { delay(2000); /* Zeit auslesen & anzeigen */ }
2. Hauptprogramm (Rain Gauge)
#include <SPI.h> #include <SD.h> #include <Wire.h> #include <RTClib.h> #include <LiquidCrystal_SR.h>
// LiquidCrystal_SR lcd(DataPin, ClockPin, EnablePin) -> Pins 6,5,9
LiquidCrystal_SR lcd(6,5,9);
RTC_DS3231 rtc;
const byte INT_BUCKET = 3; // Reed-Kontakt (FALLING)
const byte INT_MENU = 2; // Taster (RISING)
volatile int bucketTip = 0, menuSelect = 0;
float tipHour=0, tipPrevHour=0, tipDay=0, tipPrevDay=0;
int tipCounter=0, currMin, loopMin, currHour, loopHour, currDay, loopDay;
float conv = 0.00854; // Zoll pro Kipp (kalibrieren!)
unsigned long backlightOff=0, backlightDur=30000;
File myFile;
void setup() {
lcd.begin(16,2); lcd.home();
rtc.begin();
pinMode(10,OUTPUT); pinMode(7,OUTPUT); digitalWrite(7,HIGH);
backlightOff = millis()+backlightDur;
if(!SD.begin(4)) { lcd.print("insert SD Card"); return; }
pinMode(INT_BUCKET, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(INT_BUCKET), count, FALLING);
pinMode(INT_MENU, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(INT_MENU), menu, RISING);
myFile = SD.open("test.txt", FILE_WRITE);
if(myFile) { myFile.println("Rain Gauge Ready"); myFile.close(); }
DateTime now = rtc.now();
currMin=loopMin=now.minute(); currHour=loopHour=now.hour(); currDay=loopDay=now.day();
lcd.setCursor(0,0); lcd.print(printTime(now));
lcd.setCursor(1,1); lcd.print("Rain Gauge");
}
void loop() {
DateTime now = rtc.now();
currMin=now.minute(); loopMin=now.minute();
currHour=now.hour(); loopHour=now.hour();
currDay=now.day(); loopDay=now.day();
// Stündliche & tägliche Summenbildung (verschachtelte while-Schleifen)
while (loopDay - currDay == 0) {
while (loopHour - currHour == 0) {
if (millis() > backlightOff) digitalWrite(7,LOW);
if (bucketTip) { bucketTip=0; tipCounter++; logEvent(now); delay(200); }
else { now = rtc.now(); loopHour = now.hour(); }
showMenu(now);
}
// Stundenwechsel
now = rtc.now(); currHour = now.hour(); loopDay = now.day(); loopHour = now.hour();
tipPrevHour = tipCounter * conv;
tipDay += tipPrevHour; tipCounter = 0;
}
// Tageswechsel
tipPrevDay = tipDay; tipDay = 0; tipPrevHour = 0; tipCounter = 0;
}
void logEvent(DateTime ts) {
myFile = SD.open("test.txt", FILE_WRITE);
if(myFile) {
myFile.print("Event "); myFile.print(ts.year()); myFile.print('/');
myFile.print(ts.month()); myFile.print('/'); myFile.print(ts.day()); myFile.print(' ');
myFile.print(ts.hour()); myFile.print(':'); myFile.print(ts.minute()); myFile.print(':');
myFile.print(ts.second()); myFile.print(' '); myFile.println(conv,5);
myFile.close();
}
}
void showMenu(DateTime now) {
switch(menuSelect) {
case 1: lcd.clear(); lcd.print("Current Hour"); lcd.setCursor(0,1); lcd.print(tipCounter*conv); break;
case 2: lcd.clear(); lcd.print("Previous Hour"); lcd.setCursor(0,1); lcd.print(tipPrevHour); break;
case 3: lcd.clear(); lcd.print("Current Day"); lcd.setCursor(0,1); lcd.print(tipDay + tipCounter*conv); break;
case 4: lcd.clear(); lcd.print("Previous Day"); lcd.setCursor(0,1); lcd.print(tipPrevDay); break;
}
delay(500);
}
// Interrupts mit Entprellung (300 ms)
void count() {
static unsigned long last=0; unsigned long now=millis();
if(now-last > 300) { bucketTip=1; } last=now;
}
void menu() {
static unsigned long last=0; unsigned long now=millis();
if(now-last > 300) {
if(digitalRead(7)==LOW) digitalWrite(7,HIGH);
else { menuSelect++; if(menuSelect>4) menuSelect=1; }
backlightOff = now + backlightDur;
}
last=now;
}
String printTime(DateTime t) {
char buf[20]; sprintf(buf, "%02d:%02d:%02d %02d/%02d", t.hour(), t.minute(), t.second(), t.month(), t.day());
return String(buf);
}
3D-Druck Dateien (STL / STEP / Fusion 360)
- Außen: Basis, Deckel, Trichter, Filter (porös), Unterbau, Kippwanne
- Innen: Gehäuse, Frontabdeckung, LCD-Spacer, Taster-Knopf
- Montage-Modell (Fusion 360 .f3d, .step)
Schaltplan
Fritzing-Datei: rain_gauge.fzz (Haupt- & Frontplatine, Verdrahtung Nano, Shift-Register, LCD, RTC, SD, Reed, Taster, Netzteil).
Herstellungsprozess
- Präzisions-Manometer für industrielle und sicherheitsrelevante Anwendungen
- Intelligente Jalousien: Automatische Lichtsteuerung mit Arduino & Solarenergie
- Italienische Word Clock mit Arduino Nano, NeoPixel, LCD & RTC
- Digitale Höhenmessgeräte: Präzise Messung & Qualitätskontrolllösungen
- Mikrometerschraube: Definition, Geschichte und praktische Anwendung
- Druckmessgeräte: Funktionsweise, Typen und Vorteile im Überblick
- Dehnungsmessstreifen (DMS): Mechanische Spannung in präzise elektrische Signale wandeln
- Das Pirani-Manometer erklärt: Funktionsweise, Anwendungen und Vorteile
- Membran-Manometer erklärt: Präzision und Zuverlässigkeit bei Druckmessung
- Bourdon-Rohr-Manometer: Aufbau, Funktionsweise und Anwendungen