sexta-feira, 7 de outubro de 2016

Termômetro digital de precisão com o LM73.

Termômetro digital de precisão com o LM73.

O LM73 é um sensor digital de temperatura de precisão com interface I²C, com resolução máxima de 1/32 de grau Celsius (0.03125°C/LSB). Para testá-lo e ver seu desempenho, montei uma placa tendo o cuidado de deixar sua face superior exposta para fazer o acoplamento térmico e assim medir a temperatura com maior precisão.
Para mostrar a temperatura, o firmware mostra a parte inteira simplesmente convertendo os bits mais significativos em decimal e a parte fracionária de 1/32 é usado uma tabela tabela de conversão na memória do PIC12F1822:

00000b ,00°
00001b ,03°
00010b ,06°
00011b ,09°
00100b ,13°
00101b ,16°
00110b ,19°
00111b ,22°
01000b ,25°
01001b ,28°
01010b ,31°
01011b ,34°
01100b ,38°
01101b ,41°
01110b ,44°
01111b ,47°
10000b ,50°
10001b ,53°
10010b ,56°
10011b ,59°
10100b ,63°
10101b ,66°
10110b ,69°
10111b ,72°
11000b ,75°
11001b ,78°
11010b ,81°
11011b ,84°
11100b ,88°
11101b ,91°
11110b ,94°
11111b ,97°

Placa do LM73. Note o IC abaixo das letras LM, um SOT23 de 5 pinos rodeado por resina epoxi cinza.
Placa com um PIC12F1822 e o minúsculo display OLED 128x32 mostrando a temperatura do LM73.
Medindo a temperatura da geladeira.









terça-feira, 4 de outubro de 2016

Complemento do post anterior do Relógio de precisão/Termômetro/Higrômetro

         Complementando o post sobre o Relógio de precisão/Termômetro/Higrômetro com o DS3231, HDC1080 e PIC16F1503.

Mesma placa do relógio mas com um display OLED cujas duas primeiras páginas são amarelas, o resto é azul. Por usar a mesma pinagem, fica intercambiável com o display LCD.
Na última linha é mostrada a temperatura interna do DS3231.

Display como veio do vendedor, ainda com a proteção. Abaixo dele o adaptador onde usei um conector de cartão de memória CompactFlash cortado.
Adaptador conectado ao display. Embaixo da resina epoxi cinza estão os capacitores do chargepump e o circuito RC de RESET.












segunda-feira, 3 de outubro de 2016

Relógio de precisão/Termômetro/Higrômetro com o DS3231, HDC1080 e PIC16F1503

        Recentemente a Texas Instruments me forneceu duas amostras de seu novo sensor de umidade/temperatura HDC1080 com interface I²C. Há muito tempo queria montar um relógio preciso que medisse estas grandezas assim como não perdesse a hora quando falta energia elétrica.
         Este sensor usa um encapsulamento com terminais muito pequenos, assim montei uma placa adaptadora.
Sensor HDC1080 montado por baixo da placa, com a abertura expondo a parte sensora no centro do furo.

        A medição do tempo é feita pelo DS3231, um RTC de alta precisão com o cristal de quartzo incorporado no encapsulamento, com compensação de temperatura e com interface I²C. Este RTC vem num SOIC de 16 pinos dos quais somente metade é usada. Fiz um adaptador DIP para ele.
        Para controlar tudo, usei um PIC16F1503, que só consegui com encapsulamento SOIC, também tendo que fazer um adaptador DIP.

Placa do relógio, com o PIC16F1503 e o DS3231 com seus horrendos adaptadores DIP. Há também a bateria de lítio pendurada.
Vista de baixo.
        O display usado é um Winstar WO1602, de 16x2 caracteres também com interface I²C (comprado na TATO Equipamentos Eletrônicos). Este tem um backlight simples de LED e usa o controlador Sitronix ST7032. Para operar em 3,3V, este display usa um charge pump composto de dois capacitores, assim montei uma pequena placa com os mesmos mais o IC TC54 para fazer o RESET e adaptar os pequenos pinos de interface.  Preferi usar um display LCD em vez do OLED porque este tem uma vida útil muito maior, pois o OLED perde o brilho com o tempo.

Pinagem do display Winstar WO1602.
Esquema para ligar em 3V ou 5V.

Display Winstar WO1602 com a placa adaptadora e os fios para ligar o backlight. Esta placa tem os mesmo 4 pinos do display OLED para ser intercambiável.
Vista de baixo. Note os terminais do display que tem metade do espaçamento dos furos da placa.
Vista de frente.

Relógio em operação mostrando a data completa, temperatura e umidade relativa.

     Para comunicar com o display, uso duas rotinas:

Rotina de envio de comando:
Envia I²C START bit
Envia ST7032_I2C_ADDRESS=0x7C + bit de escrita pela enterface I²C=0
Envia seleção de dado/comando 0x00 (Co, RS, 0, 0, 0, 0, 0, 0)
RS=0, COMMAND
Co=0, (continuation bit)
Envia I²C STOP bit

Rotina de envio de dado:
Envia I²C START bit
Envia ST7032_I2C_ADDRESS=0x7C + bit de escrita pela enterface I²C=0
Envia seleção de dado/comando 0x40 (Co, RS, 0, 0, 0, 0, 0, 0)
RS=1, DATA
Co=0, (continuation bit)
Envia I²C STOP bit


     Para iniciar o display, envio os seguintes comandos através das rotinas mostradas acima:

RESET,  feito por hardware pelo IC TC54;

FUNCTION SET=0x38 (0, 0, 1, DL, N, DH, 0, IS)
DL 1=8bit, 0=4bit
N 1=2lines, 0=1line
DH 1=double (N must be 0), 0=normal
IS 1=extended inst., 0=normal inst.

ENTRY MODE SET=0x06 (0, 0, 0, 0, 0, 1, I/D, S)
I/D 1=cursor/blink moves to right & ddram address is incremented, 0=cursor/blink moves to left & ddram address is decremented
S 1=shift of entire display, 0=no shift

CURSOR/DISPLAY SHIFT=0x14 (0, 0, 0, 1, S/C, R/L, 0, 0)
S/C 1=screen controlled by R/L, 0=cursor controlled by R/L
R/L 1=right, 0=left

FUNCTION SET=0x39 (0, 0, 1, DL, N, DH, 0, IS)
DL 1=8bit, 0=4bit
1=2lines, 0=1line
DH 1=double (N must be 0), 0=normal
IS 1=extended inst., 0=normal inst.

INTERNAL OSC FREQUENCY=0x14 (0, 0, 0, 1, BS, F2, F1, F0)
BS 1=1/4bias, 0=1/5bias
F2 F1 F0  3V FREQ.  5V FREQ. (2 LINE MODE)
0   0   0   122Hz     120Hz
0   0   1   131Hz     133Hz
0   1   0   144Hz     149Hz
0   1   1   161Hz     167Hz
1   0   0   183Hz     192Hz
1   0   1   221Hz     227Hz
1   1   0   274Hz     277Hz
1   1   1   347Hz     347Hz

CONTRAST SET=0x71 (0, 1, 1, 1, C3, C2, C1, C0)
C3~C0 contrast low nibble

POWER/ICON CONTROL/CONTRAST SET=0x54 (0, 1, 0, 1, ION, BON, C5, C4)
ION 1=display ON, 0=display OFF
BON 1=booster ON (OPF1=0, OPF2=0), 0=booster OFF
C5~C4 contrast high nibble

FOLLOWER CONTROL=0x6F (0, 1, 1, 0, FON, RAB2, RAB1, RAB0)
FON 1=internal follower ON (OPF1=0, OPF2=0), 0=internal follower OFF
RAB2~RAB0 V0 generator amplified ratio

DISPLAY ON/OFF=0x0C (0, 0, 0, 0, 1, D, C, B)
D 1=entire dsiplay ON
C 0=cursor OFF
B 0=cursor position OFF

CLEAR DISPLAY=0x01


        Para enviar os caracteres:
Envia o comando SET DDRAM ADDRESS=0x80 + DDRAM ADDRESS
Envia dado com o caractere ASCII


Inicialização do controlador de display OLED SSD1306.

        Dando sequencia aos posts sobre displays OLED, compartilho a seguir a inicialização destes displays baseados no controlador SSD1306.
        O controlador SSD1306 da Solomon Systech, é muito popular atualmente pois é usados em módulos OLED muito usados com o Arduino e similares. Estas módulos tem comumente resolução de 128x64 (máximo do controlador), mas também pode ter 64x32, 128x32, 64x48, etc. Variam de tamanho e cores (verde, amarelo e azul sendo o mais comum) e não possuem graduação de brilho, ou seja, ou o pixel está ligado ou não, sem meio termo. Podem ter interface I²C, SPI de 4 vias, SPI de 3 vias (pino D/C, data/command, susbstituído por mais um bit na comunicação), paralela de 8 bits 8080 ou 6800. A interface é definida por hardware via 3 pinos (BS0, BS1 e BS2).
        Como não sei que linguagem (C, assembler, python, etc.) de programação ou dispositivo (PIC, MSP430, etc.) você vai usar, preferi mostrar somente os passos de inicialização:

Observação: isto é um exemplo, que uso nos meus displays, assim consulte sempre a documentação dos mesmos e do controlador pois há parâmetros que podem variar assim como a sequência.

1
Aplica-se um pulso de RESET por no mínimo 3µs. Nos módulos com somente interface I²C, geralmente o RESET é feito via um circuito RC e o pino deste não está disponível.

Típico módulo OLED I²C. Note a ausência do pino RESET.
Típico módulo com interface SPI que pode usar 3 (somente CS) ou 4  (CS e D/C) sinais. Também pode usar I²C ajustando BS0 a BS2.
Módulo com interface paralela que também pode usar SPI e I²C. Note os resistores de 0R e a tabela para ajustar BS0 a BS2.

2
Após o RESET, envia-se o comando AEh (Set display OFF, Sleep mode).

3
Comando D5h (Set display clock divide ratio/oscillator frequency) seguido com o valor 80h (clock divide ratio=1).

4
Comando A8h (Set multiplex ratio) seguido com o valor 3Fh (64MUX).

5
Comando D3h (Set display offset) seguido com o valor 00h (display offset=0).

6
Comando 40h (Set display RAM display start line) + 00h (display RAM display start line=0).

7
Comando 8Dh (Charge pump setting) seguido com o valor 14h (Charge pump enabled). O charge pump deve ser habilitado antes de ligar o display (comando AFh, display ON).

8
Comando A1h (Set segment re-map, column address 127 is mapped to SEG0). Geralmente o mapeamento é feito assim, mas pode variar dependendo do módulo.

9
Comando C8h (Set COM output scan direction, remapped mode scan from COM[n-1] to COM0). Também é geralmente feito assim, mas pode variar dependendo do módulo.

10
Comando DAh (Set COM pins hardware configuration) seguido do valor 12h (Disable COM Left/Right remap & alternate COM pin configuration). Normalmente, usa-se o modo alternado, mas pode ser usado sequencial no caso do display de 128x32 (sequential COM pin configuration).

11
Comando D6h (Set zoom in) seguido do valor 00h (Vertical zoom disabled). Comando opcional, uso pois alguns microcontroladores tem pouca memória para guardar os bitmaps dos caracteres, assim consigo dobrar a altura dos mesmos sem consumir mais memória.

12
Comando 81h (Set contrast control) seguido do valor 28h (Contrast=40). O valor de contraste, ou brilho do display, varia de 0 a 255. 40 é um brilho razoável para não consumir muita energia, assim o display OLED fica com um consumo semelhante a um LCD com backlight de LED.

13
Comando D9h (Set pre-charge period) seguido do valor F1 (Phase 2 period=15DCLK & Phase 1 period=1DCLK).

14
Comando DBh (Set VCOMH deselect level) seguido do valor 20h (VCOMH deselect level=0.77*Vcc).

15
Comando 20h (Set memory addressing mode) seguido do valor 01h (Vertical addressing mode). Há 3 modos: horizontal, vertical e page address. Uso o vertical por ser mais fácil desenhar os bitmaps dos caracteres no display.

16
Comando A4h (Resume to RAM content display). O controlador mostra no display o conteúdo da RAM. Pode-se usar o comando A5h (Entire display ON) para testar o módulo.

17
Comando A6h (Set normal display). Cada bit 1 da RAM é um pixel aceso. Pode-se usar o comando A7h (Inverse display) onde cada bit 0 é um pixel aceso.

18
Comando 22h (Set page start and end address) seguido do valores 00h (start page=0) e 07h (end page=7). Opcional na inicialização, uso para apagar o conteúdo da memória RAM que inicialmente é aleatório.

19
Comando 21h (Set column start and end address) seguido do valores 00h (start column=0) e 7Fh (end column=127). Também opcional na inicialização, uso para apagar o conteúdo da memória RAM.

20
Opcional. Envia 1024 bytes de dados (00h) para limpar a memória RAM.

21
Por último, comando AFh (Set display ON) para ligar o maldito. Se tudo estiver funcionando, neste momento, o display estará sem um único pixel aceso.



Enviando os bitmaps dos caracteres:

        Há várias maneiras de desenhar um caractere no display, a que uso constituí de 4 variáveis e uma rotina de envio:
  • ASCII_Data - Caractere a ser desenhado de acordo com a tabela de bitmaps (Exemplo "T");
  • ASCII_Data_XOR_Mask - Máscara para inverter os pixels (o que é aceso fica apagado e vice-versa);
  • Char_Column - Coluna do caractere no display (0 a 15 com fonte 16x8);
  • Char_Row - Linha do caractere no display (0 a 3 com fonte 16x8);
  • Send_ASCII - Rotina que envia o bitmap do caractere contido em ASCII_Data nas posições Char_Column  e Char_Row. Esta rotina também incrementa automaticamente Char_Column e Char_Row para facilitar o envio de textos.
        Para tudo acontecer, primeiramente deve haver obviamente uma tabela contendo os bitmaps. Usei uma com apenas 64 caracteres para não ocupar muita memória e serve para quase tudo.
Bitmaps. Para ocupar menos memória, só considerei as letras maiúsculas, números e alguns caracteres. Também substituí alguns por outros mais funcionais.
          Antes de chamar a rotina de envio, define-se onde o caractere vai ser desenhado através das variáveis Char_Column e Char_Row. A rotina define a janela de operação através dos comandos 22h (set page) e 21h (set column) com a seguinte fórmula:

Initial page = Char_Row x 2;
End page = (Char_Row x 2) + 1;
Initial column = Char_Column x 8;
End column = (Char_Column x 8) + 7;

        Após definir a janela, envia-se os bytes referentes ao bitmap do caractere. Para esta fonte 16x8, envio 2 bytes em branco (1 coluna), 12 bytes do bitmap e mais 2 bytes em branco (mais 1 coluna).
        O modo de envio é o vertical:
Modo de envio vertical.
Envio dos dados da tabela.
     Após o envio do bitmap, a rotina Send_ASCII auto-incrementa Char_Column e Char_Row, assim pode-se enviar um texto definindo a posição uma única vez.
























sexta-feira, 30 de setembro de 2016

Displays OLED 128x32 com controlador SSD1306

No post anterior, havia comentado sobre os displays OLED de 64x32 e os problemas que encontrei. Quando fiz o pedido dos displays de 64x32 também pedi de 128x32, assim, dando continuidade, segue o post sobre os displays OLED.

Display OLED de 128x32 acima e 64x32 abaixo. Tem  a mesma pinagem e também é extremamente pequeno.

Vista do lado inferior. Neste display também retirei os resistores de pull-up de 4k7 do barramento I²C e o regulador de tensão. Nesta placa há lugar para um resistor de 0R (R5) para contornar o regulador.

Adaptador para displays OLED com interface I²C usados no LaunchPad. Ele já tem montados os resistores (2k) de pull-up do barramento I²C embaixo da resina epoxi cinza.

Launchpad e um MSP430G2230 com um firmware de teste acionando o display OLED de 64x32.

Assim como no display de 64x32, o de 128x32 também tem o mapeamento do OLED diferente: usa somente a segunda metade da memória de display. Outra traquinagem que descobri é que normalmente os displays de 128x64 usam as linhas (Rows) de forma alternada. Na inicialização do controlador SSD1306 há um comando que define estes parâmetros (Comando 'Set COM pins hardware configuration', 0xDA, bit 5 COM Left/Right remap e bit 4 COM pin configuration).


Linhas alternadas como é normalmente feito em displays de 128x64.

Linhas sequenciais usadas no display de 128x32.


Bit 4 (COM pin configuration) erroneamente configurado para linhas alternadas. Note que as linhas ímpares do bitmap dos caracteres não é mostrada reduzindo o seu tamanho pela metade.
Bit 4 configurado para linhas sequenciais. Note que, assim, os caracteres são mostrados corretamente. O firmware usado é exatamente o mesmo usado no display de 64x32, apenas com este bit ajustado para linhas sequenciais.




terça-feira, 27 de setembro de 2016

Displays OLED 64x32 com controlador SSD1306

Finalmente chegaram os displays OLED 64x32 brancos que havia pedido no Aliexpress. São incrivelmente pequenos e, junto a placa com os componentes auxiliares, são um pouco maior que um DIP de 8 pinos.

Display OLED ao lado de dois PIC de 8 pinos. Veja como é pequeno.
Face inferior. Retirei o regulador de tensão contornando com um resistor de 1R e retirei os resistores de pull-up de 4k7 da interface I²C.
Display em ação com uma placa controlada por um PIC16F1503.
Placa com o MSP430F2230. Menor placa de desenvolvimento que você já viu!

Estes displays usam o famoso e bem documentado controlador SSD1306, porém o mapeamento dos pixels é diferente e me custou algumas horas para descobrir como era. Normalmente o SSD1306 é usado com displays com resolução de 128x64 usando toda sua memória gráfica de 1024 bytes, mas quando o OLED tem menos pixels (64x32 neste caso) o fabricante do OLED define como os pixels serão ligados ao controlador.

Mapa do display para a resolução normalmente usada de 128x64.
Mapa para este display. Note que por ter menos pixels, somente as páginas 4 a 7 e colunas 32 a 95 são mostradas. Isso é definido pelo fabricante do OLED, portanto podendo variar.
Há vários métodos para escrever um caractere nestes displays, o que uso consiste definir na inicialização o sentido de escrita de cima para baixo e da esquerda para a direita. Antes de enviar os bytes contendo os pixels do caractere, envio os comandos de início e final das páginas e colunas, formando uma pequena janela do tamanho exato do caractere (neste caso 2 páginas por 8 colunas, ou 16x8 pixels). Em seguida, aponto para o endereço correspondente do caractere na tabela na memória do microcontrolador e envio os bytes correspondentes.
Exemplo mostrando a janela bem como a ordem de escrita.








sexta-feira, 16 de setembro de 2016

Reaproveitando de telas LCD de Note/Net books

  Num post anterior, havia comentado sobre o reaproveitamento de telas LCD de Note/Net books com uma placa com uma placa baseada no IC MT6820-B que ainda não chegou, mas outra que havia pedido uma semana depois veio antes, baseada no IC RTD2271. Esta tem entrada VGA, DVI e áudio analógico.
       Testei com duas telas LCD que tenho, uma de um eeePC1005 da Asus de 1024x600 (modelo HSD100IFW1-F da HannStar) e outra de um notebook desconhecido de 1280x800 (modelo CLAA141WB05A da Chunghwa).
  Assim como a outra placa, esta tem um header de 30 pinos para o barramento LVDS mais a seleção de alimentação da tela, que pode ser de 12V, 5V ou 3,3V (esta última porcamente derivados dos 5V através de dois diodos). A alimentação externa é feita com uma fonte de 12V que pode ser a própria do computador. Internamente, ela tem um regulador chaveado de 5V e um linear exclusivo para o RTD2271 de 3,3V. A pinagem deste header (CN5) é igual ao da placa baseada no MT6820-B, com exceção dos dois primeiros pinos cuja função está invertida.

Foto da placa no anúncio do Aliexpress.

Placa que veio. Mesma funcionalidade, mesmos conectores e pinagem. O controlador é o RTL2271 em vez do RTL2261 e o amplificador de áudio é o NS4268 (Chaveado, classe D) em vez do SA7496  (Linear, classe AB).
Conectores. Os postes de parafusos, coloquei 3 que tinha de sucata para facilitar a montagem.
         A interface de controle usa 6 botões e um LED bicolor, usei uma placa que tinha de um monitor LCD antigo que só tem 4, assim não uso o botão AUTO (cuja função está disponível no menu) e POWER. Troquei o LED bicolor por um redondo e mais brilhante. Usando a porta VGA,  o RTD2271 sempre faz o ajuste automaticamente.

Placa de interface com 4 botões e LED bicolor com cabo devidamente modificado.
Placa de interface montada sobra a placa RTD2271
        O áudio é bem simples (IC NS4268), amplificador chaveado classe D stereo de 3W com apena os controle de volume pelos botões UP e DOWM.
        O menu de controle é bem simples e funcional, tendo seleção de entrada (VGA, HDMI ou automático), controle de volume, calibração de cor, temporizações no modo VGA e seleção de linguagem.
        Se você for comprar esta placa, compre com o teclado e um jogo de cabos LVDS. O teclado que usei funcionou mas ficou sem dois botões e os cabos LVDS usados vieram de computadores desmontados sendo que tive que adaptá-los mudando alguns pinos do conector da tela e na outra extremidade, crimpar os fios do conector do header de 30 pinos (CN5), alimentação e backlight (CN3).



Ligando a tela do eeePC à placa RTD2261:

        A tela do eeePC usa um backlight de LED com o inversor integrado à mesma. Ela usa 3,3V para o controlador e 5V para o backlight. Em vez de ligar os 3,3V no header de 30 pinos (CN5, como é comumente feito), liguei no header de seleção de tensão junto com os 5V. O controle do backligh é feito por um sinal PWM e um de habilitação, liguei os dois juntos no pino 3 de CN3 da placa RTD2271 pois esta tem controle por tensão analógica, assim o brilho sempre fica no máximo.

Pinagem do conector da tela LCD HSD100IFW1-F, note a importância de ter a documentação da tela.
Tela LCD HSD100IFW1-F com o cabo LVDS adaptado e na outra extremidade com os devidos conectores de sinal LVDS, alimentação e backlight.

















Detalhe do conector da tela LCD.
Tela LCD HSD100IFW1-F ligada à placa RTD2271.
Tela LCD HSD100IFW1-F em operação, usando a interface DVI.
Menu principal.
Controle de volume.


Ligando a tela de 1280x800 à placa RTD2261:

        Esta tela usa apenas uma lâmpada de cátodo frio para o backlight, requerendo um inversor apropriado. Usei um retirado de um notebook velho. Fiz um cabo para ligá-lo ao CN3, alimentado pelos 12V. Assim como a tela anterior, ficou sem o controle de brilho por PWM, ficando este também no máximo.
        A alimentação do controlador da tela LCD é de somente 3,3V, que vem do header de 30 pinos (CN5), mais simples que a anterior.

Pinagem do conector da tela LCD CLAA141WB05A. Note que os sinais LVDS são os mesmos.
Inversor da lâmpada de cátodo frio com o cabo devidamente modificado.

Detalhe do conector da tela LCD.

Tela LCD CLAA141WB05A em operação.

        Tabela de resoluções suportadas segundo a documentação:

Resolução                  1 2 3 4
1366x768 único de 6 bits   0 0 0 0
1280x1024 duplo de 8 bits  1 0 0 0
1024x768 único de 8 bits   0 1 0 0
1024x768 único de 6 bits   0 0 1 0
1366x768 único de 8 bits   0 0 0 1
1920x1080 duplo de 8 bits  1 0 0 1
1280x800 único de 6 bits   0 1 1 0
1440x900 duplo de 8 bits   0 1 0 1
1680x1050 duplo de 8 bits  0 0 1 1
1024x600 único de 6 bits   0 1 1 1

        Esta tabela está com algumas discrepâncias pois para 1024x600x6bits de cor fecha-se os jumpers 2, 3 e 4 mas só funcionou com 2 e 3 somente. Mesmo para 1280x800x6bits de cor, era para ser o 2 e 3 mas funcionou com 1, 2 e 3.