LCD 16x2 no Arduino mostrando quadrados ou lixo: o diagnóstico em ordem
Tela em branco, fileira de blocos ou caracteres estranhos têm causas diferentes. Siga a ordem: alimentação, contraste, ligação de dados, endereço I2C e só então o texto.
O sketch manda "Temperatura" para o display 16x2 da estufa e a tela responde com uma fileira de quadrados brancos na linha de cima. Ou com nada. Ou com "Temperatura" seguido de símbolos japoneses. Cada um desses sintomas aponta para uma causa diferente, e quase nenhuma está no texto do programa. A resposta curta: confirme a alimentação, ajuste o contraste até ver os blocos, confira os fios de dados (ou o endereço I2C) e só depois mexa no código.
O exemplo deste guia é um display de caracteres 16x2 com controlador HD44780 ou compatível, primeiro ligado em paralelo com quatro fios de dados e depois com o adaptador I2C que muitos módulos já trazem soldado atrás.
O que cada sintoma quer dizer
O controlador do display tem uma sequência de inicialização. Antes dela, ele mostra a linha de cima cheia de blocos quando o contraste está certo; depois dela, limpa a tela e espera texto. Isso dá um roteiro de diagnóstico:
- Tela totalmente vazia, sem blocos em nenhum ajuste de contraste: falta alimentação, o contraste está no extremo errado ou o pino de contraste está desligado.
- Só a luz de fundo acende, sem nada escrito: pode ser contraste; a luz de fundo é um circuito separado e não prova que o controlador está vivo.
- Fileira de blocos na linha de cima e nada mais: o display está alimentado e com contraste, mas não foi inicializado. A causa costuma ser fio de dados, RS ou E trocado, ou pinos no código diferentes da ligação.
- Texto certo com caracteres estranhos misturados: mau contato em uma linha de dados, ruído, ou caracteres que o display não tem, como letras acentuadas.
- Restos de texto antigo no fim da linha: o programa escreveu um texto mais curto por cima de um mais longo sem apagar o resto.
Como ligar o display em paralelo
O módulo tem 16 pinos. Os nomes vêm na serigrafia e seguem o padrão do HD44780:
Pino LCD Nome Liga em
1 VSS GND
2 VDD 5 V
3 V0 cursor do potenciometro de 10 k (pontas em 5 V e GND)
4 RS Arduino 12
5 RW GND (so escrita)
6 E Arduino 11
11 D4 Arduino 5
12 D5 Arduino 4
13 D6 Arduino 3
14 D7 Arduino 2
15 A 5 V (luz de fundo, ver o resistor abaixo)
16 K GND
No modo de quatro bits, os pinos D0 a D3 ficam sem ligação. O pino RW no GND deixa o display só recebendo dados, que é o que a biblioteca LiquidCrystal espera nessa configuração.
A luz de fundo é um LED. Alguns módulos já trazem o resistor em série na placa, outros não. Procure um resistor perto dos pinos 15 e 16 ou consulte a folha do seu módulo; sem essa informação, ligue o pino 15 por um resistor de algumas centenas de ohms e meça a corrente. A conta é a mesma do guia de resistor para LED.
Como diagnosticar na ordem certa
- Alimentação: com o multímetro, meça entre os pinos 2 e 1 do display. Precisa estar perto de 5 V para um módulo de 5 V.
- Contraste: gire o potenciômetro devagar de uma ponta à outra, sem programa rodando ou com a placa recém-ligada. Em algum ponto deve aparecer a fileira de blocos na linha de cima. Deixe um pouco antes de os blocos ficarem fortes demais.
- Dados: carregue o sketch abaixo. Se os blocos sumirem e o texto aparecer, o hardware está certo. Se os blocos continuarem, confira RS, E e D4 a D7, um por um, com o multímetro em continuidade e tudo desligado.
- Texto: só agora formate o que vai na tela.
#include <LiquidCrystal.h>
const uint8_t RS = 12, EN = 11, D4 = 5, D5 = 4, D6 = 3, D7 = 2;
LiquidCrystal lcd(RS, EN, D4, D5, D6, D7);
byte cedilha[8] = {
0b00000,
0b01110,
0b10000,
0b10000,
0b10001,
0b01110,
0b00100,
0b01000
};
void escreverLinha(uint8_t linha, const char *texto) {
char buffer[17];
snprintf(buffer, sizeof(buffer), "%-16s", texto);
lcd.setCursor(0, linha);
lcd.print(buffer);
}
void setup() {
lcd.begin(16, 2);
lcd.createChar(0, cedilha);
escreverLinha(0, "Estufa 1");
lcd.setCursor(0, 1);
lcd.print("Medi");
lcd.write(byte(0));
lcd.print("ao ok");
}
void loop() {
int temperatura = 24;
char texto[17];
snprintf(texto, sizeof(texto), "Temp: %d C", temperatura);
escreverLinha(0, texto);
delay(1000);
}
A função escreverLinha completa o texto com espaços até 16 caracteres. Isso elimina o resto de texto antigo sem chamar lcd.clear() a cada atualização, que faz a tela piscar. Note também que a sequência de pinos no construtor precisa ser exatamente a da tabela de ligação: trocar D4 com D5 no código produz exatamente o sintoma da fileira de blocos ou de texto embaralhado.
Por que "Atenção" vira lixo na tela
O código-fonte da IDE é salvo em UTF-8, em que "ç" e "ã" ocupam dois bytes cada. O display interpreta cada byte como um caractere da tabela interna dele, que na versão mais comum não tem acentos do português. O resultado são dois símbolos estranhos no lugar de cada letra acentuada. A solução é escrever sem acento ou criar até oito caracteres personalizados com createChar, como a cedilha do exemplo. Depois de createChar, chame setCursor antes de escrever, para voltar a posicionar o texto na tela.
Com adaptador I2C: endereço não é chute
O adaptador I2C, geralmente baseado no chip PCF8574 ou PCF8574A, reduz a ligação a quatro fios: GND, 5 V, SDA e SCL. No Uno, SDA é A4 e SCL é A5. O potenciômetro de contraste continua existindo, agora na plaquinha do adaptador, e precisa do mesmo ajuste.
Os endereços mais vistos são 0x27 e 0x3F, mas isso depende do chip e de jumpers de endereço na placa. Em vez de testar um por um, rode um scanner:
#include <Wire.h>
void setup() {
Serial.begin(115200);
Wire.begin();
Serial.println("Procurando dispositivos I2C...");
uint8_t encontrados = 0;
for (uint8_t endereco = 1; endereco < 127; endereco++) {
Wire.beginTransmission(endereco);
if (Wire.endTransmission() == 0) {
Serial.print("Encontrado em 0x");
if (endereco < 16) Serial.print("0");
Serial.println(endereco, HEX);
encontrados++;
}
}
if (encontrados == 0) {
Serial.println("Nada encontrado: confira SDA, SCL, GND e 5 V");
}
}
void loop() {}
Se o scanner não acha nada, o problema é fiação ou alimentação, não biblioteca. Se acha, ainda resta um detalhe: adaptadores diferentes ligam os pinos do PCF8574 ao display em ordens diferentes. Bibliotecas que assumem um mapeamento fixo mostram a fileira de blocos com o endereço certo. A biblioteca hd44780, com a classe hd44780_I2Cexp, tenta detectar o endereço e o mapeamento sozinha e devolve um código de erro em begin() quando falha, o que ajuda a separar problema de fiação de problema de configuração.
Erros comuns
- Reescrever o programa antes de ver os blocos: você muda o código por uma hora e o defeito era o potenciômetro no extremo.
- Pinos do construtor em ordem diferente da ligação: o display recebe comandos embaralhados e nunca sai da fileira de blocos.
- Chamar
lcd.clear()a cada volta do loop: a tela pisca e fica difícil de ler. - Escrever texto com acento direto: aparecem dois símbolos estranhos para cada letra acentuada.
- Ligar a luz de fundo sem saber se há resistor: o LED do display trabalha com corrente demais e escurece ou queima.
- Chutar o endereço I2C: você troca de biblioteca três vezes quando o adaptador estava em outro endereço ou com SDA e SCL invertidos.
Checklist
- Há cerca de 5 V entre VDD e VSS do display.
- Girar o contraste faz aparecer a fileira de blocos.
- Os pinos no construtor batem com a tabela de ligação.
- No I2C, o scanner encontrou o endereço do adaptador.
- A luz de fundo tem resistor, na placa ou externo.
- As linhas são escritas com preenchimento de espaços, sem limpar a tela a cada ciclo.
- Texto acentuado foi removido ou trocado por caracteres personalizados.
Ligue o seu display sem programa nenhum e gire o contraste de ponta a ponta: a fileira de blocos aparece? Se não aparece, o próximo passo é o multímetro, não o código.
Referência: http://labdegaragem.com/profiles/blogs/tutorial-lcd-com-arduino