“IOT feito fácil”: Brincando com o ESP32 no Arduino IDE

26 26-03:00 setembro 26-03:00 2017 — 44 Comentários

Neste tutorial, exploraremos  o ESP32, o mais novo dispositivo para uso no campo do IoT. Esta placa, desenvolvida pela Espressif, deverá ser a sucessora do ESP8266, devido ao seu baixo preço e excelentes recursos.

Mas é importante alertar que NEM TODAS as bibliotecas ou funções com que você está acostumado a trabalhar com ESP8266 e / ou Arduino estão funcionando nesta nova placa. Provavelmente isso ocorrerá em breve, mas neste momento ainda não estão todas. Confire regularmente o fórum do ESP para saber das atualizações: ESP 32 Forum WebPage.

Aqui, aprenderemos a como programar o ESP32 utilizando-se do Arduino IDE, explorando suas funções e bibliotecas mais comuns, apontar algumas das diferenças importantes com o ESP8266, bem como os novos recursos introduzidos neste grande chip.

Em suma, exploraremos:

  • Saída digital: piscar um LED
  • Entrada digital: leitura de um sensor de toque
  • Entrada analógica: leitura de uma tensão variável usando-se de um potenciômetro
  • Saída analógica: controlando o brilho de um LED
  • Saída Analógica: Controlando a posição de um Servo
  • Leitura de dados de temperatura / umidade utilizando-se de um sensor digital
  • Conectando-se à internet para obter o horário local
  • Receber dados de uma página web local simples, ligando / desligando um LED
  • Transmitir dados para uma simples webPage local
  • Incluir um OLED para apresentar localmente os dados capturados pelo sensor DHT (Temperatura e Umidade), bem como a hora local.

 

1 – O ESP32 Características principais

The ESP32 Main Characterictics

O ESP32 é um novíssimo e poderoso componente do mundo do IoT, que mesmo custando menos de US$ 10, possui grandes vantagens em relação à outras placas similares no mercado.

O ESP32 é dual processado, o que ajuda muito principalmente porque quando um processador está manipilando a comunicação, o outro fica responsável pelo controle dos IOs, por exemplo. Este recurso evita alguns problemas de instabilidade que acontecem com o ESP8266, onde uma única CPU precisa parar o que está fazendo quando manipular acomunicação WiFi. Além disso, o ESP32 possui integrado: WIFI, BLUETOOTH, DAC, vários ADC (não apenas um como o ESP8266), sensores de toque capacitivos, etc. (veja o diagrama de blocos acima). E a boa notícia é que o consumo de energia é quase o mesmo que o ESP8266.

Abaixo de um gráfico que pode nos mostrar suas principais características e diferenças do ESP32 quando comparado com ESP8266:

Ressaltemos seus pontos chave:

Características:

  • 240 MHz dual-core Tensilica LX6 microcontroller with 600 DMIPS
  • Integrated 520 KB SRAM
  • Integrated 802.11 b/g/n HT40 Wi-Fi transceiver, baseband, stack and LwIP
  • Integrated dual mode Bluetooth (classic and BLE)
  • 16 MB flash, memory-mapped to the CPU code space
  • 2.3V to 3.6V operating voltage
  • -40°C to +125°C operating temperature
  • Onboard PCB antenna / IPEX connector for external antenna

Sensores:

  • Ultra-low noise analog amplifier
  • Hall sensor
  • 10x capacitive touch interfaces
  • 32 kHz crystal oscillator

34 x GPIO:

  • 3 x UARTs, including hardware flow control
  • 3 x SPI
  • 2 x I2S
  • 18 x ADC input channels
  • 2 x DAC
  • 2 x I2C
  • PWM/timer input/output available on every GPIO pin
  • OpenOCD debug interface with 32 kB TRAX buffer
  • SDIO master/slave 50 MHz
  • Supports external SPI flash up to 16 MB
  • SD-card interface support

Segurança:

  • WEP, WPA/WPA2 PSK/Enterprise
  • Hardware accelerated encryption: AES/SHA2/Elliptical Curve Cryptography/RSA-4096

Performance:

  • Supports sniffer, Station, SoftAP and Wi-Fi direct mode
  • Max data rate of 150 Mbps@11n HT40, 72 Mbps@11n HT20, 54 Mbps@11g, and 11 Mbps@11b
  • Maximum transmit power of 19.5 dBm@11b, 16.5 dBm@11g, 15.5 dBm@11n
  • Minimum receiver sensitivity of -97 dBm
  • 135 Mbps UDP sustained throughput
  • 5 μA power consumption in Deep-sleep

 

2: BoM – Lista de materiais

 

3: Instalando o IDE do Arduino com o ESP32

ESP32 Arduino IDE Installation

Usaremos o IDE do Arduino para programar de maneira fácil o ESP32, da mesma maneira que fizemos com o ESP8266.

A maior parte da estrutura já foi implementada pela própria Expressif. A mais notável ausencia ainda é o analogWrite. Enquanto analogWrite está a caminho, existem algumas outras opções que você pode usar:

  • 16 canais LEDC que são PWM (exploraremos esta opcão no tutorial)
  • 8 canais SigmaDelta que usa modulação SigmaDelta
  • DAC de 2 canais que dá saída analógica real

 

Instalação dos Drivers:

É importante que você tenha instalado em seu computador, o driver “CP210x USB to UART”. Entre neste link: usb-to-uart-bridge-vcp-drivers e instale o driver apropriado a seu sistema operacional.

Instalando a biblioteca para o IDE32:

A novidade aqui é que a própria Expressif em seu GitHub, nos dará as instruções necessárias para a instalação da biblioteca: arduino-esp32. Siga as instruções específicas para o seu sistema operacional. Em meu caso (MacOS), a instalação é muito simples:

Abra o Terminal e execute o seguinte comando (copy -> paste e pressione enter):

mkdir -p ~/Documents/Arduino/hardware/espressif && \
cd ~/Documents/Arduino/hardware/espressif && \
git clone https://github.com/espressif/arduino-esp32.git esp32 && \
cd esp32/tools/ && \
python get.py

Em seguida, reinicie o Arduino IDE e pronto! Você verá várias placas no menu “TOOLS”. Selecione a apropriado para você. Em geral, a “genérico” ESP32 DEV MODULE funciona bem.

Ao abrir o IDE do Arduino pela primeira vez após a instalação da biblioteca, você notará que a velocidade de upload padrão é de 921,600 bauds. Isso poderá provocar instabilidade. Mude para 115.200 bauds!

4: Hello World! Piscando um LED

Hello World! Blinking a LED

Como de costume, a primeira coisa a fazer quando começamos a explorar um novo HW é piscar um LED.

Vá até o Menu – Examples no IDE e abra o sketch “Blink”.

No caso de minha placa (ESP32 DevKit) ela possui um LED interno conectado ao GPIO 02. É importante verificar se “LED_BUILTIN” é automaticamente reconhecido pelo IDE. Caso contrário, você deve adicionar a linha de código:

int LED_BUILTIN = 2;

Cada fabricante de placas de desenvolvimento para o ESP32 costuma definir por conta própria a que GPIO o LED interno deverá ser conectado. Não existe um padrão definido, como por exemplo, o “pino 13” no caso do Arduino.

/*
  ESP 32 Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
  The ESP32 has an internal blue LED at D2 (GPIO 02)
*/

int LED_BUILTIN = 2;

void setup() 
{
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() 
{
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

Abaixo podemos ver o LED interno piscando (observe a luz azul), juntamente com um LED externo conectado ao GPIO 2:

Existem várias placas diferentes no mercado e cada uma com uma pinagem diferente. O diagrama acima mostra a pinagem da placa que estou utilizando (/ESP32-Development-Board)

Perfeito! Concluímos que, DigitalWrite() está funcionando perfeitamente, da mesma forma que com o ESP8266 e o Arduino. A propósito, DigitalRead () também funcionará da mesma maneira para ler uma entrada digital, como um botão por exemplo.

5: Conhecendo o sensor de toque capacitivo

The Touch Sensor

Exploremos agora um novo sensor incluído neste chip, o Touch Sensor, ou sensor de toque, o qual poderá funcionar como um simples botão por exemplo.

O ESP32 possui 10 sensores de toque capacitivos internos. Esses sensores estão conectados à vários GPIOs:

  • T0: GPIO 4
  • T1: GPIO 0
  • T2: GPIO 2
  • T3: GPIO 15
  • T4: GPIO 13
  • T5: GPIO 12
  • T6: GPIO 14
  • T7: GPIO 27
  • T8: GPIO 33
  • T9: GPIO 32

Para lê-los, você deve usar a função: touchRead (Touch Pin #);

Por exemplo, para ler o Touch Sensor 0 (T0), o qual está associado ao GPIO4, você deverá fazer algo como:

int value = touchRead(4);

Criemos um código, onde ao tocarmos o sensor T0 (GPIO4), o LED acenderá.

Use o monitor serial para verificar os valores lidos pelo sensor, ajustando o código de acordo ao valor lido.

Abaixo o código completo:

/***************************************************** 
* ESP32 Touch Test and LED Ctrl
* Touch pin ==> Touch0 is T0 which is on GPIO 4 (D4).
* LED pin   ==> D2
* 
* MJRoBot.org 6Sept17
*****************************************************/

#define TOUTCH_PIN T0 // ESP32 Pin D4
#define LED_PIN 2
int touch_value = 100;

void setup()
{
  Serial.begin(115200);
  delay(1000); // give me time to bring up serial monitor
  Serial.println("ESP32 Touch Test");
  pinMode(LED_PIN, OUTPUT);
  digitalWrite (LED_PIN, LOW);
}

void loop()
{
  touch_value = touchRead(TOUTCH_PIN);
  Serial.println(touch_value);  // get value using T0 
  if (touch_value < 50)
  {
    digitalWrite (LED_PIN, HIGH);
  }
  else
  {
    digitalWrite (LED_PIN, LOW);
  }
  delay(1000);
}

E o GIF nos mostra o sensor funcionando como “um botão”:

 

6: Entradas analógicas

Analog Input

Existem no total, 18  entradas com capacidade de ler sinais analogicos (ADCs de 12 bits), versus apenas 1 ADC de 10bits no NodeMCU (ESP8266).

GPIO             ADC Channel

  • GPIO 0 ==> ADC2_CH1
  • GPIO 2 ==> ADC2_CH2
  • GPIO 4 ==> ADC2_CH0
  • GPIO 12 => ADC2_CH5
  • GPIO 13 => ADC2_CH4
  • GPIO 14 => ADC2_CH6
  • GPIO 15 => ADC2_CH3
  • GPIO 25 => ADC2_CH8
  • GPIO 26 => ADC2_CH9
  • GPIO 27 => ADC2_CH7
  • GPIO 32 => ADC1_CH4
  • GPIO 33 => ADC1_CH5
  • GPIO 34 => ADC1_CH6
  • GPIO 35 => ADC1_CH7
  • GPIO 36 => ADC1_CH0
  • GPIO 37 => ADC1_CH1
  • GPIO 38 => ADC1_CH2
  • GPIO 39 => ADC1_CH3

Para ler uma entrada analógica, você vai fazer o mesmo que está acostumado com o Arduino ou o ESP8266, por exemplo apra ler o ADC1_CH0, que está associado ao GPIO 36:

int analog_value = analogRead(36);

É muito importante notar que, os ADC do ESP32 possuem 12bits de resolução (versus 10 bits no caso dos ESP8266 e Arduinos), de modo que a faixa total de leitura de ADCs vai de 0 a 4.095 (em vez de 0 a 1.027) quando um sinal de 0 a um máximo de 3.3V é aplicado a uma de suas entradas analógicas.

Como entrada analógica (“sensor”), usaremos um potenciômetro de 10K ohm, conectando-o de 3.3V e GND. Usaremos sua saída variável (pino médio) conectada à entrada de um dos ADC do ESP32. O diagrama acima mostra o potenciômetro conectado ao GPIO 36 que é o canal ADC1 0. Tente também outras entradas em sua placa.

Execute o código abaixo:

/****************************************************** 
* ESP32 Analog Input Test 
* Analog Input: ADC_1_0 pin ==> GPIO36 (VP).
* 
* MJRoBot.org 6Sept17
*****************************************************/
//Analog Input
#define ANALOG_PIN_0 36
int analog_value = 0;

void setup()
{
  Serial.begin(115200);
  delay(1000); // give me time to bring up serial monitor
  Serial.println("ESP32 Analog IN Test");
}

void loop()
{
  analog_value = analogRead(ANALOG_PIN_0);
  Serial.println(analog_value);
  delay(500);
}

Gire o seu potenciômetro e observe no monitor serial do IDE as leituras variando de zero à 4.095.

Analog Input.png

7: Saídas analógicas – usando PWM

Dimming a LED: Analog Output Using PWM

Para controlar a intencidade de luz de um LED usando ESP8266 ou Arduino, usamos simplesmente o comando analogWrite (),  o qual variará o valor PWM de sua saída, simulando um valor analógico. Infelizmente, ainda não temos esse tipo de comando desenvolvido no Arduino IDE para uso com o ESP32. Mas a ótima notícia é que todos os 36 GPIOs do ESP32 possuem a capacidade de gerar saídas PWM, o que é ótimo! Somente deveremos utilizar de uma códificação um pouco mais complexo para alcançar o mesmo resultado.

Programemos um desses GPIOs com um sinal de saída PWM vara ver como funciona.

Para mais detalhes, veja este excelente tutorial: esp32-arduino-led-pwm-fading.

A primeira coisa que se deve definir na geração de um sinal PWM, é a sua frequência. Usaremos um valor de 5.000 Hz, que funciona bem com o LED. Devemos também especificar o canal “LED PWM” e a resolução do ciclo de trabalho (PWM duty cycle), em bits. Podemos escolher um canal de 0 a 15 e uma resolução entre 1 e 16 bits. Usaremos o canal 0 e uma resolução de 8 bits.

int freq = 5000;
int ledChannel = 0;
int resolution = 8;

Definamos o GPIO 2, onde está instalado nosso LED externo (e o interno, caso não quiera trabalhar com o LED externo):

#define LED_PIN 2

Esses parâmetros devem ser definidos durante a fase de setup(), usando as seguintes funções:

void setup()
{
  ledcSetup(ledChannel, freq, resolution);
  ledcAttachPin(LED_PIN, ledChannel);
}

Para ligar o LED com um brilho específico, devemos definir o “ciclo de trabalho” (Duty Cycle). Por exemplo, para desligar o LED, o ciclo de trabalho deve ser zero e a função ledcWrite (ledChannel, dutyCycle) usada para enviar o valor através de um canal PWM específico:

int dutyCycle = 0;
ledcWrite(ledChannel, dutyCycle);

Diferentes valores da variável dutyCycle ativarão o LED com um brilho diferente. Esta variável, dutyCycle, variará de 0 a 255, uma vez que a resolução utilizada foi de 8 bits.

Podemos usar o Potenciômetro (associado à variável analog_value) para configurar manualmente a variável dutyCycle. Porém, uma vez que seu intervalo de valores é diferente, usaremos a função map() para relacionar a entrada e a saída:

dutyCycle = map(analog_value, 0, 4095, 0, 255);

Abaixo o código completo:

***************************************************** 
* ESP32 Analog Input/Output Test 
* Analog Input: ADC_1_0 pin ==> GPIO36 (VP).
* PWM LED pin   ==> GPIO 02
* 
* MJRoBot.org 6Sept17
*****************************************************/
//Analog Input
#define ANALOG_PIN_0 36
int analog_value = 0;

// PMW LED
#define LED_PIN 2
int freq = 5000;
int ledChannel = 0;
int resolution = 8;
int dutyCycle = 0;

void setup()
{
  Serial.begin(115200);
  delay(1000); // give me time to bring up serial monitor
  Serial.println("ESP32 Analog IN/OUT Test");

  ledcSetup(ledChannel, freq, resolution);
  ledcAttachPin(LED_PIN, ledChannel);
  ledcWrite(ledChannel, dutyCycle);
}

void loop()
{
  analog_value = analogRead(ANALOG_PIN_0);
  Serial.println(analog_value);
  dutyCycle = map(analog_value, 0, 4095, 0, 255);
  ledcWrite(ledChannel, dutyCycle);
  delay(500);
}

É isso aí! O GIF abaixo mostra os LEDs (interno e externo) variando de intesidade a medida que se varia o potenciometro:

 

8: Controlando servo motores

Servo Control

Controlemos um Servo Motor usando as saídas PWM de nosso ESP32. O código será basicamente o mesmo que foi usado para controlar o brilho do LED.

Primeiro, é importante lembrar que a freqüência para trabalhar com um Micro Servo é de 50 Hz, então devemos mudar o parâmetro de freqüência para 50 (em vez de 5.000 usado com o LED). Devemos também especificar o canal LED PWM e a resolução do ciclo de trabalho PWM, em bits. Usaremos novamente o canal 0 e uma resolução de 8 bits.

servoPWM.png

int freq = 50;
int channel = 0;
int resolution = 8;

O servo motor será conectado ao GPIO 5 como mostra o diagrama elétrico acima.

#define SERVO_PIN 5

Da mesma maneira que fizemos com o LED, esses parâmetros devem ser definidos durante a fase de setup(), usando as seguintes funções:

void setup()
{
  ledcSetup(channel, freq, resolution);
  ledcAttachPin(SERVO_PIN, channel);
}

Para posicionar o servo em um ângulo específico, devemos definir o “ciclo de trabalho” (veja o diagrama acima).

Por exemplo, para posicionar o servo em torno de 90 graus, o ciclo de trabalho deve ser de cerca de 21 e a função ledcWrite (ledChannel, dutyCycle) deve ser usada para enviar o valor através do canal PWM:

int dutyCycle = 21;
ledcWrite(channel, dutyCycle);

Diferentes valores da variável dutyCycle posicionarão o servo com diferentes ângulos. Esta variável, dutyCycle, deve variar de 10 a 32 (esse “range” foi obtido manualmente).

Igual ao que fizemos com o LED, o potenciômetro (conectado a variável analog_value) pode ser usado para configurar manualmente a variável dutyCycle e, assim, mudar a posição do servo. Uma vez que seus intervalos de valores são diferentes, vamos usar a função map() para relacionar entrada e saída:

dutyCycle = map(analog_value, 0, 4095, 10, 33);

Abaixo o código completo:

/***************************************************** 
* ESP32 Servo Control 
* Analog Input: ADC_1_0 pin ==> GPIO36 (VP).
* PWM SERVO pin   ==> GPIO 05
* 
* MJRoBot.org 6Sept17
*****************************************************/
//Analog Input
#define ANALOG_PIN_0 36
int analog_value = 0;

// PMW SERVO
#define SERVO_PIN 5
int freq = 50;
int channel = 0;
int resolution = 8;
int dutyCycle = 21;

void setup()
{
  Serial.begin(115200);
  delay(1000); // give me time to bring up serial monitor
  Serial.println("ESP32 Servo Control");

  ledcSetup(channel, freq, resolution);
  ledcAttachPin(SERVO_PIN, channel);
  ledcWrite(channel, dutyCycle);
}

void loop()
{
  analog_value = analogRead(ANALOG_PIN_0);
  Serial.print(analog_value);
  Serial.print(" Duty Cycle ==> ");
  Serial.println(dutyCycle);
  dutyCycle = map(analog_value, 0, 4095, 10, 33);
  ledcWrite(channel, dutyCycle);
  delay(50);
}

Agora podemos trabalhar com um sensor ultra-sônico em cima do servo e criar um radar IoT !. Mas este será tema para outro tutorial! 😉

9: Servidor de WiFi

Simple WiFi Server

Testemos agora nosso ESP32 como um simples servidor de WiFi.

  • No menu EXEMPLES no IDE do Arduino, abra o sketch ESP32 WiFi / SimpleWiFiServer.ino:

Este programa “WiFi Web Server LED Blink” foi criado originalmente para arduino em 25 de Novembro de 2012 por Tom Igoe e portado para o Sparkfun esp32 em 31.01.2017 por  Jan Hendrik Berlin

Basicamante, o programa cria um simples servidor web o qual permite o controle de um LED através da web. Este sketch imprimirá o endereço IP da sua rede ESP32 WiFi no Monitor Serial do IDE. A partir daí, você poderá abrir esse endereço em um navegador para ligar e desligar o LED conectado ao GPIO 5 do ESP32.

Se o endereço IP de sua placa for, por exemplo, 10.0.1.40:

Este exemplo foi escrito para uma rede usando criptografia WPA. Para WEP ou WPA, mude a função Wifi.begin ().

Usaremos o programa sem modificações significativas. Mude o LED externo para GPIO 5

Naturalmente se preferir, altere o código para o GPIO 2 sem alterar o HW.

Entre com as credenciaois de sua rede:

const char* ssid     = "yourssid";
const char* password = "yourpasswd";

E suba o código ao seu ESP32.

A primeira coisa que você verá em seu Monitor Serial, será a informação que o seu ESP32 está conectado e qual é o seu endereço IP:

WiFi connected.
IP address: 
10.0.1.40

Abra seu navegador favorito, digitando este endereço IP. Você verá uma WebPage como a mostrada na foto acima. Lá você pode ligar ou desligar o LED remotamente, como mostra o GIF abaixo:

 

10: DHT 22 – Lendo temperatura e umidade

DHT 22 - Reading Temperature and Humidity

Um sensor muito útil para ser usado em projetos IoT é o DHT 11 ou 22. Eles são muito baratos e fáceis de incluir em seus projetos.

Adafruit Unified Sensor Library.png

Primeiro, você precisa ter a biblioteca da Adafruit instalada em seu IDE. Vá para o GitHub e faça o download da versão atualizada desta biblioteca: DHT-sensor-library

Unzip o arquivo, renomeie-o para DHT e mova a pasta completa para o diretório da de bibliotecas do Arduino

Quando utilizei a biblioteca pela primeira vez, recebi a seguinte mensagem :

fatal error: Adafruit_Sensor.h: No such file or directory

Depois de pesquisar na web, descobri que também é necessário ter a biblioteca Unified Sensor da Adafruit também instalada. Para instalá-la, utilizei o Arduino IDE Library Manager (veja a imagem acima). Depois disso tudo funcionou bem,  da mesma maneira que costumamos fazer com Arduino e NodeMCU.

Executemos alguns testes com este sensor. Siga o diagrama elétrico acima e instale o DHT22 como mostrado:

Olhando o sensor com a face “gradeada” voltada para você, conte as 4 pernas da esquerda para a direita

  1. Pin VCC ==> 3.3V
  2. Pin Data ==> GPIO 23
  3. N/C
  4. PIN GND ==> GND

Conecte um resistor de10K ohm entre VCC e Data.

Isso aí!

Voce pode utilizar a sketch “DHT tester.ino”, a qual faz parte dos examples incluídos na biblioteca, ou desenvolver o seu próprio.

I escrevi um simples programa como o mostrado abaixo:

/***************************************************** 
* ESP32 DHT Reading 
* DHT Input: ==> GPIO23.
* 
* MJRoBot.org 9Sept17
*****************************************************/

/* DHT */
#include "DHT.h"
#define DHTPIN 23  
#define DHTTYPE DHT22 
DHT dht(DHTPIN, DHTTYPE);
float localHum = 0;
float localTemp = 0;

void setup()
{
  Serial.begin(115200);
  delay(1000); // give me time to bring up serial monitor
  Serial.println("");
  Serial.println("ESP32 DHT Temperature and Humidity ");
  Serial.println("");
  dht.begin();
}

void loop()
{
  getDHT();
  Serial.print("Temp: ==> ");
  Serial.print(localTemp);
  Serial.print("  Hum ==> ");
  Serial.println(localHum);
  delay(2000);
}

/***************************************************
* Get indoor Temp/Hum data
****************************************************/
void getDHT()
{
  float tempIni = localTemp;
  float humIni = localHum;
  localTemp = dht.readTemperature();
  localHum = dht.readHumidity();
  if (isnan(localHum) || isnan(localTemp))   // Check if any reads failed and exit early (to try again).
  {
    localTemp = tempIni;
    localHum = humIni;
    return;
  }
}

ESP32 DHT Serial Monitor

No print screen do Monitor Serial mostrado acima, você poderá ver o resultado das medidas executadoas com meu programa.

11: Enviando e recebendo dados de uma página local

Sending and Receiving Data From a Local Web Page

Tomaremos os dados gerados a partir do nosso sensor DHT e o valor analógico fornecido pelo potenciômetro, enviando-os para a página web criada para controlar os LEDs.

Comecei com o código SimpleWiFiServer usado na parte 10 deste tutorial e adicionei as linhas de código pertinentes para obter os dados do potenciômetro e DHT.

Observe que voltei o LED para o GPIO 2 como você pode ver pelo diagrama elétrico.

Baixe o código completo do meu GitHub: ESP32_WiFi_Server_Sending_Receiving_Data.ino

Note que organizei mrlhor o código e agora, o loop () é apenas:

void loop()
{
  analog_value = analogRead(ANALOG_PIN_0);
  getDHT();
  WiFiLocalWebPageCtrl();
}

A novidade aqui é a função “WiFiLocalWebPageCtrl ()”. Esta função é praticamente a mesma função da configuração originalusada no SimpleWebServer(). O que incluí nesta nova função, é o que deve aparecer na página.

// the content of the HTTP response follows the header:
            //WiFiLocalWebPageCtrl(); 
              client.print("Temperature now is: ");
              client.print(localTemp);
              client.print("  oC<br>");
              client.print("Humidity now is:     ");
              client.print(localHum);
              client.print(" % <br>");
              client.print("<br>");
              client.print("Analog Data:     ");
              client.print(analog_value);
              client.print("<br>");
              client.print("<br>");
              
              client.print("Click <a href=\"/H\">here</a> to turn the LED on.<br>");
              client.print("Click <a href=\"/L\">here</a> to turn the LED off.<br>"); 

Veja abaixo, o print screen da página web:

webpage2.png

Observe que a temperatura, a umidade e os valores analógicos serão atualizados toda vez que você clicar nos links usados no controle de LED ou quando você atualizar a página.

12: Instalando um display OLED

Installing the OLED Display

Usarei aqui, um display I2C do tipo OLED de 128 x 32. Em princípio, uma vez que você tenha a biblioteca instalada, o ESP32 também funcionará com um display OLED de 128 x 64.

Uma vez que este dispositivo é um display que usa comunicação do tipo I2C, você precisará conectar 4 pinos ao ESP32:

  • SDA ==> GPIO 21
  • SCL ==> GPIO 22
  • VCC ==> 3.3V
  • GND ==> GND

Veja o diagrama elétrico acima para fazer as conecções corretamente

Agora, instale a biblioteca. Usaremos aqui a versão de Daniel Eighhoen. Abra o gerenciador da bibliotecas do IDE e procure por “OLED”. Veja a imagem abaixo. Em meu caso, tenho a versão 3.2.7 instalada.

Library.png

Uma vez instalada a biblioteca, abra o arquivo: SSD1306SimpleDemo.ino, que se encontra em Examples Menu e troque a linha  de código abaixo:

SSD1306  display(0x3c, D3, D5);

com:

SSD1306  display(0x3c, 21, 22);

O GIF abaixo mostra parte do demo (o GIF tem 10 segundos, mas o demo é um pouco mais longo). Observe também que esta demonstração foi projetada para uma exibição em tela de 128 x 64, como em meu caso, utilizei um display de 128 x 32, os gráficos vão aparecer “achatados”.

 

13: Criando e instalando novas fontes

Hello World 2.PNG

Você pode facilmente criar e instalar novas fontes em seu display OLED. Eu por exemplo, criei uma nova fonte que me permite cerca de 2 linhas de 20 caracteres cada uma na tela de um OLED de 128 X 32 .

Como criá-la:

Creating and Installing New Fonts

Vá até o site: SSD1306 Font Converter, uma excelente ferramenta criada por Daniel Eighhoen. Uma vez na ferramenta, voce deve escolher:

  • Font Family,
  • Type (Plan Bold, etc),
  • Size (10, 20, etc.) e
  • Library version (em nosso caso deve ser >=3.0.0).

Precione Create e voilá! Um arquivo “C Font” será criado na janela (como visto acima).

  • Vá lá e copie o texto para um novo “tab” do IDE.
  • Nomeie-o, por exemplo: “modified_font.h
  • No seu arquivoprincipal .ino , inclua uma nova linha no início do código como abaixo:
#include "modified_font.h"

A foto acima, mostra um novo “Hello World”, utilizando-se da nova fonte. O código final poderá ser baixado desde meu GitHub: ESP32_SSD1306_Test

 

14: Mostrando temperatura e humidade no display

Displaying Temperature and Humidity Locally

Vamos agora exibir no OLED, a temperatura e a umidade capturadas pelo sensor DHT22.

Na nossa função loop (), teremos:

void loop() 
{
  getDHT();
  displayData();
  delay(2000);
}

A função getDHT () é a mesma já utilizada anteriormente. A nova função aqui é a displayData (), a qual é mostrado abaixo:

/***************************************************
* Display Data
****************************************************/
void displayData() 
{
  display.clear();   // clear the display

  display.drawString(0, 0,  "temp: ");
  display.drawString(40, 0,  String(localTemp));
  display.drawString(90, 0,  "oC");
  display.drawString(0, 32, "hum:  ");
  display.drawString(40, 32,  String(localHum));
  display.drawString(90, 32,  "%");

  display.display();   // write the buffer to the display
  delay(10);
}

A foto acima, mostra o resultado. O código final poderá ser baixado à partir de meu GitHub: ESP32_DHT22_SSD1306

15: Incluindo “Time Stamp”

IMG_2697

Geralmente, é muito importante ao capturar-se dados com sensores, também registrar o momento em que os mesmos foram coletados.

Instalemos a biblioteca NTPClient para obter a hora exata:

Including Time Stamp

  • Abra o Gerenciador de bibliotecas do IDE e procure por “NTP”
  • Localize e instale a biblioteca NTPClient de Fabrice Weinberg
  • Abra o exemplo NTP client (pode ser tanto o “basic quanto o Advanced)

Altere a linha:

#include <ESP8266WiFi.h>

por:

#include <WiFi.h>

Entre com suas credenciais para se logar na rede Wi-Fi. No monitor serial, você deverá ver o tempo atual. Na versão básica, a hora local da Europa será mostrada. Na versão avançada, você poderá alterá-lo para sua zona de tempo.

Agora, vamos fundir esse código com o desenvolvido anteriormente. O resultado será o mostrado na foto acima e no monitor seria abaixo:

Serial Monitor

O programa completo poderá ser baixado de meu  GitHub: ESP32_Time_Stamp_DHT22_SSD1306

 

16: Selecionando multiplos displays

Nesta última etapa, colocaremos tudo junto, de maneira que possamos selecionar várias telas diferentes, cada uma com uma informação diferente. Por exemplo:

  • Temperatura
  • Umidade
  • Horário local

Mas, como podemos mostrar cada uma dessas informações uma a cada vez na tela?

Precisamos para isso, de um mecanismo de “seleção de página”. Existem vários mecanismos diferentes que poderíam ser usados. Normalmente com vários botões, selecionando menus.

Apenas por diversão, vamos tentar algo não usual aqui. O potenciômetro!

Vamos girar o potenciômetro como fazemos com um seletor de rádio e depender do valor lido, vamos definir um “display” específico para ser mostrado no OLED.

Definamos 4 possíveis exibições :

  1. display 0 ==> Display OFF
  2. display 1 ==> Hora Local
  3. display 2 ==> Temperatura
  4. display 3 ==> Umidade
  5. display 4 ==> Todas as informações em um único display

A entrada analógica pode ler 4,095 valores diferentes. Nós precisamos apenas de 5, então vamos definir intervalos para isso:

  1. 0000 – 0999: ==> display 0 ==> Display OFF
  2. 1000 – 1999: ==> display 1 ==> Hora Local
  3. 2000 – 2999: ==> display 2 ==> Temperatura
  4. 3000 – 3999: ==> display 3 ==> Umidade
  5. 4000 – 4095: ==> display 4 ==> All info

Vamos definir uma variável inteira (int) a qual receberá como conteúdo: 0, 1, 2, 3, 4 ou 5, dependendo da tela a ser mostrada:

int displayNum = 0;

Agora precisamos criar uma nova função: getDisplay (), a qual lerá o valor do potenciômetro, retornando o número de exibição correto (displayNum será uma variável local dentro desta função):

/***************************************************
* Get display
****************************************************/
int getDisplay()
{
  int displayNum = 0;
  int analog_value = analogRead(ANALOG_PIN_0);
  if      (analog_value <= 999)                         displayNum = 0;
  else if (analog_value > 1000 && analog_value <= 1999) displayNum = 1;
  else if (analog_value > 2000 && analog_value <= 2999) displayNum = 2;
  else if (analog_value > 3000 && analog_value <= 3999) displayNum = 3;
  else if (analog_value > 4000 )                        displayNum = 4;
 
  return displayNum;
}

E a função displayData(), se encarregará de apresentar o display selecionado:

/***************************************************
* Display Data
****************************************************/
void displayData(int displayNum) 
{
  String formattedTime = timeClient.getFormattedTime();
  display.clear();   // clear the display
  switch (displayNum) 
  {
    case 0:
      display.clear();
      break;
    case 1:
      display.setFont(ArialMT_Plain_24);
      display.drawString(20, 31,  String(formattedTime));
      break;
    case 2:
      display.setFont(ArialMT_Plain_24);
      display.drawString(0, 31,  "T:");
      display.drawString(30, 31,  String(localTemp));
      display.drawString(100, 31,  "oC");
      break;
    case 3:
      display.setFont(ArialMT_Plain_24);
      display.drawString(0, 31,  "H:");
      display.drawString(30, 31,  String(localHum));
      display.drawString(100, 31,  "%");
      break;
    case 4:
      display.setFont(Open_Sans_Condensed_Light_20);
      display.drawString(0, 0,  "t:");
      display.drawString(10, 0,  String(localTemp));
      display.drawString(47, 0,  "oC");
      display.drawString(75, 0, "h:");
      display.drawString(85, 0,  String(localHum));
      display.drawString(120, 0 ,  "%");
      display.setFont(ArialMT_Plain_24);
      display.drawString(20, 31,  String(formattedTime));
      break;
    default: 
      display.clear();
      break;
  }
  display.display();   // write the buffer to the display
  delay(10);
}

Ambas funções deverão fazer parte do loop():

void loop() 
{
  getDHT();
  timeClient.update();
  displayData(getDisplay());
  delay(2000);
}

O arquivo completo poderá ser baixado de meu GitHub: ESP32_Time_Stamp_DHT22_SSD1306_Multiple_Displays

Abaixo o GIF mostrando a seleção de displays a prtir do potenciômetro:

Uma outra opção legal para selecionar os displays é através de botões. No caso do ESP32, isto podería ser feito com os “sensores de toque”. O codigo não sería muito diferente do mostrado aqui. Fica a sugestão!

 

17: Conclusão

Há muito a ser explorado com este ótimo dispositivo IoT. Voltaremos com novos tutoriais! Continue seguindo nos seguindo aqui no site e no Facebook!

Como sempre, espero que este projeto possa ajudar os outros a encontrar seu caminho no excitante mundo da eletrônica, da robótica e do IoT!

Visite meu GitHub para arquivos atualizados: ESP32

Saludos desde el sur del mundo!

Até meu próximo tutorial!

Um abraço,

Marcelo

44 Respostas para “IOT feito fácil”: Brincando com o ESP32 no Arduino IDE

  1. 

    Excelente trabalho, ajudou muito.

    Curtir

  2. 

    Alguém poderia dar uma ajuda em programação para o esp32? Se possível deixe o email para contato, obrigado

    Curtir

  3. 

    Sensacional! Meus parabéns pelo trabalho e muito obrigado pelo conhecimento compartilhado

    Curtir

  4. 

    Cara que trabalhão você teve. Obrigado por compartilhar as informações. Ficou ótimo e bem explicativo!!Belo trabalho.

    Curtir

  5. 

    maravilhoso o artigo!!! Eu pensei em usar algo assim pra uso comercial, mas achei muito complicado ter que gravar e configurar um firebase para cada sensor… não sei se existe algo que “automatize” … por exemplo, quero instalar 5 sensores de temperatura em casa, um em cada cômodo e visualizar isso em uma pagina web simples … cada um eu teria que gravar manualmente o firmware e configurar um banco de dados (firebase por exemplo) e depois juntar as infos em uma unica pagina … ou estou equivocado? 🙂

    Curtir

  6. 

    Maravilhoso seu trabalho!!!!!!!!

    Curtir

  7. 

    O QUE SERIA ERRO COMPILADO PARA PLACA ESP32 DEV MODULE?

    Curtir

  8. 

    Marcelo, me ajude por favor , quando eu uso sct013 ou potenciômetro (qualquer coisa analógica), so funciona se eu deixar apenas os comandos necessários para ele funcionar , quando eu coloco os comandos para funcionar o wifi , nao consigo ler valores analógicos , vc sabe o porque ? me ajude por favor

    Curtir

  9. 

    Olá, Marcelo! Legal! Muito bem explicado. Parabéns!
    Você poderia disponibilizar os arquivos fritzing? Ajudaria muito com os componentes. Grato. Sucesso!

    Curtir

  10. 

    Marcelo, tudo bem?

    Gostei muito do seu site, sou novo no assunto e estou trabalhando com ESP32 + Velostat(Sensor de pressão), Tenho algumas dúvidas, veja se pode me ajudar com isso, gostaria de fazer o seguinte projeto, ao pressionar o Velostat gostaria e salvar a pressão exercidada no chip para posterior baixar via Bluetooth ou Wifi para um software que será em um SmartPhone ou Tablet porém eu gostaria de não ter fios alem do ESP32 + Bateria para manter ele ligado + Fios de condução do sensor + Velostat, é possível fazer isso?, você teria alguma dica para me dar?.

    Muito obrigado 🙂

    Curtir

  11. 

    Boa tarde Marcelo! Muito bom seus exemplos! Parabéns, man faz uns exemplos ai de conexão via Bluetooth no ESP32, quase não tem nada sobre isso e os que tem são muito vagos…

    Curtir

  12. 

    Estou querendo fazer um monitoramento de corrente através de webserver. Então através da intensidade de luz do LED usando ESP32 com PWM, gostaria que mostrasse o valor da corrente na tela toda vez que mudasse a intensidade da luz.

    Curtir

  13. 

    Parabéns pelo artigo! Quase um ano de publicação e o assunto ainda é novidade. Já conectou um LCD 128×64 ST7920 no esp32? Obrigado!

    Curtido por 1 pessoa

  14. 

    Olá Marcelo, parabéns pelo conteúdo, estou fascinado com IoT. Trabalho com desenvolvimento web e gostaria de interfacear ESP32 em um App desenvolvido em apache cordova. é possível utilizar REST Jquery para efetuar a troca de dados? Desde já agradeço a coolaboração!

    Curtir

    • 

      Oi Jonatas, obrigado. Infelizmente vou te ficar devendo. Eu não conheço as tecnologias que você citou, mas te diria que sem duvida seria possível. Eu fiz um ESP conversar com um RPi e enviando dados remotos, sendo este último um webserver correndo Flask. Vou repetir a experiência com MQTT. Mas não fui além disso.

      Curtir

  15. 
    José Sepúlveda Almendra Júnior 11 11-03:00 maio 11-03:00 2018 às 14:15

    Olá Marcelo,

    Meu nome é José e faço parte da EESC Jr.,empresa júnior de engenharia e arquitetura formada por aluno da USP.Pois bem,estamos realizando um projeto na área de Mecânica e Mecatrônica e seus materiais do blog estão sendo de grande ajuda.Entretanto, recentemente surgiu uma dúvida em nosso projeto,estamos planejando comprar uma placa já feita com o ESP32, estilo as que você mostra em seus vídeos e programa-la utilizando a IDE do Arduino, gostaríamos de saber se existem problemas com a comercialização de um projeto realizado dessa maneira.

    Agradeço a atenção e aguardo respostas

    Curtido por 1 pessoa

    • 

      Olá José. Legal que meu Blog ajudou voces. Olha, infelizmente não sou a melhor pessoa para te ajudar na area legal, pois nunca comercializei meus projetos, uma vez que minha preocupação sempre foi “o caminho” para chegar neles e nao o produto final! Sugiro que voces entrem em contacto com o pessoal do “Embarcados.com.br”, já vi algumas postagens (e seminários on-line) no passado onde eles discutem a questão de licenças. Boa sorte e um abraço.

      Curtir

      • 
        José Sepúlveda Almendra Júnior 11 11-03:00 maio 11-03:00 2018 às 19:42

        Obrigado pela ajuda Marcelo,agradeço a agilidade de resposta,irei da uma olhada no site indicado e ver se encontro algo.

        Agradeço pela atenção

        José

        Curtir

  16. 

    Actually, I have been trying to modify the wi-fi controlled voice robot. I am trying to send a sensor data read by nodemcu back to the app created in MIT app inventor. Can you please help me in that?

    Curtir

  17. 

    Bom dia! Parabéns pelo post!
    Estou tendo muitos problemas com a OneWire…
    Simplesmente nao compila! Poderia me ajudar?
    Obrigado.

    Curtir

  18. 

    Olá!
    Parabéns pelo artigo!

    Gostaria de saber se posso fazer esses mesmos experimentos com o ASP8166, sem danificar a mesma

    Curtido por 1 pessoa

    • 

      ESP8266***

      Curtido por 1 pessoa

      • 

        Oí Priscila. Obrigado. Olha, em termos de nível de sinal, sem problemas. De qual ESP8266 você está falando? O ESP-01? Se for, veja que algumas coisas são possíveis outra não. Por exemplo, você poderá fazer o Blink (saída digital, pior o ESP-01 possui e
        2 saídas. Mas ele não possui nenhuma entrada analógica e nem entrada de sensibilidade. Para falar com a internet você terá que alterar a biblioteca “wifi” pela “wifi8266”. O resto o código é o mesmo. Também se pode ligar um display OLED no ESP-01 já que ele só requer 2 saídas.
        Agora, se for um NodeMCU (ESP8266-12E), por exemplo vale tudo o que falei que pode acima, mais a entrada analógica, já que ele ele possui um ADC, e também saídas PWM (e com biblioteca mais simples). Só não tem a entrada sensível ao toque mesmo. Acho que é isto. Um abraço
        Marcelo

        Curtido por 1 pessoa

      • 

        É um NodeMCU (ESP8266-12E)
        Esclareceu tudo =)
        Obrigada!

        Curtido por 1 pessoa

      • 

        Super! Da para fazer praticamente tudo. Veja que tenho varios tutoriais com o NodeMCU! 😉

        Curtir

  19. 

    Tutorial muito bom!
    Você é parente do Márcio Rovai, que trabalha na Consladel?

    Curtido por 1 pessoa

  20. 

    Boa tarde Marcelo,

    Pintou uma duvida aqui quanto ao sensor touch, com essa função eu consigo por exemplo fazer uma função on off, 1 toque liga e no outro toque desliga o led?

    Grande abraço e obrigado mais uma vez!!!

    Curtir

  21. 

    Primeiro,
    Parabéns pelos tutoriais!!!
    Estou utilizando um ESP32, com sendor DHT22 e um display oled e estou tendo um problema que não consigo achar solução, é somente quando vou usar a biblioteca do DTH e já instalei tudo quanto é biblioteca, já exclui e voltei a instalar, nada novamente, trata-se do erro “exit status 1
    Erro compilando para a placa ESP32 Dev Module”
    Tu já viu algo parecido?
    Não estou conseguindo achar uma solução.
    Obs. Instalei também a biblioteca da Adafruit.
    Ficarei grato se puder me ajudar, Obrigado e parabéns novamente pelos tutoriais!

    Curtir

    • 

      Oi Cristian. Nunca vi. Já fiz dezenas de projetos com o DHT11/22 com Arduino, ESP32 e Raspberry Pi. Sempre funcionou bem com a biblioteca da Adafruit. Voce testou com um Arduino comum?

      Dei uma pesquisada e parece que outras pessoas já tiveram problemas com o ESP32/DHT22 (algo a ver com velocidade). No meu caso funcionou bem, mas pode ser por versão de FW.

      Uma alternativa seria estas bibliotecas desenvolvidas por Rob Tilaart. Voce já tentou?
      https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTNEW

      Um abraço
      Marcelo

      Curtido por 1 pessoa

      • 

        Bom dia Marcelo!

        Finalmente nessa madrugada consegui resolver o problema, primeiramente testei a biblioteca NEWS, e realmente ela funcionou já logo de cara, mas eu estava intrigado o pq de não estar conseguindo utilizar a biblioteca da Adafruit e, quando estava desistindo, resolvi desinstalar a IDE do Arduino e apagar todos os registros de arquivos do mesmo, bem como as suas bibliotecas e exemplos, apaguei tudo e iniciei uma instalação do zero. Para minha surpresa as bibliotecas já funcionaram de primeira após todas as instalações enfim, problema resolvido!!!

        Obs. Só para informar, o hiperlink do SSD1306 Font Converter não está funcionando, mas pela descrição que colocou o encontrei facilmente no Google.

        No mais, muito obrigado pelo retorno e pelos tutoriais!

        Grande abraço!

        Curtir

  22. 

    Olá Marcelo. EXCELENTES seus tutoriais!! Agora, você já pensou em elaborar vídeos para compartilhar os seus conhecimentos?

    Curtir

  23. 

    Marcelo, eu tava lendo que o ADC do ESP32 esta com alguns problemas, vc sabe me dizer quais problemas são esses? Eu tava cogitando usar ele pra um projeto de um datalogger que vai ler 10 entradas analógicas a 200hz. Vc acha que o ESP32 seria uma boa ou vc recomendaria outro microcontrolador ou um ADC externo tipo um ADS1015?

    Curtir

  24. 

    Muito tempo procurando um site bom sobre o esp32 e achei. Parabéns!!

    Curtir

  25. 

    Perfeito esse artigo!! Parabéns!! Já sou fã do blog!!!

    Curtir

  26. 

    Obrigado pelo seu empenho. Excelente tutorial. Já uso o ESP8266 12E em meus “projetos de dominação do mundo”. O irmão mais novo dele tem um ótimo potencial também.

    Curtir

  27. 

    Caramba…
    Que artigo sensacional!!!

    Curtir

Deixe um comentário