#include <WiFi.h> // Pour se connecter au réseau wifi #include "esp_camera.h" // Pour capturer une image #include <esp_http_client.h> // Pour envoyer la photo au serveur #include "soc/sens_reg.h" // Pour la ruse ADC2 // Les valeurs du cycle d'arrosage #define NB_CYCLE_WATERING 1 #define TIME_BTWN_WATERING 5000 #define WATERING_TIME 3000 // Le temps d'attente avant de lire de nouveau // le capteur d'humidité (1h en millisecondes) #define SLEEPING_TIME (3600*1000) // Les valeurs seuils du capteur d'humidité #define MAX_MOIST_VAL 2000 #define MIN_MOIST_VAL 3000 // Les pins de l'ESP-WROOM-32 pour la caméra OV2640 du modèle AI THINKER #define PWDN_GPIO_NUM 32 #define RESET_GPIO_NUM -1 #define XCLK_GPIO_NUM 0 #define SIOD_GPIO_NUM 26 #define SIOC_GPIO_NUM 27 #define Y9_GPIO_NUM 35 #define Y8_GPIO_NUM 34 #define Y7_GPIO_NUM 39 #define Y6_GPIO_NUM 36 #define Y5_GPIO_NUM 21 #define Y4_GPIO_NUM 19 #define Y3_GPIO_NUM 18 #define Y2_GPIO_NUM 5 #define VSYNC_GPIO_NUM 25 #define HREF_GPIO_NUM 23 #define PCLK_GPIO_NUM 22 camera_fb_t * fb = NULL; // Camera buffer uint64_t reg_b; // valeur du registre pour analogread() // Les broches gpio int moist_pin = 14; int relay_pin = 2; int led_pin = 4; // Les états des broches on l'on écrit int relay_state = LOW; int led_state = LOW; // Le réseau wifi const char* ssid = "le_reseau_local"; const char* password = "le_mot_de_passe_local"; // AnalogRead alternatif int alt_analogRead(int pin) { WRITE_PERI_REG(SENS_SAR_READ_CTRL2_REG, reg_b); SET_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DATA_INV); return analogRead(pin); } // Fonction pour amorcer la caméra void init_camera() { camera_config_t config; config.ledc_channel = LEDC_CHANNEL_0; config.ledc_timer = LEDC_TIMER_0; config.pin_d0 = Y2_GPIO_NUM; config.pin_d1 = Y3_GPIO_NUM; config.pin_d2 = Y4_GPIO_NUM; config.pin_d3 = Y5_GPIO_NUM; config.pin_d4 = Y6_GPIO_NUM; config.pin_d5 = Y7_GPIO_NUM; config.pin_d6 = Y8_GPIO_NUM; config.pin_d7 = Y9_GPIO_NUM; config.pin_xclk = XCLK_GPIO_NUM; config.pin_pclk = PCLK_GPIO_NUM; config.pin_vsync = VSYNC_GPIO_NUM; config.pin_href = HREF_GPIO_NUM; config.pin_sscb_sda = SIOD_GPIO_NUM; config.pin_sscb_scl = SIOC_GPIO_NUM; config.pin_pwdn = PWDN_GPIO_NUM; config.pin_reset = RESET_GPIO_NUM; config.xclk_freq_hz = 20000000; config.pixel_format = PIXFORMAT_JPEG; if (psramFound()) { config.frame_size = FRAMESIZE_UXGA; config.jpeg_quality = 10; config.fb_count = 2; } else { config.frame_size = FRAMESIZE_SVGA; config.jpeg_quality = 12; config.fb_count = 1; } esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { Serial.printf("Erreur lors de l'initialisation de la caméra : 0x%x", err); return; } } void send_a_picture() { esp_http_client_config_t config = { .url = "http://192.168.1.254/plantbot/reception_image.php" }; esp_http_client_handle_t client = esp_http_client_init(&config); esp_http_client_set_post_field(client, (const char *)fb->buf, fb->len); esp_http_client_set_method(client, HTTP_METHOD_POST); esp_http_client_set_header(client, "Content-type", "image/jpg"); esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) Serial.println("Image envoyée"); else Serial.printf("erreur %d lors de l'envoi de l'image\r\n", err); esp_http_client_cleanup(client); esp_camera_fb_return(fb); } void take_a_picture() { fb = esp_camera_fb_get(); if(!fb) { Serial.println("Echec de la capture d'image :("); return; } else { Serial.println("Image enregistrée avec succès :)"); } } void start_wifi() { WiFi.begin(ssid, password); delay(1); while(WiFi.status() != WL_CONNECTED) { delay(500); Serial.println("On attend la connection wifi..."); yield(); // Pour éviter que le watchdog ne fasse redémarrer la carte. } Serial.println(""); Serial.println("WiFi connecté"); Serial.println(WiFi.localIP()); wifi_status = true; } void end_wifi() { WiFi.disconnect(); delay(1); WiFi.mode(WIFI_OFF); delay(1); while(WiFi.status() == WL_CONNECTED) { delay(500); Serial.println("On attend la déconnection du wifi"); yield(); } Serial.println("WiFi déconnecté"); } // Allumer le flash void lights_on() { digitalWrite(led_pin, HIGH); } // Éteindre le flash void lights_off() { digitalWrite(led_pin, LOW); } // Arrosage void watering() { for(int i=0; i<NB_CYCLE_WATERING; ++i) { Serial.print(" -> Cycle numero "); Serial.println(i); relay_state = HIGH; digitalWrite(relay_pin, relay_state); // On arrose ! delay(WATERING_TIME); relay_state = !relay_state; digitalWrite(relay_pin, relay_state); // On éteint l'arrosage delay(TIME_BTWN_WATERING); // On attend un peu que l'eau pénetre dans la terre } } void setup() { Serial.begin(115200); pinMode(moist_pin, INPUT); pinMode(relay_pin, OUTPUT); pinMode(led_pin, OUTPUT); digitalWrite(relay_pin, relay_state); digitalWrite(led_pin, led_state); init_camera(); lights_off(); reg_b = READ_PERI_REG(SENS_SAR_READ_CTRL2_REG); delay(2000); // Pour s'assurer que tout est bien initialisé (capteurs, wifi, etc..) } void loop() { int v_moist = alt_analogRead(moist_pin); Serial.print("Taux d'humidité de la terre : "); Serial.println(v_moist); if(v_moist <= MAX_MOIST_VAL) { // tres mouillé Serial.print("C'est mouillé ! on va faire dodo pendant "); Serial.print(SLEEPING_TIME); Serial.println(" milli-secondes"); delay(SLEEPING_TIME); } else if(v_moist >= MIN_MOIST_VAL) { // tres sec start_wifi(); lights_on(); take_a_picture(); lights_off(); send_a_picture(); end_wifi(); watering(); Serial.println("Arrosage terminé"); delay(2000); } }