Geavanceerde kantelbuis regenmeter met Arduino-integratie
Onderdelen en benodigdheden
| Arduino Nano R3 | × | 1 |
| Tiny RTC I2C DS1307 | × | 1 |
| SD-kaartmodule - LC Studios | × | 1 |
| 7-12 VDC voeding (of adapter) | × | 1 |
| Adafruit Standaard LCD - 16x2 Wit op Blauw | × | 1 |
| Texas Instruments Shift Register - Serieel naar Parallel | × | 1 |
| Weerstand 1k ohm | × | 2 |
| Weerstand 330 ohm | × | 2 |
| Condensator 100 nF | × | 1 |
| Enkelvoudige potentiometer - 10k ohm | × | 1 |
| PCB Momentcontact drukknop | × | 1 |
| Reed-contact, SPST-NO | × | 1 |
| Magneet (7mm OD x 7mm lang) | × | 1 |
| 5x10CM eenzijdig prototypeprintplaat | × | 1 |
Benodigde tools en machines
- 3D-printer (standaard)
- Soldeerbout (standaard)
Over dit project
Dit is een kantelbuis regenmeter, gebaseerd op professionele meteorologische regenmeters. Regenwater wordt via een trechter op een kantelende emmer geleid (als een wiegje), met aan beide kanten een emmertje van ca. 2 ml. Als de ene kant vol is, kantelt de emmer en begint de andere kant te vullen. Bij elke kanteling sluit een reed-contact tijdelijk, wat een signaal stuurt naar de Arduino-hardware-interrupt. De Arduino telt elke kanteling en vertaalt dit naar neerslaghoeveelheid (inches regen), gebaseerd op het volume van de emmer en het vangoppervlak van de reservoir (16,605 vierkante inch).
De binnen-eenheid heeft een menu om 'huidig uur', 'vorig uur', 'huidige dag' en 'vorige dag' totals te tonen.
Bij elke kanteling wordt een gedateerd evenement naar een SD-kaartbestand geschreven. Dit kan later in Excel geïmporteerd worden voor analyse en grafieken.
Hoewel ik geen video heb van de daadwerkelijke kanteling, toont deze video de meter tijdens een echte regenbui.
Stap 1
Print alle onderdelen. Ik gebruikte PETG voor alle componenten – goed bestand tegen UV en temperatuur voor buitenshuis. Voor het topfilter: zet alle horizontale shells (boven/onder) uit om de poreuze structuur te creëren.

Stap 2
Voordat je de frontpanel-printplaat monteert, plaats de LCD op de PY-5*10CM-print (zonder te solderen) met pin 1 in gat C-1. Boor door de print op de vier LCD-montagegaten. Haal de LCD eraf voor later.
Stap 3
Monteer de frontpanel-printplaat. Plaats 74HC595N Shift Register IC, schakelaars en weerstanden zoals getoond. Leg alle benodigde draden naar de LCD-locaties en 15 cm lengte voor verbinding met de tweede print.

Stap 4
Monteer de LCD op de frontpanel-print, gebruik de geprinte afstandshouders om de LCD boven de IC te heffen. Bevestig met M3x15mm bouten en moeren.

Stap 5
Monteer de hoofprintplaat: Arduino met pin D12 in gat R27. Voeg condensator en weerstanden toe, leg alle bedrading voordat je SD- en RTC-modules plaatst. Zie bedradingsschema voor details.

Stap 6
Monteer SD-reader op gaten A-3 t/m B-10. Monteer TinyRTC op gaten C-24 t/m I-24. Soldeer alle verbindingen.

Stap 7
Boor gaten in de Indoor Unit Control Behuizing voor de twee draden naar de buiteneenheid en de voeding. Trek draden door, soldeer op de juiste plekken. Schuif hoofprintplaat in behuizing en bevestig met 2 M3x6mm bouten. Plaats drukknop voor schakelaar door voorkant en bevestig frontprintplaat met M3x6mm bouten. Opmerking: ik gebruikte een kleine gedraaide messing knop in plaats van het geprinte deel – betere 'feel'.

Stap 8
Bevestig de voorkant met M3-0.5x10mm platte kopschroef.
Stap 9
Sluit USB aan op PC en upload RTC-programma om tijd in te stellen. Na klokinstelling, upload hoofdprogramma. Plaats SD-kaart. Test door de reed-contact-aansluitingen van de buiteneenheid te kortsluiten. Neerslagtotaals moeten oplopen per kortsluiting. Controleer SD-kaart met teksteditor (Notepad/WordPad): bestand "Text.txt" met datumstempel per kanteling.
Stap 10
Bevestig reed-contact aan Sub Base met tyraps. Monteer magneet op de emmer en bevestig emmer met korte 1/8" messing buis (ca. 5 cm). Boor 1/8" door emmergaten voor vrije beweging. Gebruik ronde vijl indien nodig. Plaats kleine 1/8" ring aan buitenkant van emmer. Bepaal montage van buiteneenheid (ik gebruikte 1" aluminium hoek). Bevestig base met M6 bouten van binnenuit. Sub base aan Outside unit bottom met M3-0.5x10mm bouten.

Stap 11
Plaats trechter in topbehuizing. Knip ca. 24 stukken 5 cm 18-gauge galvaniseerd draad. Hitte met plier en branders aan de plastic top – deze draden weerhouden vogels van zitten. Meet regen, niet vogelpoep. Bevestig top met 4 M3-0.5x6mm bouten. Plaats filter in trechter – houdt bladeren uit en voorkomt verstoppingen. Regelmatig controleren en schoonmaken.

Stap 12
Monteer buiteneenheid en voer draden naar binnenunit. Zorg dat top in beide richtingen waterpas staat.
Stap 13
Voeding aan en water toevoegen aan buiteneenheid om werking te verifiëren.
Stap 14 (Optioneel)
Nauwkeurigheid controleren: zeer langzaam één kop water toevoegen en controleren of de meter 0,87" neerslag meet. (1 kop = 14,44 kubieke inch. Vangoppervlak 16,605" → Neerslag = 14,44/16,605 = 0,87". Corrigeer factor in hoofdprogramma indien nodig.)
Gefeliciteerd!! Geniet van het bijhouden van je neerslag.
Code
Arduino-code om tijd in te stellen op RTC Arduino
Laad deze code eerst om tijd op RTC in te stellen. Pas datum/tijd aan in de code voordat je uploadt.
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
byte decToBcd(byte val) { return ((val/10*16) + (val%10)); }
byte bcdToDec(byte val) { return ((val/16*10) + (val%16)); }
void setDateDs1307() {
second = 0; minute = 11; hour = 12;
dayOfWeek = 5; dayOfMonth = 24; month = 7; year = 20;
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(decToBcd(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 getDateDs1307() {
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(decToBcd(0));
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
second = bcdToDec(Wire.read() & 0x7f);
minute = bcdToDec(Wire.read());
hour = bcdToDec(Wire.read() & 0x3f);
dayOfWeek = bcdToDec(Wire.read());
dayOfMonth = bcdToDec(Wire.read());
month = bcdToDec(Wire.read());
year = bcdToDec(Wire.read());
Serial.print(hour, DEC); Serial.print(":");
Serial.print(minute, DEC); Serial.print(":");
Serial.print(second, DEC); Serial.print(" ");
Serial.print(month, DEC); Serial.print("/");
Serial.print(dayOfMonth, DEC); Serial.print("/");
Serial.print(year, DEC); Serial.println();
}
void setup() {
Wire.begin();
Serial.begin(19200);
setDateDs1307();
}
void loop() {
delay(2000);
getDateDs1307();
}
Hoofdprogramma Arduino-code voor regenmeter Arduino
Hoofdprogramma. Zorg dat alle bibliotheken geïnstalleerd zijn. Zie RoboIndia voor instructies voor het bijwerken van de LiquidCrystal-bibliotheek.
/* Tipping Bucket Rain Gauge - Bob Torrence */
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_SR.h>
LiquidCrystal_SR lcd(6, 5, 9);
RTC_DS3231 rtc;
int backlight = 7;
const byte interruptPin_bucket = 3;
const byte interruptPin_menu = 2;
volatile int Bucket_Tip_Occurence;
volatile int Menu_Select;
float Bucket_tip_hour_total = 0;
float Bucket_tip_current_hour_total = 0;
float Bucket_tip_previous_hour_total = 0;
float Bucket_tip_current_day_total = 0;
float Bucket_tip_previous_day_total = 0;
int current_minute, loop_minute, current_hour, loop_hour, current_day, loop_day, tip_counter;
float conversion_factor = .00854;
volatile unsigned long backlightOfftime;
volatile unsigned long backlightOnDuration = 30000;
String print_time(DateTime timestamp) {
char message[120];
sprintf(message, "%02d:%02d:%02d %02d/%02d",
timestamp.hour(), timestamp.minute(), timestamp.second(),
timestamp.month(), timestamp.day());
return message;
}
File myFile;
void setup() {
lcd.begin(16,2);
lcd.home();
rtc.begin();
pinMode(10, OUTPUT);
pinMode(backlight, OUTPUT);
digitalWrite(backlight, HIGH);
backlightOfftime = millis() + backlightOnDuration;
if (!SD.begin(4)) { lcd.print("insert SD Card"); return; }
pinMode(interruptPin_bucket, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin_bucket), count, FALLING);
pinMode(interruptPin_menu, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin_menu), menu, RISING);
myFile = SD.open("test.txt", FILE_WRITE);
if (myFile) { myFile.println("Rain Gauge Ready - unit powered up"); myFile.close(); }
DateTime now = rtc.now();
current_minute = loop_minute = now.minute();
current_hour = loop_hour = now.hour();
lcd.setCursor(0,0); lcd.print(print_time(now));
lcd.setCursor(1,1); lcd.print("Rain Gauge");
}
void loop() {
DateTime now = rtc.now();
current_minute = loop_minute = now.minute();
current_hour = loop_hour = now.hour();
current_day = loop_day = now.day();
while (loop_day - current_day == 0) {
while (loop_hour - current_hour == 0) {
if (millis() > backlightOfftime) digitalWrite(backlight, LOW);
if (Bucket_Tip_Occurence == 1) {
Bucket_Tip_Occurence = 0;
tip_counter++;
DateTime now = rtc.now();
myFile = SD.open("test.txt", FILE_WRITE);
myFile.print("Event ");
myFile.print(now.year(), DEC); myFile.print('/');
myFile.print(now.month(), DEC); myFile.print('/');
myFile.print(now.day(), DEC); myFile.print(" ");
myFile.print(now.hour(), DEC); myFile.print(':');
myFile.print(now.minute(), DEC); myFile.print(':');
myFile.print(now.second(), DEC); myFile.print(" ");
myFile.print(conversion_factor, 5); myFile.println();
myFile.close();
delay(200);
} else {
DateTime now = rtc.now();
loop_hour = now.hour();
}
switch (Menu_Select) {
case 1: lcd.clear(); lcd.setCursor(0,0); lcd.print("Current Hour");
lcd.setCursor(0,1); lcd.print(tip_counter * conversion_factor); delay(500); break;
case 2: lcd.clear(); lcd.setCursor(0,0); lcd.print("Previous Hour");
lcd.setCursor(0,1); lcd.print(Bucket_tip_previous_hour_total); delay(500); break;
case 3: lcd.clear(); lcd.setCursor(0,0); lcd.print("Current Day");
lcd.setCursor(0,1); lcd.print(Bucket_tip_current_day_total + tip_counter * conversion_factor); delay(500); break;
case 4: lcd.clear(); lcd.setCursor(0,0); lcd.print("Previous Day");
lcd.setCursor(0,1); lcd.print(Bucket_tip_previous_day_total); delay(500); break;
}
}
DateTime now = rtc.now();
current_hour = now.hour();
loop_day = now.day();
loop_hour = now.hour();
Bucket_tip_previous_hour_total = tip_counter * conversion_factor;
Bucket_tip_current_day_total += Bucket_tip_previous_hour_total;
tip_counter = 0;
}
Bucket_tip_previous_day_total = Bucket_tip_current_day_total;
Bucket_tip_current_day_total = 0;
Bucket_tip_current_hour_total = 0;
tip_counter = 0;
}
void count() {
static unsigned long last = 0;
unsigned long now = millis();
if (now - last > 300) Bucket_Tip_Occurence = 1;
last = now;
}
void menu() {
static unsigned long last = 0;
unsigned long now = millis();
if (now - last > 300) {
if (digitalRead(backlight) == LOW) digitalWrite(backlight, HIGH);
else { Menu_Select++; if (Menu_Select > 4) Menu_Select = 1; }
backlightOfftime = millis() + backlightOnDuration;
last = now;
}
}
Custom parts en behuizingen
- STL voor 3D-print buiteneenheid base (PETG, 30% infill)
- STL voor 3D-print buiteneenheid cover (PETG, 30% infill)
- STL voor 3D-print buiteneenheid trechter (PETG, 30% infill)
- STL voor 3D-print buiteneenheid filter (PETG, 20% infill, geen horizontale lagen voor poreus filter)
- STL voor 3D-print sub base (PETG, 30% infill)
- STL voor 3D-print emmer (PETG, 30% infill)
- STL voor 3D-print binnenbehuizing (PETG, 30% infill)
- STL voor 3D-print voorkant binnenunit (PETG, 30% infill)
- STL voor 3D-print afstandshouders LCD (PETG, 30% infill)
- Fusion 360 model buiteneenheid (.f3d, .step)
- STEP CAD model binnenunit (.step)
- Fusion 360 CAD model buiteneenheid (.f3z)
- STL voor 3D-print drukknop
Schema's
Project Bedradingsschema (.fzz bestand)
Productieproces
- Precisie Drukmeters voor Industriële & Veiligheidstoepassingen
- Slimme Jaloezieën: Geautomatiseerd Lichtbeheer met Arduino & Zonne-energie
- Bouw een Italiaanse Woordklok met Arduino Nano, NeoPixel, LCD en RTC
- Bouw een Betrouwbare Sigfox kWh Meter met Arduino MKR Fox 1200
- Dijtale hoogtemeters: Nauwkeurige meting en kwaliteitscontrole-oplossingen
- Mikrometerschroef: definitie, geschiedenis en praktisch gebruik
- Hoe Drukmeters Werken: Typen, Functies en Voordelen
- Reekstrekkers Onder de Loep: Hoe Ze Mechanische Spanning Omzetten in Preciese Elektrische Signalen
- De Pirani-manometer uitgelegd: werking, toepassingen en voordelen
- Membraandrukmeters uitgelegd: precisie en betrouwbaarheid
- Bourdon-manometers: ontwerp, werking en toepassingen