Station météo Arduino Nano : Kit capteurs & affichage OLED
Composants et fournitures
| Composant | Quantité |
|---|---|
| Arduino Nano R3 | 1 |
| Capteur barométrique Seeed Grove BMP280 | 1 |
| Capteur température/humidité DHT11 (4 broches) | 1 |
| Module OLED 0,96" 64x128 (ElectroPeak) | 1 |
| Capteur UV GUVA-S12SD | 1 |
| Module RTC DS3231 | 1 |
Outils et machines nécessaires
- Fer à souder (générique)
- Fil à souder sans plomb
- Imprimante 3D (générique, ex. Ender 3)
Applications et services en ligne
- Arduino IDE
- Autodesk Fusion 360 (conception boîtier)
À propos de ce projet
Depuis longtemps, je voulais créer une station météo sans connexion Internet. C'est génial de mesurer les données météorologiques de son environnement et de les consulter à volonté. J'ai donc conçu une station météo locale au look sympa qui mesure : pression atmosphérique, température, humidité, indice UV du jour (si placée près d'une fenêtre). Et ce n'est pas tout ! 😉 Elle affiche aussi l'heure, la date et le jour de la semaine.
Dans ce tutoriel, je vous montre comment réaliser cette station météo en plusieurs étapes.
Étape 1 : Construire le boîtier
J'ai utilisé Autodesk Fusion 360 pour concevoir le boîtier et l'ai imprimé en PLA vert. Des supports sont nécessaires, impression à 20% de remplissage, vitesse 70 mm/s sur mon Ender 3. Le fichier STL est fourni avec le projet.
Étape 2 : BMP280 (Pression et température)
Le BMP280 mesure la pression atmosphérique et la température. Il communique en I2C ou SPI. J'utilise le SPI. Connexions :
- CS → D10
- SDA → D11
- SDO → D12
- SCK → D13
Côté code : inclure #include <Adafruit_BMP280.h> (bibliothèque téléchargeable). Définir les broches SPI. Dans setup(), initialiser le capteur. Dans loop(), lire pression et température via bmp.readPressure() et bmp.readTemperature(). Diviser la pression par 100 pour obtenir des hPa. Pour l'altitude : bmp.readAltitude(1005.47) – remplacer 1005.47 par la pression moyenne de votre zone.
Étape 3 : DS3231 RTC (Horloge temps réel)
Pour l'écran heure/date/jour, j'utilise le module DS3231 (protocole I2C). Connexions :
- SCL → A5
- SDA → A4
D'abord, réglez l'heure et la date sur le RTC avec le programme DS3231_set.ino des exemples de la bibliothèque.
Dans le programme principal : inclure #include <DS3231.h> et lire l'heure selon la bibliothèque. J'utilise l'exemple de la bibliothèque comme référence. J'ai créé un switch pour chaque jour de la semaine.
Étape 4 : DHT11 (Humidité)
Connectez la sortie data du DHT11 à la broche D2 de l'Arduino. Dans le code : inclure #include <DHT.h>, initialiser dans setup(), lire l'humidité dans loop() avec dht.readHumidity().
Étape 5 : Capteur UV GUVA-S12SD
Le GUVA-S12SD est une photodiode Schottky à base de nitrure de gallium. Longueur d'onde de détection UV typique : 240-370 nm (couvre UVB et la plupart des UVA). Il sort une tension analogique calibrée variant avec l'intensité UV. On lit la valeur analogique via l'ADC de l'Arduino.
Dans loop() :
float sensorValue = analogRead(A0);
float sensorVoltage = sensorValue / 1024 * 5.0;
int UV_index = sensorVoltage / 0.1;
Étape 6 : Affichage OLED
J'utilise un OLED 0,96" 128×64 en I2C. Connexions :
- SCK → A5
- SDA → A4
Dans le programme : inclure Adafruit_GFX.h et Adafruit_SSD1306.h. Créer l'objet display et ajouter des bitmaps pour des icônes. Dans setup(), initialiser l'affichage. Dans loop(), afficher les données sur 4 pages (Heure, Pression, Temp/Humidité, UV) avec display.print(). Délai de 5 secondes entre chaque page.
Étape 7 : Vidéo
(Vidéo intégrée dans le projet original)
Code
Local weather station code – Code Arduino complet :
#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 pour icônes (frame0, frame1, frame2) - omis pour brièveté
const unsigned char PROGMEM frame0 [] = { ... };
const unsigned char PROGMEM frame1 [] = { ... };
const unsigned char PROGMEM frame2 [] = { ... };
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() {
// Page 1 : Heure
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);
display.println(clock.getMinute());
display.setCursor(70, 15);
if (pmFlag) { display.println(" PM"); } else { display.println(" AM "); }
display.setFont(&FreeSans9pt7b);
display.setCursor(20, 60);
display.println(clock.getDate());
display.setCursor(40, 60);
display.println("/");
display.setCursor(46, 60);
display.println(clock.getMonth(century));
display.setCursor(65, 60);
display.println("/");
display.setCursor(70, 60);
display.println("20");
display.setCursor(90, 60);
display.println(clock.getYear());
display.setCursor(30, 30);
display.setFont(&FreeSans9pt7b);
switch (clock.getDoW()) {
case 1: display.println("Saturday"); break;
case 2: display.println("Sunday"); break;
case 3: display.println("Monday"); break;
case 4: display.println("Tuesday"); break;
case 5: display.println("Wednesday"); break;
case 6: display.println("Thursday"); break;
case 7: display.println("Friday"); break;
}
display.display();
delay(5000);
// Page 2 : Pression
display.clearDisplay();
display.drawBitmap(0, 0, frame0, 40, 40, 1);
display.setFont(&FreeSans9pt7b);
display.setCursor(41, 28);
display.println(bmp.readPressure() / 100);
display.setCursor(110, 28);
display.setFont();
display.println("hPa");
display.setCursor(0, 55);
display.setFont(&FreeSans9pt7b);
display.println("Altitude:");
display.setCursor(65, 62);
display.println(bmp.readAltitude(1005.47));
display.setCursor(113, 62);
display.println("m");
display.display();
delay(5000);
// Page 3 : Température & Humidité
display.clearDisplay();
display.setFont(&FreeMonoBoldOblique12pt7b);
display.drawBitmap(0, 5, frame1, 40, 51, 1);
display.setCursor(35, 30);
display.print(bmp.readTemperature());
display.setFont(&FreeSans9pt7b);
display.setCursor(102, 28);
display.println(" *");
display.setCursor(110, 31);
display.println(" C");
display.setFont();
display.setCursor(66, 45);
display.println("RH :");
byte RH = dht.readHumidity();
display.setCursor(95, 45);
display.println(RH);
display.setCursor(110, 45);
display.println("%");
display.drawBitmap(0, 56, frame2, 135, 15, 1);
display.display();
delay(5000);
// Page 4 : 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);
display.print(" UV INDEX ");
display.setCursor(58, 45);
display.println(UV_index);
display.display();
delay(5000);
}
Pièces personnalisées et boîtiers
Fichier STL du boîtier disponible en téléchargement.
Schémas
Processus de fabrication
- Station météo solaire DIY avec Raspberry Pi
- Construction d'une station météo extérieure avec Raspberry Pi 2 et ADS‑WS1
- Construire une station météo Raspberry Pi qui envoie les données météo quotidiennes par email
- Station météo avancée v2.0 : Surveillance en temps réel de température, pression, humidité et altitude
- Station de Mixage Automatique 6-Shooter Pilotée par Arduino – Construisez Votre Propre Robot Barman
- Système de Capteur de Température Multi-Position pour Intégration Domotique
- Enregistreur de données Arduino haute performance pour ballon météo
- Station Météo Arduino Portable à 10$ – Nano, DHT22, BMP180 et LCD
- Station météo IoT temps réel – Arduino, ESP8266, DHT11 & ThingSpeak