Objetivo
Em diversos projetos se faz necessário o uso de um display demonstrativo de informações, um muito utilizado é o Display OLED em seus variados tamanhos e formas de comunicação. Em razão disso, nesse tutorial serão apresentados os dois tipos de protocolos de comunicação que podem ser utilizados pelo OLED–I2C e SPI, com suas características, diferenças e configurações necessárias para uso, ao final das explicações, desenvolveremos um programa de projeção de logotipo na tela do Display. Acompanhe o menu interativo abaixo para pular para algum tópico específico do tutorial:
Introdução
Lista de Materiais
Protocolos de Comunicação
Comunição Assíncrona
Comunicação Síncrona
Envio e Recebimento de Dados
Seleção de Escravo
Comunicação I2C
Half Duplex
Principais Diferenças entre I2C e SPI
Teste do OLED SPI
Teste do OLED I2C
Conclusão
O OLED (Diodo Orgânico Emissor de Luz) é uma melhoria do LCD (Display de Cristal Liquido) o OLED conta com uma camada orgânica que emite luz quando estimulada por um campo eletromagnético. As principais vantagens do OLED em relação à tecnologia anterior são: o fato do mesmo consumir menos energia, ser mais leve, fino, apresentar maior contraste de cores, melhor brilho e maior ângulo de visão, essas características se dão pelo fato do OLED emitir luz própria, diferentemente do LCD que precisa de uma luz de fundo.
Existem displays OLEDs com variações de tamanho, cor, controlador, protocolo de comunicação e número de pinos, para o projeto utilizaremos um display OLED 128x64 Px – 0.96”- 7 pin Branco, mas não se aflija porque eu acrescentarei as informações necessárias para desenvolvimento com outros modelos de OLED. Vamos lá?
Para realizar a atividade proposta nesse tutorial, tenha em mãos os seguintes componentes:
01 - Protoboard
01- Arduino UNO
01- Resistor de 10KΩ
01- Display OLED 128x64 Px – 0.96” – 7 Pin
Você pode adquiri-los clicando em cada componente ou em nosso site:
https://www.curtocircuito.com.br/
Os protocolos de comunicação possibilitam a transmissão de dados entre o microcontrolador e os seus periféricos, existem alguns padrões como: I²C, UART, One Wire, SPI... Nesse tutorial vamos detalhar apenas o I²C e o SPI, pois são os utilizados pelo OLED.
-Comunicação Assíncrona
Em uma comunicação simples do tipo Assíncrona, não há confirmação quanto ao envio dos dados ou quanto à taxa de transmissão e recepção, em razão disso é necessário sincronizar com antecedência para que ambos os lados estejam na mesma taxa (Ex: 96000 Bps –Bits por segundo). Para que os dados sejam transmitidos em sua totalidade um bit extra é enviado no início e no final de cada byte, ou seja, a cada 8 bits, isso impede que uma mensagem corrompida seja interpretada pelo receptor, como pode ser visto na imagem abaixo:
Lembrando que TX representa o transmissor e RX o receptor.
Imagem retirada do site da Sparkfun
A desvantagem desse tipo de comunicação é o excesso de bits extras e a necessidade da pré-configuração de velocidade de transmissão e recepção para o seu funcionamento.
O Protocolo SPI funciona de forma Síncrona, ou seja, o mesmo conta com uma ligação de clock e uma destinada ao envio dos dados, o clock é responsável por manter o sincronismo, sendo um sinal oscilante que informa ao receptor o momento exato em que ocorre a transmissão, podendo atuar no modo de borda de descida ou borda de subida, no caso abaixo vemos o data representando o dado, e o clock agindo em borda de subida, analise que quando se inicia um pulso de clock, o dado é lido pelo receptor.
Imagem retirada do site da Sparkfun
Até o momento foi explicado como é feita uma comunicação unilateral, vamos entender agora como o receptor pode agir como transmissor também, primeiro é necessário ser esclarecido que o Transmissor é nomeado como Mestre (Master) e o Receptor como Escravo (Slave), em projetos normalmente temos um Mestre que é o microcontrolador, enquanto os periféricos atuam como escravos, podendo ser mais de um.
Quando o dado é enviado do Mestre para o Escravo, o pino é denominado MOSI (Master Output/ Slave Input – Mestre Saída/ Escravo Entrada), além do clock que normalmente é representado como SCK ou CLK.
Imagem retirada do site da Sparkfun
Como a Comunicação SPI é Full Duplex as linhas de recebimento e envio são separadas, ou seja, é possível que a recepção e a transmissão sejam feitas de forma simultânea.
Além dos pinos já mencionados, há o SS (Slave Select) ou CS (Chip Select), responsável por selecionar o Escravo que enviará e receberá os dados enviados. Normalmente é utilizado mais de um SS, sendo um para cada escravo, como pode ser visto na imagem seguinte:
Imagem retirada do site da Sparkfun
Como os escravos são ativados em nível lógico baixo, todos os SS devem ficar em nível alto, com exceção do selecionado, evitando que mais de um dado seja retornado para o mestre.
Uma outra forma de fazer a ligação é a ilustrada abaixo, o clock ativa um slave por vez, essa ligação normalmente é feita em registradores de deslocamento.
Imagem retirada do site da Sparkfun
O Protocolo SPI é um dos protocolos mais utilizados, sua comunicação é feita de forma síncrona full duplex. Para este protocolo são utilizados quatro pinos (SCK: Clock, MOSI: Master Out/Slave In, MISO: Master In/ Slave Out e CS: Chip Select), além dos pinos de alimentação (VCC e GND).
Explicando de forma mais detalhada, a configuração Full Duplex é capaz de transmitir dados e receber de forma simultânea em ambos os sentidos por conta do uso de diferentes linhas, um exemplo claro do uso é em serviços telefônicos.
O Protocolo I²C é síncrono half duplex e possui a vantagem da simplicidade de ligação, esse tipo de comunicação requer apenas dois pinos de dados (SDA: Dados e SCK: Clock) e os de alimentação (VCC e GND).
A comunicação Half Duplex, assim como a comunicação Full Duplex, é feita de forma bidirecional, ou seja, o escravo e o mestre agem como transmissor e como receptor, a diferença está no fato dessa troca não ser possível de forma simultânea, por haver apenas uma linha destinada a transmissão e recepção. Um exemplo do uso é em Walk-Talk.
Principais diferenças entre I²C e SPI
Em suma, o SPI é melhor para aplicações que exigem baixo consumo de energia e baixa velocidade, enquanto o I²C é mais utilizado em projetos que necessitam de um grande número de periféricos e alteração dinâmica na função mestre entre os periféricos no barramento.
Para fazer esse projeto temos que inicialmente conferir a ligação atrás do nosso OLED, o modelo escolhido para o tutorial pode funcionar tanto em SPI quanto em I²C, ele é enviado por nossa loja já pré-configurado para SPI.
SPI
Primeiramente baixe a biblioteca U8g2, você pode encontrá-la indo em Sketch> Incluir Biblioteca > Gerenciar Bibliotecas...
Em seguida faça uma busca por U8g2 e vá em “Instalar”
Depois de instalar, vá em Arquivo> Exemplos> U8g2 > page_buffer> GraphicsTest, ao abrir o exemplo você verá que existem muitas linhas comentadas, essas linhas correspondem aos modelos de display, devemos encontrar a linha do código que corresponde ao nosso display OLED.
Display OLED:
- Controlador: SSD1306;
- Dimensões: 128x64;
- Interface: SPI
Então as linhas comentadas que condizem com o nosso modelo são essas
Eu vou apagar as barras de comentário de uma delas, eu escolhi a primeira, então ligarei meu Oled conforme os pinos declarados na linha escolhida.
Como pode ser visto, clock ou SCK deve ser ligado ao pino 13 do Arduino, o data ou SDA ao 11, o CS ao 10, o DC ao 9 e reset ao 8.
Feita a alteração no código e a ligação, vamos conectar o Arduino ao computador e fazer as configurações para carregar o programa na placa Arduino.
Vá em ferramentas, selecione a placa Arduino Uno e a COM identificada.
Em seguida, carregue o programa em
Alguns símbolos e desenhos aleatórios irão aparecer, não se preocupe se eles parecerem desorganizados, é apenas um teste para confirmar se o seu OLED está exibindo imagens.
Se o seu display ainda estiver no modo SPI e você quiser fazer a configuração para I²C, prepare o ferro de solda e o estanho e mãos a obra.
Primeiramente devemos fazer as modificações necessárias na placa, como pode ser visto escrito na mesma, a configuração I2C depende da ligação de R1, R4 e R8, como o R4 é uma ligação semelhante entre os dois modos, manteremos o resistor de 0 Ohms fechando contato nesse ponto, o R3 é apenas para o SPI, então o removeremos, depois disso, faremos um caminho de estanho interligando os terminais de R8 para fechar contato (é exatamente essa a função dos 0 Ohms nos outros casos), e faremos o mesmo para R1, ficando da forma que pode ser visto abaixo.
Perceba que o contato está fechado apenas em: R1, R4 e R8, assim como escrito na placa.
Com isso, faremos a ligação e a instalação.
Se o DC for ligado ao GND, o endereço do I2C será 0X3C, se for ligado ao VCC será 0X3D. Os dispositivos I2C contam com endereços de identificação em hexadecimal, que para os casos podem ser interpretados de forma decimal da seguinte forma: o X representa que está em hexadecimal, o 0 deve vir antes como forma de anotação, a leitura de 0X3C, ou 3C será 60 em decimal, enquanto 0X3D, ou 3D será de 61, que representa o endereço que o OLED está ligado ao Arduino.
Quanto ao resistor de 10KΩ agindo como pull-up, a sua função é impedir o estado de floating (flutuante), que é quando o nível lógico do pino fica em um estado que não é identificado como alto e nem como baixo, então ele puxa para nível lógico alto, impedindo essa ambiguidade.
Ao fazer a ligação, vamos para a programação.
Se ainda lhe resta dúvidas quanto ao endereço, carregue o programa de Scan do I2C, o programa pode ser encontrado na biblioteca wire> i2c_scanner, segue o programa abaixo para o caso de alguma dificuldade em encontrar o exemplo.
#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(9600);
while (!Serial); /* Leonardo: wait for serial monitor */
Serial.println("\nI2C Scanner");
}
void loop() {
int nDevices = 0;
Serial.println("Scanning...");
for (byte address = 1; address < 127; ++address) {
/* The i2c_scanner uses the return value of
the Write.endTransmisstion to see if
a device did acknowledge to the address. */
Wire.beginTransmission(address);
byte error = Wire.endTransmission();
if (error == 0) {
Serial.print("I2C device found at address 0x");
if (address < 16) {
Serial.print("0");
}
Serial.print(address, HEX);
Serial.println(" !");
++nDevices;
} else if (error == 4) {
Serial.print("Unknown error at address 0x");
if (address < 16) {
Serial.print("0");
}
Serial.println(address, HEX);
}
}
if (nDevices == 0) {
Serial.println("No I2C devices found\n");
} else {
Serial.println("done\n");
}
delay(5000); /* Wait 5 seconds for next scan */
}
No monitor serial deve aparecer o endereço do seu OLED, que provavelmente irá se alterar se você trocar o fio DC de GND para VCC, faça esse teste.
Utilizando a mesma biblioteca anterior –U8glib, repetiremos o processo, Arquivo> Exemplos > U8glib> GraphicsTest.
Na linha com os comentários respectivos ao modelo do display, deve ser feito o mesmo que foi feito para o caso anterior, mas respeitando o protocolo I2C, então a linha que deve ser utilizada é a de I2C.
Como pode ser visto, nessa linha é declarado o modelo do display, além do protocolo. Apague essas barras desse comentário e insira novamente as barras de comentário na linha do SPI. Ou seja, insira as duas barras na linha 59 (se não tiver), e apague as barras da linha 64.
Para carregar o programa, faça como fizemos no exemplo anterior, selecione a porta e a placa.
Exibição do logotipo no OLED
Agora que o display está testado nos dois tipos de protocolos, partiremos para o nosso projeto de projeção de logotipo no display.
Primeiramente temos que editar a imagem que usaremos para que se encaixe nos padrões exigidos pelo OLED.
Você deve editar o logo para que ele fique em preto e branco e com dimensões de 128x64, assim como pode ser visto abaixo:
Você pode utilizar um programa de edição de imagens como Photoshop, Photoscape, entre outros para que a sua imagem fique de acordo e salvar em bitmap BMP (.bmp)
Depois de preparar a imagem, é necessário ter um programa para a transformação da imagem em código, o programa utilizado está disponível no link:
http://en.radzio.dxp.pl/bitmap_converter/
Depois de baixar, abra o arquivo .exe
Depois de carregar a imagem é necessário fazer as configurações necessárias quanto à orientação do byte, com relação ao tamanho entre outros.
Em byte orientation definiremos a orientação de acordo com o modelo do OLED, para o que estamos utilizamos, definiremos como orientação horizontal. O tamanho será respectivo ao tamanho da tela, para o caso é 128x64, selecionaremos Include Size para a matriz ser do tamanho da imagem, definiremos Size Endianness, sendo que representa o sentido de leitura do menos significativo para o mais significativo, a maioria dos microcontroladores utilizam o padrão de Little Endianness, apenas algumas raras exceções utilizam o Big Endianness, então marcaremos como Little. Definiremos também a quantidade de pixels/byte, para esse caso eu utilizo 8, para finalizar, escolha um nome para a constante que será gerada e salve em File> Save Output
Será gerado um arquivo com a imagem em código hexadecimal, para o programa você usará todo o trecho de const unsigned em diante...
Depois de copiar, você deve colar no programa abaixo, assim como eu fiz.
/**********************************************************************************************************
Programa: Logotipo
Autoria: Curto Circuito
Descrição:Esse é um simples programa exemplo de exibição de Logotipo para o tutorial de OLED - I2C x SPI
***********************************************************************************************************/
#include <Wire.h> /* Biblioteca que possibilita a comunicação I2C */
#define endereco 0x3C /* Endereço do display */
const unsigned char logotipo [] = { /* define constante "logotipo" */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF0, 0xF8, 0xFC,
0xFC, 0xFE, 0xFE, 0x7F, 0x7F, 0x7F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x7E, 0x7C, 0x78, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC0, 0xF0, 0xF8, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0x0F, 0x07,
0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x1C, 0x0E, 0x07, 0x07, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x03, 0x07, 0x0F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xE0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0xF0, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x00, 0x00, 0x03, 0x8E, 0xFC, 0xF8, 0xF0, 0xE0, 0xE0,
0xC0, 0xE0, 0x70, 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFC,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x81, 0xC3, 0xEB, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFE, 0xDA, 0x92, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x0F, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x80, 0x80, 0x00, 0x0F, 0x07, 0x03, 0x00, 0x01,
0x01, 0x00, 0x01, 0x03, 0x03, 0x07, 0x0C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0,
0xF8, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x07, 0x0F, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x7E, 0x7C, 0x78, 0x78, 0x70, 0x70, 0x70, 0x70,
0x70, 0x70, 0x78, 0x38, 0x38, 0x1C, 0x1E, 0x0F, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0,
0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xE0, 0xE0, 0xF0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF, 0xFF, 0x7F,
0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
0x07, 0x0F, 0x0F, 0x1F, 0x1F, 0x1F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x01, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
void setup() { /* laço de configuração */
/* inicializa controlador do OLED */
inicializar_oled();
}
void loop() { /* laço de repetição
Percorre a matriz e desenha os bytes */
char c;
for(int i = 0; i < 1024; i++)
{
Wire.beginTransmission(endereco);
Wire.write(0x40);
Wire.write(logotipo[i]); /* desenhar o byte correspondente */
}
}
void inicializar_oled()
{
Wire.begin(); /* Inicia a comunicação Arduino I2C */
/* Aumento da frequência de SCL para 400KHz, aumentando consequentemente a taxa de atualização */
TWBR = 12;
/* Inicia a comunicação */
Wire.beginTransmission(endereco);
/* Abriremos uma lista de comandos de configurações */
Wire.write(0x00);
/* Apagar a tela */
Wire.write(0xAE);
/* Definir o máximo de fileiras 0x3F = 63, indo de 0 a 63, totalizando 64 pixels */
Wire.write(0xA8);
Wire.write(0x3F);
/* offset é 0 */
Wire.write(0xD3);
Wire.write(0x00);
/* a linha começa em 0 */
Wire.write(0x40);
/*Inverte o eixo x, sendo 0xA0 utilizado para outra inversão */
Wire.write(0xA1);
/*Inverte o eixo x, sendo 0xC0 utilizado para outra inversão */
Wire.write(0xC8);
/* Mapear COM */
Wire.write(0xDA);
Wire.write(0x12);
/* Configurar o contraste */
Wire.write(0x81);
Wire.write(0x7F); /* Este valor tem que estar entre 0x00 (min) e 0xFF (max)*/
/*Este comando ordena que o chip ative a saída da tela de acordo com o conteúdo armazenado em GDDRAM */
Wire.write(0xA4);
/* Coloca a tela em modo Normal */
Wire.write(0xA6);
/* Define a velocidade do oscilador */
Wire.write(0xD5);
Wire.write(0x80);
/* ativa o 'charge pump' */
Wire.write(0x8D);
Wire.write(0x14);
/* Liga a tela */
Wire.write(0xAF);
/* Estabelece colunas e linhas */
Wire.write(0x21); /* Colunas de 0 a 127 */
Wire.write(0x00);
Wire.write(0x7F);
Wire.write(0x22); /* Linhas de 0 a 7 */
Wire.write(0x00);
Wire.write(0x07);
/*Modo de escritura horizontal
Wire.write(0x20);
Wire.write(0x00); */
/*encerra a comunicação
Wire.endTransmission(); */
/* Limpa a memória para o caso de resíduos */
for(int i = 0; i < 1024; i++){
Wire.beginTransmission(endereco);
Wire.write(0x40);
Wire.write(0x00);
Wire.endTransmission();
}
}
Toda a parte verde corresponde ao código hexadecimal da imagem, aquele que eu gerei com o LCD Assistant, substitua pelo código hexadecimal referente ao seu logotipo.
Ao carregar, é possível visualizar o logo no OLED, como pode ser visto abaixo.
Com o acompanhamento do tutorial, é possível ter um breve vislumbre do display OLED e suas finalidades, sendo que o modelo em questão apresenta a vantagem de permitir o uso em dois procolos (SPI ou I²C), no tutorial vimos como utilizá-lo em ambas. Além do mais, aprendemos a criar uma imagem específica, abrindo um leque de possibilidades de projetos. Espero que vocês tenham gostado e não se esqueçam de deixar o feedback nos comentários.
Abraços, Curto Circuito :)
Não entendi a última parte em que você diz "Depois de copiar, você deve colar no programa abaixo, assim como eu fiz". Pode explicar melhor como colocar o logo no LCD?
Não entendi a última parte em que você diz "Depois de copiar, você deve colar no programa abaixo, assim como eu fiz". Pode explicar melhor como colocar o logo no LCD?
Desculpe, como o nosso site passou por atualizações, alguns arquivos foram perdidos e o programa para a geração do logotipo foi um deles, eu upei esse programa novamente, por favor verifique se agora ficou claro o procedimento, para qualquer dúvida estaremos a disposição.
Abraços,
Caroline Locatelli :)