Conectando o LCD no Arduino de todos os modos.
Esse artigo mostra a montagem que fiz para ligar o display LCD 20X4 no Arduino Uno.
Caro leitor, trata-se da continuação do artigo “Posso ligar esse LCD no Arduino?” apresentando o hardware funcionando e tecendo algumas considerações sobre as quatro configurações possíveis do circuito do LCD e o seu casamento com o software. Como de sempre, sua presença em meu site é motivo de orgulho e satisfação. Sinta-se à vontade para ler e propor melhorias no conteúdo.
Se você curtir esse artigo, não esqueça de dar uns cliques nos anúncios para ver o que os anunciantes tem para te oferecer. Vou ficar muito contente.
Um grande abraço e boa leitura!
O hardware:
A placa de suporte do display:
A imagem é clara. Trata-se de uma “solução técnica de baixo custo”. Não é gambiarra.
Como os conectores do módulo LCD não batiam com o protoboard, eu montei o LCD sobre essa placa usada, redirecionando os pinos para funcionarem no protoboard.
Dessa forma e tosco desse jeito, o LCD não fica solto sobre o protoboard, balançando e com risco de entrar em curto circuito. Também garanto o acesso a todos os pinos de entrada e saída do módulo LCD.
Antes que perguntem, os displays de leds da figura 1, ao lado do Arduino tem a mesma função. Eles servem para impedir que a placa Arduino fique se movendo, diminuindo o risco de curtos.
Aquele fio amarelo solto, está ligado no pino 24 do KS0066, que é o sinal OSC1. Vou falar dele mais adiante, nesse artigo.
A biblioteca LiquidCrystal e o hardware
Analisando a biblioteca LiquidCrystal, dá para ver que o construtor da classe LiquidCrystal pode ser inicializado de quatro formas diferentes (A biblioteca completa está disponível no GitHub ->nesse link<-).
Confira o trecho do código :
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | //Primeiro modo de inicialização, //Modo 8 bits habilitando leitura e escrita no display. LiquidCrystal::LiquidCrystal( uint8_t rs, uint8_t rw, uint8_t enable, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) { init(0, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7); } //Fim do primeiro modo de inicialização //Segundo modo de inicialização, //Modo 8 bits habilitando apenas a escrita no display. LiquidCrystal::LiquidCrystal( uint8_t rs, uint8_t enable, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) { init(0, rs, 255, enable, d0, d1, d2, d3, d4, d5, d6, d7); } //Fim do segundo modo de inicialização //Terceiro modo de inicialização, //Modo 4 bits, habilitando leitura e escrita no display. LiquidCrystal::LiquidCrystal( uint8_t rs, uint8_t rw, uint8_t enable, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) { init(1, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0); } //Fim do terceiro modo de inicialização //Quarto modo de inicialização, //Modo 4 bits, habilitando apenas a escrita no display. LiquidCrystal::LiquidCrystal( uint8_t rs, uint8_t enable, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) { init(1, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0); } //Fim do quarto modo de inicialização |
Analisando o código e a documentação do chip, é possível inferir que essa biblioteca se aplica a quatro tipos de configurações de hardware, a saber:
- Modo 8 bits habilitando leitura e escrita no display (RW)
- Modo 8 bits habilitando apenas a escrita no display (W)
- Modo 4 bits habilitando leitura e escrita no display (RW)
- Modo 4 bits habilitando apenas a escrita no display (W)
Conforme dito, esse artigo vai abordar as quatro possíveis variações na instalação do LCD e as quatro possíveis implementações do construtor da classe LiquidCrystal, ou seja, este artigo demonstra como implementar a biblioteca LiquidCrystal de acordo com a configuração de hardware adotada. Para elaboração do diagrama esquemático e imagens do protoboard, foi utilizado o software Fritzing e os diagramas esquemáticos estão disponíveis para download -> nesse link aqui <-
Pinagem do LCD
Tabela abaixo, para referência, mostra a pinagem do LCD utilizado:

8 bits Read Write – Hardware e programa
Diagrama esquemático, figuras 3 e 4:
Programa:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | // //Programa: Teste de Display LCD 20X4, modo 8 bits READ e WRITE //Esse programa usa o sinal RW pino nr 5 do display. //O sinal RW deve ser conectado no pino 11 do barramento do Arduino. // //Definindo os pinos que serão utilizados para ligação ao display // //Os argumentos do construtor LiquidCristal representam o número do pino //do Arduino que recebe o sinal do display: rs, rw, enable e etc. //LiquidCrystal(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7) // //De acordo com o número de argumentos, LiquidCristal consegue inicializar //o display dentro de um dos quatro modos possíveis: //8bits read e write, 8bits write, 4bits read e write ou 4 bits write. // //Tomar cuidado caso utilize os pinos TX (0) e RX (1) //do Arduino. Esses pinos podem interferir na compilação e a carga //do programa no Arduino. // //Carrega a biblioteca LiquidCrystal #include <LiquidCrystal.h> LiquidCrystal lcd(10, 11, 12, 2, 3, 4, 5, 6, 7, 8, 9); void setup() { //Define o número de colunas e linhas do LCD lcd.begin(20, 4); //Limpa a tela lcd.clear(); //Posiciona o cursor na coluna 8, linha 0 lcd.setCursor(8, 0); //Envia o texto entre aspas para o LCD lcd.print( "NETS" ); //Posiciona o cursor na coluna 9, linha 1 lcd.setCursor(9, 1); //Envia o texto entre aspas para o LCD lcd.print( "&&" ); //Posiciona o cursor na coluna 8, linha 2 lcd.setCursor(8,2); //Envia o texto entre aspas para o LCD lcd.print( "NUTS" ); //Posiciona o cursor na coluna 5, linha 3 lcd.setCursor(6,3); //Envia o texto entre aspas para o LCD lcd.print( "LCD 20x4" ); delay(5000); } void loop() { //armazena a posição do cursor int posicao_final; //Deslocando para a esquerda for ( int posicao = 0; posicao < 6; posicao++) { lcd.scrollDisplayLeft(); delay(300); } //Deslocando para direita for ( int posicao = 0; posicao < 12; posicao++) { lcd.scrollDisplayRight(); delay(300); //Guardando a posição do cursor posicao_final = posicao; } //Voltando para o centro for ( int posicao = posicao_final; posicao > 5; posicao--) { lcd.scrollDisplayLeft(); delay(300); } } |
8 bits Write – Hardware e programa
Diagrama esquemático, figuras 5 e 6:
Programa:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | // //Programa: Teste de Display LCD 20X4, modo 8 bits WRITE // //Esse programa NÃO USA o sinal RW, pino nr 5 do display. //O pino RW, nr 5 do display deve ser aterrado para funcionar com essa //versão do programa. // // //Definindo os pinos que serão utilizados para ligação ao display // //Os argumentos do construtor LiquidCristal representam o número do pino //do Arduino que recebe o sinal do display: rs, enable e etc. //LiquidCrystal(rs, enable, d0, d1, d2, d3, d4, d5, d6, d7) // //De acordo com o número de argumentos, LiquidCristal consegue inicializar //o display dentro de um dos quatro modos possíveis: //8bits read e write, 8bits write, 4bits read e write ou 4 bits write. // //Tomar cuidado caso utilize os pinos TX (0) e RX (1) //do Arduino. Esses pinos podem interferir na compilação e a carga //do programa no Arduino se estiverem em uso. // //Carrega a biblioteca LiquidCrystal #include <LiquidCrystal.h> LiquidCrystal lcd(10, 12, 2, 3, 4, 5, 6, 7, 8, 9); void setup() { //Define o número de colunas e linhas do LCD lcd.begin(20, 4); //Limpa a tela lcd.clear(); //Posiciona o cursor na coluna 8, linha 0 lcd.setCursor(8, 0); //Envia o texto entre aspas para o LCD lcd.print( "NETS" ); //Posiciona o cursor na coluna 9, linha 1 lcd.setCursor(9, 1); //Envia o texto entre aspas para o LCD lcd.print( "&&" ); //Posiciona o cursor na coluna 8, linha 2 lcd.setCursor(8,2); //Envia o texto entre aspas para o LCD lcd.print( "NUTS" ); //Posiciona o cursor na coluna 5, linha 3 lcd.setCursor(6,3); //Envia o texto entre aspas para o LCD lcd.print( "LCD 20x4" ); delay(5000); } void loop() { //armazena a posição do cursor int posicao_final; //Deslocando para a esquerda for ( int posicao = 0; posicao < 6; posicao++) { lcd.scrollDisplayLeft(); delay(300); } //Deslocando para direita for ( int posicao = 0; posicao < 12; posicao++) { lcd.scrollDisplayRight(); delay(300); //Guardando a posição do cursor posicao_final = posicao; } //Voltando para o centro for ( int posicao = posicao_final; posicao > 5; posicao--) { lcd.scrollDisplayLeft(); delay(300); } } |
4 bits Read Write – Hardware e programa
Diagrama esquemático, figuras 7 e 8:
Programa:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | //Programa: Teste de Display LCD 20X4 usando bus de 4 bits, modo RW // //Esse programa usa o sinal RW do pino nr 5 do display. //O pino nr 5 deve ser ligado ao pino nr 1 do Arduino. // // //Para fazer esse programa, eu dei uma espiada no site abaixo: // //Nesse programa foram feitas as seguintes melhorias: //Alterada a rotina setup para o texto ser escrito somente na inicialização do display //A compatibilização com o display 20X4, //Adicionada a rotina para o display voltar para o centro // //Tomar cuidado caso utilize os pinos TX (0) e RX (1) //do Arduino. Esses pinos podem interferir na compilação e a carga //do programa no Arduino se estiverem em uso. //Carrega a biblioteca LiquidCrystal #include //Define os pinos que serão utilizados para ligação ao display //Aqui eu vou habilitar o sinal RW no pino 1. LiquidCrystal lcd(12, 1, 11, 5, 4, 3, 2); void setup() { //Define o número de colunas e linhas do LCD lcd.begin(20, 4); //Limpa a tela lcd.clear(); //Posiciona o cursor na coluna 8, linha 0 lcd.setCursor(8, 0); //Envia o texto entre aspas para o LCD lcd.print( "NETS" ); //Posiciona o cursor na coluna 9, linha 1 lcd.setCursor(9, 1); //Envia o texto entre aspas para o LCD lcd.print( "&&" ); //Posiciona o cursor na coluna 8, linha 2 lcd.setCursor(8,2); //Envia o texto entre aspas para o LCD lcd.print( "NUTS" ); //Posiciona o cursor na coluna 5, linha 3 lcd.setCursor(6,3); //Envia o texto entre aspas para o LCD lcd.print( "LCD 20x4" ); delay(5000); } void loop() { //armazena a posição do cursor int posicao_final; //Deslocando para a esquerda for ( int posicao = 0; posicao < 6; posicao++) { lcd.scrollDisplayLeft(); delay(300); } //Deslocando para direita for ( int posicao = 0; posicao < 12; posicao++) { lcd.scrollDisplayRight(); delay(300); //Guardando a posição do cursor posicao_final = posicao; } //Voltando para o centro for ( int posicao = posicao_final; posicao > 5; posicao--) { lcd.scrollDisplayLeft(); delay(300); } } |
4 bits Write – Hardware e programa
Diagrama esquemático, figuras 9 e 10:
Programa:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | //Programa: Teste de Display LCD 20X4 usando bus de 4 bits, modo W // //Esse programa não usa o sinal RW do pino nr 5 do display. //O pino nr 5 deve ser aterrado (ligado no negativo). // // //Para fazer esse programa, eu dei uma espiada no site abaixo: // //Nesse programa foram feitas as seguintes melhorias: //Alterada a rotina setup para o texto ser escrito somente na inicialização do display //A compatibilização com o display 20X4, //Adicionada a rotina para o display voltar para o centro // //Tomar cuidado caso utilize os pinos TX (0) e RX (1) //do Arduino. Esses pinos podem interferir na compilação e a carga //do programa no Arduino se estiverem em uso. //Carrega a biblioteca LiquidCrystal #include //Define os pinos que serão utilizados para ligação ao display LiquidCrystal lcd(12, 11, 5, 4, 3, 2); void setup() { //Define o número de colunas e linhas do LCD lcd.begin(20, 4); //Limpa a tela lcd.clear(); //Posiciona o cursor na coluna 8, linha 0 lcd.setCursor(8, 0); //Envia o texto entre aspas para o LCD lcd.print( "NETS" ); //Posiciona o cursor na coluna 9, linha 1 lcd.setCursor(9, 1); //Envia o texto entre aspas para o LCD lcd.print( "&&" ); //Posiciona o cursor na coluna 8, linha 2 lcd.setCursor(8,2); //Envia o texto entre aspas para o LCD lcd.print( "NUTS" ); //Posiciona o cursor na coluna 5, linha 3 lcd.setCursor(6,3); //Envia o texto entre aspas para o LCD lcd.print( "LCD 20x4" ); delay(5000); } |
Resolvi testar e não deu certo:
Isso é mais comum que parece, normalmente o erro está bem na frente e algo foi pulado, passado para traz.
Algumas dicas que dou:
Vai tomar um café, uma água, um suco de laranja, almoçar, ver TV. Dá um tempo de no mínimo uma hora, que na volta você vai encontrar o problema.
Releia com calma todos os artigos pesquisados. Cheque as referências nos artigos e refaça o circuito do zero.
Releia e entenda o código. Se possível debugue o código.
Caso eventualmente você queira confirmar se o display está queimado, faça o seguinte:
Ligue o display e meça com osciloscópio o clock interno do display. No meu caso é o sinal OSC1 (aquele fio que soldei e deixei solto lá em cima). Para você localizar esse sinal, precisa consultar a documentação do seu display e ver se dá para pegar ela em algum lugar da placa.
Deve aparecer uma forma de onda semelhante à figura 11 abaixo e dentro da especificação do fabricante do seu display. Se não aparecer nada, ele está queimado ou desligado. Aparecendo a forma de onda, há grande chance do display estar funcionando.

Finalizando:
Conforme proposto no início desse artigo foi apresentado um ponto de partida para a instalação e configuração de um LCD com o Arduino, descrevendo quatro modos de ligar o display LCD com os respectivos programas, a saber:
- 4 bits modo Write
- 4 bits modo Read e Write
- 8 bits modo Write
- 8 bits modo Read e Write.
Os programas foram mantidos próximos uns dos outros, permitindo que o programador levante os difs deles e possa estudá-los mais a fundo.
À primeira vista o display é apenas uma tela para se escrever uma mensagem ao usuário. Mas ao analisarmos o datasheet conforme abordado no artigo “Posso ligar esse LCD no Arduino?”, podemos ver que se trata de um sistema com clock, controlador, memória e outras estruturas bem complexas.
Tão complexas que o display permite acesso a seus registros internos. Dá para pegar a posição do cursor, ler a memória interna do display, ler o registro de instruções e, desde que seja implementado em software, dá para escrever no registro de dados, assunto que fica para um artigo posterior.
Como de praxe, comentários e sugestões de melhoria desse artigo são bem vindos :-).