Como mostrar números grandes no display LCD I2C
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.
Boa, cou experimentar assim que possível.
Valeu Adriano, abraço!
Adilson
Tem como fazer usando um lcd keypad shield?
Oi Luis,
É sim, o princípio é o mesmo. Você só terá que adaptar o programa pq o LCD Shield com Keypad não usa I2C para comunicação com o display.
Abraço!
Adilson
how can i print decimals on temperature? thanks!
Hello ,
Merci pour votre partage concernant cet afficheur grand caractères , j’aurai souhaité réalisé cet afficheur avec un LCD 20×4 ,j’ai bien sur changé l’adresse I2C, mais pas réussi les modifications dans le code ,pour avoir l’affichage sur les 4 lignes , pourriez vous m’aider.merci pour toute infos , sinon ou je peux trouver un tableau pour creer les segments CDLT , merci Alan
Salut Alan,
Je n’ai toujours pas la version du programme pour un écran 20×4, mais vous pouvez utiliser la version pour l’écran 16×2 normalement: elle n’occupera qu’une partie de l’écran plus grand.
Salutations!
Adilson
Hello Adilson ,
Merci pour votre réponse , pour utiliser un 20*4 , ce n’est pas suffisant de changer et déclarer dans LiquidCrystal que le lcd est un 20*4 , j’ai tout repris la codification des segments pour les 4 lignes du lcd et re paramétré pour chaque chiffre exemple pour le chiffre 2 :
void custom2() // Chiffre 2
{
lcd.setCursor(x, 0);
lcd.write(5);
lcd.write(6);
lcd.write(2);
lcd.setCursor(x, 1);
lcd.write(5);
lcd.write(6);
lcd.write(7);
lcd.setCursor(x, 2);
lcd.write(7);
lcd.setCursor(x+2 ,2);
lcd.setCursor(x, 3);
lcd.write(1);
lcd.write(3);
lcd.write(3);
Ce n’est peut être pas la bonne solution , mais cela fonctionne, après recadrage la température/humidité se trouve bien centrée au centre du LCD , super ,cet afficheur est prévu en extérieur pour contrôler la température de l’eau avec une sonde étanche , c’est pourquoi , je recherchais grand chiffre pour lire de loin.
Merci encore pour votre partage , cela m’a fait un bon exercice.
Cdlt Alan
Bonjour Alan!
Parfait .. Merci beaucoup pour le partage des informations … J’attends avec impatience votre visite sur le blog chaque fois que possible. 🙂
Salutations!
Adilson
J’ai oublié de préciser que ce thermomètre est fait pour visualiser la température de l’eau piscine , tout ce qui est vendu dans le commerce en thermomètre à la surface de l’eau ,est vite HS par le chlore et les UV soleil et lune et il faut le changer tous les ans lol…..
Cdlt Alan Bonne journée j’habite sur le département 44 /Français à 5 kms de l’océan.