Minha Bancada

Conteúdos, Práticas e Experimentações em Eletrônica

Total de Visitas: 167
Principal Conteúdos Projetos Turmas Sobre

Servidor de Streaming em ESP32CAM

Seção 1


Introdução

18/OUT/2021

Comprei recentemente, em um site estrangeiro, o módulo ESP32 CAM AI-THINKER. Após muitos meses, o módulo finalmente chegou, e fui pô-lo para funcionar. Usei os inúmeros tutoriais disponíveis na Internet e tive muita dificuldade. Após muita luta, consegui fazê-lo funcionar e vou resumir alguns pontos importantes.

  1. Não vale a pena comprá-lo no exterior. Antes de comprá-lo, busquei opções por aqui e não encontrei nenhuma. Hoje a situação mudou e o mesmo módulo está disponível no Brasil, a preços muito baixos (e até inferiores aos USD 12 que paguei).
  2. Uma das coisas que priorizei foi a compra do módulo original AI THINKER. Infelizmente, chegou algo parecido. Ou seja, é o que é, e você tem que conviver com isso.
  3. Muitos dos módulos que acabam chegando não são grandes coisa do ponto de vista de fabricação e com certeza deve vir muita porcaria... Por outro lado, pelo preço, dá até pra imaginar que se a taxa de refugo não for muito alta, uma compra em larga escala seria muito vantajosa, principalmente para quem pretende utilizar o módulo para fins comerciais. De fato, durante a minha pesquisa, “topei” com diversas pessoas que pensavam em se aproveitar desse custo baixo para implementar alguma aplicação “industrializável”... E todos temos de concordar que o preço de USD 12 parece bem razoável para um módulo microprocessado, com uma câmera UXGA, WiFi, soquete microSD, capaz de fotografar, fazer streaming de vídeo e reconhecer faces. Está lançado o desafio para os desenvolvedores nacionais: que façam um módulo semelhante, melhor e a um preço ainda mais baixo!
  4. Pode ser que você tenha sorte e tudo funcione de primeira... mas pode ser que você tenha azar e dê um trabalhão danado... e é aí que está a graça 😊

Existem zilhões de tutoriais e instruções sobre como utilizar o módulo ESP32-CAM e eu não tenho nenhuma expectativa em gerar um conteúdo completo ou definitivo sobre o tema. Ao contrário, apenas quero compartilhar o resultado da minha pesquisa, que foi grande e trabalhosa. Assim, talvez ajude a outras pessoas que queiram tentar utilizar esse módulo.

Alguns sítios que me ajudaram a começar foram:

Então vamos ao que interessa.

Seção 2


Módulo ESP32-CAM

O módulo ESP32-CAM foi desenvolvido pela empresa AI-Thinker, de Shenzen, China, e utiliza o chip ESP32 desenvolvido pela empresa Espressif, de Shanghai, China. Apesar disso, o módulo parece possuir diversos “clones”, que podem ou não seguir o mesmo padrão de implementação e qualidade de seu fabricante original.

A seguir, mostro algumas características que podem ser encontradas no próprio sítio da AI-Thinker, fabricante da placa.

Características:

Aplicações:

Pinagem da placa:

Pinout


Algumas recomendações do fabricante:

  1. Please make sure that the input power of the module is at least 5V 2A, otherwise the picture may have water lines.
  2. The ESP32 GPIO32 pin controls the camera power. When the camera is working, please pull GPIO32 low.
  3. Since IO0 is connected to the camera XCLK, please leave IO0 in the air when using it, and do not connect it to high or low level.
  4. The default firmware is already included in the factory, and no additional download is provided. Please be careful if you need to re-burn other firmware.

Diagrama Esquemático da Placa

Esquematico


Mais informações podem ser obtidas ainda no GitHub

Seção 3


Programação do Módulo ESP32-CAM

O módulo pode ser programado com a IDE do Arduino. Para isso é necessário adicionar esta placa a IDE. Isto é feito em duas etapas:

  1. Deve-se adicionar o módulo da Espressif como gerenciador de placas na IDE do Arduino. Isso é feito em Arquivo > Preferências. Lá, deve-se incluir a URL da Espressif. Esta URL (https://dl.espressif.com/dl/package_esp32_index.json) deve ser separada, por vírgulas, de outras URLs eventualmente já adicionadas. Preferencias


  2. Deve-se instalar as placas Espressif. Isto é feito em Ferramentas > Placa: “xxxx” > Gerenciador de Placas...
  3. Gerenciador de Placas


Procure a Seção ESP32 e instale o módulo. Terminada a instalação, a IDE passa a contar com diversos sketchs de exemplo. Um ponto de partida é o sketch encontrado em Arquivo > Exemplos > ESP32 > Camera > CameraWebServer, listado abaixo.


				#include "esp_camera.h"
				#include 
				
				//
				// WARNING!!! PSRAM IC required for UXGA resolution and high JPEG quality
				//            Ensure ESP32 Wrover Module or other board with PSRAM is selected
				//            Partial images will be transmitted if image exceeds buffer size
				//
				
				// Select camera model
				#define CAMERA_MODEL_WROVER_KIT // Has PSRAM
				//#define CAMERA_MODEL_ESP_EYE // Has PSRAM
				//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM
				//#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has 
				//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM
				//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM
				//#define CAMERA_MODEL_AI_THINKER // Has PSRAM
				//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM
				
				#include "camera_pins.h"
				
				const char* ssid = "*********";
							const char* password = "*********";
				
				void startCameraServer();
				
				void setup() {
				  Serial.begin(115200);
				  Serial.setDebugOutput(true);
				  Serial.println();
				
				  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 PSRAM IC present, init with UXGA resolution and higher JPEG quality
				  //                      for larger pre-allocated frame buffer.
				  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;
				  }

				#if defined(CAMERA_MODEL_ESP_EYE)
				  pinMode(13, INPUT_PULLUP);
				  pinMode(14, INPUT_PULLUP);
				#endif
				
				  // camera init
				  esp_err_t err = esp_camera_init(&config);
				  if (err != ESP_OK) {
					Serial.printf("Camera init failed with error 0x%x", err);
					return;
				  }
				
				  sensor_t * s = esp_camera_sensor_get();
				  // initial sensors are flipped vertically and colors are a bit saturated
				  if (s->id.PID == OV3660_PID) {
					s->set_vflip(s, 1); // flip it back
					s->set_brightness(s, 1); // up the brightness just a bit
					s->set_saturation(s, -2); // lower the saturation
				  }
				  // drop down frame size for higher initial frame rate
				  s->set_framesize(s, FRAMESIZE_QVGA);
				
				#if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM)
				  s->set_vflip(s, 1);
				  s->set_hmirror(s, 1);
				#endif
				
				  WiFi.begin(ssid, password);
				
				  while (WiFi.status() != WL_CONNECTED) {
					delay(500);
					Serial.print(".");
				  }
				  Serial.println("");
				  Serial.println("WiFi connected");
				
				  startCameraServer();
				
				  Serial.print("Camera Ready! Use 'http://");
				  Serial.print(WiFi.localIP());
				  Serial.println("' to connect");
				}
				
				void loop() {
				  // put your main code here, to run repeatedly:
				  delay(10000);
				}
				

Estou planejando um post explicando em detalhes esse programa. Mas, por enquanto, ainda vai demorar um pouco 😊

Seção 4


Comunicação com placa ESP32-CAM

Como a placa ESP32-CAM não possui uma porta USB, a transferência do programa deve ser feita de forma indireta. A grande maioria dos sítios menciona a necessidade de um módulo conversor USB para RS232. Até o momento não consegui fazer o processo funcionar com esse módulo... e agora sei que ele é totalmente desnecessário, já que a transmissão pode ser feita com o próprio Arduino.

Aqui, faz-se necessário efetuar algumas conexões específicas, mostradas no diagrama em blocos a seguir:

Hw


Algumas observações importantes:

Com as conexões efetuadas, deve-se preparar a transmissão na IDE do Arduino. Para isso:

Essas opções de comunicação também merecem um post específico, que vai ficar para outra ocasião.

Com as conexões preparadas e a IDE configurada, basta realizar o upload de forma normal, como se fosse o envio de um sketch para o Arduino. Não é necessário fazer nada além de enviar o programa. Após um tempo, a IDE vai mostrar a mensagem:


				Leaving...
				Hard resetting via RTS pin...
				

Isto significa que o programa foi transferido com sucesso. Assim deve-se:

O monitor serial vai mostrar todo o processo de inicialização e, ao final, indicar a URL do servidor de streaming:

Monitor Serial


Conhecido o endereço IP, pode-se acessá-lo a partir de algum browser. Eu consegui acessar o servidor tanto com o Edge quanto com o Chrome, no smartphone. Deve-se notar que o servidor de streaming é a própria placa ESP32-CAM. Assim, o seu endereço IP é o da própria placa, que vai acessar a sua rede WiFi. Deve-se notar que, dependendo de como a sua rede WiFi foi configurada, pode ser impossível acessar o servidor. Em caso de problemas, pode-se tentar um ping no endereço indicado para detectar se o servidor pode ser acessado.

Finalmente, a partir deste ponto, o módulo ESP32-CAM pode ser desconectado do Arduino e alimentado diretamente e de forma independente. A seguir, mostro uma fotografia de minha montagem, inclusive com a “gambiarra” que eu montei para usar uma fonte de alimentação comum 😊.

Montagem


Fico por aqui e, no futuro, trago mais detalhes sobre os pontos que ficaram em aberto.