Montagem
Do ponto de vista elétrico, a montagem é muito simples. Mas, na prática, existem alguns detalhes a considerar.
O primeiro detalhe é que os pinos do display tem um espaçamento de 0.05", o que é a metade do espaçamento padrão para integrados DIP. Portanto não dá para espetar em uma protoboard. Para o meu teste eu soldei alguns fios grosseiramente. Olhando o display de frente, o pino 1 é o primeiro da esquerda
Além dos pinos na parte inferior do display é preciso ligar o backlight, cujos terminais estão na margem direita. Olhando o display de frente, o terminal superior é o catodo (K) e o inferior é o anodo (A).
Operando a 5V, as ligações necessárias são:
- Os pinos 1 e 4 devem ser ligados ao 5V do Arduino.
- Os pinos 2 e 3 não são usados.
- O pino 5 e o terminal K devem ser ligados ao GND do Arduino.
- O pino 6 deve ser ligado ao pino SDA do Arduino. No Uno é o pino A4, em outros modelos muda (veja aqui).
- O pino 7 deve ser ligado ao pino SCL do Arquino, que no Uno é o A5.
- Liguei o pino 8 (Reset) ao pino 12 do Arduino. Se você está confiante que nada vai dar errado durante o uso, pode ligar através de um resistor de 10K ao 5V.
- O terminal A deve ser ligado ao 5V através de um resistor. Usando os números do datasheet (tensão do LED do backlight de 3,5V e corrente de 30mA), o valor deveria ser 50 ohms. Eu usei 220 ohms e achei que ficou bom.
A interface I2C (ou TWI para não usar a marca registrada) é suportada pelo hardware do ATmega e pela biblioteca padrão Wire do Arduino (documentação aqui). Resumindo uma longa história, o I2C usa dois sinais, SCL (clock, gerado pelo mestre) e SDA (dados, bidirecional); sinalizações especiais (start e stop) indicam o início e o fim de uma comunicação. É uma interface do tipo barramento ("varal") onde múltiplos dispositivos podem ser ligados a um mestre (no nosso caso o Arduino). Cada dispositivo tem um endereço (no caso deste display, 0x3E). São necessários resistores de pull-up para os dois sinais, mas a biblioteca Wire ativa os resistores internos do ATmega.
O uso da biblioteca, no nosso caso, ser restringe a 4 funções:
- Wire.begin: configura o hardware do ATmega
- Wire.beginTransmission: determina o endereço do dispositivo com que vamos falar
- Wire.write: coloca um byte na fila de transmissão
- Wire.endTransmission: transmite os bytes enfileirados, enviando um start no início e um stop ao final
Este programa de teste se limita a mostrar uma mensagem e um relógio (tosco) no display. A sequência de iniciação foi copiada diretamente do datasheet; por ela dá para perceber que a interface I2C se conecta ao controlador de display no modo 8 bits. Uma vez que não é possível ler o sinal Busy (ocupado) do controlador, coloquei algumas pausas, grosseiramente baseadas nos tempos indicados no datasheet. O datasheet não explicita isto, mas o sinal de Reset é ativo baixo (isto é, precisa ficar em nível alto durante a operação normal).
- // Teste de conexão do display WO1602G ao Arduino
- // http://dqsoft.blogspot.com
- #include <Wire.h>
- const int pinRst = 12;
- const int addrDisp = 0x3E;
- const byte selReg = 0;
- const byte selDado = 0x40;
- byte seg, minuto, hora;
- // Iniciação
- void setup()
- {
- // Pulsa pino de reset
- pinMode (pinRst, OUTPUT);
- digitalWrite (pinRst, LOW);
- delay (1);
- digitalWrite (pinRst, HIGH);
- delay (500);
- // Inicia I2C
- Wire.begin();
- // Configura o display
- DisplayInit();
- // Mostra mensagens
- DisplayWrite (0, 0, "DQSoft");
- DisplayWrite (1, 0, "00:00:00");
- }
- // Rotina chamada periodicamente
- // Coloca um "relógio" na segunda linha
- void loop ()
- {
- if (++seg == 60)
- {
- seg = 0;
- if (++minuto == 60)
- {
- minuto = 0;
- if (++hora == 99)
- hora = 0;
- DisplayWriteDec (1, 0, hora);
- }
- DisplayWriteDec (1, 3, minuto);
- }
- DisplayWriteDec (1, 6, seg);
- delay (1000); // aguarda um segundo
- }
- // Faz a iniciação do display
- void DisplayInit ()
- {
- DisplayOut (selReg, 0x38);
- DisplayOut (selReg, 0x39);
- DisplayOut (selReg, 0x14);
- DisplayOut (selReg, 0x79);
- DisplayOut (selReg, 0x50);
- DisplayOut (selReg, 0x6C);
- DisplayOut (selReg, 0x0C);
- DisplayOut (selReg, 0x01);
- delay (2);
- }
- // Mostra número decimal de 00 a 99
- void DisplayWriteDec (byte l, byte c, byte num)
- {
- char aux[3];
- aux[0] = 0x30 + num / 10;
- aux[1] = 0x30 + num % 10;
- aux[2] = 0;
- DisplayWrite (l, c, aux);
- }
- // Posiciona o cursor e mostra mensagem
- void DisplayWrite (byte l, byte c, char *msg)
- {
- byte addr = c;
- if (l == 1)
- addr += 0x40;
- DisplayOut (selReg, 0x80 + addr);
- while (*msg)
- {
- DisplayOut (selDado, *msg++);
- }
- }
- // Envia um byte de controle e um byte de dado
- void DisplayOut (byte c, byte d)
- {
- Wire.beginTransmission (addrDisp);
- Wire.write (c);
- Wire.write (d);
- Wire.endTransmission ();
- delayMicroseconds (30);
- }
Nenhum comentário:
Postar um comentário