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)

Circuito Arduino Uno com DHT11 e display LCD 16x2 I2C

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:

I2C Scanner 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:

Biblioteca DHT IDE Arduino

Faça o mesmo para a biblioteca LiquidCrystalI2C:

Biblioteca Liquid Crystal I2C

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.

3.8/5 - (6 votes)