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);
}
Concluindo, gostei muito deste display. Existem alguns desafios quanto à montagem mecânica, mas o resultado é muito legível e elegante (a foto no início não faz justiça ao display).
Nenhum comentário:
Postar um comentário