Campainha de vídeo Smart Wi-Fi usando ESP32 e câmera

Tempo de leitura: 8 minutes

Hoje em dia, o sistema de segurança é um dos campos mais pesquisados ​​e com o aumento das ameaças à segurança, as empresas estão lançando novos produtos de segurança inteligentes para combater essas ameaças. A IoT é uma vantagem adicional neste domínio que pode desencadear automaticamente um evento, como chamar a polícia, corpo de bombeiros ou o seu vizinho, em caso de qualquer emergência. Anteriormente, construímos muitos sistemas de segurança como o sistema de monitoramento Raspberry Pi Visitor, câmera de vigilância de vídeo, campainha sem fio, alarme de segurança de porta baseado em IoT, etc. Hoje usaremos ESP32 e câmera para construir uma campainha Wi-Fi inteligente.

Esta campainha inteligente pode ser facilmente alimentada por uma tomada AC e sempre que alguém na porta pressiona o botão da campainha, ela tocará uma música específica no seu telefone e enviará uma mensagem de texto com um link da página de streaming de vídeo onde você pode ver a pessoa em a porta de qualquer lugar do mundo.

 

Componentes necessários

  • ESP32-CAM
  • Placa de Programação FTDI
  • Conversor 127V ou 220V para 5V
  • Campainha
  • Botão de apertar
  • LED (2)

 

Diagrama de circuito

O diagrama do circuito para esta campainha Smart Wi-Fi é muito simples, basta conectar dois LEDs, um botão e uma campainha aos pinos GPIO ESP32. Uma campainha é usada para emitir um som sempre que o botão é pressionado. Um LED é usado para indicar o status de energia e o outro LED é usado para indicar o status da rede. O LED da rede estará em um estado alto se o ESP estiver conectado a uma rede, caso contrário, ele piscará.

Configuração IFTTT para campainha Wi-Fi

O IFTTT é um serviço gratuito baseado na web que permite aos usuários criar cadeias de declarações condicionais simples, chamadas de “receitas”, que são acionadas com base em alterações em outros serviços da web, como Gmail, Facebook, Instagram e Pinterest. IFTTT é uma abreviatura de “If This Then That”.

Neste projeto, o IFTTT é utilizado para enviar um e-mail sempre que a temperatura ou umidade ultrapassar um limite pré-definido. Anteriormente, usamos o IFTTT em muitos projetos baseados em IoT para enviar e-mails ou SMS sobre eventos específicos, como consumo excessivo de eletricidade, pulso alto, entrada de intruso, etc.

Primeiro faça login no IFTTT com suas credenciais ou cadastre-se se você não tiver uma conta nele.

Agora procure por ‘Webhooks’ e clique na seção Webhooks em serviços

Agora, na janela Webhooks, clique em ‘Documentação’ no canto superior direito para obter a chave privada.

Copie esta chave. Ele será usado no programa.

Depois de obter a chave privada, agora criaremos um miniaplicativo usando Webhooks e serviços de e-mail. Para criar um miniaplicativo, clique em seu perfil e, em seguida, clique em ‘Create’.

Agora, na próxima janela, clique no ícone ‘This’.

Agora procure por Webhooks na seção de pesquisa e clique em ‘Webhooks’.

Agora escolha o gatilho ‘Receive a Web Request’ e, na janela seguinte, insira o nome do evento como button_pressed e clique em criar um gatilho.

Agora, para completar o miniaplicativo, clique em ‘This’ para criar uma reação para o evento button_pressed.

Aqui, reproduziremos uma música específica no telefone quando o botão da campainha IoT for pressionado. Para essa pesquisa por “Android device” na seção de pesquisa.

Agora no dispositivo Android, escolha o gatilho ‘Play a specific song’.

Agora digite o título da música que deseja tocar quando o botão da campainha for pressionado. No meu caso, estou tocando uma música chamada ‘123’ do meu Google Play Music. Você também pode usar o Spotify ou outros aplicativos de música.

Depois disso, clique em ‘Criar ação’ e em ‘Concluir’ para concluir o processo.

Agora crie outro miniaplicativo para enviar uma mensagem com o link da página da web para o telefone quando o botão da campainha for pressionado.

Portanto, para criar este miniaplicativo, escolha ‘Webhooks’ nesta seção e na seção ‘that’ escolha ‘Android SMS’.

Agora, ele pedirá para inserir o número do telefone e o corpo da mensagem. Para este projeto de campainha Wi-Fi, estamos enviando uma mensagem com o link do servidor da Web para que você possa ver o vídeo ao vivo diretamente.

Explicação do código

O código completo junto com o vídeo para esta câmera de campainha Wi-Fi é fornecido no final deste documento. Ele também pode ser baixado aqui. Abaixo, explicamos algumas partes importantes do código.

Primeiro, inclua todos os arquivos de biblioteca necessários para este código.

#include "esp_camera.h"
#include <WiFi.h>

Em seguida, insira as credenciais do Wi-Fi.

const char* ssid = "Nome do Wi-Fi";
const char* password = "Senha Wi-Fi";

Depois disso, insira o nome do host IFTTT e a chave privada que você copiou do site IFTTT.

const char *host = "maker.ifttt.com";
const char *privateKey = "Sua chave privada";

Defina todos os pinos que você está usando neste projeto. Estou usando os pinos GPIO 2, 14 e 15 para conectar o botão de pressão, LED e campainha.

const int buttonPin = 2;
const int led1 = 14;
const int buzzer = 15;

Dentro do loop de configuração vazio, defina o pino do botão como entrada e os pinos do LED e da campainha como saída.

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(led1, OUTPUT);
  pinMode(buzzer, OUTPUT);

Ele tentará se conectar ao Wi-Fi usando as credenciais fornecidas e, quando conectado a uma rede, o estado do LED mudará de baixo para alto.

WiFi.begin(ssid, password);
  int led = LOW; 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    digitalWrite(led1, led);
    led = !led;
  }
  Serial.println("");
  Serial.println("WiFi connected");
  digitalWrite(led1, HIGH);

Enquanto estiver desconectado de uma rede, o ESP32 será reiniciado até se conectar a uma rede.

while (WiFi.status() == WL_DISCONNECTED) {
    ESP.restart();
    digitalWrite(led1, LOW);
    Serial.print("Conexão perdida");

O ESP32 irá ler o estado do botão, e se o botão estiver no estado LOW (puxado para cima), ou seja, um botão foi pressionado, ele envia o evento e liga a campainha por 3 segundos.

int reading = digitalRead(buttonPin);
if (buttonState == LOW) {
        send_event("button_pressed");
        Serial.print("button pressed");
        digitalWrite(buzzer, HIGH);
        delay(3000);
          digitalWrite(buzzer, LOW);

 

Testando a campainha Smart Wi-Fi

Depois de montar o circuito, ligue a campainha usando um soquete CA. Agora, sempre que o botão da campainha IoT é pressionado, o smartphone começa a tocar uma música chamada ‘123’ e uma mensagem será recebida com um link de uma página da web conforme mostrado abaixo, onde o feed de vídeo ao vivo pode ser visto.

O código completo e o vídeo de trabalho para esta campainha Smart Wi-Fi podem ser encontrados no final do documento ou você pode baixar o código aqui. Se você tiver alguma dúvida sobre este projeto, deixe-a na seção de comentários.

 

Código

#include "esp_camera.h"
#include <WiFi.h>
//
// AVISO!!! Certifique-se de ter selecionado ESP32 Wrover Module,
// ou outra placa que tenha PSRAM habilitado
//
// Select camera model
//#define CAMERA_MODEL_WROVER_KIT
//#define CAMERA_MODEL_ESP_EYE
//#define CAMERA_MODEL_M5STACK_PSRAM
//#define CAMERA_MODEL_M5STACK_WIDE
#define CAMERA_MODEL_AI_THINKER
#include "camera_pins.h"
void send_event(const char *event);
const char* ssid = "Galaxy-M20";
const char* password = "ac312124";
const char *host = "maker.ifttt.com";
const char *privateKey = "hUAAAz0AVvc6-NW1UmqWXXv6VQWmpiGFxx3sV5rnaM9";
const int buttonPin = 2;
int buttonState;             //a leitura atual do pino de entrada
int lastButtonState = LOW;   // a leitura anterior do pino de entrada
const int led1 = 14;
const int buzzer = 15;
long lastDebounceTime = 0;  // a última vez que o pino de saída foi alternado
long debounceDelay = 50;    // o tempo de debounce; aumentar se a saída piscar
void startCameraServer();
void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(led1, OUTPUT);
  pinMode(buzzer, OUTPUT);
  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;
  //init com especificações altas para pré-alocar buffers maiores
  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("A inicialização da câmera falhou com o erro 0x%x", err);
    return;
  }
  sensor_t * s = esp_camera_sensor_get();
  //os sensores iniciais são invertidos verticalmente e as cores estão um pouco saturadas
  if (s->id.PID == OV3660_PID) {
    s->set_vflip(s, 1);//flip it back
    s->set_brightness(s, 1);//up the blightness just a bit
    s->set_saturation(s, -2);//lower the saturation
  }
  //drop down frame size para maior frame rate inicial
  s->set_framesize(s, FRAMESIZE_QVGA);
#if defined(CAMERA_MODEL_M5STACK_WIDE)
  s->set_vflip(s, 1);
  s->set_hmirror(s, 1);
#endif
  WiFi.begin(ssid, password);
  int led = LOW; 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    digitalWrite(led1, led);
    led = !led;
  }
  Serial.println("");
  Serial.println("WiFi connected");
  digitalWrite(led1, HIGH);
  startCameraServer();
  Serial.print("Câmera pronta! Usar 'http://");
  Serial.print(WiFi.localIP());
  Serial.println("' conectar");
}
void loop() {
  while (WiFi.status() == WL_DISCONNECTED) {
    ESP.restart();
    digitalWrite(led1, LOW);
    Serial.print("Conexão perdida");
  }
  int reading = digitalRead(buttonPin);
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay)
  {
    // se o estado do botão mudou:
    if (reading != buttonState)
    {
      Serial.print("Botão agora ");
      Serial.println(HIGH == reading ? "HIGH" : "LOW");
      buttonState = reading;
      // Quando o botão está no estado LOW (puxado para cima), o botão foi pressionado, então envie o evento.
      if (buttonState == LOW) {
        send_event("button_pressed");
        Serial.print("button pressed");
        digitalWrite(buzzer, HIGH);
        delay(3000);
          digitalWrite(buzzer, LOW);
      }
    }
  }
  // salve a leitura. Da próxima vez no loop,
  lastButtonState = reading;
}
void send_event(const char *event)
{
  Serial.print("Conectando à ");
  Serial.println(host);
  // Use a classe WiFiClient para criar conexões TCP
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("Conexão falhou");
    return;
  }
  // Agora criamos um URI para a solicitação
  String url = "/trigger/";
  url += event;
  url += "/with/key/";
  url += privateKey;
  Serial.print("Solicitando URL: ");
  Serial.println(url);
  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  while(client.connected())
  {
    if(client.available())
    {
      String line = client.readStringUntil('\r');
      Serial.print(line);
    } else {
      // No data yet, wait a bit
      delay(50);
    };
  }
  Serial.println();
  Serial.println("fechando a conexão");
  client.stop();
}