IOT FEITO FÁCIL”: BRINCANDO COM O ESP32 NO ARDUINO IDE

este 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.

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:

1 - O ESP32 Características principais

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:

Sensores:

34 x GPIO:

Segurança:

Performance:

2: BoM – Lista de materiais

3: Instalando o IDE do Arduino com o ESP32


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:

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


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


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:

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);
 
}

6: Entradas analógicas


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

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.


7: Saídas analógicas – usando 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:

<strong>int dutyCycle = 0;</strong>
 
<strong>ledcWrite(ledChannel, dutyCycle);</strong>

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 ==&gt; GPIO36 (VP).
 
* PWM LED pin   ==&gt; 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()
 
dutyCycle{
 
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


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.


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 ==&gt; GPIO36 (VP).
 
* PWM SERVO pin   ==&gt; 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 ==&gt; ");
 
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


Testemos agora nosso ESP32 como um simples servidor de WiFi.

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


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.


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: ==&gt; 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: ==&gt; ");
 
Serial.print(localTemp);
 
Serial.print("  Hum ==&gt; ");
 
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;
 
}
 
}


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

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


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&lt;br&gt;");
 
client.print("Humidity now is:     ");
 
client.print(localHum);
 
client.print(" % &lt;br&gt;");
 
client.print("&lt;br&gt;");
 
client.print("Analog Data:     ");
 
client.print(analog_value);
 
client.print("&lt;br&gt;");
 
client.print("&lt;br&gt;");
 
&nbsp;
 
client.print("Click &lt;a href=\"/H\"&gt;here&lt;/a&gt; to turn the LED on.&lt;br&gt;");
 
client.print("Click &lt;a href=\"/L\"&gt;here&lt;/a&gt; to turn the LED off.&lt;br&gt;");

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


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


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:

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.


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


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:


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

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

#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


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:


Altere a linha:

#include &lt;ESP8266WiFi.h&gt;
 
por:
 
#include &lt;WiFi.h&gt;

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:


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:

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 &lt;= 999)                         displayNum = 0;
 
else if (analog_value &gt; 1000 &amp;&amp; analog_value &lt;= 1999) displayNum = 1;
 
else if (analog_value &gt; 2000 &amp;&amp; analog_value &lt;= 2999) displayNum = 2;
 
else if (analog_value &gt; 3000 &amp;&amp; analog_value &lt;= 3999) displayNum = 3;
 
else if (analog_value &gt; 4000 )                        displayNum = 4;
 
&nbsp;
 
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!

Você também pode gostar de ler

Soluções para o Transporte Inteligente de Cargas e Pessoas

Em 29/02/2024 às 14h10 - Atualizado em 29/02/2024 às 14h12

Como você contrata e o que espera de um profissional de TI

Em 02/12/2022 às 06h01 - Atualizado em 07/02/2023 às 15h03

COMO CRIAR A SUA REDE LORA | TUDO SOBRE IOT

Em 02/12/2022 às 05h09 - Atualizado em 07/02/2023 às 15h03

IOT FEITO SIMPLES: CONTROLANDO SERVOS COM O NODEMCU E O BLYNK

Em 01/12/2022 às 14h20 - Atualizado em 07/02/2023 às 15h03

ROBÔ CONTROLADO POR VOZ VIA WIFI

Em 01/12/2022 às 13h31 - Atualizado em 07/02/2023 às 15h03

O IOT FEITO SIMPLES: MONITORANDO MÚLTIPLOS SENSORES

Em 30/11/2022 às 10h44 - Atualizado em 07/02/2023 às 15h02

IOT FEITO FÁCIL: ESP-MICROPYTHON-MQTT-THINGSPEAK

Em 30/11/2022 às 10h13 - Atualizado em 07/02/2023 às 15h02