Système d'arrosage urbain intelligent : Irrigation automatisée pilotée par capteurs
Composants et fournitures
| Capteur d'humidité du sol (sortie analogique) | × | 2 |
| Capteur de pluie | × | 1 |
| Bouteille en plastique (type bidon de lait) - réservoir d'eau | × | 1 |
| Tuyau souple en plastique (Ø intérieur ~6-8 mm) | × | 1 |
| Fils de connexion (jumper wires) | × | 37 |
| Kit SparkFun Inventor's Kit pour Arduino 101 (inclut Arduino 101, servo, breadboard, potentiomètre, LCD) | × | 1 |
| Pâte à modeler / argile (étanchéité) | × | 1 |
| Tige rigide en plastique (support tuyau de sortie) | × | 1 |
| Résistance 330 Ω | × | 1 |
Outils nécessaires
- Ciseaux
- Tournevis cruciforme
- Ruban adhésif (électrique et standard)
Applications et services en ligne
- Nordic Semiconductor nRF Connect SDK (configuration horaire via BLE)
- Arduino IDE (programmation)
À propos du projet
Ce dispositif améliore l'irrigation des plantes en milieu urbain. Basé sur un Arduino 101, il exploite les outils embarqués et quelques capteurs externes pour calculer les conditions optimales d'arrosage dans son environnement, puis arrose automatiquement la plante au moment calculé.
Principes de fonctionnement
Gravité et pression
Le réservoir d'eau (bidon de lait découpé) est placé en hauteur. Il collecte l'eau de pluie tout en étant principalement rempli par le réseau domestique. La gravité fait écouler l'eau par un tuyau de sortie percé dans le fond du bidon. Un servomoteur contrôle l'ouverture : bras relevé = fermé, bras abaissé de 135° = ouvert. La pression de l'eau dans le bidon assure un débit continu pendant l'arrosage.
Capteur TMP36 et moteur de reconnaissance de motifs Intel Curie (PME)
Cette combinaison détermine l'heure optimale d'arrosage, idéale vers 25 °C. Le TMP36 fournit une tension analogique proportionnelle à la température. Le système effectue 30 mesures par heure (toutes les 2 minutes), calcule la moyenne des 29 dernières (la première étant souvent aberrante), et soumet cette moyenne au PME.
Le PME (Pattern Matching Engine) est un réseau de neurones artificiel de 128 neurones intégré à l'Arduino 101. Il apprend et classe les données de température sur une journée (8h-21h) pour identifier l'heure la plus proche de 25 °C. Cette heure devient celle de l'arrosage du lendemain. Après chaque cycle, les données sont effacées et réapprises.
Si le PME ne parvient pas à classifier, le système bascule sur des constantes mensuelles (heures de pic thermique moyen par mois), moins précises pour les plantes.
Horloge temps réel (RTC) et Bluetooth Low Energy (BLE)
L'horloge temps réel du Curie gère l'ordonnancement : heure d'arrosage, plages d'acquisition, mois pour les constantes de secours. La date/heure initiale est configurée via BLE depuis un smartphone (application nRF Connect). Le téléphone agit en « central » et écrit l'heure, les minutes, le jour et le mois en hexadécimal sur la caractéristique BLE de l'Arduino 101 (périphérique).
Construction pas à pas
Composants électriques
- Arduino 101
- Breadboard 400 points avec rails d'alimentation
- Potentiomètre rotatif
- Écran LCD 16×2
- Résistance 330 Ω
- Capteur de température TMP36
- Servomoteur 180° avec bras
- Capteur de pluie + carte de contrôle
- Capteurs d'humidité du sol + cartes de contrôle (optionnels)
- Nombreux fils de connexion (voir schéma Fritzing)
Alimentation
Sur batteries : 2× boîtiers 4×AA avec interrupteur + 8 piles NiMH 1,2 V.
Sur USB : Câble USB A-B selon longueur nécessaire.
Composants mécaniques
- Bidon de lait (découpé)
- Tuyau souple ~20-30 cm
- Pâte à modeler, colle chaude ou mastic pour étanchéité
- Tige rigide (support tuyau)
- Panier en plastique (boîtier électronique)
- Surface surélevée (table, banc) pour le réservoir
- Une plante à arroser
Étapes de montage
- Câblage : Suivre le schéma Fritzing. Les capteurs d'humidité sont optionnels. Les fils du capteur de pluie et du servo doivent être assez longs pour atteindre leurs positions.
- Alimentation sur batteries (optionnel) : Insérer les piles, relier le + d'un boîtier au - de l'autre, scotcher les deux boîtiers ensemble (couvercles solidaires, boîtiers solidaires, couvercle amovible en un bloc). Laisser accès aux interrupteurs.
- Fixation batterie : Scotcher le double couvercle sous l'Arduino + breadboard pour glisser les boîtiers par dessous.
- Boîtier : Placer l'ensemble dans le panier, découper deux fentes : programmation/USB et sortie capteurs/actionneurs. Regrouper les fils avec du scotch électrique.
- Réservoir : Couper le haut du bidon (ouverture large). Percer un trou dans le fond, sous l'ouverture. Insérer le tuyau. Sceller haut et bas avec la pâte à modeler (sans boucher le tuyau).
- Servo sur réservoir : Fixer le servo le plus bas possible sur le bidon. Attacher le tuyau et la tige rigide au bras du servo (tige aussi scotchée au tuyau).
- Installation : Fixer le bidon sur la surface surélevée. Placer la plante sous l'embout du tuyau (position abaissée). Enfoncer les capteurs d'humidité si utilisés. Poser le capteur de pluie au sol près de la plante. Brancher capteurs et servo sur le dispositif, placé à distance du bidon et de la plante.
Programmation
Téléverser le code fourni via l'Arduino IDE avec Curie Core 2.0.2 ou supérieur. Le code est abondamment commenté.
Fonctionnement du dispositif
- Au démarrage, l'appareil attend une connexion BLE via nRF Connect.
- Une fois connecté, saisir séquentiellement (en hexadécimal) : identifiant (n'importe quel nombre), heure, minute, jour, mois.
- Après déconnexion, l'Arduino attend 8h (jour même ou lendemain).
- À 8h : si la mémoire flash est vide → cycle d'apprentissage 14h (8h-21h) → classification PME → détermination heure optimale → reprise cycle. Si données présentes → utilisation de l'heure mémorisée comme constante.
- À l'heure d'arrosage : vérification pluie (capteur) et humidité sol (optionnel). Si pluie ou sol trop humide → arrosage annulé pour la journée.
Cette solution simplifie et optimise l'irrigation urbaine tout en valorisant l'eau de pluie via le réservoir.
Code
Arduino 101 - Système d'irrigation (Arduino)
Code complet pour le système d'irrigation Arduino 101. Téléverser avec Curie Core 2.0.2 et IDE 1.8.x+. La bibliothèque CuriePME est disponible sur GitHub.
/* Solution d'irrigation urbaine - Utilise CuriePME pour apprendre les données de température
et classifier la condition optimale (25°C) pour l'arrosage. Arrose à cette heure et réapprend indéfiniment.
DOIT ÊTRE DÉMARRÉ AVANT 8h DU JOUR CIBLE.
Sources : WeatherSpark.com (Vancouver), Just4Growers.com (température optimale plantes). */
#include "CuriePME.h"
#include <CurieBLE.h>
#include <CurieTime.h>
#include <SerialFlash.h>
#include <SPI.h>
#include <LiquidCrystal.h>
#include <Servo.h>
Servo waterPipe;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
#define thermometer A3
#define rainSensor 1
#define humidity1 A4
#define humidity2 A1
// Variables pour mesures horaires (30 par heure)
int tm1...tm30, average, progav;
float voltage, temperatureC;
int tm, hourTime = -1, minuteTime = -1, dayTime = -1, monthTime = -1, confirmTime = -1;
// Service BLE
BLEService plantService("19B10000-E8F2-537E-4F6C-D104768A1214");
BLEUnsignedCharCharacteristic timeCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
void setup() {
waterPipe.attach(9); waterPipe.write(0);
pinMode(rainSensor, INPUT);
lcd.begin(16, 2); lcd.clear();
if (!SerialFlash.begin(ONBOARD_FLASH_SPI_PORT, ONBOARD_FLASH_CS_PIN));
lcd.setCursor(0, 0); lcd.print("Input Time: BLE");
BLE.begin();
BLE.setLocalName("Arduino 101");
BLE.setAdvertisedService(plantService);
plantService.addCharacteristic(timeCharacteristic);
BLE.addService(plantService);
timeCharacteristic.setValue(0);
BLE.advertise();
lcd.setCursor(0, 1); lcd.print("Waiting");
// Attente connexion BLE et réception horaire (5 écritures)
BLEDevice central = BLE.central();
if (central) {
lcd.setCursor(8, 1); lcd.print(" Done"); delay(3000);
while (central.connected()) {
if (timeCharacteristic.written()) {
if (confirmTime == -1) confirmTime = timeCharacteristic.value();
else if (hourTime == -1) hourTime = timeCharacteristic.value();
else if (minuteTime == -1) minuteTime = timeCharacteristic.value();
else if (dayTime == -1) dayTime = timeCharacteristic.value();
else if (monthTime == -1) {
monthTime = timeCharacteristic.value();
lcd.clear(); lcd.setCursor(0, 0); lcd.print("Time set.");
lcd.setCursor(0, 1); lcd.print("Disconnect device.");
}
}
}
} else { goto x; } // x: label pour boucle attente connexion
setTime(hourTime, minuteTime, 0, dayTime, monthTime, 2017);
CuriePME.begin();
lcd.clear(); lcd.setCursor(0, 0); lcd.print("Checking for save."); delay(3000);
const char *filename = "NeurData.dat";
if (check_if_exists(filename)) {
restoreNetworkKnowledge();
lcd.setCursor(0, 1); lcd.print("Found!"); delay(3000); lcd.clear(); goto z;
} else {
lcd.setCursor(0, 1); lcd.print("Not found!"); delay(3000); lcd.clear();
}
// Phase d'apprentissage initial : 8h à 21h (14 heures)
lcd.clear(); lcd.setCursor(0, 0); lcd.print("Learning");
for (int i = 8; i < 22; i++) {
// 30 mesures à 2 min d'intervalle (code tronqué pour brièveté)
// ... acquisition tm1..tm30 ...
// Conversion, calcul moyenne (excluant tm1), commitSample(i, average)
// Arrosage aux heures constantes mensuelles pendant cette phase initiale
// (janv/fév/nov/déc à 12h, mar/avr/oct à 14h, mai/juin/sept à 15h, juil/août à 16h)
}
saveNetworkKnowledge(); // Sauvegarde en flash
z: delay(1);
}
void commitSample(int category, uint8_t s1) {
uint8_t vector[1]; vector[0] = s1;
CuriePME.learn(vector, 1, category);
}
void loop() {
// Classification de 25°C dans les données apprises
uint8_t vector[1]; vector[0] = 25;
int answer = CuriePME.classify(vector, 1);
if (answer == CuriePME.noMatch) {
// Constantes mensuelles de secours
if (month() == 1 || month() == 2 || month() == 11 || month() == 12) answer = 12;
else if (month() == 3 || month() == 4 || month() == 10) answer = 14;
else if (month() == 5 || month() == 6 || month() == 9) answer = 15;
else if (month() == 7 || month() == 8) answer = 16;
}
CuriePME.forget(); // Efface pour réapprendre (flash non effacé)
// Attente 8h lendemain
lcd.clear(); lcd.setCursor(0, 0); lcd.print("Waiting");
while (hour() != 8);
// Nouveau cycle d'apprentissage + arrosage à l'heure 'answer'
lcd.clear(); lcd.setCursor(0, 0); lcd.print("Learning");
for (int i = 8; i < 22; i++) {
// ... acquisition 30 mesures, calcul moyenne, commitSample ...
if (hour() == answer) {
// Arrosage si pas pluie et sol pas trop humide
int readRain = digitalRead(rainSensor);
if (readRain != HIGH) { // && humidité OK
waterPipe.write(135); delay(7000); waterPipe.write(0);
}
}
}
// Boucle infinie
}
void saveNetworkKnowledge() {
// Sauvegarde réseau neuronal en flash (code tronqué)
// Note : ne s'exécute qu'une fois. Pour réinitialiser : exemple "EraseEverything" de CurieSerialFlash.
}
Schéma
Schéma Fritzing du circuit. Les batteries seraient connectées à gauche. Les capteurs d'humidité du sol sont optionnels.
rainpoweredsmartirrigationsystem_OHtd4bVfb3.fzz
Processus de fabrication
- Titane : propriétés clés, applications et utilisations industrielles
- Castagnettes : histoire, artisanat et performance
- L'histoire, la production et l'avenir de la colle : des adhésifs anciens aux innovations modernes
- Le fil à coudre : types, histoire, production et contrôle qualité
- L'acétylène : production, utilisations et manipulation — aperçu complet
- Aperçu complet de l'amiante : des usages anciens aux risques sanitaires modernes
- Étain : de l'âge du bronze à l'industrie moderne — usages, production et avenir
- Système d'arrosage automatique des plantes avec Raspberry Pi et tableau de bord web
- Siemens et Bentley annoncent une solution conjointe pour accélérer la numérisation des centrales électriques