start:arduino:esp32:camsd
Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
start:arduino:esp32:camsd [2021/10/15 11:57] – gerardadmin | start:arduino:esp32:camsd [2023/01/27 16:08] (Version actuelle) – modification externe 127.0.0.1 | ||
---|---|---|---|
Ligne 353: | Ligne 353: | ||
} | } | ||
</ | </ | ||
+ | |||
+ | ==== Esp32 cam Serveur ==== | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | <code c Esp32CamServeur001.ino> | ||
+ | /********* | ||
+ | Rui Santos | ||
+ | Complete project details at https:// | ||
+ | | ||
+ | IMPORTANT!!! | ||
+ | - Select Board "AI Thinker ESP32-CAM" | ||
+ | - GPIO 0 must be connected to GND to upload a sketch | ||
+ | - After connecting GPIO 0 to GND, press the ESP32-CAM on-board RESET button to put your board in flashing mode | ||
+ | | ||
+ | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
+ | of this software and associated documentation files. | ||
+ | |||
+ | The above copyright notice and this permission notice shall be included in all | ||
+ | copies or substantial portions of the Software. | ||
+ | *********/ | ||
+ | |||
+ | #include " | ||
+ | #include < | ||
+ | #include " | ||
+ | #include " | ||
+ | #include " | ||
+ | #include " | ||
+ | #include " | ||
+ | #include " | ||
+ | #include " | ||
+ | |||
+ | //Replace with your network credentials | ||
+ | const char* ssid = " | ||
+ | const char* password = " | ||
+ | |||
+ | #define PART_BOUNDARY " | ||
+ | |||
+ | // This project was tested with the AI Thinker Model, M5STACK PSRAM Model and M5STACK WITHOUT PSRAM | ||
+ | #define CAMERA_MODEL_AI_THINKER | ||
+ | //#define CAMERA_MODEL_M5STACK_PSRAM | ||
+ | //#define CAMERA_MODEL_M5STACK_WITHOUT_PSRAM | ||
+ | |||
+ | // Not tested with this model | ||
+ | //#define CAMERA_MODEL_WROVER_KIT | ||
+ | |||
+ | #if defined(CAMERA_MODEL_WROVER_KIT) | ||
+ | #define PWDN_GPIO_NUM | ||
+ | #define RESET_GPIO_NUM | ||
+ | #define XCLK_GPIO_NUM | ||
+ | #define SIOD_GPIO_NUM | ||
+ | #define SIOC_GPIO_NUM | ||
+ | | ||
+ | #define Y9_GPIO_NUM | ||
+ | #define Y8_GPIO_NUM | ||
+ | #define Y7_GPIO_NUM | ||
+ | #define Y6_GPIO_NUM | ||
+ | #define Y5_GPIO_NUM | ||
+ | #define Y4_GPIO_NUM | ||
+ | #define Y3_GPIO_NUM | ||
+ | #define Y2_GPIO_NUM | ||
+ | #define VSYNC_GPIO_NUM | ||
+ | #define HREF_GPIO_NUM | ||
+ | #define PCLK_GPIO_NUM | ||
+ | |||
+ | #elif defined(CAMERA_MODEL_M5STACK_PSRAM) | ||
+ | #define PWDN_GPIO_NUM | ||
+ | #define RESET_GPIO_NUM | ||
+ | #define XCLK_GPIO_NUM | ||
+ | #define SIOD_GPIO_NUM | ||
+ | #define SIOC_GPIO_NUM | ||
+ | | ||
+ | #define Y9_GPIO_NUM | ||
+ | #define Y8_GPIO_NUM | ||
+ | #define Y7_GPIO_NUM | ||
+ | #define Y6_GPIO_NUM | ||
+ | #define Y5_GPIO_NUM | ||
+ | #define Y4_GPIO_NUM | ||
+ | #define Y3_GPIO_NUM | ||
+ | #define Y2_GPIO_NUM | ||
+ | #define VSYNC_GPIO_NUM | ||
+ | #define HREF_GPIO_NUM | ||
+ | #define PCLK_GPIO_NUM | ||
+ | |||
+ | #elif defined(CAMERA_MODEL_M5STACK_WITHOUT_PSRAM) | ||
+ | #define PWDN_GPIO_NUM | ||
+ | #define RESET_GPIO_NUM | ||
+ | #define XCLK_GPIO_NUM | ||
+ | #define SIOD_GPIO_NUM | ||
+ | #define SIOC_GPIO_NUM | ||
+ | | ||
+ | #define Y9_GPIO_NUM | ||
+ | #define Y8_GPIO_NUM | ||
+ | #define Y7_GPIO_NUM | ||
+ | #define Y6_GPIO_NUM | ||
+ | #define Y5_GPIO_NUM | ||
+ | #define Y4_GPIO_NUM | ||
+ | #define Y3_GPIO_NUM | ||
+ | #define Y2_GPIO_NUM | ||
+ | #define VSYNC_GPIO_NUM | ||
+ | #define HREF_GPIO_NUM | ||
+ | #define PCLK_GPIO_NUM | ||
+ | |||
+ | #elif defined(CAMERA_MODEL_AI_THINKER) | ||
+ | #define PWDN_GPIO_NUM | ||
+ | #define RESET_GPIO_NUM | ||
+ | #define XCLK_GPIO_NUM | ||
+ | #define SIOD_GPIO_NUM | ||
+ | #define SIOC_GPIO_NUM | ||
+ | | ||
+ | #define Y9_GPIO_NUM | ||
+ | #define Y8_GPIO_NUM | ||
+ | #define Y7_GPIO_NUM | ||
+ | #define Y6_GPIO_NUM | ||
+ | #define Y5_GPIO_NUM | ||
+ | #define Y4_GPIO_NUM | ||
+ | #define Y3_GPIO_NUM | ||
+ | #define Y2_GPIO_NUM | ||
+ | #define VSYNC_GPIO_NUM | ||
+ | #define HREF_GPIO_NUM | ||
+ | #define PCLK_GPIO_NUM | ||
+ | #else | ||
+ | #error " | ||
+ | #endif | ||
+ | |||
+ | static const char* _STREAM_CONTENT_TYPE = " | ||
+ | static const char* _STREAM_BOUNDARY = " | ||
+ | static const char* _STREAM_PART = " | ||
+ | |||
+ | httpd_handle_t stream_httpd = NULL; | ||
+ | |||
+ | static esp_err_t stream_handler(httpd_req_t *req){ | ||
+ | camera_fb_t * fb = NULL; | ||
+ | esp_err_t res = ESP_OK; | ||
+ | size_t _jpg_buf_len = 0; | ||
+ | uint8_t * _jpg_buf = NULL; | ||
+ | char * part_buf[64]; | ||
+ | |||
+ | res = httpd_resp_set_type(req, | ||
+ | if(res != ESP_OK){ | ||
+ | return res; | ||
+ | } | ||
+ | |||
+ | while(true){ | ||
+ | fb = esp_camera_fb_get(); | ||
+ | if (!fb) { | ||
+ | Serial.println(" | ||
+ | res = ESP_FAIL; | ||
+ | } else { | ||
+ | if(fb-> | ||
+ | if(fb-> | ||
+ | bool jpeg_converted = frame2jpg(fb, | ||
+ | esp_camera_fb_return(fb); | ||
+ | fb = NULL; | ||
+ | if(!jpeg_converted){ | ||
+ | Serial.println(" | ||
+ | res = ESP_FAIL; | ||
+ | } | ||
+ | } else { | ||
+ | _jpg_buf_len = fb->len; | ||
+ | _jpg_buf = fb->buf; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | if(res == ESP_OK){ | ||
+ | size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, | ||
+ | res = httpd_resp_send_chunk(req, | ||
+ | } | ||
+ | if(res == ESP_OK){ | ||
+ | res = httpd_resp_send_chunk(req, | ||
+ | } | ||
+ | if(res == ESP_OK){ | ||
+ | res = httpd_resp_send_chunk(req, | ||
+ | } | ||
+ | if(fb){ | ||
+ | esp_camera_fb_return(fb); | ||
+ | fb = NULL; | ||
+ | _jpg_buf = NULL; | ||
+ | } else if(_jpg_buf){ | ||
+ | free(_jpg_buf); | ||
+ | _jpg_buf = NULL; | ||
+ | } | ||
+ | if(res != ESP_OK){ | ||
+ | break; | ||
+ | } | ||
+ | // | ||
+ | } | ||
+ | return res; | ||
+ | } | ||
+ | |||
+ | void startCameraServer(){ | ||
+ | httpd_config_t config = HTTPD_DEFAULT_CONFIG(); | ||
+ | config.server_port = 80; | ||
+ | |||
+ | httpd_uri_t index_uri = { | ||
+ | .uri = "/", | ||
+ | .method | ||
+ | .handler | ||
+ | .user_ctx | ||
+ | }; | ||
+ | | ||
+ | // | ||
+ | if (httpd_start(& | ||
+ | httpd_register_uri_handler(stream_httpd, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void setup() { | ||
+ | WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, | ||
+ | |||
+ | Serial.begin(115200); | ||
+ | Serial.setDebugOutput(false); | ||
+ | | ||
+ | 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; | ||
+ | } | ||
+ | | ||
+ | // Camera init | ||
+ | esp_err_t err = esp_camera_init(& | ||
+ | if (err != ESP_OK) { | ||
+ | Serial.printf(" | ||
+ | return; | ||
+ | } | ||
+ | // Wi-Fi connection | ||
+ | WiFi.begin(ssid, | ||
+ | while (WiFi.status() != WL_CONNECTED) { | ||
+ | delay(500); | ||
+ | Serial.print(" | ||
+ | } | ||
+ | Serial.println("" | ||
+ | Serial.println(" | ||
+ | | ||
+ | Serial.print(" | ||
+ | Serial.print(WiFi.localIP()); | ||
+ | | ||
+ | // Start streaming web server | ||
+ | startCameraServer(); | ||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | delay(1); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== ESP32 CAm et Photos ---> sur Google Drive ==== | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | <code txt script googledrive.txt> | ||
+ | // Enregistrement sur Google Drive d'une image prise par l' | ||
+ | // trouvé ici: https:// | ||
+ | |||
+ | function doPost(e) { | ||
+ | // décodage des données reçues en base64 | ||
+ | var data = Utilities.base64Decode(e.parameters.data); | ||
+ | // création d'un nom de fichier à partir de la date et de l' | ||
+ | var nomFichier = Utilities.formatDate(new Date(), " | ||
+ | // création d'un blob (binary large object) à partir des données reçues | ||
+ | var blob = Utilities.newBlob(data, | ||
+ | // Dans Google Drive, on récupère tous les répertoires nommés " | ||
+ | var folder, folders = DriveApp.getFoldersByName(" | ||
+ | if (folders.hasNext()) { // s'il y en a | ||
+ | folder = folders.next(); | ||
+ | } else { // s'il n'y en a pas | ||
+ | folder = DriveApp.createFolder(" | ||
+ | } | ||
+ | var file = folder.createFile(blob); | ||
+ | return ContentService.createTextOutput(' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <code c esp32camPhotosDrive001.ino > | ||
+ | /* | ||
+ | | ||
+ | |||
+ | Basé sur le sketch de Guillermo Sampallo: | ||
+ | | ||
+ | |||
+ | Plus d' | ||
+ | |||
+ | | ||
+ | |||
+ | */ | ||
+ | |||
+ | #include " | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | const char* ssid = " | ||
+ | const char* password = " | ||
+ | // à remplacer par l'url de votre Google Apps Script: | ||
+ | String urlScript = "/ | ||
+ | |||
+ | const int delaiImage = 60000; // nombre de millisecondes entre 2 enregistrements succesifs | ||
+ | const int delaiReponse = 30000; // nombre de millisecondes max d' | ||
+ | |||
+ | const char* host = " | ||
+ | String nomFichier = " | ||
+ | String mimeType = "& | ||
+ | String monImage = "& | ||
+ | |||
+ | void setup() | ||
+ | { | ||
+ | Serial.begin(115200); | ||
+ | delay(10); | ||
+ | |||
+ | WiFi.mode(WIFI_STA); | ||
+ | |||
+ | Serial.println("" | ||
+ | Serial.print(" | ||
+ | Serial.println(ssid); | ||
+ | WiFi.begin(ssid, | ||
+ | |||
+ | while (WiFi.status() != WL_CONNECTED) { | ||
+ | Serial.print(" | ||
+ | delay(500); | ||
+ | } | ||
+ | |||
+ | Serial.println("" | ||
+ | Serial.println(" | ||
+ | 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; | ||
+ | config.jpeg_quality = 10; | ||
+ | config.fb_count = 1; | ||
+ | |||
+ | esp_err_t err = esp_camera_init(& | ||
+ | if (err != ESP_OK) { | ||
+ | Serial.printf(" | ||
+ | delay(1000); | ||
+ | ESP.restart(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | enregistreImage(); | ||
+ | delay(delaiImage); | ||
+ | } | ||
+ | |||
+ | void enregistreImage() { | ||
+ | Serial.println(" | ||
+ | |||
+ | WiFiClientSecure client; | ||
+ | |||
+ | if (client.connect(host, | ||
+ | Serial.println(" | ||
+ | |||
+ | camera_fb_t * fb = NULL; | ||
+ | fb = esp_camera_fb_get(); | ||
+ | if (!fb) { | ||
+ | Serial.println(" | ||
+ | delay(1000); | ||
+ | ESP.restart(); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | char *input = (char *)fb-> | ||
+ | char output[base64_enc_len(3)]; | ||
+ | String imageFile = ""; | ||
+ | for (int i = 0; i < fb->len; i++) { | ||
+ | base64_encode(output, | ||
+ | if (i % 3 == 0) imageFile += urlencode(String(output)); | ||
+ | } | ||
+ | String Data = nomFichier + mimeType + monImage; | ||
+ | |||
+ | esp_camera_fb_return(fb); | ||
+ | |||
+ | Serial.println(" | ||
+ | |||
+ | client.println(" | ||
+ | client.println(" | ||
+ | client.println(" | ||
+ | client.println(" | ||
+ | client.println(); | ||
+ | client.print(Data); | ||
+ | int Index; | ||
+ | for (Index = 0; Index < imageFile.length(); | ||
+ | client.print(imageFile.substring(Index, | ||
+ | } | ||
+ | |||
+ | Serial.println(" | ||
+ | long int StartTime = millis(); | ||
+ | while (!client.available()) { | ||
+ | Serial.print(" | ||
+ | delay(100); | ||
+ | if ((StartTime + waitingTime) < millis()) { | ||
+ | Serial.println(); | ||
+ | Serial.println(" | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | Serial.println(); | ||
+ | while (client.available()) { | ||
+ | Serial.print(char(client.read())); | ||
+ | } | ||
+ | } else { | ||
+ | Serial.println(" | ||
+ | } | ||
+ | client.stop(); | ||
+ | } | ||
+ | |||
+ | / | ||
+ | |||
+ | // urlencode sert à remplacer les caractères indésirables | ||
+ | // dans une url (par exemple, remplacer un espace par %20`) | ||
+ | |||
+ | // | ||
+ | String urlencode(String str) | ||
+ | { | ||
+ | String encodedString = ""; | ||
+ | char c; | ||
+ | char code0; | ||
+ | char code1; | ||
+ | char code2; | ||
+ | for (int i = 0; i < str.length(); | ||
+ | c = str.charAt(i); | ||
+ | if (c == ' ') { | ||
+ | encodedString += ' | ||
+ | } else if (isalnum(c)) { | ||
+ | encodedString += c; | ||
+ | } else { | ||
+ | code1 = (c & 0xf) + ' | ||
+ | if ((c & 0xf) > 9) { | ||
+ | code1 = (c & 0xf) - 10 + ' | ||
+ | } | ||
+ | c = (c >> 4) & 0xf; | ||
+ | code0 = c + ' | ||
+ | if (c > 9) { | ||
+ | code0 = c - 10 + ' | ||
+ | } | ||
+ | code2 = ' | ||
+ | encodedString += ' | ||
+ | encodedString += code0; | ||
+ | encodedString += code1; | ||
+ | } | ||
+ | yield(); | ||
+ | } | ||
+ | return encodedString; | ||
+ | } | ||
+ | |||
+ | |||
+ | // *************** Encodage de l' | ||
+ | //Copyright (c) 2013 Adam Rudd. | ||
+ | // | ||
+ | |||
+ | const char PROGMEM b64_alphabet[] = " | ||
+ | " | ||
+ | " | ||
+ | |||
+ | 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, | ||
+ | |||
+ | for (i = 0; i < 4; i++) { | ||
+ | output[encLen++] = pgm_read_byte(& | ||
+ | } | ||
+ | i = 0; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | if (i) { | ||
+ | for (j = i; j < 3; j++) { | ||
+ | a3[j] = ' | ||
+ | } | ||
+ | |||
+ | a3_to_a4(a4, | ||
+ | |||
+ | for (j = 0; j < i + 1; j++) { | ||
+ | output[encLen++] = pgm_read_byte(& | ||
+ | } | ||
+ | |||
+ | while ((i++ < 3)) { | ||
+ | output[encLen++] = ' | ||
+ | } | ||
+ | } | ||
+ | output[encLen] = ' | ||
+ | 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); | ||
+ | } | ||
+ | </ | ||
+ |
/home/chanteri/www/fablab37110/data/attic/start/arduino/esp32/camsd.1634291824.txt.gz · Dernière modification : 2023/01/27 16:08 (modification externe)