terça-feira, 14 de agosto de 2012

Usando o LCD 16x4: μLiquidCrystal

Recentemente (ontem) descobri que o .NET MF inclui suporte avançado para interfaces gráficas. Existem algumas placas como a Tahoe II, ChipworkX, or FEZ Cobra que tem display gráfico e que podem ser manipulados pelas classes implementadas no .NETMF, um dia vou utilizar, até porque eu tenho alguns displays (LCD) prevenientes da sucata que eu pretendo utilizar para alguma finalidade.

Contudo, o mais comum entre os hobbistas brasileiros são os tradicionais display's alfanuméricos em linha, em especial o de 16 caracteres por duas linhas "16x2". Eu já fiz enumeras aplicações utilizando PIC e LCD's seja para mostrar um simples valor ou debugar uma aplicação.

 O meu objetivo com esse artigo é fazer uma apanhado de tudo que eu encontrei sobre LCD nesse mar de internet e mostrar uma solução viável e relativamente elegante que pode ser utilizada para aplicações futuras (minhas também). É importante notar que esse blog para mim é uma espécie de documentação dos meus códigos, assim eu não perco nada.

Os LCD de 16x2 são muito populares porque a maneira de comunicar é através de um barramento paralelo podendo ser usado com as velhas portas LPT1 (impressoras) o que popularizou bastante o seu uso além de permitir uma "emulação manual" da mensagem, ou seja, você pode prender uma porção de chaves e repetir exaustivamente o procedimento de entrada dos dados até mostrar a mensagem no LCD, a alguns anos atrás isso aqui no Brasil era vital porque na maior parte dos entusiastas não tinham osciloscópio e o diagnóstico do código era por Led mesmo (aceso e apagado).

Os tempos mudaram mas o preço ainda continua bem atrativo, comprei dois por R$ 17,00 a unidade na loja Solda Fria enquanto o equivalente gráfico custava a bagatela de R$ 60,00, quase o preço do Netduino.

A desvantagem da comunicação paralela é quantidade de IO's que serão "mortas", oito para ser mais exato e isso é um problema quando só se tem 14IO's disponíveis (lamentável o Netduino usar um Chip com 50 IO e só disponibilizar na placa 14 pinos). Outra desvantagem grande é quando é necessário colocar o LCD longe da placa de controle, vide o exemplo do controlador doméstico; controlando portas e janelas pelos pinos IO é conveniente que a unidade de controle fique num lugar perto do roteador para transferir os dados e ao mesmo tempo perto do centro da casa equidistante dos pontos de controle e o LCD nisso tudo não ficará perto da placa sendo necessário passar um cabo de 5 pares (10 fios)  para o LCD.

Naturalmente a aplicação ditará a forma mais fácil de se implementar o LCD. Contudo nesse artigo  procurei uma solução que atendesse a maioria das aplicações de maneira geral e com um custo em termos de software menor. A melhor solução foi a apresentada por Pavel Bánský em seu blog. Trata-se de dois artigos onde o primeiro artigo foi realizada uma análise da multiplexação do sinal do LCD para utilização de 3 fios e a segundo artigo relacionado foi construída uma aplicação envolvendo o hardware de I²C do microcontrolador para reduzir o custo de software.

Além do trabalho do Pavel ainda tem uma excelente referência na internet que é o projeto μLiquidCrystal que começou como um porjeto do Szymon Kobalczyk's  e depois foi ganhando corpo e agora é um pacote completo de classes para tratamento de dispositivos como LCD's e Display's.

Praticamente todos esses LCD's populares são feitos com o controlador HD44780que provê essa comunicação paralela. O conector padrão de 16 pinos em linha no canto inferior direito da placa do LCD também é bem típico podendo utilizar uma combinação de 8 bit's paralelos de informação ou 4 bits (pseudo serial), ou seja, dos  16 pinos 8 são para comunicação uma alimentação lógica, dois pinos para alimentação da luz de fundo, o pino de terra e a alimentação do LCD propriamente dito e mais dois pinos de comunicação serial totalizado os 16 pinos.


As instruções de escrita e leitura é um padrão que Pavel Bánský mostrou que é simples de se multiplexar com registrador de deslocamento e colocar o código para dentro do Netduino. Pavel usou o CMOS 4094 que é o mesmo que o 74HC595 só que é TTL que aceita como nível alto valores acima de 2,5V o que significa que você pode pendurar um LCD de 5V diretamente com as IO's do Netduino sem precisar de um circuito extra, apenas o registrador de deslocamento 74HC595. Mais ainda, se você quiser usar um LCD de 3,3V basta colocar um divisor restivo de feito com uma série de 1,68kOhms e 3,3kOhms que o nível de saída será de 3,3V.

Pavel implementou o tratamento do LCD em duas camas de funções uma por baixo da outra. A classe que realmente é incluída nos códigos é a LiquidCrystal e em um segundo nível a requerida  ILiquidCrystalTransferProvider que trata da interfaceamento de hardware assim você pode utilizar a mesma classe por cima com manipuladores de hardware diferentes, os dois implementados por Pavel são: GpioLiquidCrystalTransferProvider e HC4094 que na página do Szymon ele passou a chamar de Shifter74Hc595LiquidCrystalTransferProvider, isso porque Szymon estava usando o 74595 para interfacear o LCD.

Tem outras coisas implementas relacionas com algumas placas de expansão para LCD dotadas de chip para comunicação, como estamos no Brasil, o máximo que se encontra é uma comunicação serial feita com uma placa de expansão com PIC16F628 ou algo do tipo. As implementações feitas pelo Pavel e pelo  Szymon incluem suporte aos chips MCP23008 e PCF8574P numa classe chamada BaseShifterLiquidCrystalTransferProvicer.

O Szymon no seu blog mencionou a comunicação SPI para conversar como o LCD, uma alternativa caso o barramento I²C esteja carregado muito embora eu não tenha visto a forma com que ocorre o tratamento da comunicação SPI. A SPI no Netduino está disponível através dos pinos 11 (MOSI), 12 (MOSO) e 13 (SPCK) e outro pino qualquer para selecionar o escravo desejado. Essa implementação do Szymon faz parte do  μLiquidCrystal, que realmente não testei, mas vale a pena dar uma olhada.


Com relação ao circuito, vale algumas considerações. A primara diz respeito a um transistor NPN (eu usei o BC548 mas o 2N2222 é equivalente americano) que tipicamente se coloca para controle da luz de fundo do LCD através de uma saída do registrador de deslocamento assim é possível ligar e desligar o LCD pelo código caso deseje economizar energia.A outra é controle do brilho do LCD que pode ser feito colocando um potenciômetro de 47kOhms a 2kOhms, ou se não quiser ajustar apenas coloque um divisor resistivo e pronto.

O Pavel criou uma biblioteca (que como tava velha tive que recriá-la no .NETMF 4.2) chamada de Bansky.SPOT.LCD onde existem os métodos ITransferProvider e SendByte utilizados para interfacear uma camada com a outra.

O código de teste é esse:

>// Create instance of shift register 
// (Serve para o 74595!!)
HC4094 shifter = new HC4094(Pins.GPIO_PIN_D0 ,     
                                Pins.GPIO_PIN_D2, 
                                Pins.GPIO_PIN_D1,
                                false);          
// Create new LCD instance 
LCD4Bit lcd = new LCD4Bit(shifter);

// Turn display on, turn back light on,
//hide small cursor, show big blinking cursor
lcd.Display(true, true, false, true);

//Limpa a janela
lcd.Clear();  
//Escrever a mensagem na 1ª Linha
lcd.Write("Victor M. >>>>>>>>"); 
//Passa o cursor para 2ª Linha
lcd.SetPosition(40);          
//Escreve na 2ª Linha
lcd.Write(".NETMF Q2");

Thread.Sleep(Timeout.Infinite);

Note que o fluxo do processo é bem simples:
  1. Criar a classe da primeira camada informando os pinos do hardware que estão sendo usados para tal função;
  2. Criar a classe de manipulação do LCD partindo do hardware;
  3. Ajustar o que se deseja mostrar no LCD (no caso o quadro piscante);
  4. Limpar o LCD;
  5. Escrever a mensagem.

Não existe muito mais o que falar sobre o LCD, é bem simples mesmo, o que meu mais trabalho foi montar o circuito na protoboard do que entender o funcionamento. E ai na foto eu mostro resultado final:



Você pode fazer download do programa aqui para testá-lo.

Nenhum comentário:

Postar um comentário