Recents in Beach


Receba o meu conteúdo GRATUITAMENTE


Como ganhar dinheiro com IOT!



Já pensou em ganhar dinheiro com Internet das Coisas, ESP32, Arduino, automação, esses tipos de coisas? A dica hoje é para quem quer desenvolver hardware e software e quer entrar neste mercado. Para tal, vamos criar um projeto de sensor de gás que mede temperatura e umidade com automação de dois relés. Tudo isso controlado pela nuvem, ou seja, Firebase, além do APP FernandoK.





DESENVOLVIMENTO DA PLACA DE CIRCUITO FINAL


Primeiro passo para iniciar um projeto profissional é conectar os sensores, ESP, entre outras placas, no protoboard. Tudo funcionando corretamente? Agora que vamos integrar ao Firebase. Passamos tudo para uma placa padrão e executamos testes. Vamos, então, para produção de uma placa final, de circuito impresso, dupla face. A minha, neste caso, fiz com a Filitec, uma empresa de Santo André.




GRÁFICOS COM OS DADOS DO FIREBASE






COMANDOS DOS BOTÕES






INFORMAÇÕES DISPONÍVEIS NO FIREBASE






LONG TAIL






CASE: SQUARE SISTEMA DE PAGAMENTO

“Se eu não o tivesse feito, esse conhecimento teria sido intermediado. Estaríamos com um produto desajeitado, projetado por um comitê. Mais demorado, mais caro e muito menos legal.”


Fez 50 unidades manualmente


Diferentemente das empresas anteriores de McKelvey e Dorsey, a Square era uma combinação de hardware e software: o pequeno acessório a ser conectado ao telefone eram os átomos, enquanto o aplicativo para o telefone e os serviços de Web, a serem ativados pelo hardware, eram os bits. Isso significava que estavam no negócio de eletrônica, quisessem ou não.




M5STACK POSSÍVEIS APLICAÇÕES




Furadeira Remota:




RECURSOS USADOS

·         3 Diodos M7 (smd – 1000V/1A)
·         1 LM7805
·         1 LM1117-3V3
·         2 resistores de 1k
·         2 resistores de 6k8
·         5 resistores de 10k
·         2 Leds 5mm
·         2 Capacitor eletrolítico 100uF
·         2 Capacitores de 10uF
·         1 Capacitor de 100nF
·         3 transistores BC847
·         1 Buzzer 1210 (12V)
·         2 Relés 12Vdc
·         1 ESP WROOM 32 DevKit  - 30 pinos
·         1 HTU21D
·         1 Módulo MQ-2





ESQUEMA

Sensores



Relés



Sinalização



Fonte e proteções





CÓDIGO FONTE

Declarações

#include <SparkFunHTU21D.h> //Biblioteca com as funções do sensor HTU21D
#include <IOXhop_FirebaseESP32.h> //Biblioteca com as funçoes do Firebase
#include <ArduinoJson.h>  //Biblioteca com as funções de manipulação de JSON
#include "esp_task_wdt.h" // Biblioteca com as funções de task 

// URL da base de dados fornecido pelo Firebase para a conexão http
#define FIREBASE_HOST "URL.firebaseio.com"  // SUA URL AQUI

#define FIREBASE_AUTH "" // Autenticação

const char *ssid     = "SSID"; // Coloque o nome da sua rede wifi aqui
const char *password = "SENHA"; // Coloque a sua senha wifi aqui
                                                             // LED POWER VERMELHO(Desc Placa: D5)
const int pin_WiFi = 19; //Led indicador de conexão com WiFi // LED WIFI VERDE (Desc Placa: D5)
const int pin_digitalMQ2 = 26; //Leitura da saída digital do MQ-2
const int pin_analogicaMQ2 = 39; //Leitura analógica do MQ-2
const int pin_Rele1 = 16; //Acionamento do relé 1
const int pin_Rele2 = 17; //Acionamento do relé 2
const int pin_Buzzer = 18; //Acionamento do Buzzer //ok

const String PATH_COMMANDS = "/Commands"; //Caminho padrão para os comandos no Firebase

String temp, humd; //Variáveis que receberão a temperatura e umidade do HTU21D

// Pinos do sensor (i2c - canal 1)
#define SDA 21 //Ligado ao SDA do HTU21D
#define SCL 22 //Ligado a oSCL do HTU21D

// Objeto que representa o HTU21D
HTU21D htudSensor;

// Objeto que representa a conexão I2C (wire) do sensor
TwoWire wireSensor = TwoWire(1); //usandoo canal 1



Setup()

void setup()
{
  esp_task_wdt_init(10, true); //inicia o WatchDog de tasks
  disableCore0WDT(); //Desabilita o WatchDogTimer de Hardware do Core 0

  //Ajusta as direções dos GPIO's
  pinMode(pin_WiFi, OUTPUT);
  pinMode(pin_digitalMQ2, INPUT);
  pinMode(pin_analogicaMQ2, INPUT);
  pinMode(pin_Rele1, OUTPUT);
  pinMode(pin_Rele2, OUTPUT);
  pinMode(pin_Buzzer, OUTPUT);

  //Inicia os pinos do Relé em nível baixo
  digitalWrite(pin_Rele1, LOW);
  digitalWrite(pin_Rele2, LOW);

  htu21Begin(); //inicia o HTU21D
  Serial.begin(115200); //Inicia a saída serial

  delay(3000); //Aguarda 3s

  //inicia a conexão com o WiFi
  WiFi.begin(ssid, password);
  //Enquanto não conectado, faz o Led indicador de rede piscar e envia uma mensagem pela serial
  while (WiFi.status() != WL_CONNECTED)
  {
    digitalWrite(pin_WiFi, LOW);
    delay(250);
    digitalWrite(pin_WiFi, HIGH);
    delay(500);
    Serial.println("Conectando ao WiFi ...");
  }

  //inicia a conexão com o Firebase
  Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);

  //Inicia a função de callback usando o caminho de COMANDOS
  Firebase.stream(PATH_COMMANDS, [](FirebaseStream stream)
  {
    String path, value; //Variáveis que recebem o caminho e valor retornado pelo callback
    // Se o evento que vem do callback é de alteração "put"
    if (stream.getEvent() == "put")
    {
      // Obtemos os valores de path e value
      path = stream.getPath();
      value = stream.getDataString();

      if (path.equals("/")) //se é o callback inicial quando a conexão é estabelecida
      {
        // Sincronizamos as saídas para os relés de acordo com a mensagem recebida
        syncFirebase(value); //executa a função que interpreta o valor recebido e atualiza o estado dos relés
        Serial.println("Firebase sincronizado"); //envia a mensagem pela serial de sincronização
      }

      Serial.println(path + " - " + value); //imprime na serial o caminho e o valor recebido (para debug)

      if (path == "/RELE1") // se o caminho é para o RELE1...
        //... e o valor é ON, ajusta para LOW  ligando o relé 1, caso contrário o desliga.
        value == "ON" ? digitalWrite(pin_Rele1, HIGH) : digitalWrite(pin_Rele1, LOW);
      else if (path == "/RELE2")// se o caminho é para o RELE1...
        //... e o valor é ON, ajusta para LOW  ligando o relé 1, caso contrário o desliga.
        value == "ON" ? digitalWrite(pin_Rele2, HIGH) : digitalWrite(pin_Rele2, LOW);
    }
  });

  //cria a task que irá monitorar a saída digital do MQ-2 e acionará o buzzer se for necessário
  xTaskCreatePinnedToCore(gasAlerta, "gasAlerta", 10000, NULL, 0, NULL, 0);
}


Loop()

void loop()
{
  if (WiFi.status() != WL_CONNECTED) {
    WiFi.begin(); //..se a conexão caiu, tenta se conectar novamente . . .
  }
  //...e sinaliza as tentativas piscando o LED indicador da conexão. . .
  while (WiFi.status() != WL_CONNECTED)
  {
    digitalWrite(pin_WiFi, LOW);
    delay(250);
    digitalWrite(pin_WiFi, HIGH);
    delay(500);
    Serial.println("Conectando ao WiFi ...");
  }
  readClimate(); //função que obtem os valores do sensor HTU21D
  sendClimateFirebase(); //função que envia os dados para o Firebase
  delay(3000); //aguarda 3 segundos antes de reiniciar o processo
}


htu21Begin() e readClimate()

// Função que inicia o sensor de temperatura e umidade HTU21D
void htu21Begin()
{
  wireSensor.begin(SDA, SCL, 400000);
  htudSensor.begin(wireSensor);
}

// Função que lê os valores do sensor HTU21D
void readClimate()
{
  // Retorna 999 caso dê erro de leitura
  float h = htudSensor.readHumidity(); //obtem a umidade
  float t = htudSensor.readTemperature(); //obtem a temperatura

  if (t < 900) //verifica se a leitura de temoeratura é válida
    temp = String(t);
  else
    temp = "";

  if (h < 900) //verifica se a leitura de umidade é válida
    humd = String(h);
  else
    humd = "";
}


sendClimateFirebase()

// Função que envia os dados para o Firebase
void sendClimateFirebase()
{
  StaticJsonBuffer<150> jsonBufferSensor; //reserva de memória para objeto JSON que contem os dados dos sensores
  StaticJsonBuffer<50> jsonBufferTimestamp; //reserva de memória para o objeto JSON que contem o instante dos dados

  JsonObject& timestamp = jsonBufferTimestamp.createObject(); //cria o objeto JSON que conterá o instante
  timestamp[".sv"] = "timestamp"; //cria o campo do instante

  JsonObject& sensorData = jsonBufferSensor.createObject(); //cria o objeto JSON que conterá os dados dos sensores

  if (temp != "" && humd != "")//se os valores de temperatura e umidade são válidos...
  {
    sensorData["Temperatura"] = temp; //...atribui os valores ao JSON
    sensorData["Umidade"] = humd;
  }
  else //...se não são válidos, atribui uma mensagem de erro.
  {
    sensorData["Temperatura"] = "Erro na leitura";
    sensorData["Umidade"] = "Erro na leitura";
  }

  //atribui as leituras do sensor MQ-2 ao objeto JSON de dados
  sensorData["MQ-2-analogico"] = String(analogRead(pin_analogicaMQ2));
  sensorData["MQ-2-digital"] = String(digitalRead(pin_digitalMQ2));

  sensorData["timestamp"] = timestamp; //atribui o instante

  Firebase.push("/Dados", sensorData); //envia para o Firebase

  jsonBufferSensor.clear(); //limpa os objetos JSON criados
  jsonBufferTimestamp.clear();
}



syncFirebase()

// Função que ativa/desativa todos os relés de acordo com a mensagem recebida ao iniciar o Firebase
//(Sincronizando as saídas do ESP com os valores atuais do Firebase)
void syncFirebase(String value)
{
  /*
    EXEMPLO DE MENSAGEM RECEBIDA:
    "RELE1":"ON","RELE2":"ON"
  */

  //obtem uma substring a partir do texto "RELE1"
  String aux = value.substring(value.indexOf("RELE1"));
  //obtem a posição do  primeiro separador de valor ":"
  int posVar = aux.indexOf(":\"");

  String status = "";

  if (posVar != -1) //se foi encontrado o separador ....
  {
    posVar += 2; // ...acrescenta duas posição para saltar o separador
    for (int i = posVar; aux.charAt(i) != '\"'; i++) //varre a substring até as próximas aspas...
      status += aux.charAt(i);//...obtendo o valor

    Serial.println("Status RELE1:" + status); //envia para a serial o valor obtido

    if (status.equals("ON")) //...se o valor é ON, ativa o relé. (lógica invertida de ativação)
      digitalWrite(pin_Rele1, LOW);
    else if (status.equals("OFF")) //...se o valor é OFF, desativa o relé.
      digitalWrite(pin_Rele1, HIGH);
  }

  //repete o processo para o relé 2
  status = "";

  aux = value.substring(value.indexOf("RELE2"));
  posVar = aux.indexOf(":\"");
  if (posVar != -1)
  {
    posVar += 2;
    for (int i = posVar; aux.charAt(i) != '\"'; i++)
      status += aux.charAt(i);

    Serial.println("Status RELE2:" + status);

    if (status.equals("ON"))
      digitalWrite(pin_Rele2, HIGH);
    else if (status.equals("OFF"))
      digitalWrite(pin_Rele2, LOW);
  }
}


gasAlerta()

void gasAlerta(void *p) //task que monitora a saída digital do MQ-2
{
  esp_task_wdt_add(NULL); //adiciona a task na lista do Watch
  while (1) //loop da task
  {
    if (digitalRead(pin_digitalMQ2) == LOW) //se um disparo for detectado...(nível baixo)
    {
      digitalWrite(pin_Buzzer, HIGH); //...liga o buzzer...
      Serial.println("Gas detectado!"); // ...envia o alerta para a serial
      delay(3000);//...aguarda por 3s....
      digitalWrite(pin_Buzzer, LOW);//...desliga o buzzer.
    }
    esp_task_wdt_reset(); //reinicia o WatchDog de task
    delay(1); //um pequeno intervalo antes de reiniciar o loop da task
  }
}





FAÇA O DOWNLOADO DOS ARQUIVOS







Postar um comentário

3 Comentários

  1. Amei esse vídeo, muito bom parabéns Sr. Fernando.

    ResponderExcluir
  2. Ola Fernando e todos que visualizar este comentario, é possível diversas aplicações na automação seja residencial ou industrial, mas o problema que mais encontro são EMI ja fiz alguns projetos que quase foram parar nas mãos de alguns importadores mas por causa das EMI não pude dar sequencia ao projeto que ate o momento estão parados, seria interessante você fazer um vídeo de como isolar o circuito e/ou como protege-los dessas eventuais EMI. Moro em uma cidade muito industrializada que tem muitas aplicações possíveis mas quando faço os testes na planta da empresa lasca tudo! se alguém se interessar em compartilhar comigo possíveis soluçoes teria o maior prazer em compartilhar possíveis lucros.

    ResponderExcluir
  3. Fernando, sujestao de video, index.html com botoes carregado no hosting do firebase

    ResponderExcluir