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.