Dans cette partie de la série, je vais récapituler le plus important des parties précédentes. Rétrospectivement, nous avons déjà apporté quelques changements et ajouts à notre gardien de l’usine. Par exemple, nous avons augmenté le nombre de capteurs d’humidité du sol de 6 et ajouté un capteur combiné de température et d’humidité. Pour les plantes, ce sont une bonne base. Cependant, un autre facteur environnemental important est toujours absent pour notre flore. C’est la lumière, surtout l’illumination! L’éclairage dans l’unité Lux est mesuré par mesure génétique.
La plupart des plantes se sentent plus à l’aise dans la gamme d’éclairage de 300-1500 lux (selon le type de plante). Bien sûr, nous voulons en tenir compte et garder un œil sur la luminosité de Lux en tout temps avec notre moniteur d’usine. À cette fin, nous enregistrons l’éclairage dans l’unité Lux et l’afficher comme une valeur d’information sur l’écran du téléphone mobile de la manière habituelle.
Pour cette tâche, dans notre cas, le capteur d’éclairage BH1750 est adapté, car il est compatible avec les niveaux de données de 3,3 volts de l’ESP32, ainsi que l’éclairage comme un paquet de données via l’interface I2C directement dans l’unité Lux à notre ESP.
Le capteur de lumière peut être commandé, par exemple à AZ-Delivery Shop Module GY-302.
Si vous êtes intéressé par plus de détails sur le module, vous trouverez par exemple. Ici pour plus d’informations.
Le BH1750 a une très grande portée de mesure et la résolution peut être choisie par paramètres de configuration entre 0,5 lux, 1 lux et 4 lux.
Pour notre projet, nous sélectionnons la résolution moyenne de 1 lux.
Avec l’ajout du capteur de lumière, nous avons maintenant mis nos capteurs nécessaires ensemble pour le projet
Ici, vous trouverez les pièces précédentes moniteur de plante, dont je voudrais recommander, comme des informations importantes, par exemple sur l’étalonnage des capteurs d’humidité du sol, est inclus:
Revenons à la liste des pièces importantes. Vous trouverez toutes les parties pertinentes de ce projet dont vous avez besoin pour une réplique dans la liste des parties suivantes:
Nombre |
Description |
Note |
1 |
|
|
|
Alternative à DHT 22 |
|
1 |
|
|
1 |
|
|
6 |
|
|
1 |
Pour la configuration de la planche à pain |
|
1 |
Capteur d’éclairage |
|
12 |
|
Jetons un coup d’oeil au plan schéma/câblage mis à jour du moniteur d’usine :
Nous reconnaissons le capteur de lumière nouvellement ajouté BH1570. Nous connectons la périphérie comme suit :
module RGB_Led
RGB-Led Anode |
Broche ESP32 |
Rouge |
0 |
Vert |
15 |
Bleu |
14 |
Capteurs d’humidité du sol
Capteur d’humidité |
Broche ESP32 |
1 |
Sp |
2 |
Sn |
3 |
34 |
4 |
35 |
5 |
32 |
6 |
33 |
Capteur de température/humidité DHT 22
épingler |
Broche ESP32 |
DONNÉES /IN OUT |
4 |
Capteur d’éclairage BH1570
BROCHE BH1570 |
Broche ESP32 |
Sda |
21 |
Scl |
|
Addr |
Gnd |
Après nous nous sommes convaincus du câblage correct télécharger le code suivant sur notre ESP :
#include <Pilote/Adc.H (en)> Construire dans la bibliothèque. Aucune bibliothèque externe n’est nécessaire #include 'lt;esp_wifi.h’gt; #include <Wifi.H (en)> #include <WiFiClient (WiFiClient).H (en)> #include <ESPmDNS (EN ANGLAIS).H (en)> #include <BlynkSimpleEsp32.H (en)> #include <Eeprom.H (en)> #include <Préférences.H (en)> #include <Fil.H (en)> #include "DHT.h" REQUIRES les bibliothèques Arduino suivantes: - Bibliothèque de capteurs DHT: https://github.com/adafruit/DHT-sensor-library - Capteur unifié Adafruit Lib: https://github.com/adafruit/Adafruit_Sensor Module LED RGB de définition de port #define LED_Rot 0 LED rouge #define LED_Blau 14 LED bleue #define LED_Gruen 15 // LED verte // Définitions des ports I2C #define SDA1 21 #define SCL1 22 // Paramètres PWM LED #define PWMfreq 5000 // Fréquence de base de 5 kHz pour affichage LED #define PWMledChannelA 0 #define PWMledChannelB 1 #define PWMledChannelC 2 #define Résolution PWM 8 // Résolution 8 bits pour LED PWM // Définitions de temps / timing pour les requêtes de capteur #define ADCAttenuation ADC_ATTEN_DB_11 // ADC_ATTEN_DB_11 = 0-3.6V amortisseur ADC (extension ADC #define MoisureSens_Poll_MinInterval 3600 // Intervalle minimal de transmission des valeurs mesurées entre deux mesures d'humidité du sol en secondes. #define DHT_Poll_MinInterval 2700 // Intervalle de transmission de la valeur mesurée minimale entre deux mesures de température et d'humidité en secondes. #define BH_Poll_MinInterval 1800 // Intervalle de transmission de la valeur mesurée minimale entre deux requêtes d'intensité lumineuse en secondes. #define DEBUG // Une fois définies, diverses informations et valeurs mesurées sont sorties sur l'interface série. Veuillez supprimer avant une utilisation productive! #define MaxSensors 6 // Nombre maximum de capteurs d'humidité connectables #define MinSensorValue 500 // Valeur AD la plus petite pour signaler un canal d'entrée de capteur (1-6) comme "actif" au système. (Le capteur d'humidité est connecté pendant la phase de démarrage) #define StartInit vrai #define RunTime faux #define Sens_Calib vrai #define Sens_NOTCalib faux #define EEPROM_SIZE 512 // Définition de la taille de l'EEPROM interne // Définitions de l'application Blynk #define BLYNK_GREEN "# 23C48E" #define BLYNK_BLUE "# 04C0F8" #define BLYNK_YELLOW "# ED9D00" #define BLYNK_RED "# D3435C" #define BLYNK_BLACK "#000000" #define BLYNK_WHITE "#FFFFFF" #define BLYNK_PRINT Série 1 #define BLYNK_NO_BUILTIN #define BLYNK_NO_FLOAT // # définir BLYNK_DEBUG // Configuration DHT #define DHTPIN 4 // Broche numérique connectée au capteur DHT #define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321 // # define DHTTYPE DHT21 // Si un DHT 21 (AM2301) est utilisé dans votre projet, veuillez définir ce paramètre struct SystemRunParameters { int Les données[MaxSensors * 2] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}; // Données d'étalonnage du capteur d'humidité. Veuillez noter le texte du projet et ajuster les valeurs en conséquence octet StatusBorderPercentValues[MaxSensors * 2][2] = { {10, 50}, // Tableau bidimensionnel pour les valeurs limites en pourcentage (feu de circulation) individuellement pour chaque capteur d'humidité (1 -6) {10, 50}, {10, 50}, {10, 50}, {10, 50}, {10, 50} }; String SensorName[MaxSensors + 3] = {"Usine 1", "Usine 2", "Usine 3", "Usine 4", "Usine 5", "Usine 6", "Humidité", "Température", "Intensité lumineuse"}; // Nom du capteur, qui est également affiché dans l'APP comme en-tête }; struct MoistureSensorData { int Pourcent[MaxSensors] = {0, 0, 0, 0, 0, 0}; // Données du capteur d'humidité en pourcentage octet Old_Percent[MaxSensors] = {0, 0, 0, 0, 0, 0}; // Précédent _ Données du capteur d'humidité en pourcentage (objectif: enregistrer la quantité de données.) bool DataValid [MaxSensors] = {faux, faux, faux, faux, faux, faux}; }; struct DHTSensorData { flotter Humidité = 0 ; // Données du capteur d'humidité en pourcentage flotter La température = 0; flotter Old_Humidity = 0 ; // Données du capteur d'humidité en pourcentage flotter Ancienne_Température = 0; bool DataValid = faux; bool SensorEnabled = faux; }; struct BHLightSensorData { int Lux = 0 ; // Intensité lumineuse en lux int Old_Lux = 0 ; // Intensité lumineuse en lux bool DataValid = faux; bool SensorEnabled = faux; }; DHT dht(DHTPIN, DHTTYPE); // Initialiser l'instance du capteur DHT TwoWire I2CWire = TwoWire(0); // Variables globales char auth[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // Entrez dans l'application Blynk conformément aux instructions du jeton d'authentification (e-mail). // Vos données d'accès WiFi. char ssid[] = "Your_WLAN_SSID"; // Veuillez vous adapter à votre propre SSID WLAN char passer[] = "Votre _WLAN _Passwort!"; // Veuillez vous adapter à votre propre mot de passe WiFi carboniser ESPName[] = "PlantSensor1"; SystemRunParameters SysConfig; MoistureSensorData MMeasure; DHTSensorData DHTMeasure; BHLightSensorData BHMeasure; octet Capteurs d'humidité attachés = 0; // Capteurs d'humidité actifs détectés (nombre) octet BH1750I2CAddress = 0; // Adresse BH1750 I2C détectée bool Connected2Blynk = faux; // Variable booléenne. Stocke l'état de connexion dans le cloud Blynk non signé longue Moisure_ServiceCall_Handler = 0; // Variable de délai pour le délai entre les relevés de Moisure non signé longue DHT_ServiceCall_Handler = 0; // Variable de délai pour le délai entre les lectures DHT non signé longue BH_ServiceCall_Handler = 0; // Variable de délai pour le délai entre les lectures du BH1750 non signé longue chipid; néant installer() { pinMode(LED_Rot, PRODUCTION); pinMode(LED_Blau, PRODUCTION); pinMode(LED_Gruen, PRODUCTION); En série.commencer(115200); // initialise la communication série à 115200 bits par seconde: I2CWire.commencer(SDA1, SCL1, 400000); // rejoindre le bus i2c (adresse facultative pour le maître) //chipid=ESP.getEfuseMac (); // L'ID de puce est essentiellement son adresse MAC (longueur: 6 octets). // sprintf (ESPName, "% d% d% d% d% d% d% d% d% d% d% d% d% d% d% d% d% d", chipid); ledcSetup(PWMledChannelA, PWMfreq, PWMresolution); ledcSetup(PWMledChannelB, PWMfreq, PWMresolution); ledcSetup(PWMledChannelC, PWMfreq, PWMresolution); ledcAttachPin(LED_Rot, PWMledChannelA); // attache le canal au GPIO à contrôler ledcAttachPin(LED_Blau, PWMledChannelB); ledcAttachPin(LED_Gruen, PWMledChannelC); SetLedConfig(255, 255, 255); #ifdef DÉBOGUER En série.impression(F("Verbindung zu WLAN")); #fin si Wifi.déconnecter(); Wifi.setHostname(ESPName); // esp_wifi_set_mode (WIFI_MODE_STA); Wifi.mode(WIFI_STA); Wifi.commencer(ssid, passer); Wifi.setSleep(faux); si (Wifi.waitForConnectResult() != WL_CONNECTED) { tandis que (Wifi.statut() != WL_CONNECTED) { retard(1000); Wifi.commencer(ssid, passer); // réessayez, si la première connexion échoue #ifdef DÉBOGUER En série.impression(F(".")); #fin si } } #ifdef DÉBOGUER En série.println(F("erfolgreich.")); En série.impression(F("Adresse IP: ")); En série.println(Wifi.localIP()); En série.impression(F("Nom d'hôte:")); En série.println(ESPName); #fin si si (!MDNS.commencer(ESPName)) { En série.println("Erreur lors de la configuration du répondeur MDNS!"); } MDNS.addService("plante", "tcp", 400); Blynk.config(auth); // à la place de Blynk.begin (auth, ssid, pass); tandis que (Blynk.relier() == faux) { retard(500); En série.impression("."); } #ifdef DÉBOGUER En série.println(F("Systemkonfiguration:")); #fin si si (EEPROM.commencer(EEPROM_SIZE)) { #ifdef DÉBOGUER En série.impression(EEPROM_SIZE); En série.println(F("Octets EEPROM")); #fin si } Run_MoistureSensors(StartInit); #ifdef DÉBOGUER En série.impression(Capteurs d'humidité attachés); En série.println(F("Bodenfeuchtigkeitsensor (fr)")); #fin si dht.commencer(); DHTMeasure.SensorEnabled = Run_DHTSensor (StartInit); si (DHTMeasure.SensorEnabled) { #ifdef DÉBOGUER En série.println(F("1 capteur DHT 22")); #fin si } BHMeasure.SensorEnabled = Run_BH1750Sensor(StartInit); si (BHMeasure.SensorEnabled) { #ifdef DÉBOGUER En série.println(F("1 capteur de lumière B1750")); #fin si } } néant CheckConnection() { Connected2Blynk = Blynk.connecté(); si (!Connected2Blynk) { En série.println("Non connecté au serveur Blynk"); Blynk.relier(3333); // délai d'attente défini sur 10 secondes, puis continuer sans Blynk } autre { En série.println("Connecté au serveur Blynk"); } } bool Run_BH1750Sensor (bool Init) // Runtime Funktion für den BH170 Lichtsensor { octet ec; si ((millis() - BH_ServiceCall_Handler >= BH_Poll_MinInterval * 1000) | (Init)) { BH_ServiceCall_Handler = millis(); si (Init) { bool BH1750 Détecté = faux; I2CWire.beginTransmission(35); ec = I2CWire.endTransmission(vrai); si (ec == 0) { BH1750 Détecté = vrai; BH1750I2CAddress = 35; // BH1750 I2C Adresse ist DEC 35 } autre { I2CWire.beginTransmission(92); ec = I2CWire.endTransmission(vrai); si (ec == 0) { BH1750 Détecté = vrai; BH1750I2CAddress = 92; // BH1750 I2C Adresse ist DEC 92 } } si (BH1750 Détecté) { // Capteur d'intialisation I2CWire.beginTransmission(BH1750I2CAddress); I2CWire.écrire(0x01); // Allumez-le avant de pouvoir le réinitialiser I2CWire.endTransmission(); I2CWire.beginTransmission(BH1750I2CAddress); I2CWire.écrire(0x07); // Réinitialiser I2CWire.endTransmission(); I2CWire.beginTransmission(BH1750I2CAddress); I2CWire.écrire(0x10); // Mode de résolution H en continu (résolution de 1 lux) Weitere Modis möglich, gemäß Datenblatt //I2CWire.write(0x11); // Mode de résolution H en continu 2 (résolution de 0,5 lux) //I2CWire.write(0x20); // Mode de résolution H unique (résolution 1 lux) //I2CWire.write(0x21); // Mode de résolution H unique2 (résolution 0,5 lux) I2CWire.endTransmission(); Blynk.setProperty(V9, "Couleur", BLYNK_WHITE); Blynk.setProperty(V9, "étiquette", SysConfig.SensorName[8]); } autre { Blynk.setProperty(V9, "étiquette", "Deaktiviert"); Blynk.setProperty(V9, "Couleur", BLYNK_BLACK); Blynk.virtualWrite(V9, 0); revenir BH1750 Détecté; } } I2CWire.beginTransmission(BH1750I2CAddress); ec = I2CWire.endTransmission(vrai); si (ec == 0) { I2CWire.demande de(BH1750I2CAddress, 2); BHMeasure.Lux = I2CWire.lis(); BHMeasure.Lux <<= 8; // Verschieben der unteren 8 bits in die höhreren 8 bits der 16 bits breiten Zahl BHMeasure.Lux |= I2CWire.lis(); BHMeasure.Lux = BHMeasure.Lux / 1.2; BHMeasure.DataValid = vrai; si (BHMeasure.Lux != BHMeasure.Old_Lux) { BHMeasure.Old_Lux = BHMeasure.Lux; Update_Blynk_APP(8, vrai); // Lichtstärkeanzeige in Lux aktualisieren #ifdef DÉBOGUER En série.impression ("Lichtstärke in Lux:"); En série.println (BHMeasure.Lux); #fin si } } autre { BHMeasure.DataValid = faux; BHMeasure.SensorEnabled = faux; Blynk.setProperty(V9, "Couleur", BLYNK_BLUE); } } revenir vrai; } bool Run_DHTSensor (bool Init) // Runtime Funktion für den DHT Temp und Luftfeuchtesensor { si ((millis() - DHT_ServiceCall_Handler >= DHT_Poll_MinInterval * 1000) | (Init)) { DHT_ServiceCall_Handler = millis(); DHTMeasure.Humidité = dht.readHumidity(); DHTMeasure.Température = dht.readTemperature(faux); // Lire la température en Celsius (isFahrenheit = true) si (Init) { si (isnan(DHTMeasure.Humidité) || isnan(DHTMeasure.Température)) { Blynk.setProperty(V7, "étiquette", "Deaktiviert"); Blynk.setProperty(V8, "étiquette", "Deaktiviert"); Blynk.virtualWrite(V7, 0); Blynk.virtualWrite(V8, -20); Blynk.setProperty(V7, "Couleur", BLYNK_BLACK); Blynk.setProperty(V8, "Couleur", BLYNK_BLACK); DHTMeasure.DataValid = faux; revenir faux; } autre { Blynk.setProperty(V7, "Couleur", BLYNK_WHITE); Blynk.setProperty(V7, "étiquette", SysConfig.SensorName[6]); Blynk.setProperty(V8, "Couleur", BLYNK_WHITE); Blynk.setProperty(V8, "étiquette", SysConfig.SensorName[7]); DHTMeasure.DataValid = vrai; DHTMeasure.Old_Humidity = DHTMeasure.Humidité; Update_Blynk_APP(6, vrai); // Luftfeuchteanzeige DHTMeasure.Ancienne_Température = DHTMeasure.Température; Update_Blynk_APP(7, vrai); // Temperaturanzeige revenir vrai; } } si (isnan(DHTMeasure.Humidité) || isnan(DHTMeasure.Température)) { Blynk.setProperty(V7, "Couleur", BLYNK_BLUE); Blynk.setProperty(V8, "Couleur", BLYNK_BLUE); DHTMeasure.DataValid = faux; DHTMeasure.SensorEnabled = faux; revenir faux; } DHTMeasure.DataValid = vrai; si (DHTMeasure.Humidité != DHTMeasure.Old_Humidity) { DHTMeasure.Old_Humidity = DHTMeasure.Humidité; Update_Blynk_APP(6, vrai); // Luftfeuchteanzeige } si (DHTMeasure.Température != DHTMeasure.Ancienne_Température) { DHTMeasure.Ancienne_Température = DHTMeasure.Température; Update_Blynk_APP(7, vrai); // Temperaturanzeige } } revenir vrai; } bool SetLedConfig(octet rouge, octet vert, octet Bleu) { ledcWrite(PWMledChannelA, rouge); // Rote LED ledcWrite(PWMledChannelB, Bleu); // LED Blaue ledcWrite(PWMledChannelC, vert); // Gruene LED revenir vrai; } int ReadMoistureSensor_Raw_Val(octet Capteur) { int ReturnValue, je; longue somme = 0; #définir NUM_READS 6 adc1_config_width(ADC_WIDTH_BIT_12); // Plage 0-4095 commutateur (Capteur) { Cas 0: { adc1_config_channel_atten(ADC1_CHANNEL_0, ADCAttenuation); pour (je = 0; je < NUM_READS; je++) { // Algorithme de moyenne somme += adc1_get_raw( ADC1_CHANNEL_0 ); // Lire analogique } ReturnValue = somme / NUM_READS; Pause; } Cas 1: { adc1_config_channel_atten(ADC1_CHANNEL_3, ADCAttenuation); pour (je = 0; je < NUM_READS; je++) { // Algorithme de moyenne somme += adc1_get_raw( ADC1_CHANNEL_3 ); // Lire analogique } ReturnValue = somme / NUM_READS; Pause; } Cas 2: { adc1_config_channel_atten(ADC1_CHANNEL_6, ADCAttenuation); pour (je = 0; je < NUM_READS; je++) { // Algorithme de moyenne somme += adc1_get_raw( ADC1_CHANNEL_6 ); // Lire analogique } ReturnValue = somme / NUM_READS; Pause; } Cas 3: { adc1_config_channel_atten(ADC1_CHANNEL_7, ADCAttenuation); pour (je = 0; je < NUM_READS; je++) { // Algorithme de moyenne somme += adc1_get_raw( ADC1_CHANNEL_7 ); // Lire analogique } ReturnValue = somme / NUM_READS; Pause; } Cas 4: { adc1_config_channel_atten(ADC1_CHANNEL_4, ADCAttenuation); pour (je = 0; je < NUM_READS; je++) { // Algorithme de moyenne somme += adc1_get_raw( ADC1_CHANNEL_4 ); // Lire analogique } ReturnValue = somme / NUM_READS; Pause; } défaut: { adc1_config_channel_atten(ADC1_CHANNEL_5, ADCAttenuation); pour (je = 0; je < NUM_READS; je++) { // Algorithme de moyenne somme += adc1_get_raw( ADC1_CHANNEL_5 ); // Lire analogique } ReturnValue = somme / NUM_READS; Pause; } } revenir ReturnValue; } néant Update_Local_Display() { octet rouge1 = 0; octet jaune1 = 0; octet vert1 = 0; pour (octet je = 0; je < Capteurs d'humidité attachés; je++) { si (MMeasure.DataValid[je]) { si ( MMeasure.Pour cent[je] > SysConfig.StatusBorderPercentValues[je][1]) { vert1++; } autre si ( MMeasure.Pour cent[je] > SysConfig.StatusBorderPercentValues[je][0]) { jaune1++; } autre { rouge1++; } } } si (rouge1 > 0) { SetLedConfig(255, 0, 0); } autre si (jaune1 > 0) { SetLedConfig(255, 255, 0); } autre si (vert1 > 0) { SetLedConfig(0, 255, 0); } autre { SetLedConfig(0, 0, 255); } } néant Update_Blynk_APP(octet Capteur, bool Calibré) { commutateur (Capteur) { Cas 0: { si ((MMeasure.DataValid[0]) & (Calibré)) { si ( MMeasure.Pour cent[0] > SysConfig.StatusBorderPercentValues[0][1]) { Blynk.setProperty(V1, "Couleur", BLYNK_GREEN); } autre si ( MMeasure.Pour cent[0] > SysConfig.StatusBorderPercentValues[0][0]) { Blynk.setProperty(V1, "Couleur", BLYNK_YELLOW); } autre { Blynk.setProperty(V1, "Couleur", BLYNK_RED); } retard(100); Blynk.virtualWrite(V1, MMeasure.Pour cent[0]); } autre { Blynk.setProperty(V1, "Couleur", BLYNK_BLUE); } Pause; } Cas 1: { si ((MMeasure.DataValid[1]) & (Calibré)) { si ( MMeasure.Pour cent[1] > SysConfig.StatusBorderPercentValues[1][1]) { Blynk.setProperty(V2, "Couleur", BLYNK_GREEN); } autre si ( MMeasure.Pour cent[1] > SysConfig.StatusBorderPercentValues[1][0]) { Blynk.setProperty(V2, "Couleur", BLYNK_YELLOW); } autre { Blynk.setProperty(V2, "Couleur", BLYNK_RED); } retard(100); Blynk.virtualWrite(V2, MMeasure.Pour cent[1]); } autre { Blynk.setProperty(V3, "Couleur", BLYNK_BLUE); } Pause; } Cas 2: { si ((MMeasure.DataValid[2]) & (Calibré)) { si ( MMeasure.Pour cent[2] > SysConfig.StatusBorderPercentValues[2][1]) { Blynk.setProperty(V3, "Couleur", BLYNK_GREEN); } autre si ( MMeasure.Pour cent[2] > Sysconfig.StatusBorderPercentValues[2][0]) { Blynk Blynk.Setproperty(V3 (V3), "couleur", BLYNK_YELLOW); } Autre { Blynk Blynk.Setproperty(V3 (V3), "couleur", BLYNK_RED); } Retard(100); Blynk Blynk.virtualWrite (en)(V3 (V3), MMeasure (MMeasure).Pourcentage d’entre nous[2]); } Autre { Blynk Blynk.Setproperty(V3 (V3), "couleur", BLYNK_BLUE); } Pause; } Cas 3: { Si ((MMeasure (MMeasure).DataValid (en)[3]) & (Calibré)) { Si ( MMeasure (MMeasure).Pourcentage d’entre nous[3] > Sysconfig.StatusBorderPercentValues[3][1]) { Blynk Blynk.Setproperty(V4 (V4), "couleur", BLYNK_GREEN); } Autre Si ( MMeasure (MMeasure).Pourcentage d’entre nous[3] > Sysconfig.StatusBorderPercentValues[3][0]) { Blynk Blynk.Setproperty(V4 (V4), "couleur", BLYNK_YELLOW); } Autre { Blynk Blynk.Setproperty(V4 (V4), "couleur", BLYNK_RED); } Retard(100); Blynk Blynk.virtualWrite (en)(V4 (V4), MMeasure (MMeasure).Pourcentage d’entre nous[3]); } Autre { Blynk Blynk.Setproperty(V4 (V4), "couleur", BLYNK_BLUE); } Pause; } Cas 4: { Si ((MMeasure (MMeasure).DataValid (en)[4]) & (Calibré)) { Si ( MMeasure (MMeasure).Pourcentage d’entre nous[4] > Sysconfig.StatusBorderPercentValues[4][1]) { Blynk Blynk.Setproperty(V5 (V5), "couleur", BLYNK_GREEN); } Autre Si ( MMeasure (MMeasure).Pourcentage d’entre nous[4] > Sysconfig.StatusBorderPercentValues[4][0]) { Blynk Blynk.Setproperty(V5 (V5), "couleur", BLYNK_YELLOW); } Autre { Blynk Blynk.Setproperty(V5 (V5), "couleur", BLYNK_RED); } Retard(100); Blynk Blynk.virtualWrite (en)(V5 (V5), MMeasure (MMeasure).Pourcentage d’entre nous[4]); } Autre { Blynk Blynk.Setproperty(V5 (V5), "couleur", BLYNK_BLUE); } Pause; } Cas 5: { Si ((MMeasure (MMeasure).DataValid (en)[5]) & (Calibré)) { Si ( MMeasure (MMeasure).Pourcentage d’entre nous[5] > Sysconfig.StatusBorderPercentValues[5][1]) { Blynk Blynk.Setproperty(V6 (V6), "couleur", BLYNK_GREEN); } Autre Si ( MMeasure (MMeasure).Pourcentage d’entre nous[5] > Sysconfig.StatusBorderPercentValues[5][0]) { Blynk Blynk.Setproperty(V6 (V6), "couleur", BLYNK_YELLOW); } Autre { Blynk Blynk.Setproperty(V6 (V6), "couleur", BLYNK_RED); } Retard(100); Blynk Blynk.virtualWrite (en)(V6 (V6), MMeasure (MMeasure).Pourcentage d’entre nous[5]); } Autre { Blynk Blynk.Setproperty(V6 (V6), "couleur", BLYNK_BLUE); } Pause; } Cas 6: { Si (DHTMeasure.DataValid (en)) { Si (DHTMeasure.Humidité < 40) // https://www.pflanzenfreunde.com/luftfeuchtigkeit.htm Und https://www.brune.info/magazin/richtige-luftfeuchtigkeit-fuer-pflanzen/ { Blynk Blynk.Setproperty(V7 (V7), "couleur", BLYNK_RED); } Autre Si (DHTMeasure.Humidité < 60) { Blynk Blynk.Setproperty(V7 (V7), "couleur", BLYNK_YELLOW); } Autre Si (DHTMeasure.Humidité < 85) { Blynk Blynk.Setproperty(V7 (V7), "couleur", BLYNK_GREEN); } Autre { Blynk Blynk.Setproperty(V7 (V7), "couleur", BLYNK_YELLOW); } Blynk Blynk.virtualWrite (en)(V7 (V7), DHTMeasure.Humidité); } Pause; } Cas 7: { Si (DHTMeasure.DataValid (en)) { Si (DHTMeasure.Température > 43) // https://www.spektrum.de/lexikon/biologie-kompakt/hitzeresistenz/5543 { Blynk Blynk.Setproperty(V8 (V8), "couleur", BLYNK_RED); } Autre Si (DHTMeasure.Température < 11) // https://de.wikipedia.org/wiki/K%C3%A4ltestress_bei_Pflanzen { Blynk Blynk.Setproperty(V8 (V8), "couleur", BLYNK_RED); } Autre { Blynk Blynk.Setproperty(V8 (V8), "couleur", BLYNK_WHITE); } Blynk Blynk.virtualWrite (en)(V8 (V8), DHTMeasure.Température); } Pause; } Cas 8: { Si (BHMeasure (BHMeasure).DataValid (en)) { Si (BHMeasure (BHMeasure).Lux < 500) // https://www.zimmerpflanzenlexikon.info/artikel/lichtbedarf-von-pflanzen { Blynk Blynk.Setproperty(V9 (V9), "couleur", BLYNK_RED); } Autre Si (BHMeasure (BHMeasure).Lux < 1000) { Blynk Blynk.Setproperty(V9 (V9), "couleur", BLYNK_GREEN); } Autre Si (BHMeasure (BHMeasure).Lux < 1500) { Blynk Blynk.Setproperty(V9 (V9), "couleur", BLYNK_WHITE); } Autre { Blynk Blynk.Setproperty(V9 (V9), "couleur", BLYNK_YELLOW); } Blynk Blynk.virtualWrite (en)(V9 (V9), BHMeasure (BHMeasure).Lux); } Pause; } } Commutateur de fin } Vide Get_Moisture_DatainPercent() { Octet CalibDataOffset = 0; Pour (Octet Ⅰ = 0; Ⅰ < AttachedMoistureSensors; Ⅰ++) { CalibDataOffset = Ⅰ * 2; Int RawMoistureValue = ReadMoistureSensor_Raw_Val(Ⅰ); Si ((Sysconfig.Données[CalibDataOffset] == 0) || (Sysconfig.Données[CalibDataOffset + 1] == 0)) Valeur De minADC maxADC Valeur ADC { MMeasure (MMeasure).Pourcentage d’entre nous[Ⅰ] = RawMoistureValue; MMeasure (MMeasure).DataValid (en)[Ⅰ] = Faux; } Autre { RawMoistureValue = Sysconfig.Données[CalibDataOffset + 1] - RawMoistureValue; RawMoistureValue = Sysconfig.Données[CalibDataOffset] + RawMoistureValue; MMeasure (MMeasure).Pourcentage d’entre nous[Ⅰ] = Carte(RawMoistureValue, Sysconfig.Données[CalibDataOffset], Sysconfig.Données[CalibDataOffset + 1], 0, 100); Si ((MMeasure (MMeasure).Pourcentage d’entre nous[Ⅰ] > 100 ) | (MMeasure (MMeasure).Pourcentage d’entre nous[Ⅰ] < 0 )) { MMeasure (MMeasure).Pourcentage d’entre nous[Ⅰ] = RawMoistureValue; MMeasure (MMeasure).DataValid (en)[Ⅰ] = Faux; } Autre { MMeasure (MMeasure).DataValid (en)[Ⅰ] = Vrai; } } } Retour ; } Vide Run_MoistureSensors (Bool Init) Fonction principale pour l’utilisation de capteurs d’humidité du sol { Octet MinSensValue = 100; Si ((Millis() - Moisure_ServiceCall_Handler >= MoisureSens_Poll_MinInterval * 1000) | (Init)) { Moisure_ServiceCall_Handler = Millis(); Si (Init) { Pour (Int Ⅰ. = 0; Ⅰ. < MaxSensors (en); Ⅰ.++) { Int MSensorRawValue (en anglais seulement) = ReadMoistureSensor_Raw_Val(Ⅰ.); Si ( MSensorRawValue (en anglais seulement) > MinSensorValue) { AttachedMoistureSensors++; } Autre { Pause; } } Si (AttachedMoistureSensors < 1) { #ifdef Debug Série.println(Q(« Aucun capteur d’humidité du sol détecté. système s’arrêta.)); #endif SetLedConfig SetLedConfig SetLedConfig SetLed(255, 0, 255); digitalWrite (en)(LED_Rot, Haute); Affichage led suspendu du système : violet digitalWrite (en)(LED_Blau, Haute); digitalWrite (en)(LED_Gruen, Faible); Retard(1200000); esp_deep_sleep_start(); Tandis que (1) {} } Pour (Int Ⅰ. = 0; Ⅰ. < AttachedMoistureSensors; Ⅰ.++) { Si (Ⅰ. == 0) { Blynk Blynk.Setproperty(V1 (V1), "étiquette", Sysconfig.SensorName (SensorName)[0]); } Si (Ⅰ. == 1) { Blynk Blynk.Setproperty(V2 (V2), "étiquette", Sysconfig.SensorName (SensorName)[1]); } Si (Ⅰ. == 2) { Blynk Blynk.Setproperty(V3 (V3), "étiquette", Sysconfig.SensorName (SensorName)[2]); } Si (Ⅰ. == 3) { Blynk Blynk.Setproperty(V4 (V4), "étiquette", Sysconfig.SensorName (SensorName)[3]); } Si (Ⅰ. == 4) { Blynk Blynk.Setproperty(V5 (V5), "étiquette", Sysconfig.SensorName (SensorName)[4]); } Si (Ⅰ. == 5) { Blynk Blynk.Setproperty(V6 (V6), "étiquette", Sysconfig.SensorName (SensorName)[5]); } } Pour (Int Ⅰ. = AttachedMoistureSensors; Ⅰ. < MaxSensors (en); Ⅰ.++) { Si (Ⅰ. == 0) { Blynk Blynk.Setproperty(V1 (V1), "étiquette", "Handicapé"); Blynk Blynk.Setproperty(V1 (V1), "couleur", BLYNK_BLACK); } Si (Ⅰ. == 1) { Blynk Blynk.Setproperty(V2 (V2), "étiquette", "Handicapé"); Blynk Blynk.Setproperty(V2 (V2), "couleur", BLYNK_BLACK); } Si (Ⅰ. == 2) { Blynk Blynk.Setproperty(V3 (V3), "étiquette", "Handicapé"); Blynk Blynk.Setproperty(V3 (V3), "couleur", BLYNK_BLACK); } Si (Ⅰ. == 3) { Blynk Blynk.Setproperty(V4 (V4), "étiquette", "Handicapé"); Blynk Blynk.Setproperty(V4 (V4), "couleur", BLYNK_BLACK); } Si (Ⅰ. == 4) { Blynk Blynk.Setproperty(V5 (V5), "étiquette", "Handicapé"); Blynk Blynk.Setproperty(V5 (V5), "couleur", BLYNK_BLACK); } Si (Ⅰ. == 5) { Blynk Blynk.Setproperty(V6 (V6), "étiquette", "Handicapé"); Blynk Blynk.Setproperty(V6 (V6), "couleur", BLYNK_BLACK); } } } Get_Moisture_DatainPercent(); Pour (Int Ⅰ. = 0; Ⅰ. < AttachedMoistureSensors; Ⅰ.++) { Si (MMeasure (MMeasure).DataValid (en)[Ⅰ.]) { Si (MMeasure (MMeasure).Pourcentage d’entre nous[Ⅰ.] != MMeasure (MMeasure).Old_Percent[Ⅰ.]) { MMeasure (MMeasure).Old_Percent[Ⅰ.] = MMeasure (MMeasure).Pourcentage d’entre nous[Ⅰ.]; Si (MMeasure (MMeasure).Pourcentage d’entre nous[Ⅰ.] < MinSensValue ) { MinSensValue = MMeasure (MMeasure).Pourcentage d’entre nous[Ⅰ.]; }; #ifdef Debug Série.Imprimer(Q("Capteur de valeur hydratation")); Série.Imprimer(Ⅰ.); Série.Imprimer(Q(" en pourcentage :")); Série.Imprimer(MMeasure (MMeasure).Pourcentage d’entre nous[Ⅰ.]); Série.println(Q(" %")); #endif Update_Blynk_APP(Ⅰ., Sens_Calib); Mettre à jour les valeurs des téléphones mobiles } } Autre { Update_Blynk_APP(Ⅰ., Sens_NOTCalib); Mettre à jour les valeurs des téléphones mobiles Série.Imprimer(Q("Capteur")); Série.Imprimer(Ⅰ.); Série.Imprimer(Q(" pas calibré. S’ll vous plaît, étalonner. Valeur des données brutes:")); Série.println(MMeasure (MMeasure).Pourcentage d’entre nous[Ⅰ.]); } } Update_Local_Display(); Mise à jour Local Plant Guardian Display (Led) } } Boucle principale Vide Boucle() { Run_MoistureSensors(Duree); Si (DHTMeasure.SensorEnabled) { Run_DHTSensor(Duree); } Si (BHMeasure (BHMeasure).SensorEnabled) { Run_BH1750Sensor(Duree); } Blynk Blynk.Courir(); }
Dans le code, avant de le télécharger pour la première fois, le Doit toutefois, les lignes de code suivantes peuvent encore être adaptées à leurs propres besoins :
données int[MaxSensorsMD2] - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
|
Valeurs s’il vous plaît selon la description dans Partie 1 la série.
#define MoisureSens_Poll_MinInterval 3600
|
Intervalle entre deux Mesures de l’humidité du sol en quelques secondes. La valeur influence la fréquence à laquelle les données de téléphone mobile des capteurs d’humidité du sol sont mises à jour, et donc aussi quel volume de données est généré pour la transmission par fois. Plus l’intervalle est élevé, plus l’intervalle est grand. S'il vous plaît d’une valeur qui correspond à votre propre volume de données ou votre propre budget.
[Exemple : 3600 s 1 heure]
#define DHT_Poll_MinInterval 2700
|
Intervalle entre deux Mesures de température/humidité en quelques secondes. La valeur influence la fréquence à laquelle les données de téléphone mobile des mesures de température/humidité sont mises à jour, et donc aussi quel volume de données est généré pour la transmission par fois. Plus l’intervalle est élevé, plus l’intervalle est grand. Veuillez définir une valeur qui correspond à votre propre volume de données ou votre budget.
[Exemple : intervalle de transfert de données de 2700 s et 45 minutes]
#define BH_Poll_MinInterval 1800
|
Intervalle entre deux Mesures d’illumination en quelques secondes. La valeur influe sur la fréquence à laquelle les données de téléphonie mobile Mesures d’illumination et donc aussi la quantité de données requises pour le transfert par temps. Plus l’intervalle est élevé, plus l’intervalle est grand. Veuillez définir une valeur qui correspond à votre propre volume de données ou votre budget.
[Exemple : intervalle de transfert de données de 1800 s et 30 minutes]
char auth[] - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx char ssid[] - "Deine_WLAN_SSID"; char pass[] - "Votre _WLAN _Passwort!"; |
Valeurs s’il vous plaît selon la description dans Partie 2 la série.
Il Anc les paramètres/lignes de code suivants à adapter aux besoins respectifs :
nom de capteur de chaîne[maxsensors] - "plante 1", "plante 2", "plante 3", "plante 4", "plante 5", "plante 6"; |
Nom du capteur qui apparaît comme un titre dans l’APP.
byte StatusBorderPercentValues[MaxSensorsMD2][2] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
Tableau bidimensionnel pour les limites de pourcentage (feux de circulation) par capteur d’humidité (1 -6). Affecte l’affichage du « feu de circulation » et l’affichage des valeurs dans l’APP. D’abord qui (10) précise la limite de transition entre le statut "rouge" et le statut "jaune". La deuxième valeur indique la limite de transition entre le statut jaune et le statut vert. Exemple : de 51 % d’humidité du sol « verte » à partir de 9 % d’humidité du sol « rouge ».
#define DEBUG
|
Si la définition "DEBUG" existe, les messages en temps d’exécution sont supprimés sur l’interface sérielle. Pour une utilisation productive, la définition «DEBUG» pourrait être supprimée afin d’éviter une utilisation inutile des ressources.
Maintenant, comme dans les autres parties, revenons à la personnalisation de notre application mobile. En cela, nous devons maintenant créer un nouvel élément « H-Level » et le configurer comme décrit ci-dessous.
Nous ajoutons le temps « niveau H » 1 pour afficher l’humidité actuelle du sol
Et configurez le nouvel élément comme suit :
- Couleur: Rouge
- Épingle d’entrée: V9 (virtuel)
- Valeur minimale: 0
- Valeur maximale: 1400 (ou 1500)
L’ajustement le plus important ici est encore la variable d’entrée. Cela doit être réglé à "V9" pour fhere
Nous définissons à nouveau le « push » comme taux de lecture
Le résultat final, lorsque le projet est activé, devrait maintenant ressembler à ceci :
Félicitations! Vous avez configuré avec succès votre garde d’usine.
Veuillez noter ce qui suit :
Nous avons maintenant 9 éléments d’affichage "H-Level" sur notre DashBoard. Chaque élément « de niveau H » nous coûte 200 énergies. Cela fait 9-200 à 1800 points d’énergie. L’ajout d’articles supplémentaires qui sont plus chers que 200 points d’énergie n’est possible qu’avec les achats IN-APP payés à partir de ce moment. Les autres exemples et captures d’écran avec des diagrammes sont donc soumis à une charge! Pour la fonction générale du moniteur végétal, ceux-ci ne sont en aucun cas nécessaires!
En outre, il est possible de Pas garantit qu’à l’avenir l’APP ou les points d’énergie achetés seront toujours utilisés ou seront utilisés dans les séries futures. Par conséquent, s’il vous plaît décider de votre propre responsabilité si vous voulez investir de l’argent dans ce.
Même si l’application est en tout cas aussi sans autre investissement entièrement fonctionnel et un déjà un véritable accrocheur, je ne veux pas retenir de vous les extensions déjà possibles payées. Cela ne nécessite pas de modification du code ESP. Toutes les captures d’écran sont configurables via l’APP Blynk seul, quel que soit le firmware.
Exemple de faisabilité : Courbe de température (ensemble dans un graphique) :
Exemple de faisabilité : Courbe de température (séparée en deux graphiques)
Exemple de faisabilité Progression de l’illumination
Pour plus d’informations sur l’APP Blynk et son utilisation dans les contrôleurs, veuillez visiter :
- Blynk Introduction -gt; https://www.blynk.cc/getting-started
- Documentation -gt; http://docs.blynk.cc/
- Générateur de croquis -gt; https://examples.blynk.cc/
- Dernière bibliothèque Blynk -gt; https://github.com/blynkkk/blynk-library/releases/download/v0.6.1/Blynk_Release_v0.6.1.zip
- Dernier serveur Blynk --gt; https://github.com/blynkkk/blynk-server/releases/download/v0.41.5/server-0.41.5.jar
- Blynk Accueil -gt; https://www.blynk.cc
Veuillez noter que ce projet ne convient pas aux centrales hydroélectriques ou aux aéroles. Les plantes ont des exigences différentes pour votre environnement. Étant donné que notre moniteur d’usine ne connaît pas les exigences individuelles des plantes, l’interprétation des valeurs du gardien de plante est exclusivement entre les mains de l’utilisateur.
Le moniteur de plante ne remplace pas le soin responsable des plantes!
Vous pouvez également utiliser ce projet ainsi que d’autres projets de la mine sur mon Git Hub PageTrouver.
Amusez-vous à reconstruire.
5 commentaires
Siegfried
Hallo Tobias,
ich habe selten so gute Beiträge gelesen wie deine “Pflanzenwächter 1-5”. Da ist wirklich alles dabei und für richtige Experten “volles Programm”!
Meine vorsichtige Frage: Hast Du auch eine vereinfachte Version, z. B. ohne Handy App und WLAN. Dafür mit Display für die Anzeige vor Ort (2,8" TFT LCD Shield wie RM68090 oder ähnlich)? Das könnte eine interessante Ergänzung zu dem perfekten Erfassungsmodul sein!?
Freundliche Grüße aus München,
Siegfried
Helmut Lieven
Hallo und danke für das SUPER Projekt. Ich suche schon lange etwas um die Bodenfeuchtigkeit zu messen.
Das Projekt funktioniert mit allen Anzeigen auf dem Handy. Nur ein Problem bereit mir die Feuchtigkeitsanzeige, habe 2 Sensoren angeschlossen. Wenn ich die Werte mit Code Teil 1 auswerte und in Code Teil 5 übertrage kommt die Anzeige BITTE Kalibrieren. Bei geänderten Werten funktioniert es aber die Anzeige % weicht von der ersten Messung ab. Wie kann man am besten Daten ändern?
Gruß Helmut
Dieter
Hallo, ich bin noch Anfänger, und finde die Anleitungen sehr gut. Frage könnte man noch ein Tutorial machen in den man eine Pumpe, bzw Lüfter bei bestimmten Werten schalten kann?
Wäre echt toll.
Danke.
Tobias
Hallo Knut,
versuche mal einen Sensor in trockene Erde und den anderen in feuchte Erde zu stecken. Das sollte in jedem Fall unterschiedliche Ergebnisse liefern. Des weiteren ist eine Kalibrierung der Sensoren wichtig. Ist dies durchgeführt worden ?
Knut Dorendorff
Hallo,
ich habe für 6 Bodenfeuchtsensoren alles eingerichtet und auch dazu den Code installiert. Ich habe im Moment nur 2 Sensoren angeschlossen. Diese arbeiten auch, zeigen aber für beide Sensoren den gleichen Wert an. Habe mehrmals überprüft, ob irgendwo überbrücken sind, aber nein. Ist das ein typischen verhalten bei nur angeschlossenen 2 Sensoren oder muss ich dann im Code etwas verändern?
Danke
Knut