Arduino Nano Weerstation: Sensor Kit & OLED Display
Onderdelen en benodigdheden
| Arduino Nano R3 | × | 1 |
| Seeed Grove - Barometer Sensor (BMP280) | × | 1 |
| DHT11 Temperatuur & Vochtigheid Sensor (4 pinnen) | × | 1 |
| ElectroPeak 0.96" OLED 64x128 Display Module | × | 1 |
| GUVA-S12SD UV-sensor | × | 1 |
| DS3231 RTC | × | 1 |
Benodigde tools en machines
- Solderbout (generiek)
- Solderdraad, Loodvrij
- 3D-printer (generiek)
Apps en online diensten
- Arduino IDE
- Autodesk Fusion 360
Over dit project
Lang wilde ik al een weerstation maken zonder internet. Het is geweldig om weerdata van je directe omgeving te meten en te bekijken wanneer je wilt. Zo bouwde ik een cool lokaal weerstation dat luchtdruk, temperatuur, vochtigheid en de UV-index van de dag meet (als je het bij het raam plaatst). En het heeft nog meer! 😉 Het heeft ook een klokscherm voor tijd, datum en dag van de week.
In deze tutorial laat ik stap voor stap zien hoe je dit coole weerstation bouwt.
Stap 1: Behuizing bouwen
Ik gebruikte Autodesk Fusion 360 voor de behuizing, geprint met groen PLA. Benodigt supports, geprint met 20% infill, 70 mm/s op mijn Ender 3. Het STL-bestand is bij het project inbegrepen.
Stap 2: BMP280 (Luchtdruk & Temperatuur)
De BMP280 meet luchtdruk en temperatuur via I2C of SPI. Ik gebruik SPI. Aansluitingen:
- CS → D10
- SDA → D11
- SDO → D12
- SCK → D13
In de code: bibliotheek Adafruit_BMP280.h includeren. SPI-pinnen definieren. In setup() sensor initialiseren. In loop() druk en temperatuur lezen met bmp.readPressure() en bmp.readTemperature(). Druk delen door 100 voor hPa. Hoogte met bmp.readAltitude(1005.47) – pas de waarde (1005.47) aan aan jouw gemiddelde luchtdruk.
Stap 3: DS3231 RTC (Klok)
Voor het klokscherm (tijd, datum, dag) gebruik ik de DS3231 RTC module (I2C). Aansluitingen:
- SCL → A5
- SDA → A4
Eerst tijd en datum instellen op de RTC met het voorbeeldprogramma DS3231_set.ino uit de bibliotheek.
In het hoofdprogramma: #include <DS3231.h> en tijddata uitlezen per bibliotheekinstructies. Ik gebruikte het bibliotheekvoorbeeld als referentie en maakte een switch-case voor de dag van de week.
Stap 4: DHT11 (Vochtigheid)
Voor vochtigheid meet ik met de DHT11. Data out → Arduino D2. In code: #include <DHT.h>, in setup() initialiseren, in loop() lezen met dht.readHumidity().
Stap 5: GUVA-S12SD UV-sensor
De GUVA-S12SD is een Gallium Nitride Schottky-fotodiod met UV-detectiewavelength 240-370 nm (dekt UVB en meeste UVA). Het levert een gecalibreerde analoge spanning afhankelijk van UV-intensiteit. We lezen de analoge waarde via Arduino ADC.
In loop():
float sensorValue = analogRead(A0);
float sensorVoltage = sensorValue / 1024 * 5.0;
int UV_index = sensorVoltage / 0.1;
Stap 6: OLED Display
Ik gebruik een 0.96" 128x64 OLED display (I2C). Aansluitingen:
- SCK → A5
- SDA → A4
In code: Adafruit_GFX.h en Adafruit_SSD1306.h includeren. Display-variabele aanmaken en bitmaps toevoegen voor afbeeldingen. In setup() display initialiseren. In loop() data tonen met display.print() op vier pagina's: Tijd, Luchtdruk, Temperatuur & Vochtigheid, UV-index. 5 seconden vertraging per pagina.
Videoclip
Zie de projectpagina voor de videoclip van het werkende weerstation.
Code
De complete Arduino-code voor het lokale weerstation:
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_BMP280.h>
#include <DS3231.h>
#include <DHT.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeMonoBoldOblique12pt7b.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET 4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define BMP_SCK 13
#define BMP_MISO 12
#define BMP_MOSI 11
#define BMP_CS 10
DS3231 clock;
bool century = false;
bool h12Flag;
bool pmFlag;
Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO, BMP_SCK);
#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
// Bitmaps voor iconen (frame0, frame1, frame2) - zie originele code voor volledige arrays
void setup() {
Serial.begin(57600);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 failed"));
}
Wire.begin();
dht.begin();
if (!bmp.begin()) {
Serial.println(F("Problem.bmp"));
while (1) delay(10);
}
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 9);
display.setFont(&FreeSans9pt7b);
display.println("**** LOCAL ****");
display.setCursor(0, 38);
display.setFont(&FreeMonoBoldOblique12pt7b);
display.println("wather");
display.setCursor(27, 58);
display.println("Station");
display.display();
delay(2000);
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,
Adafruit_BMP280::SAMPLING_X2,
Adafruit_BMP280::SAMPLING_X16,
Adafruit_BMP280::FILTER_X16,
Adafruit_BMP280::STANDBY_MS_500);
}
void loop() {
// Tijd weergeven
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(13, 15);
display.setFont(&FreeMonoBoldOblique12pt7b);
display.print(clock.getHour(h12Flag, pmFlag));
display.setCursor(38, 15);
println(":");
display.setCursor(50, 15);
println(clock.getMinute());
display.setCursor(70, 15);
if (pmFlag) println(" PM"); else println(" AM ");
display.setFont(&FreeSans9pt7b);
display.setCursor(20, 60);
println(clock.getDate());
display.setCursor(40, 60);
println("/");
display.setCursor(46, 60);
println(clock.getMonth(century));
display.setCursor(65, 60);
println("/");
display.setCursor(70, 60);
println("20");
display.setCursor(90, 60);
println(clock.getYear());
display.setCursor(30, 30);
display.setFont(&FreeSans9pt7b);
switch (clock.getDoW()) {
case 1: println("Saturday"); break;
case 2: println("Sunday"); break;
case 3: println("Monday"); break;
case 4: println("Tuesday"); break;
case 5: println("Wednesday"); break;
case 6: println("Thursday"); break;
case 7: println("Friday"); break;
}
display.display();
delay(5000);
// Luchtdruk weergeven
display.clearDisplay();
display.drawBitmap(0, 0, frame0, 40, 40, 1);
display.setFont(&FreeSans9pt7b);
display.setCursor(41, 28);
println(bmp.readPressure() / 100);
display.setCursor(110, 28);
display.setFont();
println("hPa");
display.setCursor(0, 55);
display.setFont(&FreeSans9pt7b);
println("Altitude:");
display.setCursor(65, 62);
println(bmp.readAltitude(1005.47));
display.setCursor(113, 62);
println("m");
display.display();
delay(5000);
// Temperatuur & Vochtigheid
display.clearDisplay();
display.setFont(&FreeMonoBoldOblique12pt7b);
display.drawBitmap(0, 5, frame1, 40, 51, 1);
display.setCursor(35, 30);
print(bmp.readTemperature());
display.setFont(&FreeSans9pt7b);
display.setCursor(102, 28);
println(" *");
display.setCursor(110, 31);
println(" C");
display.setFont();
display.setCursor(66, 45);
println("RH :");
byte RH = dht.readHumidity();
display.setCursor(95, 45);
println(RH);
display.setCursor(110, 45);
println("%");
display.drawBitmap(0, 56, frame2, 135, 15, 1);
display.display();
delay(5000);
// UV-index
display.clearDisplay();
float sensorValue = analogRead(A0);
float sensorVoltage = sensorValue / 1024 * 5.0;
int UV_index = sensorVoltage / 0.1;
display.setFont(&FreeSans9pt7b);
display.setCursor(0, 15);
print(" UV INDEX ");
display.setCursor(58, 45);
println(UV_index);
display.display();
delay(5000);
}
Schema's
Productieproces
- DIY Zonne-energie Weerstation Met Raspberry Pi
- Een buitenweerstation bouwen met Raspberry Pi 2 en ADS-WS1
- Een Raspberry Pi-weerstation bouwen dat dagelijkse weergegevens e-mailt
- Geavanceerd Weerstation v2.0: Real-time Temperatuur, Druk, Vochtigheid & Hoogte Monitoring
- Arduino-gestuurde 6-Shooter Drank Mixstation – Bouw je eigen Cocktail Automaat
- Meerpositie-temperatuursensorsysteem voor slimme thuisintegratie
- High-Performance Arduino Weerballon Datalogger
- Bouw een $10 Draagbare Arduino Weerstation (AWS) – Eenvoudige DIY met Nano, DHT22, BMP180 & LCD
- Realtime Weerstation met Arduino & ThingSpeak IoT
- Bouw een WiFi Weerstation met ESP8266 en DHT22 Temperatuursensor
- Slimme polsband bouwen met Arduino MKR GSM 1400 en Hologram IoT