=======ESP8266 e ESP32=======
**ESP8266** e **ESP32** são uma série de microcontroladores de **baixo custo** e **baixo consumo de energia** criados pela Espressif Systems e desenvolvidos para serem utilizados nas mais diversas aplicações [[Internet of Things|IoT]] existentes hoje. Por possuírem um módulo integrado **WiFi** e **Bluetooth** (o segundo somente disponível no **ESP32**) e também uma antena integrada, tornam-se perfeitos para implementações com **conectividade a curta distância ou à internet**. Isso se torna a principal vantagem em relação ao [[Arduino|Arduino]], que precisa de um módulo WiFi ou Bluetooth externo para poder realizar conexões do mesmo tipo. Em algumas versões do **ESP8266** e do **ESP32**, o seu design é criado para que possa ser colocado numa protoboard, como se fosse um CI, para que fique fácil prototipar um circuito. Além disso, o **ESP32** é um sucessor do **ESP8266**, com mais funcionalidades e melhor desempenho.
Ambos os microcontroladores podem ser programados em C++, Lua, JavaScript e Python. Dentro da ADA, já utilizamos C++ (utilizando a [[IDE Arduino|IDE do Arduino]]) e Lua (utilizando a ferramenta online ChilliPeppr) em nosso projeto sobre [[Galvanic Skin Response|GSR]]. Daremos maior foco nessas duas linguagens.
----
=====Diferenças entre os microcontroladores=====
Os microcontroladores possuem diferenças sutis nas versões de seus componentes. No entanto, o **ESP32** possui mais funcionalidades e também maior número de GPIOs e interfaces em relação ao **ESP8266**, permitindo uma implementação mais completa de um projeto. Mesmo assim, ambos os microcontroladores são bons para qualquer projeto [[Internet of Things|IoT]].
^Componente^ESP8266^ESP32^
|MCU|Xtensa Single-core 32-bit L106|Xtensa Dual-Core 32-bit LX6 com 600 DMIPS|
|802.11 b/g/n Wi-Fi|HT20|HT40|
|Bluetooth|Não possui|4.2 e BLE (Bluetooth Low Energy)|
|Frequência típica|80 MHz|160 MHz|
|SRAM|Não possui|Possui|
|Flash|Não possui|Possui|
|GPIO|17|36|
|Hardware PWM|Nenhum|Nenhum|
|Software PWM|8 canais|16 canais|
|Número de interfaces SPI|2|4|
|Número de interfaces I2C|1|2|
|Número de interfaces I2S|2|2|
|Número de interfaces UART|2|2|
|Conversor analógico-digital|10 bits|12 bits|
|Conversor digital-analógico|Não possui|Possui dois de 8 bits|
|Controller Area Network (CAN)|Não possui|Possui|
|Interface Ethernet MAC|Não possui|Possui|
|Sensor de toque|Não possui|Possui|
|Sensor de temperatura|Não possui|Possui|
|Sensor de efeito Hall|Não possui|Possui|
|Temperatura de funcionamento|-40ºC até 125ºC|-40ºC até 125ºC|
----
=====Pinout dos microcontroladores=====
As imagens abaixo mostram a pinagem do **ESP8266** e do **ESP32** respectivamente.
{{:esp8266-pinout.png|}}
Fonte: [[https://circuits4you.com/2017/12/31/nodemcu-pinout/]]
{{:esp32-pinout.jpg|}}
Fonte: [[https://circuits4you.com/2018/12/31/esp32-devkit-esp32-wroom-gpio-pinout/]]
----
=====Programação em C++=====
A programação do **ESP8266** e do **ESP32** em C++ é feita através da [[IDE Arduino|IDE do Arduino]].
Ao abrir a IDE, vá em Arquivo -> Preferências. A janela abaixo será aberta.
{{:esp_tutorial_cpp_1.png?direct|}}
Na opção "URLs Adicionais para Gerenciadores de Placas:", adicione
* http://arduino.esp8266.com/stable/package_esp8266com_index.json para programar um **ESP8266**;
* https://dl.espressif.com/dl/package_esp32_index.json para programar um **ESP32**.
Também é possível adicionar ambos os links.
{{:esp_tutorial_cpp_2.png?direct|}}
Após esse passo, vá em Ferramentas -> Placa: -> Gerenciador de Placas. A janela abaixo será aberta.
{{:esp_tutorial_cpp_3.png?direct|}}
Em "//Refine sua busca...//", digite "esp8266" para buscar o instalador do **ESP8266**.
{{:esp_tutorial_cpp_4.png?direct|}}
Digite "esp32" para buscar o instalador do **ESP32**.
{{:esp_tutorial_cpp_5.png?direct|}}
Também é possível instalar ambos.
Após a instalação, aparecerá a palavra "**INSTALLED**" em frente ao nome do instalador. Isso garantirá que os arquivos necessários para programar a sua placa foram instalados com sucesso.
Após a instalação, verifique em Ferramentas -> Placa: se existe a opção "Generic ESP8266 Module" caso tenha instalado os arquivos para o **ESP8266** e se existe a opção "ESP32 Dev Module" caso tenha instalado para o **ESP32**. Se sim, marque a opção referente a sua placa. A partir desse momento, basta criar seu código e compilar que a IDE programará seu ESP, assim como no caso do [[Arduino|Arduino]].
----
=====Programação em Lua=====
Para a programação em Lua, deve ser seguido o tutorial disponibilizado no próprio [[http://chilipeppr.com/esp32|site da ChilliPeppr]].
{{:esp_tutorial_lua_1.png|}}
Para uma explicação mais clara e dinâmica, o vídeo abaixo explica passo a passo como configurar o firmware de seu microcontrolador e como sincronizar com o ChilliPeppr. Apesar do vídeo explicar apenas para o **ESP32**, para o **ESP8266** é análogo.
{{youtube>njAeHfoVIoY}}
----
=====Exemplos de código=====
====Conexão WiFi====
O ícone do **ESP32** e do **ESP8266** é o módulo WiFi integrado, facilitando a criação de protótipos que se conectem à internet. Os códigos abaixo, em C++ e em Lua, mostram como que é feita a conexão a um WiFi específico, com SSID "ADAWiFi" e senha "12345678".
Em C++ ([[IDE Arduino|IDE do Arduino]]):
#include
#include
//----Configuração Serial----
#define SERIAL_SPEED 115200
//----Configuração do WiFi----
#define WIFI_SSID "ADAWiFi"
#define WIFI_PASSWD "12345678"
#define MAX_WIFI_INIT_RETRY 10
#define WIFI_RETRY_DELAY 500
//Função de inicialização do WiFi
int WiFi_init(const char* wifi_ssid, const char* wifi_passwd){
int retries = 0;
Serial.print("Conectando ao WiFi ");
Serial.print(wifi_ssid);
Serial.println("..........");
//Colocando o WiFi no modo station (ele se conecta aos WiFis)
WiFi.mode(WIFI_STA);
//Começa a se conectar no WiFi
WiFi.begin(wifi_ssid, wifi_passwd);
//Checa o estado da conexão. Se for WL_CONNECTED, então está conectado
while ((WiFi.status() != WL_CONNECTED) && (retries < MAX_WIFI_INIT_RETRY)) {
retries++;
delay(WIFI_RETRY_DELAY);
Serial.println("#");
}
//Retorna o estado da conexão
return WiFi.status();
}
void setup() {
//Configurando o monitor serial
Serial.begin(SERIAL_SPEED);
delay(100);
//Tenta se conectar ao WiFi até que realmente esteja conectado
while(WiFi.status() != WL_CONNECTED){
Serial.println("Nova tentativa de se conectar ao WiFi:");
delay(500);
if (WiFi_init(WIFI_SSID, WIFI_PASSWD) != WL_CONNECTED) {
Serial.println("Erro ao se conectar ao WiFi....");
}
else {
//Se conectado, irá mostrar o IP da conexão
Serial.print("Conexão WiFi ok com o IP ");
Serial.print(String(WiFi.localIP()[0]) + "." + String(WiFi.localIP()[1]) + "." +
String(WiFi.localIP()[2]) + "." + String(WiFi.localIP()[3]));
Serial.println("....");
}
delay(2000);
}
}
void loop() {
//Aqui você faz seu código
}
Em Lua (interface do ChilliPeppr):
--Nova tabela que guardará os dados do WiFi
station_cfg = {}
station_cfg.ssid = "ADAWiFi"
station_cfg.pwd = "12345678"
--Colocando o WiFi no modo station, que fará o ESP se conectar aos WiFis
wifi.setmode(wifi.STATION)
--Configura o WiFi com os dados fornecidos
wifi.sta.config(station_cfg)
--Se conecta ao WiFi
wifi.sta.connect()
--Tenta se conectar até que realmente a conexão seja estabelecida
tmr.alarm(1, 1000, 1, function()
if wifi.sta.getip() == nil then
print("IP não disponível, aguardando...")
else
tmr.stop(1)
print("O modo do ESP é: " .. wifi.getmode())
print("O endereço MAC do módulo é: " .. wifi.ap.getmac())
print("Configuração feita. O IP é " .. wifi.sta.getip())
end
end)
====MQTT====
Não basta apenas conectar seu ESP à internet: deve-se também usar um protocolo de comunicação para que ela possa ser usufruída, como o [[MQTT|MQTT]]. Abaixo há um exemplo de uma implementação do protocolo [[MQTT|MQTT]] em C++ ([[IDE Arduino|IDE do Arduino]]) em que o ESP se subscreve em um tópico, fazendo o papel de //subscriber//, e logo em seguida que é recebida uma mensagem num tópico, é publicada uma outra mensagem em outro tópico, fazendo o papel de //publisher//.
#include
#include
#include
//----Configuração Serial----
#define SERIAL_SPEED 115200
//----Configuração do WiFi----
#define WIFI_SSID "ADAWiFi"
#define WIFI_PASSWD "12345678"
#define MAX_WIFI_INIT_RETRY 10
#define WIFI_RETRY_DELAY 500
//----Configuração do MQTT----
#define MQTT_CLIENT_ID "ADA"
#define MQTT_SERVER "broker.do.seu.mqtt" //Já usamos este: https://www.cloudmqtt.com/
#define MQTT_UNAME "usuariomqtt"
#define MQTT_PASSW "senhamqtt"
#define MQTT_BROKER_PORT 18002 //A porta depende de seu broker!
#define MQTT_TOPIC_1 "esp/topic1"
#define MQTT_TOPIC_2 "esp/topic2"
WiFiClient wifi_client;
PubSubClient mqtt_client(wifi_client, MQTT_SERVER, MQTT_BROKER_PORT);
bool mqtt_status;
//A função de callback do MQTT é chamada em cada mensagem recebida através do MQTT
//num tópico em que se está subscrito
void mqtt_callback(const MQTT::Publish& pub){
Serial.println("Do tópico " + pub.topic() + ", foi recebida a mensagem: " +
pub.payload_string() + "...\n");
mqtt_client.publish(MQTT_TOPIC_2, "Publicando no topico!");
}
int MQTT_init(){
Serial.println("Inicializando comunicação MQTT.........");
//Colocando uma função de "callback" quando uma mensagem chega no tópico em que se está subscrito
mqtt_client.set_callback(mqtt_callback);
//Máximo de tentativas para se conectar ao broker
mqtt_client.set_max_retries(255);
//Conectando ao broker do MQTT
if (mqtt_client.connect(
MQTT::Connect(MQTT_CLIENT_ID).set_keepalive(20000).set_auth(String(MQTT_UNAME), String(MQTT_PASSW))
)) {
Serial.println("Sucesso ao conectar ao Broker..........");
//Tenta se subscrever a um tópico específico
if (mqtt_client.subscribe(MQTT_TOPIC_1)) {
Serial.println("Subscrição ao tópico do MQTT [" + String(MQTT_TOPIC_1) + "]
bem sucedida.........");
}
else {
Serial.println("Não foi possível se subscrever ao tópico [" + String(MQTT_TOPIC_1) +
"].........");
mqtt_client.disconnect();
return false;
}
}
else {
Serial.println("Erro ao se conectar ao Broker..........");
}
return mqtt_client.connected();
}
//Função de inicialização do WiFi
int WiFi_init(const char* wifi_ssid, const char* wifi_passwd){
int retries = 0;
Serial.print("Conectando ao WiFi ");
Serial.print(wifi_ssid);
Serial.println("..........");
//Colocando o WiFi no modo station (ele se conecta aos WiFis)
WiFi.mode(WIFI_STA);
//Começa a se conectar no WiFi
WiFi.begin(wifi_ssid, wifi_passwd);
//Checa o estado da conexão. Se for WL_CONNECTED, então está conectado
while ((WiFi.status() != WL_CONNECTED) && (retries < MAX_WIFI_INIT_RETRY)) {
retries++;
delay(WIFI_RETRY_DELAY);
Serial.println("#");
}
//Retorna o estado da conexão
return WiFi.status();
}
void setup() {
//Configurando o monitor serial
Serial.begin(SERIAL_SPEED);
delay(100);
//A variável mqtt_status é pré-definida para ser falsa
mqtt_status = false;
//Tenta se conectar ao WiFi até que realmente esteja conectado
while(WiFi.status() != WL_CONNECTED){
Serial.println("Nova tentativa de se conectar ao WiFi:");
delay(500);
if (WiFi_init(WIFI_SSID, WIFI_PASSWD) != WL_CONNECTED) {
Serial.println("Erro ao se conectar ao WiFi....");
}
else {
//Se conectado, irá mostrar o IP da conexão
Serial.print("Conexão WiFi ok com o IP ");
Serial.print(String(WiFi.localIP()[0]) + "." + String(WiFi.localIP()[1]) + "." +
String(WiFi.localIP()[2]) + "." + String(WiFi.localIP()[3]));
Serial.println("....");
//A partir daqui, podemos nos conectar ao broker do MQTT
//mas sempre devemos checar se ainda há conexão com o WiFi
while(WiFi.status() == WL_CONNECTED && mqtt_status == false){
//Inicialização da conexão ao broker do MQTT
Serial.println("Nova tentativa de se conectar ao broker do MQTT:");
mqtt_status = MQTT_init();
//"mqtt_status = true" significa sucesso
if (!mqtt_status)
Serial.println("Erro na conexão MQTT....");
else
Serial.println("Conexão MQTT ok....");
}
}
delay(2000);
}
}
void loop() {
//Aqui você faz seu código
}
Até agora, não trabalhamos com o protocolo [[MQTT|MQTT]] em Lua na ADA, mas você pode implementar [[https://www.foobarflies.io/a-simple-connected-object-with-nodemcu-and-mqtt/|utilizando este tutorial]] ou [[https://nodemcu.readthedocs.io/en/master/en/modules/mqtt/|acessando a documentação oficial]].
----
=====Referências externas=====
* [[https://www.espressif.com/|Espressif Systems]]
* [[https://pt.wikipedia.org/wiki/ESP32|Wikipedia - ESP32]]
* [[http://chilipeppr.com/|ChilliPeppr]]
* [[https://makeradvisor.com/esp32-vs-esp8266/|Maker Advisor - ESP32 vs ESP8266]]
* [[https://www.cnx-software.com/2016/03/25/esp8266-and-esp32-differences-in-one-single-table/|CNXSOFT - ESP8266 and ESP32 differences in one single table]]
* [[http://www.robertprice.co.uk/robblog/nodemcu-wifi-setup/|Robert Price - NodeMCU WiFi setup]]