Programação do ESP32 - Liga/desliga motor
Tags: esp32, cpp, diy, programming
Published: 2021-12-22 23:42:07

## Github do projeto

Todo o código esta disponível em meu [github](https://github.com/HenriqueBros/Food-Water-Dog).

## PlatformIO IDE no VS code

Para programar o ESP32 doit-devkit-v1(modelo) eu utilizei a extensão PlatformIO no VS code.

![PlatformIO](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ompseysgwwtq5hy8y01.png)

## Broker rodando no Raspberry

![ubutu-broker](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vawcxcmlb1kip111661h.png)

## Código embarcado no ESP32

Utilizei a linguagem C++ para a programação, no inicio do código importei as bibliotecas.

```
// Bibliotecas necessárias
#include <Arduino.h>
#include "WiFi.h"
#include "PubSubClient.h"
```

A importação do Arduino.h é necessária pois estou utilizando o PlatformIO.

Depois defini as variáveis que irei utilizar.

```
#define PIN_LED 25 // Pino usado no ESP-32

#define TOPICO_SUBSCRIBE_LED "topico_liga_desliga_led" // Nome do Tópico, pode ser qualquer nome
#define ID_MQTT "esp32_mqtt" // ID do seu MQTT

const char* SSID = "Nome_Rede_Wifi";
const char* PASSWORD = "sua_senha";

const char* BROKER_MQTT = "Endereço do MQTT Broker";
int BROKER_PORT = 1883;//porta_do_broker

WiFiClient espClient;
PubSubClient MQTT(espClient);
```

```
//Declarando funções
void initMQTT(void);
void mqtt_callback(char* topic, byte* payload, unsigned int length);
void reconnectMQTT(void);
void reconnectWiFi(void);
void VerificaConexoesWiFIEMQTT(void);
```

```C++
/* Função: inicializa e conecta-se na rede WI-FI desejada */
void initWiFi(void) 
{
    delay(10);
    Serial.println("------Conexao WI-FI------");
    Serial.print("Conectando-se na rede: ");
    Serial.println(SSID);
    Serial.println("Aguarde");
      
    reconnectWiFi();
}
```

```
/* Função: inicializa parâmetros de conexão MQTT(endereço do broker, porta e seta função de callback) */
void initMQTT(void) 
{
    MQTT.setServer(BROKER_MQTT, BROKER_PORT); //informa qual broker e porta deve ser conectado
    MQTT.setCallback(mqtt_callback); //atribui função de callback (função chamada quando qualquer informação de um dos tópicos subescritos chega)
}
```
A função *mqtt_callback* roda a lógica principal da aplicação, fazendo com que o motor seja iniciado e desligado após 9 segundos. com o sinal enviado via celular para o *broker MQTT*, que esta no raspberry.
```
/* Função: função de callback */
void mqtt_callback(char* topic, byte* payload, unsigned int length) 
{
    String msg;
  
    /* obtém a string do payload recebido */
    for(int i = 0; i < length; i++) 
    {
       char c = (char)payload[i];
       msg += c;
    }
 
    Serial.print("Chegou a seguinte mensagem via MQTT: ");
    Serial.println(msg);
    
    if (msg.equals("1"))
    {
        digitalWrite(PIN_LED, HIGH);
        Serial.print("LED aceso mediante comando MQTT");
        delay(9000);
        digitalWrite(PIN_LED, LOW);
    }
  
}
```
Caso o *subscriber* não consiga se conectar com o *broker* ele fica tentando se conectar ate que haja exito.
```
/* Função: reconecta-se ao broker MQTT */
void reconnectMQTT(void) 
{
    while (!MQTT.connected()) 
    {
        Serial.print("* Tentando se conectar ao Broker MQTT: ");
        Serial.println(BROKER_MQTT);
        if (MQTT.connect(ID_MQTT)) 
        {
            Serial.println("Conectado com sucesso ao broker MQTT!");
            MQTT.subscribe(TOPICO_SUBSCRIBE_LED); 
        } 
        else
        {
            Serial.println("Falha ao reconectar no broker.");
            Serial.println("Haverá nova tentativa de conexão em 2s");
            delay(2000);
        }
    }
}

```
Estas funções verificam se há conexão com o Wifi e ao Broker MQTT.

A função *VerificaConexoesWiFIEMQTT* chama as funções *reconnectMQTT* e *reconnectWiFi*.
```
/* Função: verifica o estado das conexões WiFI e ao broker MQTT. */
void VerificaConexoesWiFIEMQTT(void)
{
    if (!MQTT.connected()) 
        reconnectMQTT();
      
     reconnectWiFi();
}
 
/* Função: reconecta-se ao WiFi */
void reconnectWiFi(void) 
{
    if (WiFi.status() == WL_CONNECTED)
        return;
          
    WiFi.begin(SSID, PASSWORD); 
      
    while (WiFi.status() != WL_CONNECTED) 
    {
        delay(100);
        Serial.print(".");
    }
    
    Serial.println();
    Serial.print("Conectado com sucesso na rede ");
    Serial.print(SSID);
    Serial.println("IP obtido: ");
    Serial.println(WiFi.localIP());
}
```
O *setup* é a primeira coisa que o programa roda assim que é iniciado, definindo o *Serial*, o pino como saída é setado inicialmente como desligado, depois chamando as funções *initWiFi* e *initMQTT*. 
```
void setup() {
  Serial.begin(115200);

  pinMode(PIN_LED, OUTPUT);
  digitalWrite(PIN_LED,LOW);
 
  initWiFi();

  initMQTT();
}
```
A função *loop* fica chamando periodicamente à cada 2 segundos as funções *VerificaConexoesWiFIEMQTT, MQTT.loop*
```
void loop() {
    VerificaConexoesWiFIEMQTT();

    MQTT.loop();
    delay(2000);
}
```

## Configurações do PlatformIO

```
[env:esp32doit-devkit-v1]
platform = espressif32
board = esp32doit-devkit-v1
framework = arduino
monitor_speed = 115200
upload_speed = 921600
upload_port = COM3 ; Porta serial do seu computador
lib_deps = knolleary/PubSubClient@^2.8 ; biblioteca necessárias para o uso do MQTT
```

A porta serial você pode encontra no *Gerenciador de Dispositivos*, o meu no caso esta na porta 3 (COM3), lembre-se de instalar o drive da placa para que seu computador reconheça o dispositivo.

![porta](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8vfb5t3rimb681y0g49n.png)

## Exemplo do funcionamento do ESP32

O exemplo foi feito na protoboard e com led, acendendo e apagando após 9 segundos.

![prototipo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3m12unftpovyfxnhxtpk.gif)