Hoje eu mostro uma nova versão de um post que eu publiquei à algum tempo onde eu usei um display LCD 16×2 para mostrar números grandes que ocupavam as duas linhas do display. Aqui, vou usar o mesmo princípio para mostrar como mostrar números grandes no display LCD I2C.
Neste post, uso então o display mencionado juntamente com uma placa Arduino Uno e um sensor DHT11 para mostrar as informações de temperatura e umidade em intervalos regulares.
Material usado
Nesse projeto vamos usar o seguinte material:
Coloquei na lista o LCD 16×2 I2C mas você também pode montar o projeto com display LCD 20×4 I2C realizando pequenas modificações no programa como veremos mais adiante.
Circuito LCD 16×2 I2C com Arduino Uno e DHT11
A conexão do display e dos sensores será feita conforme a imagem abaixo. O sensor de temperatura DHT11 está conectado na porta digital 7 do Arduino e o display I2C nos pinos analógicos A4 (SDA) e A5 (SCL)
A alimentação tanto do display como do sensor de temperatura DHT11 é feita por meio do pino 5V do Arduino.
Verificando o endereço I2C do display
Antes de partir para o programa, vamos descobrir o endereço I2C do display que estamos usando para evitar erros no funcionamento do projeto, sendo o mais comum deles justamente a configuração incorreta do endereço I2C.
Carregue o programa abaixo (I2C_Scanner) no Arduino. Ele faz uma varredura no barramento I2C e lista os dispositivos que foram detectados.
//Programa: I2CScanner - Escaneamento de barramento I2C
#include <Wire.h>
void setup()
{
Wire.begin();
Serial.begin(9600);
Serial.println("\nI2C Scanner");
}
void loop()
{
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ )
{
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
Serial.print("Dispositivo I2C encontrado no endereco 0x");
if (address<16)
Serial.print("0");
Serial.print(address,HEX);
Serial.println(" !");
nDevices++;
}
else if (error==4)
{
Serial.print("Erro desconhecido no endereco 0x");
if (address<16)
Serial.print("0");
Serial.println(address,HEX);
}
}
if (nDevices == 0)
Serial.println("Nenhum dispositivo I2C encontrado\n");
else
Serial.println("Concluido. Novo escaneamento em 5 segundos...\n");
delay(5000); // wait 5 seconds for next scan
}
Confira o endereço I2C do dispositivo no Serial Monitor:
Guarde o endereço que foi mostrado no Serial Monitor pois vamos utilizá-lo no nosso programa. No caso, o endereço detectado foi o 0x3B.
Bibliotecas e programa números grandes no display LCD I2C
No programa vamos usar as bibliotecas DHT11 e LiquidCrystal_I2C, e ambas podem ser instaladas a partir da própria IDE do Arduino no menu Sketch -> Incluir Biblioteca -> Gerenciar Bibliotecas. Na janela do gerenciador de bibliotecas, procure por DHT11 e selecione a biblioteca DHT Sensor Library by Adafruit e clique em Instalar, conforme a imagem abaixo:
Faça o mesmo para a biblioteca LiquidCrystalI2C:
Todo mundo que já usou um display LCD 16×2 sabe que podemos mostrar na tela letras, números e caracteres especiais nas suas duas linhas, e esse é o uso mais comum desse tipo de componente.
O que o programa faz é criar blocos customizáveis que vão formar os números, onde cada número vai ocupar uma parte da linha superior e uma parte da linha inferior do display. Assim o número 1 por exemplo, será formado pelos blocos 1 (UB), 2 (RT), e 5 (LR). Você pode alterar esses blocos para criar sua própria “fonte” e usar números com cantos mais retos ou mais arredondados ou até letras, dependendo da necessidade.
Carregue o programa abaixo no Arduino, tomando o cuidado de configurar na linha 07 o endereço I2C que vimos lá no Serial Monitor, lembra? 🙂
Na linha 07 você também define o tipo de display LCD que você está usando. No nosso caso, estamos usando um LCD 16×2 (16 linhas e 2 colunas). Se você optar por um display LCD 20×4 por exemplo, a linha ficaria:
LiquidCrystal_I2C lcd(0x3B, 20, 4);
Depois de tudo isso, o nosso programa ficou assim:
//Programa: LCD 16x2 I2C Numeros Grandes com DHT11
//Autor: Arduino e Cia
#include <DHT.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3B, 16, 2);
//Pino digital ligado ao pino DATA do DHT11
#define DHTPIN 7
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
int x, numero;
int intervalo = 3000;
//Arrays para criação dos segmentos e customização dos números
byte LT[8] =
{B01111, B11111, B11111, B11111, B11111, B11111, B11111, B11111};
byte UB[8] =
{B11111, B11111, B11111, B00000, B00000, B00000, B00000, B00000};
byte RT[8] =
{B11110, B11111, B11111, B11111, B11111, B11111, B11111, B11111};
byte LL[8] =
{B11111, B11111, B11111, B11111, B11111, B11111, B11111, B01111};
byte LB[8] =
{B00000, B00000, B00000, B00000, B00000, B11111, B11111, B11111};
byte LR[8] =
{B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11110};
byte UMB[8] =
{B11111, B11111, B11111, B00000, B00000, B00000, B11111, B11111};
byte LMB[8] =
{B11111, B00000, B00000, B00000, B00000, B11111, B11111, B11111};
void setup()
{
Serial.begin(9600);
lcd.init();
lcd.backlight();
//Associa cada segmento criado, a um número
lcd.createChar(0, LT);
lcd.createChar(1, UB);
lcd.createChar(2, RT);
lcd.createChar(3, LL);
lcd.createChar(4, LB);
lcd.createChar(5, LR);
lcd.createChar(6, UMB);
lcd.createChar(7, LMB);
//Inicializa o Sensor de Temperatura DHT11
dht.begin();
}
void loop()
{
//Leitura da temperatura e umidade
float h = dht.readHumidity();
float t = dht.readTemperature();
//Mostra as informacoes no Serial Monitor
Serial.print(F("Temperatura: "));
Serial.print(t, 0);
Serial.print(F("°C - Umidade: "));
Serial.print(h, 0);
Serial.println(F(" %"));
//Mostra temperatura no display
MostraTemperatura(t);
//Aguarda o intervalo
delay(intervalo);
//Mostra a umidade no display
MostraUmidade(h);
delay(intervalo);
}
void MostraTemperatura(int temperatura)
{
lcd.clear();
lcd.setCursor(12, 0);
lcd.print("o");
//Primeiro digito da temperatura
x = 4;
numero = temperatura / 10;
mostranumero();
//Primeiro digito da temperatura
x = 8;
numero = temperatura % 10;
mostranumero();
}
void MostraUmidade(int umidade)
{
lcd.clear();
lcd.setCursor(12, 0);
lcd.print("%");
//Primeiro digito da umidade
x = 4;
numero = umidade / 10;
mostranumero();
//Segundo digito da umidade
x = 8;
numero = umidade % 10;
mostranumero();
}
void custom0()//Seleciona os segmentos para formar o numero 0
{
lcd.setCursor(x, 0); //Seleciona a linha superior
lcd.write((byte)0); //Segmento 0 selecionado
lcd.write(1); //Segmento 1 selecionado
lcd.write(2);
lcd.setCursor(x, 1); //Seleciona a linha inferior
lcd.write(3);
lcd.write(4);
lcd.write(5);
}
void custom1() //Seleciona os segmentos para formar o numero 1
{
lcd.setCursor(x, 0);
lcd.write(1);
lcd.write(2);
lcd.setCursor(x + 1, 1);
lcd.write(5);
}
void custom2() //Seleciona os segmentos para formar o numero 2
{
lcd.setCursor(x, 0);
lcd.write(6);
lcd.write(6);
lcd.write(2);
lcd.setCursor(x, 1);
lcd.write(3);
lcd.write(7);
lcd.write(7);
}
void custom3() //Seleciona os segmentos para formar o numero 3
{
lcd.setCursor(x, 0);
lcd.write(6);
lcd.write(6);
lcd.write(2);
lcd.setCursor(x, 1);
lcd.write(7);
lcd.write(7);
lcd.write(5);
}
void custom4() //Seleciona os segmentos para formar o numero 4
{
lcd.setCursor(x, 0);
lcd.write(3);
lcd.write(4);
lcd.write(2);
lcd.setCursor(x + 2, 1);
lcd.write(5);
}
void custom5() //Seleciona os segmentos para formar o numero 5
{
lcd.setCursor(x, 0);
lcd.write((byte)0);
lcd.write(6);
lcd.write(6);
lcd.setCursor(x, 1);
lcd.write(7);
lcd.write(7);
lcd.write(5);
}
void custom6() //Seleciona os segmentos para formar o numero 6
{
lcd.setCursor(x, 0);
lcd.write((byte)0);
lcd.write(6);
lcd.write(6);
lcd.setCursor(x, 1);
lcd.write(3);
lcd.write(7);
lcd.write(5);
}
void custom7() //Seleciona os segmentos para formar o numero 7
{
lcd.setCursor(x, 0);
lcd.write(1);
lcd.write(1);
lcd.write(2);
lcd.setCursor(x + 1, 1);
lcd.write((byte)0);
}
void custom8() //Seleciona os segmentos para formar o numero 8
{
lcd.setCursor(x, 0);
lcd.write((byte)0);
lcd.write((byte)6);
lcd.write(2);
lcd.setCursor(x, 1);
lcd.write(3);
lcd.write(7);
lcd.write(5);
}
void custom9() //Seleciona os segmentos para formar o numero 9
{
lcd.setCursor(x, 0);
lcd.write((byte)0);
lcd.write((byte)6);
lcd.write((byte)2);
lcd.setCursor(x + 2, 1);
lcd.write((byte)5);
}
void mostranumero() //Mostra o numero na posicao definida por "X"
{
switch (numero)
{
case 0: custom0();
break;
case 1: custom1();
break;
case 2: custom2();
break;
case 3: custom3();
break;
case 4: custom4();
break;
case 5: custom5();
break;
case 6: custom6();
break;
case 7: custom7();
break;
case 8: custom8();
break;
case 9: custom9();
break;
}
}
Pronto. Assim que for carregado, o programa vai mostrar os valores de temperatura e umidade lidos pelo sensor DHT11, alternando esses valores no display a cada 3 segundos. Na linha 16 a variável intervalo (configurada em milisegundos) armazena justamente esse tempo entre as trocas do display.
