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


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.

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 Monitorhttps://mjrobot.files.wordpress.com/2017/09/esp32-dht-serial-monitor.png?w=1160 1160w, https://mjrobot.files.wordpress.com/2017/09/esp32-dht-serial-monito... 150w, https://mjrobot.files.wordpress.com/2017/09/esp32-dht-serial-monito... 300w, https://mjrobot.files.wordpress.com/2017/09/esp32-dht-serial-monito... 768w, https://mjrobot.files.wordpress.com/2017/09/esp32-dht-serial-monito... 1024w" sizes="(max-width: 580px) 100vw, 580px" />

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 original usada 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”

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 Monitorhttps://mjrobot.files.wordpress.com/2017/09/serial-monitor.png?w=1160 1160w, https://mjrobot.files.wordpress.com/2017/09/serial-monitor.png?w=150 150w, https://mjrobot.files.wordpress.com/2017/09/serial-monitor.png?w=300 300w, https://mjrobot.files.wordpress.com/2017/09/serial-monitor.png?w=768 768w, https://mjrobot.files.wordpress.com/2017/09/serial-monitor.png?w=1024 1024w" sizes="(max-width: 580px) 100vw, 580px" />

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 os tutoriais aqui no site do Garagem, no MJRoBot.org 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



Exibições: 5267

Comentar

Você precisa ser um membro de Laboratorio de Garagem (arduino, eletrônica, robotica, hacking) para adicionar comentários!

Entrar em Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)

Comentário de Lauro Becker em 11 setembro 2021 às 0:21

Antes tarde do que nunca... Belíssimo tutorial. parabéns.

Comentário de Leonardo Hilgemberg Lopes em 6 outubro 2017 às 18:23

Parabéns mesmo Marcelo!

Show de bola o tutorial!

quero testar esse AD de 12-bits!

Comentário de Jose Augusto Cintra em 29 setembro 2017 às 22:21

Parabéns Marcelo!

Tutorial nota 10!

Comprei um desses, mas não pude testar. Agora já sei onde buscar informações

Comentário de Tiago Alexandre em 27 setembro 2017 às 23:32

Muito bom o tutorial, acho que vou ter que comprar esse esp32 rsrs

Comentário de José Gustavo Abreu Murta em 27 setembro 2017 às 20:50

Boa noite amigo Marcelo,
Muito poderoso esse ESp32 !
Tenho que conseguir um para mim.
Grande abraço.
Gustavo

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço