In questa parte della serie, riassumerò quella più importante delle parti precedenti. In retrospettiva, abbiamo già apportato alcune modifiche e aggiunte al nostro custode dello stabilimento. Ad esempio, abbiamo ampliato il numero di sensori di umidità del suolo di 6 e aggiunto un sensore combinato di temperatura e umidità. Per le piante, queste sono una buona base. Tuttavia, manca ancora un altro importante fattore ambientale per la nostra flora. Questa è la luce, specialmente l'illuminazione! L'illuminazione nell'unità Lux è misurata mediante misurazione genica.
La maggior parte delle piante si sentono più a proprio agio nella gamma di illuminazione di 300-1500 lux (a seconda del tipo di pianta). Naturalmente, vogliamo tenerne conto e tenere d'occhio la luminosità in Lux in ogni momento con il nostro monitor dell'impianto. A tale scopo, registriamo l'illuminazione nell'unità Lux e la visualizziamo come valore informativo sul display del telefono cellulare nel solito modo.
Per questo compito, nel nostro caso, il sensore di illuminazione BH1750 è adatto, in quanto è compatibile con i livelli di dati 3.3 volt dell'ESP32, così come l'illuminazione come un pacchetto di dati tramite l'interfaccia I2C direttamente nell'unità Lux al nostro ESP.
Il sensore di luce può essere ordinato, ad esempio presso il negozio di consegna Modulo GY-302.
Se siete interessati a ulteriori dettagli sul modulo, troverete ad esempio Qui per ulteriori informazioni.
Il BH1750 ha un ampio intervallo di misura e la risoluzione può essere scelta da parametri di configurazione tra 0,5 lux, 1 lux e 4 lux.
Per il nostro progetto selezioniamo la risoluzione media di 1 lux.
Con l'aggiunta del sensore di luce, abbiamo ora messo insieme i nostri sensori necessari per il progetto
Qui troverete le precedenti parti del monitor dell'impianto, il cui studio vorrei raccomandare, come informazioni importanti, ad esempio sulla calibrazione dei sensori di umidità del suolo, è incluso:
Torniamo alla lista delle parti importanti. Tutte le parti rilevanti di questo progetto necessarie per una replica sono disponibili nell'elenco delle parti seguenti:
Numero |
Descrizione |
Nota |
1 |
|
|
|
Alternativa al DHT 22 |
|
1 |
|
|
1 |
|
|
6 |
|
|
1 |
Per la configurazione della breadboard |
|
1 |
Sensore di illuminazione |
|
12 |
|
Diamo un'occhiata al piano schematico/cablaggio aggiornato del monitor dell'impianto:
Riconosciamo il sensore di luce BH1570 appena aggiunto. Colleghiamo la periferia come segue:
modulo RGB_Led
Anodo a LED RGB |
ESP32 Pin |
Rosso |
0 |
Verde |
15 |
Blu |
14 |
Sensori di umidità del suolo
Sensore di umidità |
ESP32 Pin |
1 |
Sp |
2 |
Sn |
3 |
34 |
4 |
35 |
5 |
32 |
6 |
33 |
Sensore temperatura/umidità DHT 22
spilla |
ESP32 Pin |
DATI /IN OUT |
4 |
Sensore di illuminazione BH1570
BH1570 PIN |
ESP32 Pin |
Sda |
21 |
Scl |
|
Addr |
Gnd |
Dopo che ci siamo convinti del cablaggio corretto caricare il seguente codice sul nostro ESP:
#include <autista/Adc.H> Compila nella libreria. Nessuna libreria esterna necessaria #include <esp_wifi.h> #include <Wifi.H> #include <WiFiClient (Client WiFi).H> #include <ESPmDNS (informazioni in base al tano).H> #include <BlynkSimpleEsp32.H> #include <Eeprom.H> #include <Preferenze.H> #include <Filo.H> #include "DHT.h" REQUIRES le seguenti librerie Arduino: - Libreria Sensori DHT: https://github.com/adafruit/DHT-sensor-library - Adafruit Unified Sensor Lib: https://github.com/adafruit/Adafruit_Sensor Definizione porta Modulo LED RGB # define LED_Rot 0 LED rosso # define LED_Blau 14 LED blu # define LED_Gruen 15 Gruene LED Definizioni delle porte I2C # define SDA1 21 # define SCL1 22 Impostazioni PWM LED # define PWMfreq 5000 5 Frequenza di base Khz per display LED # define PWMledCanaleA 0 # define PWMledCanaleB 1 # define PWMledCanaleC 2 # define Risoluzione PWM 8 Risoluzione a 8 bit per LED PWM Definizioni di tempo/temporizzazione per le query di sensori # define ADCAttenuazione ADC_ATTEN_DB_11 ADC_ATTEN_DB_11 - attenuazione ADC (estensione ADC) 0-3.6V # define MoisureSens_Poll_MinInterval 3600 Intervallo minimo di trasferimento delle misurazioni tra due misurazioni dell'umidità del suolo in pochi secondi. # define DHT_Poll_MinInterval 2700 Intervallo minimo di trasferimento delle misurazioni tra due misurazioni di temperatura e di volo dell'aria in secondi. # define BH_Poll_MinInterval 1800 Intervallo minimo di trasferimento dei valori misurato tra due query di intensità luminosa in secondi. # define Eseguire il debug Con la definizione, diverse informazioni e valori misurati vengono emessi sull'interfaccia seriale. Si prega di eliminare prima dell'uso produttivo ! # define MaxSensors 6 Numero massimo di umidità collegabilisensori # define MinSensorValue (valore incuito) 500 Mnidest valore AD per segnalare un canale di ingresso del sensore (1-6) come "Attivo" al sistema. (Il sensore di umidità è collegato durante la fase di avvio) # define InizioInit Vero # define Runtime False # define Sens_Calib Vero # define Sens_NOTCalib False # define EEPROM_SIZE 512 Definizione Dimensioni dell'EEPROMS interno Definizioni APP 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 Seriale 1 # define BLYNK_NO_BUILTIN # define BLYNK_NO_FLOAT BLYNK_DEBUG #define Configurazione DHT # define DHTPIN (DHTPIN) 4 Pin digitale collegato al sensore DHT # define DHTTYPE (Tipo di dati) DHT22 DHT 22 (AM2302), AM2321 #define DHTTYPE DHT21 - Se un DHT 21 (AM2301) viene utilizzato nel singolo progetto, si prega di definire la regolazione elettronica Struct Parametri SystemRun { Int Dati[MaxSensors * 2] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}; Dati di calibrazione per il sensore di umidità. Si prega di osservare il testo del progetto e regolare i valori di conseguenza Byte StatusBorderPercentValues (Valori di StatusBorderPercentValues)[MaxSensors * 2][2] = { {10, 50}, Matrice bidirezionale doppia per limiti percentuali (semaforo) singolo per sensore di umidità (1 -6) {10, 50}, {10, 50}, {10, 50}, {10, 50}, {10, 50} }; Stringa SensorName (Nome Sensore)[MaxSensors + 3] = {"Pianta 1", "Pianta 2", "Pianta 3", "Pianta 4", "Pianta 5", "Pianta 6", "Umidità", "Temperatura", "Intensità luminosa"}; Nome del sensore che appare anche come intestazione nella }; Struct Dati Di umidità { Int Percentuale[MaxSensors] = {0, 0, 0, 0, 0, 0}; Dati del sensore di umidità in percentuale Byte Old_Percent[MaxSensors] = {0, 0, 0, 0, 0, 0}; Precedente _ Dati del sensore di umidità in percentuale (scopo: Salvare dataQuantity.) Bool DataValid [MaxSensors] = {False, False, False, False, False, False}; }; Struct Dati DHTSensorData { Galleggiante Umidità = 0 ; Dati del sensore di umidità percentuale Galleggiante Temperatura = 0; Galleggiante Old_Humidity = 0 ; Dati del sensore di umidità percentuale Galleggiante Old_Temperature = 0; Bool DataValid = False; Bool SensorEnabled (Abilitato) = False; }; Struct BHLightSensorData (DatiSensorData) { Int Lux = 0 ; Intensità luminosa in Lux Int Old_Lux = 0 ; Intensità luminosa in Lux Bool DataValid = False; Bool SensorEnabled (Abilitato) = False; }; Dht Dht(DHTPIN (DHTPIN), DHTTYPE (Tipo di dati)); Il sensore DHT iniala l'istanza TwoWire I2CFilo = TwoWire(0); Variabili globali Char Auth[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; Inserisci qui la tua app Blynk (e-mail) in base alle istruzioni Token di autenticazione. Le tue credenziali WiFi. Char Ssid[] = "Deine_WLAN_SSID"; Si prega di adattare al proprio SSID WLAN Char Passare[] = "Il tuo _Passwort _WLAN!"; Si prega di regolare la propria password Wi-Fi Char Nome ESP[] = "PlantSensor1"; Parametri SystemRun Sysconfig; Dati Di umidità MMisura; Dati DHTSensorData DHTMeasure (Misure DHT); BHLightSensorData (DatiSensorData) BHMisura; byte AttachedMoistureSensors = 0; Rilevati sensori di umidità attiva (conteggio) byte IndirizzoBH1750I2CAddress = 0; Rilevato BH1750 Indirizzo I2C Bool Connesso2Blynk = False; Variabile Bool. Archivia Connectionstate nel cloud Blynk Unsigned Lungo Moisure_ServiceCall_Handler = 0; Variabile di ritardo per ritardo tra le letture moisure Unsigned Lungo DHT_ServiceCall_Handler = 0; Variabile di ritardo per ritardo tra letture DHT Unsigned Lungo BH_ServiceCall_Handler = 0; Variabile di ritardo per ritardo tra letture BH1750 Unsigned Lungo chipid; Vuoto Installazione() { PinMode (Modalità pin)(LED_Rot, Output); PinMode (Modalità pin)(LED_Blau, Output); PinMode (Modalità pin)(LED_Gruen, Output); Seriale.Iniziare(115200); inizializzare la comunicazione seriale a 115200 bit al secondo: I2CFilo.Iniziare(SDA1, SCL1, 400000); join bus i2c (indirizzo opzionale per master) chipid-ESP.getEfuseMac(); L'ID chip è essenzialmente il suo indirizzo MAC (lunghezza: 6 byte). sprintf(ESPName, "%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", chipid); ledcSetup(PWMledCanaleA, PWMfreq, Risoluzione PWM); ledcSetup(PWMledCanaleB, PWMfreq, Risoluzione PWM); ledcSetup(PWMledCanaleC, PWMfreq, Risoluzione PWM); ledcAttachPin(LED_Rot, PWMledCanaleA); collegare il canale al GPIO da controllare ledcAttachPin(LED_Blau, PWMledCanaleB); ledcAttachPin(LED_Gruen, PWMledCanaleC); SetLedConfig (configurazione di Windows)(255, 255, 255); #ifdef DEBUG Seriale.Stampare(F("Verbindung zu WLAN")); #endif Wifi.Scollegare(); Wifi.setHostname (nomehost)(Nome ESP); esp_wifi_set_mode(WIFI_MODE_STA); Wifi.Modalità(WIFI_STA); Wifi.Iniziare(Ssid, Passare); Wifi.setSleep (letto)(False); Se (Wifi.waitForConnectResult() != WL_CONNECTED) { Mentre (Wifi.Stato() != WL_CONNECTED) { Ritardo(1000); Wifi.Iniziare(Ssid, Passare); riprovare, se il primo Connect non riesce #ifdef DEBUG Seriale.Stampare(F(".")); #endif } } #ifdef DEBUG Seriale.println(F(" erfolgreich.")); Seriale.Stampare(F("Indirizzo IP: ")); Seriale.println(Wifi.localIP (informazioni in locale)()); Seriale.Stampare(F("Nome host: ")); Seriale.println(Nome ESP); #endif Se (!Mdns.Iniziare(Nome ESP)) { Seriale.println("Errore durante la configurazione del risponditore MDNS!"); } Mdns.addService (servizio aggiuntivo)("pianta", "tcp", 400); Blynk.Config(Auth); al posto di Blynk.begin (auth, ssid, pass); Mentre (Blynk.connettersi() == False) { Ritardo(500); Seriale.Stampare("."); } #ifdef DEBUG Seriale.println(F("Sistemazione:")); #endif Se (Eeprom.Iniziare(EEPROM_SIZE)) { #ifdef DEBUG Seriale.Stampare(EEPROM_SIZE); Seriale.println(F(" Byte EEPROM")); #endif } Run_MoistureSensors(InizioInit); #ifdef DEBUG Seriale.Stampare(AttachedMoistureSensors); Seriale.println(F(" Bodenfeuchtigkeitsensor(en)")); #endif Dht.Iniziare(); DHTMeasure (Misure DHT).SensorEnabled (Abilitato) = Run_DHTSensor (InizioInit); Se (DHTMeasure (Misure DHT).SensorEnabled (Abilitato)) { #ifdef DEBUG Seriale.println(F("1 Sensore DHT 22")); #endif } BHMisura.SensorEnabled (Abilitato) = Run_BH1750Sensor(InizioInit); Se (BHMisura.SensorEnabled (Abilitato)) { #ifdef DEBUG Seriale.println(F("1 Sensore di luce B1750")); #endif } } Vuoto CheckConnection (connessione di controllo)() { Connesso2Blynk = Blynk.Collegato(); Se (!Connesso2Blynk) { Seriale.println("Non connesso al server Blynk"); Blynk.connettersi(3333); timeout impostato su 10 secondi e quindi continuare senza Blynk } Altro { Seriale.println("Connesso al server Blynk"); } } Bool Run_BH1750Sensor (Bool Init) Runtime Funktion f'r den BH170 Lichtsensor { byte Ce; Se ((millis() - BH_ServiceCall_Handler >= BH_Poll_MinInterval * 1000) | (Init)) { BH_ServiceCall_Handler = millis(); Se (Init) { Bool BH1750Rilevato = False; I2CFilo.beginTransmission(35); Ce = I2CFilo.endTransmission(true); if (ec == 0) { Bh1750dected = true; Indirizzo BH1750I2CAddress = 35; // BH1750 I2C indirizzo DEC 35 } else { I2CWire.beginTransmission(92); ec = I2CWire.trasferimento finale(true); if (ec == 0) { Bh1750dected = true; Indirizzo BH1750I2CAddress = 92; // BH1750 I2C indirizzo DEC 92 } } if (Bh1750dected) { // Intialize Sensor I2CWire.beginTransmission(Indirizzo BH1750I2CAddress); I2CWire.write(0x01); // Turn it on before we can reset it I2CWire.trasferimento finale(); I2CWire.beginTransmission(Indirizzo BH1750I2CAddress); I2CWire.write(0x07); // Reset I2CWire.trasferimento finale(); I2CWire.beginTransmission(Indirizzo BH1750I2CAddress); I2CWire.write(0x10); // Continuously h-Resolution Mode (1 lux Resolution) //I2CWire.write ( 0x11); // Continuously H-Resolution Mode 2 (0.5 lux Resolution) //I2CWire.write (0x20); // One Time h-Resolution Mode ( 1 lux Resolution)) //I2CWire.write ( 0x21); // One Time h-Resolution Mode2 (0.5 lux Resolution)) I2CWire.trasferimento finale(); Blynk.setProperty(V9, "color", BLYNK_WHITE); Blynk.setProperty(V9, "etichetta", SysConfig.Nome del sensore[8]); } else { Blynk.setProperty(V9, "etichetta", "Disattivato"); Blynk.setProperty(V9, "color", BLYNK_BLACK); Blynk.write virtuale(V9, 0); return Bh1750dected; } } I2CWire.beginTransmission(Indirizzo BH1750I2CAddress); ec = I2CWire.trasferimento finale(true); if (ec == 0) { I2CWire.requestFrom(Indirizzo BH1750I2CAddress, 2); BHMeasure.Lux = I2CWire.read(); BHMeasure.Lux <<= 8; // Spostamento degli 8 bit inferiori verso 8 bit più alti del numero di 16 Bit BHMeasure.Lux |= I2CWire.read(); BHMeasure.Lux = BHMeasure.Lux / 1.2; BHMeasure.Datavalide = true; if (BHMeasure.Lux != BHMeasure.Old_Lux) { BHMeasure.Old_Lux = BHMeasure.Lux; Update_Blynk_APP(8, true); // Aggiorna la visualizzazione Dell'intensità luminosa in Lux # ifdef DEBUG Seriale.print ("Intensità luminosa in Lux :"); Seriale.println (BHMeasure.Lux); # endif } } else { BHMeasure.Datavalide = false; BHMeasure.Lettore di sensori = false; Blynk.setProperty(V9, "color", BLYNK_BLUE); } } return true; } bool Run_DHTSensor (bool Init) / Funzione Runtime per DHT Temp e sensore di umidità { if ((millis() - DHT_ServiceCall_Handler >= DHT_Poll_MinInterval * 1000) | (Init)) { DHT_ServiceCall_Handler = millis(); DHTMeasure.Humidity = dht.readHumidity(); DHTMeasure.Temperatura = dht.temperatura del read(false); // Read temperature as Celsius (Fahrenheit = true) if (Init) { if (isnan(DHTMeasure.Humidity) || isnan(DHTMeasure.Temperatura)) { Blynk.setProperty(V7, "etichetta", "Disattivato"); Blynk.setProperty(V8, "etichetta", "Disattivato"); Blynk.write virtuale(V7, 0); Blynk.write virtuale(V8, -20); Blynk.setProperty(V7, "color", BLYNK_BLACK); Blynk.setProperty(V8, "color", BLYNK_BLACK); DHTMeasure.Datavalide = false; return false; } else { Blynk.setProperty(V7, "color", BLYNK_WHITE); Blynk.setProperty(V7, "etichetta", SysConfig.Nome del sensore[6]); Blynk.setProperty(V8, "color", BLYNK_WHITE); Blynk.setProperty(V8, "etichetta", SysConfig.Nome del sensore[7]); DHTMeasure.Datavalide = true; DHTMeasure.Old_Humidity = DHTMeasure.Humidity; Update_Blynk_APP(6, true); // Indicatore di umidità DHTMeasure.Temperature Old_Temperature = DHTMeasure.Temperatura; Update_Blynk_APP(7, true); // Indicazione della temperatura return true; } } if (isnan(DHTMeasure.Humidity) || isnan(DHTMeasure.Temperatura)) { Blynk.setProperty(V7, "color", BLYNK_BLUE); Blynk.setProperty(V8, "color", BLYNK_BLUE); DHTMeasure.Datavalide = false; DHTMeasure.Lettore di sensori = false; return false; } DHTMeasure.Datavalide = true; if (DHTMeasure.Humidity != DHTMeasure.Old_Humidity) { DHTMeasure.Old_Humidity = DHTMeasure.Humidity; Update_Blynk_APP(6, true); // Indicatore di umidità } if (DHTMeasure.Temperatura != DHTMeasure.Temperature Old_Temperature) { DHTMeasure.Temperature Old_Temperature = DHTMeasure.Temperatura; Update_Blynk_APP(7, true); // Indicazione della temperatura } } return true; } bool SetLedConfig(byte Red, byte Green, byte Blue) { ledcWrite(PWMledChannelA, Red); // LED rosso ledcWrite(PWMledChannelB, Blue); // LED blu ledcWrite(PWMledChannelC, Green); // Gruene LED return true; } int ReadMoistureSensor_Raw_Val(byte Sensore) { int ReturnValue, i; long sum = 0; # define # NUM_READS 6 adc1_config_width(ADD_WIDTH_BIT_12); // Range 0-4095 switch (Sensore) { case 0: { adc1_config_channel_atten(ADDC1_CHANNEL_0, Addattenuazione); for (i = 0; i < NUM_READS; i++) { // Averaging algorithm sum += adc1_get_raw( ADDC1_CHANNEL_0 ); // Read analogico } ReturnValue = sum / NUM_READS; break; } case 1: { adc1_config_channel_atten(ADDC1_CHANNEL_3, Addattenuazione); for (i = 0; i < NUM_READS; i++) { // Averaging algorithm sum += adc1_get_raw( ADDC1_CHANNEL_3 ); // Read analogico } ReturnValue = sum / NUM_READS; break; } case 2: { adc1_config_channel_atten(ADDC1_CHANNEL_6, Addattenuazione); for (i = 0; i < NUM_READS; i++) { // Averaging algorithm sum += adc1_get_raw( ADDC1_CHANNEL_6 ); // Read analogico } ReturnValue = sum / NUM_READS; break; } case 3: { adc1_config_channel_atten(ADDC1_CHANNEL_7, Addattenuazione); for (i = 0; i < NUM_READS; i++) { // Averaging algorithm sum += adc1_get_raw( ADDC1_CHANNEL_7 ); // Read analogico } ReturnValue = sum / NUM_READS; break; } case 4: { adc1_config_channel_atten(ADDC1_CHANNEL_4, Addattenuazione); for (i = 0; i < NUM_READS; i++) { // Averaging algorithm sum += adc1_get_raw( ADDC1_CHANNEL_4 ); // Read analogico } ReturnValue = sum / NUM_READS; break; } default: { adc1_config_channel_atten(ADDC1_CHANNEL_5, Addattenuazione); for (i = 0; i < NUM_READS; i++) { // Averaging algorithm sum += adc1_get_raw( ADDC1_CHANNEL_5 ); // Read analogico } ReturnValue = sum / NUM_READS; break; } } return ReturnValue; } void Update_Local_Display() { byte red1 = 0; byte yellow1 = 0; byte green1 = 0; for (byte i = 0; i < AttachedMoistureSensors; i++) { if (MMeasure.Datavalide[i]) { if ( MMeasure.Percent[i] > SysConfig.Statusbordercentvalues[i][1]) { green1++; } else if ( MMeasure.Percent[i] > SysConfig.Statusbordercentvalues[i][0]) { yellow1++; } else { red1++; } } } if (red1 > 0) { SetLedConfig(255, 0, 0); } else if (yellow1 > 0) { SetLedConfig(255, 255, 0); } else if (green1 > 0) { SetLedConfig(0, 255, 0); } else { SetLedConfig(0, 0, 255); } } void Update_Blynk_APP(byte Sensore, bool Calibrated) { switch (Sensore) { case 0: { if ((MMeasure.Datavalide[0]) & (Calibrated)) { if ( MMeasure.Percent[0] > SysConfig.Statusbordercentvalues[0][1]) { Blynk.setProperty(V1, "color", BLYNK_GREEN); } else if ( MMeasure.Percent[0] > SysConfig.Statusbordercentvalues[0][0]) { Blynk.setProperty(V1, "color", BLYNK_YELLOW); } else { Blynk.setProperty(V1, "color", BLYNK_RED); } delay(100); Blynk.write virtuale(V1, MMeasure.Percent[0]); } else { Blynk.setProperty(V1, "color", BLYNK_BLUE); } break; } case 1: { if ((MMeasure.Datavalide[1]) & (Calibrated)) { if ( MMeasure.Percent[1] > SysConfig.Statusbordercentvalues[1][1]) { Blynk.setProperty(V2, "color", BLYNK_GREEN); } else if ( MMeasure.Percent[1] > SysConfig.Statusbordercentvalues[1][0]) { Blynk.setProperty(V2, "color", BLYNK_YELLOW); } else { Blynk.setProperty(V2, "color", BLYNK_RED); } delay(100); Blynk.write virtuale(V2, MMeasure.Percent[1]); } else { Blynk.setProperty(V3, "color", BLYNK_BLUE); } break; } case 2: { if ((MMeasure.Datavalide[2]) & (Calibrated)) { if ( MMeasure.Percent[2] > SysConfig.Statusbordercentvalues[2][1]) { Blynk.setProperty(V3, "color", BLYNK_GREEN); } else if ( MMeasure.Percent[2] > Sysconfig.StatusBorderPercentValues (Valori di StatusBorderPercentValues)[2][0]) { Blynk.Setproperty(V3, "colore", BLYNK_YELLOW); } Altro { Blynk.Setproperty(V3, "colore", BLYNK_RED); } Ritardo(100); Blynk.virtualWrite (Scrittura virtuale)(V3, MMisura.Percentuale[2]); } Altro { Blynk.Setproperty(V3, "colore", BLYNK_BLUE); } Pausa; } Caso 3: { Se ((MMisura.DataValid[3]) & (Calibrato)) { Se ( MMisura.Percentuale[3] > Sysconfig.StatusBorderPercentValues (Valori di StatusBorderPercentValues)[3][1]) { Blynk.Setproperty(V4, "colore", BLYNK_GREEN); } Altro Se ( MMisura.Percentuale[3] > Sysconfig.StatusBorderPercentValues (Valori di StatusBorderPercentValues)[3][0]) { Blynk.Setproperty(V4, "colore", BLYNK_YELLOW); } Altro { Blynk.Setproperty(V4, "colore", BLYNK_RED); } Ritardo(100); Blynk.virtualWrite (Scrittura virtuale)(V4, MMisura.Percentuale[3]); } Altro { Blynk.Setproperty(V4, "colore", BLYNK_BLUE); } Pausa; } Caso 4: { Se ((MMisura.DataValid[4]) & (Calibrato)) { Se ( MMisura.Percentuale[4] > Sysconfig.StatusBorderPercentValues (Valori di StatusBorderPercentValues)[4][1]) { Blynk.Setproperty(V5, "colore", BLYNK_GREEN); } Altro Se ( MMisura.Percentuale[4] > Sysconfig.StatusBorderPercentValues (Valori di StatusBorderPercentValues)[4][0]) { Blynk.Setproperty(V5, "colore", BLYNK_YELLOW); } Altro { Blynk.Setproperty(V5, "colore", BLYNK_RED); } Ritardo(100); Blynk.virtualWrite (Scrittura virtuale)(V5, MMisura.Percentuale[4]); } Altro { Blynk.Setproperty(V5, "colore", BLYNK_BLUE); } Pausa; } Caso 5: { Se ((MMisura.DataValid[5]) & (Calibrato)) { Se ( MMisura.Percentuale[5] > Sysconfig.StatusBorderPercentValues (Valori di StatusBorderPercentValues)[5][1]) { Blynk.Setproperty(V6, "colore", BLYNK_GREEN); } Altro Se ( MMisura.Percentuale[5] > Sysconfig.StatusBorderPercentValues (Valori di StatusBorderPercentValues)[5][0]) { Blynk.Setproperty(V6, "colore", BLYNK_YELLOW); } Altro { Blynk.Setproperty(V6, "colore", BLYNK_RED); } Ritardo(100); Blynk.virtualWrite (Scrittura virtuale)(V6, MMisura.Percentuale[5]); } Altro { Blynk.Setproperty(V6, "colore", BLYNK_BLUE); } Pausa; } Caso 6: { Se (DHTMeasure (Misure DHT).DataValid) { Se (DHTMeasure (Misure DHT).Umidità < 40) // https://www.pflanzenfreunde.com/luftfeuchtigkeit.htm Und https://www.brune.info/magazin/richtige-luftfeuchtigkeit-fuer-pflanzen/ { Blynk.Setproperty(V7, "colore", BLYNK_RED); } Altro Se (DHTMeasure (Misure DHT).Umidità < 60) { Blynk.Setproperty(V7, "colore", BLYNK_YELLOW); } Altro Se (DHTMeasure (Misure DHT).Umidità < 85) { Blynk.Setproperty(V7, "colore", BLYNK_GREEN); } Altro { Blynk.Setproperty(V7, "colore", BLYNK_YELLOW); } Blynk.virtualWrite (Scrittura virtuale)(V7, DHTMeasure (Misure DHT).Umidità); } Pausa; } Caso 7: { Se (DHTMeasure (Misure DHT).DataValid) { Se (DHTMeasure (Misure DHT).Temperatura > 43) // https://www.spektrum.de/lexikon/biologie-kompakt/hitzeresistenz/5543 { Blynk.Setproperty(V8 (in questo stato del sistema, "colore", BLYNK_RED); } Altro Se (DHTMeasure (Misure DHT).Temperatura < 11) // https://de.wikipedia.org/wiki/K%C3%A4ltestress_bei_Pflanzen { Blynk.Setproperty(V8 (in questo stato del sistema, "colore", BLYNK_RED); } Altro { Blynk.Setproperty(V8 (in questo stato del sistema, "colore", BLYNK_WHITE); } Blynk.virtualWrite (Scrittura virtuale)(V8 (in questo stato del sistema, DHTMeasure (Misure DHT).Temperatura); } Pausa; } Caso 8: { Se (BHMisura.DataValid) { Se (BHMisura.Lux < 500) // https://www.zimmerpflanzenlexikon.info/artikel/lichtbedarf-von-pflanzen { Blynk.Setproperty(V9 (in via del, "colore", BLYNK_RED); } Altro Se (BHMisura.Lux < 1000) { Blynk.Setproperty(V9 (in via del, "colore", BLYNK_GREEN); } Altro Se (BHMisura.Lux < 1500) { Blynk.Setproperty(V9 (in via del, "colore", BLYNK_WHITE); } Altro { Blynk.Setproperty(V9 (in via del, "colore", BLYNK_YELLOW); } Blynk.virtualWrite (Scrittura virtuale)(V9 (in via del, BHMisura.Lux); } Pausa; } } Interruttore finale } Vuoto Get_Moisture_DatainPercent() { byte CalibDataOffset = 0; Per (byte Ho = 0; Ho < AttachedMoistureSensors; Ho++) { CalibDataOffset = Ho * 2; Int RawMoistureValue = ReadMoistureSensor_Raw_Val(Ho); Se ((Sysconfig.Dati[CalibDataOffset] == 0) || (Sysconfig.Dati[CalibDataOffset + 1] == 0)) Valore MinADC maxADC VALORE ADC { MMisura.Percentuale[Ho] = RawMoistureValue; MMisura.DataValid[Ho] = False; } Altro { RawMoistureValue = Sysconfig.Dati[CalibDataOffset + 1] - RawMoistureValue; RawMoistureValue = Sysconfig.Dati[CalibDataOffset] + RawMoistureValue; MMisura.Percentuale[Ho] = Mappa(RawMoistureValue, Sysconfig.Dati[CalibDataOffset], Sysconfig.Dati[CalibDataOffset + 1], 0, 100); Se ((MMisura.Percentuale[Ho] > 100 ) | (MMisura.Percentuale[Ho] < 0 )) { MMisura.Percentuale[Ho] = RawMoistureValue; MMisura.DataValid[Ho] = False; } Altro { MMisura.DataValid[Ho] = Vero; } } } Ritorno ; } Vuoto Run_MoistureSensors (Bool Init) Funzione principale per il funzionamento dei sensori di umidità del suolo { Byte MinSensValore = 100; Se ((millis() - Moisure_ServiceCall_Handler >= MoisureSens_Poll_MinInterval * 1000) | (Init)) { Moisure_ServiceCall_Handler = millis(); Se (Init) { Per (Int Ho. = 0; Ho. < MaxSensors; Ho.++) { Int MSensorRawValue (valore MSensorRawValue) = ReadMoistureSensor_Raw_Val(Ho.); Se ( MSensorRawValue (valore MSensorRawValue) > MinSensorValue (valore incuito)) { AttachedMoistureSensors++; } Altro { Pausa; } } Se (AttachedMoistureSensors < 1) { #ifdef Eseguire il debug Seriale.println(D("Nessun sensore di umidità del suolo rilevato. sistema in pausa.)); #endif SetLedConfig (configurazione di Windows)(255, 0, 255); digitalWrite (Scrittura digitale)(LED_Rot, alto); Display led sospeso del sistema: viola digitalWrite (Scrittura digitale)(LED_Blau, alto); digitalWrite (Scrittura digitale)(LED_Gruen, Basso); Ritardo(1200000); esp_deep_sleep_start(); Mentre (1) {} } Per (Int Ho. = 0; Ho. < AttachedMoistureSensors; Ho.++) { Se (Ho. == 0) { Blynk.Setproperty(V1 (in via di, "etichetta", Sysconfig.SensorName (Nome Sensore)[0]); } Se (Ho. == 1) { Blynk.Setproperty(V2, "etichetta", Sysconfig.SensorName (Nome Sensore)[1]); } Se (Ho. == 2) { Blynk.Setproperty(V3, "etichetta", Sysconfig.SensorName (Nome Sensore)[2]); } Se (Ho. == 3) { Blynk.Setproperty(V4, "etichetta", Sysconfig.SensorName (Nome Sensore)[3]); } Se (Ho. == 4) { Blynk.Setproperty(V5, "etichetta", Sysconfig.SensorName (Nome Sensore)[4]); } Se (Ho. == 5) { Blynk.Setproperty(V6, "etichetta", Sysconfig.SensorName (Nome Sensore)[5]); } } Per (Int Ho. = AttachedMoistureSensors; Ho. < MaxSensors; Ho.++) { Se (Ho. == 0) { Blynk.Setproperty(V1 (in via di, "etichetta", "Disabilitato"); Blynk.Setproperty(V1 (in via di, "colore", BLYNK_BLACK); } Se (Ho. == 1) { Blynk.Setproperty(V2, "etichetta", "Disabilitato"); Blynk.Setproperty(V2, "colore", BLYNK_BLACK); } Se (Ho. == 2) { Blynk.Setproperty(V3, "etichetta", "Disabilitato"); Blynk.Setproperty(V3, "colore", BLYNK_BLACK); } Se (Ho. == 3) { Blynk.Setproperty(V4, "etichetta", "Disabilitato"); Blynk.Setproperty(V4, "colore", BLYNK_BLACK); } Se (Ho. == 4) { Blynk.Setproperty(V5, "etichetta", "Disabilitato"); Blynk.Setproperty(V5, "colore", BLYNK_BLACK); } Se (Ho. == 5) { Blynk.Setproperty(V6, "etichetta", "Disabilitato"); Blynk.Setproperty(V6, "colore", BLYNK_BLACK); } } } Get_Moisture_DatainPercent(); Per (Int Ho. = 0; Ho. < AttachedMoistureSensors; Ho.++) { Se (MMisura.DataValid[Ho.]) { Se (MMisura.Percentuale[Ho.] != MMisura.Old_Percent[Ho.]) { MMisura.Old_Percent[Ho.] = MMisura.Percentuale[Ho.]; Se (MMisura.Percentuale[Ho.] < MinSensValore ) { MinSensValore = MMisura.Percentuale[Ho.]; }; #ifdef Eseguire il debug Seriale.Stampare(D("Sensore del valore dell'umidità")); Seriale.Stampare(Ho.); Seriale.Stampare(D(" in percentuale :")); Seriale.Stampare(MMisura.Percentuale[Ho.]); Seriale.println(D(" %")); #endif Update_Blynk_APP(Ho., Sens_Calib); Aggiornare i valori del telefono cellulare } } Altro { Update_Blynk_APP(Ho., Sens_NOTCalib); Aggiornare i valori del telefono cellulare Seriale.Stampare(D("Sensore")); Seriale.Stampare(Ho.); Seriale.Stampare(D(" non calibrato. Si prega di calibrare. Valore dati non elaborati:")); Seriale.println(MMisura.Percentuale[Ho.]); } } Update_Local_Display(); Aggiorna display locale del guardiano dell'impianto (Led) } } Ciclo principale Vuoto Ciclo() { Run_MoistureSensors(Runtime); Se (DHTMeasure (Misure DHT).SensorEnabled (Abilitato)) { Run_DHTSensor(Runtime); } Se (BHMisura.SensorEnabled (Abilitato)) { Run_BH1750Sensor(Runtime); } Blynk.Correre(); }
Nel codice, prima di caricarlo per la prima volta, il Deve tuttavia, le seguenti righe di codice possono ancora essere adattate alle proprie esigenze:
dati int[MaxSensors'2]: .0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
|
I valori si prega di secondo la descrizione in Parte 1 la serie.
#DEFINE MOISURESENS_POLL_MININTERVAL 3600
|
Intervallo tra due Misurazioni dell'umidità del suolo in pochi secondi. Il valore influenza la frequenza con cui vengono aggiornati i dati del telefono cellulare dei sensori di umidità del suolo, e quindi anche il volume di dati generato per la trasmissione per volta. Più alto è, maggiore è l'intervallo. Si prega impostato su un valore che corrisponde al proprio volume di dati o budget.
[Esempio: 3600 s 1 ora]
#define DHT_Poll_MinInterval 2700
|
Intervallo tra due Misurazioni di temperatura/umidità in pochi secondi. Il valore influenza la frequenza con cui vengono aggiornati i dati del telefono cellulare delle misurazioni di temperatura/umidità, e quindi anche il volume di dati generato per la trasmissione per volta. Più alto è, maggiore è l'intervallo. Impostare su un valore che corrisponda al volume o al budget di dati.
[Esempio: 2700 s - Intervallo di trasferimento dati di 45 minuti]
BH_Poll_MinInterval #define 1800
|
Intervallo tra due Misurazioni dell'illuminazione in pochi secondi. Il valore influenza la frequenza con cui i dati del telefono cellulare Misurazioni dell'illuminazione e quindi anche la quantità di dati necessari per il trasferimento per volta. Più alto è, maggiore è l'intervallo. Impostare su un valore che corrisponda al volume o al budget di dati.
[Esempio: 1800 s - Intervallo di trasferimento dati di 30 minuti]
char auth[] - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx char ssid[] - "Deine_WLAN_SSID"; char pass[] - "Il tuo _Passwort _WLAN!"; |
I valori si prega di secondo la descrizione in Parte 2 la serie.
esso potere i seguenti parametri/linee di codice da adattare alle rispettive esigenze:
stringa sensorname[maxsensors] - "pianta 1", "pianta 2", "pianta 3", "pianta 4", "pianta 5", "pianta 6"; |
Nome del sensore che appare come un titolo nell'APP.
Byte StatusBorderPercentValues[MaxSensors2][2][2], . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
Matrice bidimensionale per limiti percentuali (luci di traffico) per sensore di umidità (1 -6). Influisce sul display "semaforo" e sulla visualizzazione dei valori nell'APP. Il primo chi (10) specifica il limite di transizione tra lo stato "rosso" e lo stato "giallo". Il secondo valore indica il limite di transizione tra lo stato giallo e lo stato verde. Esempio: dal 51% umidità del suolo "verde" dal 9% umidità del suolo "rosso".
#define DEBUG
|
Se esiste la definizione "DEBUG", i messaggi di runtime vengono restituiti sull'interfaccia seriale. Per un utilizzo produttivo, la definizione "DEBUG" potrebbe essere eliminata per evitare l'utilizzo non necessario delle risorse.
Ora, come nelle altre parti, torniamo alla personalizzazione della nostra app mobile. In questo ora dobbiamo creare un nuovo elemento "H-Level" e configurarlo come descritto di seguito.
Aggiungiamo il "Livello H" 1 tempo per visualizzare l'umidità del suolo corrente
E configurare il nuovo elemento come segue:
- Colore: Rosso
- Pin di ingresso: V9 (virtuale)
- Valore minimo: 0
- Valore massimo: 1400 (o 1500)
La regolazione più importante qui è di nuovo la variabile di input. Questo deve essere impostato su "V9" per fhere
Definiamo di nuovo "push" la velocità di lettura
Il risultato finale, quando il progetto è attivato, dovrebbe ora avere un aspetto simile al seguente:The end result, when the project is activated, should now look something like this:
Congratulazioni! La protezione dell'impianto è stata configurata correttamente.
Si prega di notare quanto segue:
Ora abbiamo 9 elementi di visualizzazione "H-Level" sul nostro DashBoard. Ogni elemento "h-level" ci costa 200 energia. Questo fa 9,200 x 1800 punti di energia. L'aggiunta di articoli aggiuntivi più costosi di 200 punti energia è possibile solo con acquisti IN-APP a pagamento da questo punto in elom. Gli altri esempi e screenshot con diagrammi sono quindi soggetti a un costo! Per la funzione generale del monitor dell'impianto, questi non sono affatto necessari!
Inoltre, è possibile Non garantito che in futuro l'APP o i punti di energia acquistati saranno ancora utilizzati o saranno utilizzati in serie future. Pertanto, si prega di decidere sulla propria responsabilità se si desidera investire denaro in questo.
Anche se l'applicazione è in ogni caso anche senza ulteriore investimento completamente funzionale e un già un vero e proprio eye-catcher, non voglio trattenere da voi le estensioni già possibili a pagamento. Ciò non richiede una modifica nel codice ESP. Tutti gli screenshot sono configurabili tramite blynk APP da solo, indipendentemente dal firmware.
Esempio di fattibilità: Curva di temperatura (insieme in un grafico) :
Esempio di fattibilità: Curva di temperatura (separata in due grafici)
Esempio di fattibilità Progressione dell'illuminazione
Per ulteriori informazioni sull'APP Blynk e sul suo utilizzo nei controller, visitare:
- Introduzione a Blynk -> https://www.blynk.cc/getting-started
- Documentazione -> http://docs.blynk.cc/
- Generatore di schizzi -> https://examples.blynk.cc/
- Ultima libreria Blynk -> https://github.com/blynkkk/blynk-library/releases/download/v0.6.1/Blynk_Release_v0.6.1.zip
- Server Blynk più recente -> https://github.com/blynkkk/blynk-server/releases/download/v0.41.5/server-0.41.5.jar
- Blynk Home -> https://www.blynk.cc
Si prega di notare che questo progetto non è adatto per impianti di idrocoltura o radici d'aria. Le piante hanno requisiti diversi per il vostro ambiente. Poiché il nostro monitor impianto non conosce i requisiti individuali degli impianti, l'interpretazione dei valori del tutore dell'impianto è esclusivamente nelle mani dell'utente.
Il monitor dell'impianto non sostituisce la cura responsabile delle piante!
È inoltre possibile utilizzare questo progetto così come altri miei progetti sul mio Pagina Hub GitPer trovare.
Divertiti a ricostruire.
5 commenti
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