Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Une solution d'arrosage des plantes urbaines

Composants et fournitures

Capteur d'humidité du sol
Tout capteur d'humidité du sol avec sortie analogique peut être utilisé. Deux électrodes et un diviseur de tension pourraient également être utilisés. CECI SONT FACULTATIFS.
× 2
Capteur de pluie
× 1
Pot à lait
Tout récipient pouvant contenir de l'eau, être coupé et fixé à une surface fera l'affaire. être monté sur une surface élevée.
× 1
Tube creux flexible en plastique souple
Tout type de tube fera l'affaire. J'ai utilisé une corde à sauter avec les extrémités coupées, car elle est très flexible et le centre est creux.
× 1
Câbles de raccordement (générique)
Plus ou moins.
× 37
Kit de l'inventeur SparkFun pour Arduino 101
J'ai utilisé l'Arduino 101, le servo, la maquette, le potentiomètre et l'écran LCD.
× 1
Pâte à modeler
× 1
Tige courte en plastique
Ou n'importe quelle canne non flexible. Ceci est utilisé pour soutenir le tuyau de sortie du réservoir d'eau.
× 1
Résistance 330 ohm
× 1

Outils et machines nécessaires

Ciseaux
Tournevis Phillips
Ruban électrique
et aussi du ruban adhésif normal.

Applications et services en ligne

Nordic Semiconductor nRF Connect SDK
Arduino IDE

À propos de ce projet

Ce dispositif améliore l'irrigation des plantes en milieu urbain. Alimenté par un Arduino 101, il utilise des outils embarqués ainsi que quelques capteurs externes pour calculer les conditions optimales d'arrosage des plantes dans son propre environnement, puis arrose la plante elle-même à l'heure calculée.

Il est basé sur les concepts suivants :

Gravité et pression

Cet appareil puise sa source d'eau dans un réservoir que j'ai fabriqué à l'aide d'un pot à lait, d'un tube en plastique, d'argile pour le scellant du tube et d'un servomoteur. Ce récipient est positionné de telle sorte qu'en plus d'être surélevé, il puisse récupérer l'eau de pluie au-dessus de l'appareil.

La cruche est remplie principalement par une alimentation en eau domestique (en raison de la pluie qui n'est pas toujours disponible), mais est complétée par l'eau de pluie. Lorsque de l'eau est présente dans la cruche, la force d'attraction de la gravité tire l'eau vers la Terre à l'intérieur de la cruche. Un trou est découpé dans la base de la verseuse pour permettre l'insertion d'un tuyau de sortie. La force de gravité tire donc l'eau à travers ce tuyau de sortie. Le servo régule lorsque l'eau est autorisée à sortir complètement du tuyau. Dans des circonstances normales, le bras du servo est en position verticale, ce qui empêche l'eau de s'écouler du tuyau. Cependant, lors de l'arrosage de la plante, le bras s'abaisse de 135 degrés, permettant ainsi à l'eau de s'écouler du tuyau et d'irriguer les plantes. Le bras se relève une fois cette opération terminée.

La pression de l'eau contre la carafe contribue non seulement à la stabilité de la carafe, mais aide également à la sortie de l'eau, permettant un débit d'eau continu pendant l'irrigation.

Capteur de température TMP36 et moteur de recherche de motifs Intel Curie

Cette combinaison de concepts aide à piloter le calcul qui détermine le moment optimal pour arroser les plantes. Le TMP36 est un capteur de température qui fonctionne comme un thermomètre, mais avec une sortie analogique électronique. Cette sortie peut être lue par un appareil, tel qu'un microcontrôleur, et convertie en une température. Dans ce projet, l'appareil tente de calculer le moment optimal pour arroser les plantes, qui est le plus proche de 25 degrés Celsius. Il fait 30 enregistrements par heure, à des intervalles de deux minutes, et à la fin de chaque période calcule la moyenne de 29 d'entre eux (à l'exclusion du premier, car il est généralement inexact). C'est là qu'intervient le Pattern Matching Engine.

L'Intel Curie PME, ou pattern-matching engine, est un réseau de neurones artificiels intégré à l'Arduino 101. Ses bibliothèques sont disponibles sur GitHub. Composé de 128 neurones, il est capable d'apprendre et de classer des données, enregistrées dans des vecteurs, à partir de données existantes, ou de vecteurs classés en catégories. Plus il y a de catégories disponibles, plus les options de classification peuvent être poursuivies par le PME.

Pour ce projet, le PME enregistre des données de température au cours d'une journée et tente de classer la condition optimale, 25 degrés Celsius, parmi ces données. Le résultat devient l'heure du lendemain pour arroser la plante.

Les données sont enregistrées toutes les heures de 8h à 21h. La première fois que cela est fait, les données seront enregistrées sur le Flash série intégré . Cela permettra à l'appareil de démarrer sur un ensemble de données même s'il a été éteint. Après avoir obtenu l'ensemble de données, il tente de classer les conditions optimales. S'il est en mesure de le faire, alors la catégorie sélectionnée devient l'heure utilisée pour le prochain tour. Sinon, l'appareil utilisera des constantes mensuelles, ou l'heure de la journée chaque mois où les températures sont les plus élevées. Il convient de noter que ce ne sont pas toujours les meilleures températures pour arroser les plantes , c'est pourquoi j'ai utilisé le PME.

Après la première session d'apprentissage, les données sont effacées et réapprises le lendemain, la plante étant arrosée à l'heure choisie. Ce cycle se répète indéfiniment, ou jusqu'à ce que l'appareil soit déconnecté de l'alimentation, auquel lorsqu'il est rallumé, il utilise les paramètres enregistrés comme l'heure sélectionnée et continue de fonctionner.

Horloge en temps réel Intel Curie et Bluetooth Low Energy

L'Intel Curie RTC, ou horloge en temps réel, est un composant crucial de cet appareil. Le RTC contrôle quand tout se produit sur l'appareil. Pour ce projet, le RTC est particulièrement essentiel pour garder une trace de l'heure, utilisée pour arroser la plante et quand enregistrer les données, et le mois, utilisé pour déterminer les constantes de température de pointe de sauvegarde. Cependant, la date précise de cette RTC doit être définie manuellement, soit en code, soit par saisie utilisateur. Ce problème a été résolu avec BLE.

Bluetooth Low Energy est une version plus récente de Bluetooth conçue pour les appareils à faible consommation d'énergie. Il fonctionne sur un système central-périphérique, où un central, ou une entrée, écrit sur des périphériques ou des sorties. Cela agit plus comme un système de tableau d'affichage, où le central place des données sur un bulletin pour que tous les périphériques puissent les lire. Dans ce cas, j'ai utilisé nRF Connect de Nordic Semiconductor sur mon appareil mobile en tant que centrale et l'Arduino 101 en tant que périphérique. L'appareil mobile a la capacité de se connecter à l'Arduino et de lui envoyer des données. Dans ce cas, l'appareil mobile doit envoyer des données quatre fois, une fois pour chacun des champs de saisie obligatoires.

Les données saisies sur l'appareil mobile sont saisies en hexadécimal. C'est assez facile à convertir à partir de la base 10, mais un convertisseur en ligne peut être utilisé.

Comment construire

La construction de cette solution d'irrigation nécessite un peu de connaissances en circuits, mais pas trop. Il nécessite également quelques composants non électriques pour terminer. Voici la liste complète des pièces :

Composants électriques

  • Arduino 101
  • Planche à pain 400 attaches, avec +- rails
  • Potentiomètre rotatif
  • LCD 16 x 2
  • Résistance 330 Ohm
  • Capteur de température TMP36
  • Servo à 180 degrés, avec palonnier d'asservissement
  • Capteur de pluie et tableau de commande
  • Capteur d'humidité du sol et tableau de commande (en option, matériel inclus comme référence)
  • Une quantité importante de câbles de démarrage ; voir le diagramme de Fritzing

Pour fonctionner sur piles (peut ne pas durer trop longtemps ; la configuration que j'ai utilisée) :

  • 2 boîtes à piles 4 x AA avec interrupteur marche/arrêt et fils électriques
  • 8 piles rechargeables NiMH AA 1,2 V

Pour fonctionner sur alimentation USB, à partir d'une verrue murale ou d'un ordinateur portable :

  • Câble USB Male A - Male B dont la longueur dépend de vos besoins

Composants matériels non électriques

  • Cruche à lait
  • Tube en plastique flexible, environ 20-30 cm de long
  • Pâte à modeler, colle chaude ou tout ce qui peut être utilisé comme scellant
  • Tige en plastique, pour soutenir le bras tubulaire
  • Panier d'artisanat, pour tenir l'appareil
  • Surface surélevée pour contenir le pichet, c'est-à-dire un petit banc ou une table
  • Une plante

Outils

  • Ruban, à la fois régulier et électrique
  • Ciseaux
  • Tournevis Phillips, pour fixer le palonnier au servo

Étapes

1. Construisez le circuit selon le schéma de Fritzing ci-dessous. Veuillez noter que les capteurs d'humidité du sol sont facultatifs et que le capteur de pluie et le servo peuvent nécessiter des fils plus longs pour atteindre les emplacements souhaités. Voir la deuxième photo ci-dessous pour la disposition finale du circuit.

2. (Passez à l'étape 5 si vous utilisez l'alimentation USB). Insérez les piles dans les deux boîtiers de piles et attachez le fil positif d'un boîtier et le fil négatif de l'autre ensemble.

3. Collez les boîtes ensemble à l'aide de ruban isolant. Fixez les boîtes de manière à ce que les couvercles des deux soient attachés et que les étuis des deux soient attachés, et que le couvercle soit amovible en une seule pièce. Laissez les fentes ouvertes pour les interrupteurs d'alimentation.

4. Collez le double couvercle du boîtier de la batterie sous l'Arduino 101 et la planche à pain. Cela permettra de remplacer facilement les piles en les faisant glisser par le dessous de la carte.

5. Insérez l'appareil dans le panier d'artisanat et découpez deux fentes sur un côté de l'appareil. Le premier emplacement sera pour la programmation (ou l'alimentation USB si vous choisissez de le faire), et le second sera une prise pour les capteurs et actionneurs non situés sur l'appareil. N'hésitez pas à utiliser du ruban isolant pour fixer les fils lâches ensemble dans cette prise.

6. Prenez un pot à lait et coupez le haut pour que le pot ait une ouverture assez grande pour recueillir l'eau et une capacité assez grande pour être fiable. Je recommande que la coupe soit quelque part près de la base du manche.

7. Découpez un petit trou dans la base de la verseuse directement sous la plus grande partie de l'ouverture dans le haut de la verseuse. Insérez une extrémité du tube en plastique dans ce trou. Assurez-vous que le trou est suffisamment petit pour que le tuyau reste en place, mais suffisamment grand pour qu'il ne comprime pas le tuyau.

8. Utilisez l'argile pour sceller les zones supérieure et inférieure autour du tuyau dans le trou. Assurez-vous que l'argile ne pénètre pas dans le tuyau lui-même.

9. À l'aide de l'argile et du ruban électrique, fixez le servo le plus bas possible à la base du pot à lait. Collez le milieu du tube et une tige en plastique sur le palonnier du servo. Assurez-vous que la tige en plastique est également collée à l'extrémité supérieure du tube. Utilisez l'image ci-dessous comme référence pour les étapes 8 à 10.

10. Fixez la verseuse sur la surface surélevée. Utilisez du ruban adhésif si nécessaire.

11. Placez une plante juste en dessous de la sortie du tube lorsqu'elle est en position abaissée. Collez les capteurs d'humidité dans le sol si vous les utilisez et placez le capteur de pluie près de la plante le long du sol. Branchez les capteurs et le servo dans l'appareil, avec l'appareil placé un peu plus loin du pot et de la plante.

Programmation

Programmez l'Arduino 101 avec le code joint. Téléchargez à l'aide de l'IDE Arduino et de Curie Core 2.0.2 ou supérieur (si disponible). De nombreux commentaires utiles sont inclus dans le code.

Fonctionnement de l'appareil

Lorsque l'appareil est allumé pour la première fois, il attend qu'un appareil mobile soit connecté. Une fois qu'un appareil est connecté à l'aide de nRF Connect, il attendra la saisie de l'heure. Pour ce faire, saisissez séquentiellement les codes hexadécimaux pour l'heure, la minute, le jour et le mois de base 10 dans l'ordre dans nRF Connect, comme indiqué dans le diagramme ci-dessous.

Une entrée ID, ou n'importe quel nombre, doit être saisie et envoyée avant de saisir les heures.

Après avoir tapé l'heure, le 101 attendra que l'appareil mobile se déconnecte. Après cela, il attendra 8 heures du matin, soit le jour en cours, soit le lendemain.

À 8 heures du matin, la carte vérifiera s'il y a quelque chose d'enregistré dans la mémoire flash. Sinon, il passera par le processus de collecte de 14 heures comme décrit précédemment, puis classera les données et déterminera le moment optimal, auquel point il répétera le cycle de collecte. Si quelque chose est stocké, alors ces données sont utilisées comme constante horaire et les cycles se poursuivent normalement.

Pendant les périodes d'arrosage de la plante par la planche, la présence de pluie ou un excès d'humidité du sol (facultatif) empêchera l'arrosage de la plante. Il sautera alors l'arrosage de la journée et attendra la suivante.

Cette solution est conçue pour rendre l'irrigation des plantes urbaines plus simple et plus optimisée en utilisant une configuration automatique pour s'en occuper. Il conserve également l'eau de pluie ainsi que les fournitures existantes de la maison en utilisant un réservoir, ce qui permet d'utiliser à bon escient la pluie non dirigée vers les plantes.

Espérons que ce projet fera de notre monde en constante évolution un endroit légèrement meilleur !

Code

  • Système d'irrigation Arduino 101
Système d'irrigation Arduino 101Arduino
Code d'utilisation du système d'irrigation Arduino 101. Téléchargez à l'aide de Curie core 2.0.2 et de tout IDE 1.8.x ou supérieur. CuriePME peut être trouvé sur GitHub.
/*Ceci est un croquis pour une solution d'irrigation urbaine.Il utilise le CuriePME pour apprendre les données de température et classer les conditions optimales d'arrosage des plantes par rapport à celles-ci.Il arrose ensuite la plante à ce moment-là et réapprend les données, en faisant du vélo à l'infini.Veuillez noter que ce croquis DOIT ÊTRE EXÉCUTÉ AVANT 8 heures du matin du jour cible pour démarrer l'appareil.Sources de données : "WeatherSpark.com." Météo habituelle à Vancouver, Canada, toute l'année - Weather Spark. N.p., s.d. La toile. 04 juillet 2017.  "Just 4 Growers:Global Garden Community." Juste pour les producteurs. N.p., s.d. La toile. 10 juillet 2017. . */// Bibliothèques à utiliser avec ce code. Tous, à l'exception de CuriePME, peuvent être trouvés dans l'ide. CuriePME peut être téléchargé à partir du référentiel GitHub.#include "CuriePME.h"#include #include #include #include #include #include // Servo pinout code.Servo waterPipe;// LCD pinout code.LiquidCrystal lcd(12, 11, 5, 4, 3, 2);// Constantes/variables globales.#define thermomètre A3 #define rainSensor 1#define humidity1 A4#define humidity2 A1int tm1;int tm2;int tm3;int tm4;int tm5;int tm6;int tm7;int tm8;int tm9;int tm10;int tm11;int tm13;int t int tm14;int tm15;int tm16;int tm17;int tm18;int tm19;int tm20;int tm21;int tm22;int tm23;int tm24;int tm25;int tm26;int tm27;int tm28;int tm30;int tm30;int;int moyenne;int progav;float voltage;float temperatureC;int tm;int hourTime =-1;int minuteTime =-1;int dayTime =-1;int monthTime =-1;int confirmTime =-1;// service BLE data.BLEService plantService("19B10000-E8F2-537E-4F6C-D104768A1214");// Caractéristique BLE, lisible/inscriptible par la centrale.BLEUnsignedCharCharacteristic timeCha racteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);void setup() { // Cela s'exécute une fois. waterPipe.attach(9) ; waterPipe.write(0); pinMode(rainSensor, INPUT); lcd.begin (16, 2); // Commence et efface l'écran LCD. lcd.clear(); if (!SerialFlash.begin(ONBOARD_FLASH_SPI_PORT, ONBOARD_FLASH_CS_PIN)); lcd.setCursor(0, 0); lcd.print("Temps d'entrée :BLE"); // Initialise le service BLE avec le nom, le service, la caractéristique et la valeur de caractéristique. BLE.begin(); BLE.setLocalName("Arduino 101"); BLE.setAdvertisedService(plantService); plantService.addCharacteristic(timeCharacteristic); BLE.addService(plantService); timeCharacteristic.setValue(0); // 0 jusqu'à ce qu'il soit écrit par le central. BLE.publicité(); lcd.setCursor(0, 1); lcd.print("En attente"); // Prêt à se connecter.x :BLEDevice central =BLE.central(); if (central) { // Si un périphérique est lié à la carte. lcd.setCursor(8, 1); lcd.print("Terminé"); retard (3000); while (central.connected()) { // Pendant que l'appareil est toujours connecté. if (timeCharacteristic.write()) { // Code qui remplit séquentiellement tous les créneaux de variables temporelles après l'envoi de chaque octet depuis le périphérique. Les données sont envoyées quatre fois, plus une pour la confirmation du lien. 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("Heure définie."); lcd.setCursor(0, 1); lcd.print("Déconnecter le périphérique."); } } } } else { aller à x; // Bouclage si un appareil n'est pas encore connecté. } // Définit l'heure avec les variables collectées. Les secondes et l'année n'ont pas d'importance pour ce système. setTime(hourTime, minuteTime, 00, dayTime, monthTime, 2017); // Initialiser le PME. lcd.clear(); CuriePME.begin(); lcd.setCursor(0, 0); lcd.print("Vérification de la sauvegarde."); retard (3000); const char *filename ="NeurData.dat"; if (check_if_exists(filename) ==true) { restoreNetworkKnowledge(); lcd.setCursor(0, 1); lcd.print("Trouvé!"); retard (3000); lcd.clear(); aller à z; } else { lcd.setCursor(0, 1); lcd.print("Non trouvé !"); retard (3000); lcd.clear(); } /* La partie restante de la configuration collecte les données de température au cours de la journée. Il effectue 30 contrôles par heure, espacés de 2 minutes d'intervalle, et à la fin de l'heure il fait une moyenne des données de l'heure en trouvant la moyenne arithmétique de toutes les données à l'exception du premier scan. Cette moyenne est ensuite introduite dans le PME et apprise. Cela se répète de 8 h 00 à 21 h 00, date à laquelle l'ensemble de données complet appris par le PME est enregistré dans la mémoire CurieFlash par défaut si et quand l'appareil perd de l'alimentation ou doit être redémarré. */ lcd.clear(); lcd.setCursor(0, 0); lcd.print("Apprentissage"); for (int i =8; i <22; i++) // Répétez cette opération 14 fois, chaque sauvegarde dans une catégorie différente. { // Collecte 30 données de température, enregistrées sous la forme d'un int mappé entre 0 et 255. voltage =analogRead(thermometer) * 3.3; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm1 =contraindre(tm, 0, 255); retard (114000); // Compense le retard de vérification ci-dessus. tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm2 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm3 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm4 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm5 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm6 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm7 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm8 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm9 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm10 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm11 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm12 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm13 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm14 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm15 =contraindre(tm, 0, 255); // Pendant la première période d'apprentissage, l'arrosage des plantes se fera au pic des températures du mois. if ((mois() ==1 || mois() ==2 || mois() ==11 || mois() ==12) &&heure() ==12) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("En cours d'exécution..."); // Arrosez la plante s'il ne pleut pas et que l'humidité du sol est suffisamment basse. int readRain =digitalRead(rainSensor); if (readRain ==HIGH) { lcd.setCursor (0, 1); lcd.print("Il pleut en ce moment."); aller à a2 ; } // Décommentez pour utiliser des capteurs d'humidité. // else if (analogRead(humidity1)> 400 || analogRead(humidity2)> 400) // Ajustez-les en fonction de votre sol. //{ //lcd.setCursor(0, 1); //lcd.print("Sol trop humide."); // aller à a2; //} else { waterPipe.write(135); retard (7000); // Arroser pendant 7 secondes. waterPipe.write(0); } lcd.setCursor(0, 1); lcd.print("Terminé");a2:délai(3000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Apprentissage"); } else if ((mois() ==3 || mois() ==4 || mois() ==10) &&heure() ==14) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("En cours d'exécution..."); lcd.clear(); lcd.setCursor(0, 0); lcd.print("En cours d'exécution..."); // Arrosez la plante s'il ne pleut pas et que l'humidité du sol est suffisamment basse. int readRain =digitalRead(rainSensor); if (readRain ==HIGH) { lcd.setCursor (0, 1); lcd.print("Il pleut en ce moment."); aller à a31; } // Décommentez pour utiliser des capteurs d'humidité. // else if (analogRead(humidity1)> 400 || analogRead(humidity2)> 400) // Ajustez-les en fonction de votre sol. //{ //lcd.setCursor(0, 1); //lcd.print("Sol trop humide."); // aller à a31; //} else { waterPipe.write(135); retard (7000); // Arroser pendant 7 secondes. waterPipe.write(0); } lcd.setCursor(0, 1); lcd.print("Terminé");a31:délai(3000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Apprentissage"); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Apprentissage"); } else if ((mois() ==5 || mois() ==6 || mois() ==9) &&heure() ==15) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("En cours d'exécution..."); lcd.clear(); lcd.setCursor(0, 0); lcd.print("En cours d'exécution..."); // Arrosez la plante s'il ne pleut pas et que l'humidité du sol est suffisamment basse. int readRain =digitalRead(rainSensor); if (readRain ==HIGH) { lcd.setCursor (0, 1); lcd.print("Il pleut en ce moment."); aller à a3; } // Décommentez pour utiliser des capteurs d'humidité. // else if (analogRead(humidity1)> 400 || analogRead(humidity2)> 400) // Ajustez-les en fonction de votre sol. //{ //lcd.setCursor(0, 1); //lcd.print("Sol trop humide."); // aller à a3; //} else { waterPipe.write(135); retard (7000); // Arroser pendant 7 secondes. waterPipe.write(0); } lcd.setCursor(0, 1); lcd.print("Terminé");a3:délai(3000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Apprentissage"); } else if ((mois() ==7 || mois() ==8) &&heure() ==16) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("En cours d'exécution..."); lcd.clear(); lcd.setCursor(0, 0); lcd.print("En cours d'exécution..."); // Arrosez la plante s'il ne pleut pas et que l'humidité du sol est suffisamment basse. int readRain =digitalRead(rainSensor); if (readRain ==HIGH) { lcd.setCursor (0, 1); lcd.print("Il pleut en ce moment."); aller à a4 ; } // Décommentez pour utiliser des capteurs d'humidité. // else if (analogRead(humidity1)> 400 || analogRead(humidity2)> 400) // Ajustez-les en fonction de votre sol. //{ //lcd.setCursor(0, 1); //lcd.print("Sol trop humide."); // aller à a4; //} else { waterPipe.write(135); retard (7000); // Arroser pendant 7 secondes. waterPipe.write(0); } lcd.setCursor(0, 1); lcd.print("Terminé");a4:délai(3000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Apprentissage"); } délai(110000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm16 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm17 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm18 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm19 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm20 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm21 =contrainte(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm22 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm23 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm24 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm25 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm26 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm27 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm28 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm29 =contraindre(tm, 0, 255); retard (120000); tension =lecture analogique (thermomètre) * 3,3 ; tension /=1024,0 ; températureC =(tension - 0,5) * 100; tm =map(températureC, -40, 125, 0, 255); tm30 =contrainte(tm, 0, 255); retard (120000); // Reconvertir les données aux spécifications du capteur de température. tm1 =carte(tm1, 0, 255, -40, 125); tm1 =contraindre(tm1, -40, 125); tm2 =carte(tm2, 0, 255, -40, 125); tm2 =contrainte(tm2, -40, 125); tm3 =carte(tm3, 0, 255, -40, 125); tm3 =contraindre(tm3, -40, 125); tm4 =map(tm4, 0, 255, -40, 125); tm4 =constrain(tm4, -40, 125); tm5 =map(tm5, 0, 255, -40, 125); tm5 =constrain(tm5, -40, 125); tm6 =map(tm6, 0, 255, -40, 125); tm6 =constrain(tm6, -40, 125); tm7 =map(tm7, 0, 255, -40, 125); tm7 =constrain(tm7, -40, 125); tm8 =map(tm8, 0, 255, -40, 125); tm8 =constrain(tm8, -40, 125); tm9 =map(tm9, 0, 255, -40, 125); tm9 =constrain(tm9, -40, 125); tm10 =map(tm10, 0, 255, -40, 125); tm10 =constrain(tm10, -40, 125); tm11 =map(tm11, 0, 255, -40, 125); tm11 =constrain(tm11, -40, 125); tm12 =map(tm12, 0, 255, -40, 125); tm12 =constrain(tm12, -40, 125); tm13 =map(tm13, 0, 255, -40, 125); tm13 =constrain(tm13, -40, 125); tm14 =map(tm14, 0, 255, -40, 125); tm14 =constrain(tm14, -40, 125); tm15 =map(tm15, 0, 255, -40, 125); tm15 =constrain(tm15, -40, 125); tm16 =map(tm16, 0, 255, -40, 125); tm16 =constrain(tm16, -40, 125); tm17 =map(tm17, 0, 255, -40, 125); tm17 =constrain(tm17, -40, 125); tm18 =map(tm18, 0, 255, -40, 125); tm18 =constrain(tm18, -40, 125); tm19 =map(tm19, 0, 255, -40, 125); tm19 =constrain(tm19, -40, 125); tm20 =map(tm20, 0, 255, -40, 125); tm20 =constrain(tm20, -40, 125); tm21 =map(tm21, 0, 255, -40, 125); tm21 =constrain(tm21, -40, 125); tm22 =map(tm22, 0, 255, -40, 125); tm22 =constrain(tm22, -40, 125); tm23 =map(tm23, 0, 255, -40, 125); tm23 =constrain(tm23, -40, 125); tm24 =map(tm24, 0, 255, -40, 125); tm24 =constrain(tm24, -40, 125); tm25 =map(tm25, 0, 255, -40, 125); tm25 =constrain(tm25, -40, 125); tm26 =map(tm26, 0, 255, -40, 125); tm26 =constrain(tm26, -40, 125); tm27 =map(tm27, 0, 255, -40, 125); tm27 =constrain(tm27, -40, 125); tm28 =map(tm28, 0, 255, -40, 125); tm28 =constrain(tm28, -40, 125); tm29 =map(tm29, 0, 255, -40, 125); tm29 =constrain(tm29, -40, 125); tm30 =map(tm30, 0, 255, -40, 125); tm30 =constrain(tm30, -40, 125); // Find the arithmetic mean and commit it to memory. average =(tm2 + tm3 + tm4 + tm5 + tm6 + tm7 + tm8 + tm9 + tm10 + tm11 + tm12 + tm13 + tm14 + tm15 + tm16 + tm17 + tm18 + tm19 + tm20 + tm21 + tm22 + tm23 + tm24 + tm25 + tm26 + tm27 + tm28 + tm29 + tm30) / 29; commitSample(i, average); } saveNetworkKnowledge(); // Save this new data to flash memory.z:delay(1);}void commitSample (int category, uint8_t s1){ // Commit to memory a single vector (the average), along with the category, which represents the hour of that data. uint8_t vector[1]; vector[0] =s1; CuriePME.learn(vector, 1, category);}void loop() { // Infinitely repeats. /* This code attempts to classify the optimum temperature for watering plants, 25 Celsius, among the data learned by the PME. If it can classify the data, the returned category becomes the hour at which the plant will be watered. The data is then erased and relearned, which infinitely repeats. IF IT CANNOT CLASSIFY THE DATA, it will take the monthly defaults from earlier in the sketch. */ uint8_t vector[1]; vector[0] =25; int answer =CuriePME.classify(vector, 1 ); if (answer ==CuriePME.noMatch) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("NO MATCHES!"); 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; } } else { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Category:"); lcd.setCursor(0, 1); lcd.print(answer); } delay(3000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Optimization Done"); delay(3000); CuriePME.forget(); // Erase and relearn. This does not erase the flash memory. lcd.clear(); lcd.setCursor(0, 0); lcd.print("Waiting"); while (hour() !=8); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Learning"); // Learn the data again. for (int i =8; i <22; i++) { voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm1 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm2 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm3 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm4 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm5 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm6 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm7 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm8 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm9 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm10 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm11 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm12 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm13 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm14 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm15 =constrain(tm, 0, 255); // The time in the day at which to water the plant, as determined by the PME. if (hour() ==answer) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Running..."); // Water the plant if it is not raining and soil moisture is low enough. int readRain =digitalRead(rainSensor); if (readRain ==HIGH) { lcd.setCursor(0, 1); lcd.print("Raining right now."); goto a5; } // Uncomment to use moisture sensors. //else if (analogRead(humidity1)> 400 || analogRead(humidity2)> 400) // Adjust these to match your soil. //{ // lcd.setCursor(0, 1); // lcd.print("Soil too moist."); // goto a5; //} else { waterPipe.write(135); delay(7000); // Water for 7 seconds. waterPipe.write(0); } lcd.setCursor(0, 1); lcd.print("Done");a5:delay(3000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Learning"); } delay(110000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm16 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm17 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm18 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm19 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm20 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm21 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm22 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm23 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm24 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm25 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm26 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm27 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm28 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm29 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm30 =constrain(tm, 0, 255); delay(120000); tm1 =map(tm1, 0, 255, -40, 125); tm1 =constrain(tm1, -40, 125); tm2 =map(tm2, 0, 255, -40, 125); tm2 =constrain(tm2, -40, 125); tm3 =map(tm3, 0, 255, -40, 125); tm3 =constrain(tm3, -40, 125); tm4 =map(tm4, 0, 255, -40, 125); tm4 =constrain(tm4, -40, 125); tm5 =map(tm5, 0, 255, -40, 125); tm5 =constrain(tm5, -40, 125); tm6 =map(tm6, 0, 255, -40, 125); tm6 =constrain(tm6, -40, 125); tm7 =map(tm7, 0, 255, -40, 125); tm7 =constrain(tm7, -40, 125); tm8 =map(tm8, 0, 255, -40, 125); tm8 =constrain(tm8, -40, 125); tm9 =map(tm9, 0, 255, -40, 125); tm9 =constrain(tm9, -40, 125); tm10 =map(tm10, 0, 255, -40, 125); tm10 =constrain(tm10, -40, 125); tm11 =map(tm11, 0, 255, -40, 125); tm11 =constrain(tm11, -40, 125); tm12 =map(tm12, 0, 255, -40, 125); tm12 =constrain(tm12, -40, 125); tm13 =map(tm13, 0, 255, -40, 125); tm13 =constrain(tm13, -40, 125); tm14 =map(tm14, 0, 255, -40, 125); tm14 =constrain(tm14, -40, 125); tm15 =map(tm15, 0, 255, -40, 125); tm15 =constrain(tm15, -40, 125); tm16 =map(tm16, 0, 255, -40, 125); tm16 =constrain(tm16, -40, 125); tm17 =map(tm17, 0, 255, -40, 125); tm17 =constrain(tm17, -40, 125); tm18 =map(tm18, 0, 255, -40, 125); tm18 =constrain(tm18, -40, 125); tm19 =map(tm19, 0, 255, -40, 125); tm19 =constrain(tm19, -40, 125); tm20 =map(tm20, 0, 255, -40, 125); tm20 =constrain(tm20, -40, 125); tm21 =map(tm21, 0, 255, -40, 125); tm21 =constrain(tm21, -40, 125); tm22 =map(tm22, 0, 255, -40, 125); tm22 =constrain(tm22, -40, 125); tm23 =map(tm23, 0, 255, -40, 125); tm23 =constrain(tm23, -40, 125); tm24 =map(tm24, 0, 255, -40, 125); tm24 =constrain(tm24, -40, 125); tm25 =map(tm25, 0, 255, -40, 125); tm25 =constrain(tm25, -40, 125); tm26 =map(tm26, 0, 255, -40, 125); tm26 =constrain(tm26, -40, 125); tm27 =map(tm27, 0, 255, -40, 125); tm27 =constrain(tm27, -40, 125); tm28 =map(tm28, 0, 255, -40, 125); tm28 =constrain(tm28, -40, 125); tm29 =map(tm29, 0, 255, -40, 125); tm29 =constrain(tm29, -40, 125); tm30 =map(tm30, 0, 255, -40, 125); tm30 =constrain(tm30, -40, 125); average =(tm2 + tm3 + tm4 + tm5 + tm6 + tm7 + tm8 + tm9 + tm10 + tm11 + tm12 + tm13 + tm14 + tm15 + tm16 + tm17 + tm18 + tm19 + tm20 + tm21 + tm22 + tm23 + tm24 + tm25 + tm26 + tm27 + tm28 + tm29 + tm30) / 29; progav =(tm30 - tm2) / 2; commitSample(i, average); }}/* A quick note on the flash memory data:The data will only ever be saved once; that is, it cannot be changed with this code. As a result, if the device loses power, IT WILL DEFAULT TO THE SETTINGS OF THE FIRST TIME IT WAS USED WHEN IT IS REACTIVATED, even if the monthly averages have changed. Keeping the device on an extra day will allow it to software obtain new averages, but the flash memory will stay the same. To erase flash completely, upload "EraseEverything" from "CurieSerialFlash" in the IDE. Then reupload this sketch to save new averages to the flash memory.*/void saveNetworkKnowledge() // Code for saving to flash memory....This file has been truncated, please download it to see its full contents.

Schémas

Fritzing diagram for the circuit. Note that batteries would be attached on the left. The soil moisture sensors are optional. rainpoweredsmartirrigationsystem_OHtd4bVfb3.fzz

Processus de fabrication

  1. Titane
  2. castagnettes
  3. Colle
  4. Filetage
  5. Acétylène
  6. Amiante
  7. Étain
  8. Arrosage automatisé des plantes Raspberry Pi avec site Web
  9. Siemens et Bentley lancent une solution pour accélérer la numérisation des usines