=======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]]