Enregistreur de Données Environnementales Arduino avec Carte SD et RTC
Composants et fournitures
| Arduino UNO (ou Nano/Mega) | 1 |
| Module carte SD (lecteur microSD) – interface SPI | 1 |
| RTC DS3231 (horloge temps réel I2C, haute précision ±2 ppm) | 1 |
| Capteur température/humidité/pression BME280 (I2C ou SPI) | 1 |
| Capteur qualité d'air MQ-135 (CO2, NH3, benzène, fumée, analogique) | 1 |
| Capteur luminosité BH1750 (I2C, luxmètre numérique) | 1 |
| Carte microSD (formatée FAT32, ≤32 Go) | 1 |
| Pile CR2032 (sauvegarde RTC) | 1 |
| Boîtier étanche IP65 (pour usage extérieur) | 1 |
| Alimentation 5V (USB ou batterie LiPo + boost) | 1 |
À propos de ce projet
Objectif
Créer un data logger autonome enregistrant sur carte SD les paramètres environnementaux : température, humidité, pression atmosphérique, qualité d'air, luminosité – avec horodatage précis (RTC). Fonctionne sur batterie pour déploiement terrain (serre, cave, station météo, surveillance qualité air intérieur/extérieur).
Architecture
- Arduino : acquisition capteurs, horodatage, écriture SD
- BME280 : T° (±0,5°C), H% (±3%), Pression (±1 hPa) via I2C (0x76/0x77)
- MQ-135 : résistance variable selon concentration gaz → tension sur entrée analogique (calibration nécessaire)
- BH1750 : luminosité 1–65535 lux via I2C (0x23)
- DS3231 : date/heure précises, alimenté par pile CR2032
- Module SD : SPI (broches 10/11/12/13 sur UNO), fichier CSV journalier
Câblage
Bus I2C (partagé BME280 + BH1750 + DS3231)
- SDA → A4 (UNO) / 20 (Mega)
- SCL → A5 (UNO) / 21 (Mega)
- Pull-ups 4,7 kΩ vers 3,3V (si non présentes sur modules)
Module SD (SPI hardware)
- CS → D10
- MOSI → D11
- MISO → D12
- SCK → D13
- VCC → 5V (ou 3,3V selon module), GND → GND
MQ-135
- VCC → 5V, GND → GND
- AOUT → A0 (analogique)
- DOUT (seuil numérique) → non utilisé ici
- Préchauffer 24-48h avant premières mesures fiables
RTC DS3231
- VCC → 3,3V ou 5V, GND → GND
- SDA/SCL → bus I2C partagé
- Pile CR2032 insérée
Format des données (CSV)
Un fichier par jour : YYYYMMDD.CSV
timestamp,temp_C,humidity_%,pressure_hPa,air_quality_raw,lux
2024-01-15 14:30:00,21.4,45.2,1013.25,247,1250
2024-01-15 14:35:00,21.3,45.5,1013.30,245,1180
...
Intervalle d'enregistrement configurable (ex. 5 min = 288 entrées/jour).
Code Arduino
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_BME280.h>
#include <Adafruit_Sensor.h>
#include <BH1750.h>
// Configuration
const int SD_CS_PIN = 10;
const int MQ135_PIN = A0;
const unsigned long LOG_INTERVAL_MS = 5UL * 60 * 1000; // 5 minutes
// Objets
RTC_DS3231 rtc;
Adafruit_BME280 bme;
BH1750 lightMeter;
File dataFile;
unsigned long lastLog = 0;
char filename[13];
void setup() {
Serial.begin(115200);
Wire.begin();
// RTC
if (!rtc.begin()) {
Serial.println("ERREUR: RTC non trouvé !");
while (1);
}
if (rtc.lostPower()) {
Serial.println("RTC: perte alimentation, remise à l'heure compilation");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
// BME280
if (!bme.begin(0x76)) {
if (!bme.begin(0x77)) {
Serial.println("ERREUR: BME280 non trouvé !");
while (1);
}
}
// BH1750
if (!lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) {
Serial.println("ERREUR: BH1750 non trouvé !");
while (1);
}
// Carte SD
if (!SD.begin(SD_CS_PIN)) {
Serial.println("ERREUR: Carte SD échec !");
while (1);
}
Serial.println("Initialisation OK");
// Créer/ouvrir fichier du jour
updateFilename();
dataFile = SD.open(filename, FILE_WRITE);
if (dataFile) {
// En-tête si fichier vide
if (dataFile.size() == 0) {
dataFile.println("timestamp,temp_C,humidity_%,pressure_hPa,air_quality_raw,lux");
}
dataFile.close();
}
}
void loop() {
unsigned long now = millis();
if (now - lastLog >= LOG_INTERVAL_MS) {
lastLog = now;
logData();
}
// Vérifier changement de jour (nouveau fichier)
static int lastDay = -1;
DateTime nowDt = rtc.now();
if (nowDt.day() != lastDay) {
lastDay = nowDt.day();
if (dataFile) dataFile.close();
updateFilename();
}
}
void updateFilename() {
DateTime now = rtc.now();
sprintf(filename, "%04d%02d%02d.CSV", now.year(), now.month(), now.day());
dataFile = SD.open(filename, FILE_WRITE);
if (dataFile && dataFile.size() == 0) {
dataFile.println("timestamp,temp_C,humidity_%,pressure_hPa,air_quality_raw,lux");
}
}
void logData() {
DateTime now = rtc.now();
char timestamp[20];
sprintf(timestamp, "%04d-%02d-%02d %02d:%02d:%02d",
now.year(), now.month(), now.day(),
now.hour(), now.minute(), now.second());
float temp = bme.readTemperature();
float hum = bme.readHumidity();
float pres = bme.readPressure() / 100.0F; // Pa → hPa
int airRaw = analogRead(MQ135_PIN);
uint16_t lux = lightMeter.readLightLevel();
// Affichage série
Serial.print(timestamp);
Serial.print(" T="); Serial.print(temp, 1);
Serial.print(" H="); Serial.print(hum, 1);
Serial.print(" P="); Serial.print(pres, 1);
Serial.print(" AQ="); Serial.print(airRaw);
Serial.print(" L="); Serial.println(lux);
// Écriture SD
dataFile = SD.open(filename, FILE_WRITE);
if (dataFile) {
dataFile.print(timestamp);
dataFile.print(",");
dataFile.print(temp, 1); dataFile.print(",");
dataFile.print(hum, 1); dataFile.print(",");
dataFile.print(pres, 1); dataFile.print(",");
dataFile.print(airRaw); dataFile.print(",");
dataFile.println(lux);
dataFile.flush(); // Force écriture physique
dataFile.close();
} else {
Serial.println("ERREUR écriture SD !");
}
}
Bibliothèques requises
RTClib(Adafruit ou equivalent)Adafruit_BME280+Adafruit_SensorBH1750(par claws)SD(incluse dans Arduino IDE)
Calibration MQ-135 (qualité air)
Le MQ-135 donne une valeur brute (0-1023). Pour obtenir ppm CO2 équivalent :
- Préchauffer 24-48h en continu
- Mesurer
R0(résistance capteur dans air pur) :
R0 = Rload * (1023 - raw) / raw(Rload = 10-20 kΩ selon module) - Formule ppm :
ppm = 116.602 * (Rs/R0)^-2.769(approximation CO2) - Pour usage relatif (détection pics), la valeur brute suffit souvent
- Utiliser Arduino Pro Mini 3,3V 8 MHz (sans régulateur/USB) + LowPower.h
- Mettre en sommeil profond entre mesures :
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF)en boucle - Alimentation : LiPo 3,7V + régulateur LDO 3,3V (ex. MCP1700) ou 5V boost
- Désactiver LED power-on (couper piste ou dessouder)
- Module SD : certains consomment en veille – ajouter MOSFET coupure VCC
- Importer CSV dans Excel, LibreOffice Calc, Python (pandas), Grafana
- Graphiques temporels, alertes seuils, corrélations multi-capteurs
- Export vers IoT (MQTT, InfluxDB) si ajout module WiFi/LoRa
Gestion énergie (autonomie batterie)
Avec ces optimisations : ~1-2 ans sur 2×AA lithium (3,6V) ou mois sur LiPo 2000 mAh.
Exploitation des données
Processus de fabrication
- Capteur d'Empreinte Intégré à l'Écran : Évolution, Technologie et Avantages
- Tutoriel capteur de lumière Raspberry Pi – Câbler une LDR et lire les niveaux de lumière avec Python
- Créer un verrou RFID sécurisé avec Arduino – Guide étape par étape
- Capteur CO2 K30 : Surveillance en temps réel de la qualité de l'air intérieur
- Construisez un Stadiomètre Numérique : Suivez la Croissance avec Arduino et Capteur Laser
- Intégrer un capteur d'empreintes capacitif DFRobot (ID809) avec Arduino ou ESP8266
- Tour de Capteurs avec Arduino Cloud : Température, Mouvement et Gaz
- Pistolet à eau intelligent à détection de mouvement avec Arduino Nano
- Tutoriel Arduino Débutant 01 : Démarrez votre Premier Projet