/* L'ESP32-CAM prend une photo et l'enregistre sur Google Drive. Basé sur le sketch de Guillermo Sampallo: https://github.com/gsampallo/esp32cam-gdrive Plus d'informations: https://electroniqueamateur.blogspot.com/2020/05/enregistrement-sur-google-drive-des.html */ #include "esp_camera.h" #include #include const char* ssid = "**********"; // nom du réseau Wifi const char* password = "**********"; // mot de passe du réseau Wifi // à remplacer par l'url de votre Google Apps Script: String urlScript = "/macros/s/*******************/exec"; const int delaiImage = 60000; // nombre de millisecondes entre 2 enregistrements succesifs const int delaiReponse = 30000; // nombre de millisecondes max d'attente pour la réponse de Google const char* host = "script.google.com"; String nomFichier = "filename=ESP32-CAM.jpg"; String mimeType = "&mimetype=image/jpeg"; String monImage = "&data="; void setup() { Serial.begin(115200); delay(10); WiFi.mode(WIFI_STA); Serial.println(""); Serial.print("Connexion a "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(500); } Serial.println(""); Serial.println("Adresse IP: "); Serial.println(WiFi.localIP()); Serial.println(""); camera_config_t config; config.ledc_channel = LEDC_CHANNEL_0; config.ledc_timer = LEDC_TIMER_0; config.pin_d0 = 5; config.pin_d1 = 18; config.pin_d2 = 19; config.pin_d3 = 21; config.pin_d4 = 36; config.pin_d5 = 39; config.pin_d6 = 34; config.pin_d7 = 35; config.pin_xclk = 0; config.pin_pclk = 22; config.pin_vsync = 25; config.pin_href = 23; config.pin_sscb_sda = 26; config.pin_sscb_scl = 27; config.pin_pwdn = 32; config.pin_reset = -1; config.xclk_freq_hz = 20000000; config.pixel_format = PIXFORMAT_JPEG; config.frame_size = FRAMESIZE_VGA; // UXGA|SXGA|XGA|SVGA|VGA|CIF|QVGA|HQVGA|QQVGA config.jpeg_quality = 10; config.fb_count = 1; esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { Serial.printf("Echec de l'initialisation 0x%x", err); delay(1000); ESP.restart(); } } void loop() { enregistreImage(); delay(delaiImage); } void enregistreImage() { Serial.println("Connexion a " + String(host)); WiFiClientSecure client; if (client.connect(host, 443)) { Serial.println("Connection reussie"); camera_fb_t * fb = NULL; fb = esp_camera_fb_get(); if (!fb) { Serial.println("Echec de la prise de photo "); delay(1000); ESP.restart(); return; } char *input = (char *)fb->buf; char output[base64_enc_len(3)]; String imageFile = ""; for (int i = 0; i < fb->len; i++) { base64_encode(output, (input++), 3); if (i % 3 == 0) imageFile += urlencode(String(output)); } String Data = nomFichier + mimeType + monImage; esp_camera_fb_return(fb); Serial.println("Image envoyee a Google Drive."); client.println("POST " + urlScript + " HTTP/1.1"); client.println("Host: " + String(host)); client.println("Content-Length: " + String(Data.length() + imageFile.length())); client.println("Content-Type: application/x-www-form-urlencoded"); client.println(); client.print(Data); int Index; for (Index = 0; Index < imageFile.length(); Index = Index + 1000) { client.print(imageFile.substring(Index, Index + 1000)); } Serial.println("Attente de la reponse."); long int StartTime = millis(); while (!client.available()) { Serial.print("."); delay(100); if ((StartTime + waitingTime) < millis()) { Serial.println(); Serial.println("Pas de reponse."); break; } } Serial.println(); while (client.available()) { Serial.print(char(client.read())); } } else { Serial.println("Echec de la connexion a " + String(host) + "."); } client.stop(); } /************** Encodage de l'url *******************************/ // urlencode sert à remplacer les caractères indésirables // dans une url (par exemple, remplacer un espace par %20`) //https://github.com/zenmanenergy/ESP8266-Arduino-Examples/ String urlencode(String str) { String encodedString = ""; char c; char code0; char code1; char code2; for (int i = 0; i < str.length(); i++) { c = str.charAt(i); if (c == ' ') { encodedString += '+'; } else if (isalnum(c)) { encodedString += c; } else { code1 = (c & 0xf) + '0'; if ((c & 0xf) > 9) { code1 = (c & 0xf) - 10 + 'A'; } c = (c >> 4) & 0xf; code0 = c + '0'; if (c > 9) { code0 = c - 10 + 'A'; } code2 = '\0'; encodedString += '%'; encodedString += code0; encodedString += code1; } yield(); } return encodedString; } // *************** Encodage de l'image en base64 ************************* //Copyright (c) 2013 Adam Rudd. //https://github.com/adamvr/arduino-base64 const char PROGMEM b64_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; int base64_encode(char *output, char *input, int inputLen) { int i = 0, j = 0; int encLen = 0; unsigned char a3[3]; unsigned char a4[4]; while (inputLen--) { a3[i++] = *(input++); if (i == 3) { a3_to_a4(a4, a3); for (i = 0; i < 4; i++) { output[encLen++] = pgm_read_byte(&b64_alphabet[a4[i]]); } i = 0; } } if (i) { for (j = i; j < 3; j++) { a3[j] = '\0'; } a3_to_a4(a4, a3); for (j = 0; j < i + 1; j++) { output[encLen++] = pgm_read_byte(&b64_alphabet[a4[j]]); } while ((i++ < 3)) { output[encLen++] = '='; } } output[encLen] = '\0'; return encLen; } int base64_enc_len(int plainLen) { int n = plainLen; return (n + 2 - ((n + 2) % 3)) / 3 * 4; } inline void a3_to_a4(unsigned char * a4, unsigned char * a3) { a4[0] = (a3[0] & 0xfc) >> 2; a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4); a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6); a4[3] = (a3[2] & 0x3f); }