Tire fotos com ESP32 CAM e armazene no Google Drive 2

Neste tutorial você verá como é possível tirar fotos com ESP32-CAM e armazenar essas imagens no Google Drive.

Figura 1 – ESP32 CAM e Conversor USB

Hoje existem diversas câmeras espalhadas pelo mundo, tornando-o mais seguro por um lado e menos privado por outro. Com o avanço da tecnologia e a chegada das placas de desenvolvimento, cada vez mais podemos criar nosso próprios protótipos e desenvolver aplicações que nos trarão benefícios para nosso cotidiano.

Mas que benefício eu posso conseguir através das câmeras? Como posso criar algum projeto com câmera que traga algum beneficio ao meu cotidiano? Pois bem, através deste tutorial você conhecerá o ESP32 CAM e como é possível através dele tirar fotos para armazenar no Google Drive e verá onde você pode aplicar este tutorial a um projeto.

Se interessou? Então continue lendo!

Material necessário

Para fazer o projeto você precisará dos seguintes componentes:

Serviço Web necessário

Para fazer o carregamento das fotos utilizaremos o Google Drive.

O Google Drive é um serviço de armazenamento e sincronização de arquivos grátis até 15 GB, que oferece a edição de documentos, de apresentações, upload e download de imagens, entre outras coisas.

Funcionamento do Circuito

O circuito é composto pelo ESP32 CAM juntamente com o Conversor USB TTL. O conversor USB será utilizado apenas para fazer a gravação no ESP32 CAM. Após carregar o código para a placa é possível utilizar uma fonte externa para alimentação do ESP respeitando a tensão contínua de 5V.

Depois de carregado o código no módulo, o ESP32 CAM se conectará a uma rede WiFi e fará a captura de uma imagem e à enviará a sua conta do Google Drive repetindo esse processo de captura e envio em aproximadamente 8 a 10 segundos.

Projeto finalizado
Figura 2 – ESP32 CAM capturando imagem

Montagem do circuito

Com todos os componentes em mãos vamos à montagem do circuito. Abaixo temos o esquemático eletrônico montado em uma protoboard.

Esquemático para tirar fotos com ESP32-CAM
Figura 3 – Esquemático eletrônico

Obs.: o pino IO0 deve ser conectado ao GND apenas para carregar o código no ESP32 CAM.

Configuração do Google Drive

Após montado o circuito, vamos a configuração do Google Drive para receber as fotos que serão enviadas através do ESP32-CAM.

Primeiramente, você deve criar uma conta Google para utilizar o Google Drive, caso não tenha uma conta crie uma utilizando este link. Depois de criada a conta acesse a raiz do Google Drive como mostra a imagem abaixo adicionando o código.

No Google Drive clique com o botão direito em Meu Drive > Mais > Script do Google Apps.

No Script iremos adicionar o código para o Google Drive salvar a imagem quando recebê-la. Então apague este código function myFunction( ) e adicione o código abaixo.

function doPost(e) {
  
  var imagem = Utilities.base64Decode(e.parameters.data);//Decofica a imagem
  
  var nome_do_Arquivo = Utilities.formatDate(new Date(), "GMT-3", "dd/MM/yyyy-HH:mm:ss")+".jpg"; //Define nome da imagem com a data e o horário
  
  var salvar_imagem = Utilities.newBlob(imagem, e.parameters.mimetype, nome_do_Arquivo); 

  var pasta, pastas = DriveApp.getFoldersByName("ESP32-CAM"); //Verifica se a pasta já existe
  
  if (pastas.hasNext()) {
   
    pasta = pastas.next();
  
  } 
  else {
    
    pasta = DriveApp.createFolder("ESP32-CAM");  //Cria a pasta
  
  }
  
  var Arquivar = pasta.createFile(salvar_imagem); //Salva o arquivo na pasta
  
  return ContentService.createTextOutput('Completo')

}

Após adicionar o código no Script clique em Publicar > Implantar como aplicativo da web… e dê um nome para o projeto e clique em OK.

Depois de clicar em OK você deve selecionar a opção Anyone, even anonymous e depois clicar em Deploy.

Após clicar em Deploy aparecerá uma tela perguntando sobre a permissão em acessar sua conta, clique em Analisar permissões e depois selecione sua conta do Google.

Depois de selecionar a conta clique em Avançado e depois Acessar upload (não seguro).

Após clicar em Acessar upload clique em Permitir.

Após permitir clique em Deploy novamente aparecerá um link para fazer a comunicação com o código no Script.

Você deverá salvar este link em um bloco de notas para posteriormente usarmos ele no código que será carregado na ESP32-CAM.

Depois se salvar o link e clicar em OK você pode fechar a aba do projeto e está finalizada a parte de configuração do Google Drive. Logo você vai poder tirar fotos com ESP32-CAM!

Bibliotecas e gerenciador de placas

Após configurado o Google Drive vamos a adição de bibliotecas necessárias para o funcionamento do código e instalação da placa no IDE do Arduino. Assim, após essa última configuração, você poderá finalmente tirar fotos com ESP32-CAM.

Será necessário utilizar a biblioteca Base64.

Para usar esta biblioteca coloque os arquivos Base64.cpp e Base64.h na pasta onde tem seu código de programação para o ESP32-CAM como mostra a imagem abaixo.

Figura 5 – Pasta com o sketch e a biblioteca

Posteriormente mostraremos qual código será colocado dentro do arquivo .ino que aparece na imagem acima.

Obs.: Caso você já tenha instalado o ESP 32 na IDE do Arduino, pule esta etapa.

Na Arduino IDE vá em Arquivos > Preferências e adicione o link abaixo em “URLs Adicionais para Gerenciadores de Placas” e clique em OK.

https://dl.espressif.com/dl/package_esp32_index.json

Depois vá em Ferramentas > Placas > Gerenciador de Placas… e pesquise ESP32 e clique em instalar.

Figura 6 – Gerenciador de Placas Arduino

Após instalado a placa vá em Ferramentas > Placa e selecione a placa AI Thinker ESP32-CAM.

 

Escolhendo a placa ESP32-CAM na IDE
Figura 7 – Selecionando placa

Código

Com o circuito montado e o Google Drive configurado vamos ao código que será carregado no ESP32 CAM.

Adicione no código nas variáveis ssid e password os dados de conexão da sua rede wi-fi.

//Dados para conexão com a rede Wi-fi
const char* ssid     = "nome_da_rede";  //Insira o SSID da rede
const char* password = "senha_da_rede"; //Insira a senha da rede

Adicione no código na variável meuScript o endereço obtido na configuração do Google Drive.

//Inserir endereço gerado pelo Google Drive
String meuScript = "/macros/s/XXXXXXXXXXXXXXXXXXXXXXXXXX/exec";

Obs.: somente adicione a parte do meio do código, troque o XXXXXXXXXXXXXXXXXXXXX pelos os caracteres que adquirimos no Google Drive. Não deve ser substituído pelo link todo.

//Bibliotecas utilizadas
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "Base64.h"
#include "esp_camera.h"

//Dados para conexão com a rede Wi-fi
const char* ssid     = "nome_da_rede";  //Insira o SSID da rede
const char* password = "senha_da_rede"; //Insira a senha da rede

//Dados para conexão com o Google Drive
const char* host = "script.google.com";

//Inserir endereço gerado pelo Google Drive
String meuScript = "/macros/s/XXXXXXXXXXXXXXXXXXXXXXXX/exec"; 


//Dados para o arquivo de imagem
String nomedoArquivo = "filename=ESP32-CAM.jpg";
String mimeType = "&mimetype=image/jpeg";
String Imagem = "&data=";

int tempo_espera = 10000;  //Espera 10 segundos para o Google responder

//Definição dos pinos
#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
#define flash 4


void setup()
{
  
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
  
  Serial.begin(115200);
  delay(100);
  
  WiFi.mode(WIFI_STA);

  Serial.println("");
  Serial.print("Conectando na rede: ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);  

  while (WiFi.status() != WL_CONNECTED) {  
    Serial.print(".");
    delay(500); 
  }

  //Definindo flash da câmera
  pinMode(flash,OUTPUT);

  Serial.println("Conectado!");
  Serial.println();
  Serial.print("endereço STAIP: ");
  Serial.println(WiFi.localIP());
  Serial.println();

  //Configuração do pinos da câmera
  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;
  config.frame_size = FRAMESIZE_VGA;  
  config.jpeg_quality = 4;
  config.fb_count = 1;
  
  esp_err_t err = esp_camera_init(&config); //Inicialização da câmera
  
  if (err != ESP_OK) {
    
    Serial.printf("O início da câmera falhou com erro 0x%x", err);//Informa erro se a câmera não for iniciada corretamente
    delay(1000);
    ESP.restart();//Reinicia o ESP
    
  }
  
}

void loop() {
  
  Captura_Imagem(); //Captura e envia imagem
  
  delay(1000);
  
}

void Captura_Imagem() {
  
  Serial.println("Conectando ao " + String(host));
  
  WiFiClientSecure client;
  
  if (client.connect(host, 443)) { //Conectando no Google
    
    Serial.println("Conexão com sucesso!");
    
    camera_fb_t * fb = NULL;
    
    digitalWrite(flash,HIGH);
    delay(100);
    
    fb = esp_camera_fb_get(); //Função que captura imagem na ESP
    
    digitalWrite(flash,LOW);
    delay(100);
    
    if(!fb) {
      
      Serial.println("Falha ao capturar imagem!");
      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 = nomedoArquivo+mimeType+Imagem;
    
    esp_camera_fb_return(fb); 
    
    Serial.println("Enviando imagem capturada ao Google Drive.");
    
    client.println("POST " + meuScript + " 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("Aguardando resposta."); 
    
    long int tempo_inicio = millis();
    
    while (!client.available()) { //Aguarda resposta do envio da imagem
      Serial.print(".");
      delay(100);
      if ((tempo_inicio+tempo_espera) < millis()) {
        Serial.println();
        Serial.println("Sem Resposta.");
        break;
      }
    }
    
    Serial.println();   
    
    while (client.available()) {
      Serial.print(char(client.read())); //Mostra na tela a resposta
    }  
  } else {         
    Serial.println("Conexão ao " + String(host) + " falhada.");
  }
  client.stop();
}


String urlencode(String str)  //Função de codificação
{
    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;
}

Após adicionar o código no seu sketch que está na pasta junto com a Base64.cpp e Base64.h salve e feche seu sketch e abra-o novamente. Assim que abrir seu projeto novamente aparecerão a Base64.cpp e Base64.h da seguinte forma como mostra a imagem abaixo.

Bibliotecas para tirar fotos com ESP32-CAM
Figura 8 – bibliotecas referenciadas

Carregando o código no ESP32 – CAM

Para carregar o código no ESP32-CAM certifique-se que o pino IO0 está conectado ao GND. Então conecte o cabo do conversor no computador e selecione a porta COM que aparecerá na IDE do arduino em Ferramentas > Porta.

Após isso faça o upload do código e quando aparecer “Connecting…” aperte o botão RST que se encontra embaixo do ESP32-CAM.

Figura 9 – bibliotecas referenciadas

Se aparecer esta imagem significa que o código foi carregado com sucesso.

Figura 10 – código carregado

Depois de carregado o código desconecte o pino IO0 do GND e aperte o botão RST novamente, isso fará com que seu código comece a rodar no ESP32-CAM.

Depois de alguns segundos você verá no seu Google Drive as imagens chegando.

FOTOS do ESP32-CAM no GDrive
Figura 11 – Imagens carregadas no Google Drive

Conclusão

Bom no inicio do tutorial comentamos que onde seria possível aplicar este tutorial a um projeto. Uma ótima aplicação seria construir um Olho Mágico Smart, imagine que alguém chegue na sua casa e aperte a campainha e o ESP32-CAM dispare uma foto e envie uma notificação no seu smartphone ou até mesmo no seu smartwatch juntamente com o arquivo de imagem.

Seria um benefício ótimo não é? Utilize seus conhecimentos e tente criar este projeto e compartilhe conosco. Veja o vídeo de demonstração abaixo:

Obs: A notificação em relação ao smartwatch pode variar de acordo com a compatibilidade do mesmo. Você deve verificar como funciona o sistema de notificação do seu dispositivo e se há suporte.

Gostou de aprender como tirar fotos com o ESP32-CAM? Deixe seu comentário logo abaixo. Para saber mais sobre o mundo maker, arduino entre outros dispositivos acesse o blog.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

2 Comentários

  1. OI! Comprei recentemente uma espcam e resolvi testar o código, porém está aparecendo esse erro:
    [E][camera.c:1049] camera_probe(): Detected camera not supported.
    [E][camera.c:1249] esp_camera_init(): Camera probe failed with error 0x20004

    Pelo que entendi, conectou certinho na rede, mas a camera não captura a imagem. Será que veio com defeito?

    1. Boa tarde Erika obrigado pela leitura, creio que deve ser má conexão do cabo flat, pois tive esse problema também…sugiro a você que tire o cabo flat da câmera e conecte novamente com cuidado para não danificar o equipamento, isso deve resolver o problema.

      Felipe Santos do Nascimento