Ir ao conteúdo
  • Cadastre-se

Estudando o CI LM3914 - driver para display de 10 leds


Posts recomendados

Pessoal, passando a limpo uns manuais, uma anotações esparsas, reparei que não entendi como usar o LM3914. Apliquei, uma vez, para verificar tensões entre 2,8v e 3,7, uma bateria 18650, mas acho que foi na sorte.

 

 

Peço ajuda através de um exemplo prático. Gostaria do seguinte.

 

Alimentação: 9v

Entrada variável: 0v - 9v (0v não acende led nenhum, 9v acende todos ou o último, dependendo da opção por "dot" ou "bar")

"Passo" para a sequência de acendimento: 1v

Leds vermelhos: 2,2v 20mA

 

Dentre o nada que entendi, como pode o passo ser menor do que a referência interna fixa, que é de 1,25v segundo o manual?

E teria algum problema alimentar com 9v e o limite high ser também de 9v? A alimentação é completamente independente da entrada do sinal?

 

Manual pela TI: https://www.ti.com/lit/ds/symlink/lm3914.pdf

 

Exemplo com tensões diferentes das que eu gostaria, logo com resistores inadequados:

 

custom_diagram_1_LM3914.gif

Link para o comentário
Compartilhar em outros sites

O segredo são os divisores de tensão com resistores. 

Existem muitas maneiras de se trabalhar com eles nesse ci. 

Mas pro seu caso, acho que o mais fácil é colocar um divisor no terminal SIG pra que 9V seja igual a 1,25V.

São praticamente os mesmos esquemas que já está acostumado a fazer com os comparadores. 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Metendo a colher na vossa sopa, uma alternativa a este ci é um mc quase tão ou mais barato que ele. O barato é que surge a oportunidade pra um ligeiro aumento de sabedoria no ramo co-irmão da eletrônica: a programação.

Teorizei algo como...

Clipboard01.png.8d2c3c44726de0bd96b8e1cc48aa9be6.png

Como alguns amigos sabem, gosto de desafios (mas não sabem que tenho alguns pic16f683), talvez eu faça algo do tipo com ele e vá colocar lenha na fogueira pra entornar o caldo de vez😁

Teoricamente com 1 entrada analógica e 4 saídas, dá um barrgraph de 12 leds...

Mas sei lá... pelo menos fica aí mais uma semente ..🙃

  • Curtir 2
  • Amei 1
Link para o comentário
Compartilhar em outros sites

@.if ,

 

Já que você gosta de desafios e prefere usar um microcontrolador.... que tal usar a técnica acima e fazer um bargraph tipo BARRA em vez de ponto ( vários Leds acesos ao mesmo tempo em vez de apenas 1 ) ?

Vai precisar de multiplexação e uma temporização adequada ao olho humano !

 

Paulo

  • Curtir 2
  • Haha 1
Link para o comentário
Compartilhar em outros sites

Em 24/03/2024 às 19:20, aphawk disse:

Já que você gosta de desafios e prefere usar um microcontrolador.... que tal usar a técnica acima e fazer um bargraph tipo BARRA em vez de ponto ( vários Leds acesos ao mesmo tempo em vez de apenas 1 ) ?

Vai precisar de multiplexação e uma temporização adequada ao olho humano !

 

Acho que desanimei alguém ..... o pior é que dá para fazer ..... se alguém quiser tentar segue  a dica : são 6 leds .... para o pior caso, que é full de escala do Bargraph, os 6 precisam acender , cada um por no minimo 1/6 do periodo de 60 Hz que é a persistência da retina humana .... claro que se acenderem cada um a 1/6 do tempo de 50 Hz  persistência fica ainda melhor ..... basta montar uma tabela das 3 saidas do microcontrolador para as 7 possibilidades, uma interrupção a cada 1/6 dos 60 Hz ( ou 50 ) , e ir seguindo a tabela.

Na verdade, a cada "passo" na tabela, tem de manter todos os leds apagados por pelo menos 1 ou 2 milisegundos para termos a impressão de que estão todos apagados mesmo.....

Tão vendo, não é nenhum bicho de 7 cabeças ..... cadê os que tem vontade de aprender ???????????

 

Paulo

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Essa conversa do @aphawk me fez lembrar desse antigo tópico.... 

Pois a rotina descrita para o uCon fizemos ali, com os velhos CMOS. 

E na última página do tópico não faltou um circuito da @.if feito em linguagem C. Se olhar já é meio caminho andado, basta pouco pra transformar ponto móvel em barra. 

  • Curtir 2
  • Haha 1
Link para o comentário
Compartilhar em outros sites

  • Membro VIP
17 horas atrás, aphawk disse:

cadê os que tem vontade de aprender ??????

De aprender eu não sei... mas de ensinar... Vejamos...

17 horas atrás, aphawk disse:

basta montar uma tabela das 3 saidas do microcontrolador para as 7 possibilidades, uma interrupção a cada 1/6 dos 60 Hz ( ou 50 ) , e ir seguindo a tabela.

No caso acima não precisa de interrupção. Afinal os dados ou bits ou estado de saída ficam parados. Aquela ideia foi mesmo pra maximizar estados mostráveis - no caso - nos leds. O detalhe - que alguém bem que poderia achar curioso - é que entra em cena um terceiro estado lógico já que você - caro amigo recem chegado no ramo - aprendeu na teoria que em binário só existem 0 e 1. Na prática acrescentamos mais um que tem sua glória: ele se chama tristate ou alta impedância ou simplesmente desconectado. No caso daquele mc ele se torna uma "entrada" sob o controle do registrador TRIS.

No caso do ex. do meu post sua utilidade está quase bem explícita sua função Z. Qualquer momento eu testo numa simulação.

 

No caso de Paulão é pra quando se precisa de muitas saídas ou leds - p.ex. prum display matricial. Tem um exemplo que publiquei há muitos (e muitos) anos que usava vários 74HC595 pra escrever textos em vários displays matriciais que levava o conceito que menciona o amigo

17 horas atrás, aphawk disse:

uma interrupção a cada 1/6 dos 60 Hz ( ou 50 ) , e ir seguindo a tabela.

de uma multiplexação a um nível ligeiramente elevado. Modéstia a parte, foi criação 100% original. Preguiça de procurar mas a qualquer momento se achar que devo, linko-o.

 

Falando nisso...

7 horas atrás, Renato.88 disse:

basta pouco pra transformar ponto móvel em barra. 

Algo como...

unsigned char a,tmp;
for(;;)
{
tmp=0;
a=adc_read(0)/128;
while (a--) tmp|=1<<a;
PORTB=tmp;
}
    

Tem algo pra dar certo... Testei o conceito

unsigned char a,tmp;
int main()
{
    a=8;
    while (a--) tmp|=1<<a;
    
    while (tmp) {if (tmp&1) printf("1");tmp>>=1;}

    return 0;
}

em...

https://www.onlinegdb.com/online_c_compiler

😁

 

6 minutos atrás, rmlazzari58 disse:

Com mc tipo Arduíno fica bico:


 

se PC0 =1

  display

se PC1 = 1

  PC0 = 1

Médio... muita decisão pro mc tomar... E se forem p.ex. 48 leds?🤪

  • Curtir 1
  • Amei 1
Link para o comentário
Compartilhar em outros sites

7 horas atrás, Renato.88 disse:

basta pouco pra transformar ponto móvel em barra

Com mc tipo Arduíno fica bico: Lá na

7 horas atrás, Renato.88 disse:

última página do tópico


 

se PC0 =1

  display

se PC1 = 1

  PC0 = 1

   display

se PC2 = 1

   PC0 = 1

   PC1 = 1

   display

se PC3 = 1

   PC0 = 1

   PC1 = 1

   PC2 = 1

   display

 

 

etc., até PD7. Ou algo assim...

14 minutos atrás, .if disse:

Médio... muita decisão pro mc tomar... E se forem p.ex. 48 leds?

IF é sempre minimalista: não toma espaço, mas faz milhões de coisas, rs...

 

Como disse, tem que melhorar. A ideia não é que quando a onda bata no negativo, a barra seja 0, quando a onda seja zero, a barra bata no meio e quando o pico for positivo, barra cheia. A ideia é onda no meio, barra zero, pico positivo ou negativo, barra cheia, é isso?

 

Mas tô aqui elaborando um estudo sobre o 3914 "for dummies", vamos ver se dá certo. Depois posto para a conferência pelos mestre. Dando certo, vai para o caderninho passado a limpo.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Membro VIP

https://i.imgur.com/5poG925.mp4

#include <pic.h>
__CONFIG(CP_OFF & MCLRE_OFF & FOSC_INTOSCIO & PWRTE_ON & WDTE_OFF & BOREN_ON); 

//***************************************************
unsigned char const port[7]=
{
0b000,
0b010,
0b001,
0b100,
0b010,
0b100,
0b001
};
//....................................................
unsigned char const tris[7]=
{
0b000,
0b100,
0b100,
0b001,
0b001,
0b010,
0b010
};
//***************************************************
void delay(unsigned int dl)
{
while(dl--);
}

unsigned int adc_read(unsigned char channel)
{
ADCON0 = (channel << 2) | 0x83;  // enable ADC, fosc/32 , referência=vdd
while(GO_DONE);
//  continue; // wait for conversion complete
return ADRESH*256 + ADRESL;
}

//***************************************************
void main()
{
unsigned char i;
OPTION_REG = 0b10000000 ; //pullup disable
CMCON0 = 0b111 ;//dis comparador
ANSEL = 0b01101000;//
TRISIO = 0b11000;//GPIO4=entrada analógica
for(;;)
{
i=adc_read(3)/165;
if (i>6) i=0; //nem precisa.. só por segurança
TRISIO=tris[i]|0b00010000;
GPIO=port[i];
//delay(20000);
}
}

Ocupou 124 bytes de flash mas acho que dá pra reduzir.

Quero usar 4 saídas pra 12 leds mas to com preguiça de bolar a tabela... Bola aí pra mim...Baseia nisso daqui ó...

Clipboard01.png😁

  • Haha 1
Link para o comentário
Compartilhar em outros sites

  • Membro VIP
17 horas atrás, .if disse:

124 bytes de flash mas acho que dá pra reduzir.

edit ... 91 agora.

#include <pic.h>
__CONFIG(CP_OFF & MCLRE_OFF & FOSC_INTOSCIO & PWRTE_ON & WDTE_OFF & BOREN_ON); 
//***************************************************
unsigned char const port[7]=
{
0b000,
0b010,
0b001,
0b100,
0b010,
0b100,
0b001
};
//....................................................
unsigned char const tris[7]=
{
0b10000,
0b10100,
0b10100,
0b10001,
0b10001,
0b10010,
0b10010
};
//***************************************************
unsigned char adc_read(unsigned char channel)
{
ADCON0 = (channel << 2) | 0x03;  // res. 8 bits em ADRESH enable ADC, fosc/32 , referência=vdd
while(GO_DONE);
return ADRESH;
}
//***************************************************
void main()
{
unsigned char i;
OPTION_REG = 0b10000000 ; //pullup disable
CMCON0 = 0b111 ;//tudo digital
ANSEL = 0b01101000;//fosc/64, GPIO3=entrada analógica
TRISIO = 0b11000;//GPIO4=entrada analógica
for(;;)
{
i=adc_read(3)/42;
TRISIO=tris[i];//  |0b00010000; //GPIO4=entrada analógica
GPIO=port[i];
}
}

Coloquei um gerador de sinal como firula...

Me cadastrei no vimeo pro Vídeo ficar incorporado no post 😁

 

Pra este caso...

Em 24/03/2024 às 19:20, aphawk disse:

um bargraph tipo BARRA em vez de ponto ( vários Leds acesos ao mesmo tempo em vez de apenas 1 ) ?

...com o hw acima, de fato precisamos de...

Em 26/03/2024 às 15:40, aphawk disse:

uma interrupção a cada

período qualquer. Veja que há leds em antiparalelo, neste caso jamais acenderiam simultaneamente. Além de aumentar pra 12 leds (pow Paul.. ninguém quis bolar a tabela pra nós😪) não deixa de ser um acréscimo desafiador já que pra um mc de mais pinos é sem graça pois fica fácil d+

  • Haha 1
Link para o comentário
Compartilhar em outros sites

@.if ,

 

Parabéns, ficou muito bom kkkkk

Só não dá para saber se na prática os Leds que não deveriam acender  ficarão mesmo totalmente apagados, sem ficar com aquele fundinho iluminado de leve .... só montando mesmo.

Justamente para eliminar a possibilidade desse efeito é que eu sugeri o uso da interrupção. E, claro, usar  os tempos dessa interrupção para fazer a impressão de que todos os leds da barra estejam acesos. Que tal tentar implementar isso ? Quanto menor os tempos, maior a impressão de vários Leds acesos.

Mas olha que legal que ficou o resultado, agora uma jogadinha de converter a tensão na entrada em tensão RMS, criar uma "integral" para simular um circuito RC para carga e descarga, e já tem um verdadeiro VU calibrado !

Olha, isso que você fez é a minha ideia de um aprendizado de verdade, é o que os professores deveriam fazer para que os alunos aprendam, indo da teoria básica para a prática, e algo simples de montar para que vejam o mundo de possibilidades que um minúsculo micro controlador pode nos oferecer!

 

Até que a idade ainda não afetou seu raciocínio kkkkkkkkkkkk

 

Novamente, parabéns, velho amigo !

 

Paulo

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

@.if , tiraste leite de pedra para montar o programa com menos de 100 bytes. 

@aphawk , até dá para multiplexar isso daí mas fica uma pergunta: estando o display no máximo, 1/12 avos de tempo aceso vai dar brilho ou vai ficar com aparência de pilha fraca, aquela coisa meia bomba que tá animada mas dobra na entrada? kkkkk

Já vi multiplex de 1/3 de tempo, fica bom.

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

@Sérgio Lembo ,

 

KKKKKKKK se usar Leds de alto brilho fica perfeito !

Já se usar Leds comuns teria de montar drivers de alta corrente, e nesse tipo de circuito que usa até alta impedância nem sei se é possível .....

Consegui multiplex de 1/8 do tempo ficar bom, mas tive de liberar o máximo de corrente possível.

Link para o comentário
Compartilhar em outros sites

  • Membro VIP
18 horas atrás, aphawk disse:

tempos dessa interrupção

 

16 horas atrás, Sérgio Lembo disse:

multiplexar isso daí mas fica uma pergunta: estando o display no máximo, 1/12 avos de tempo aceso

e perceba que são 12 leds mas apenas 4 pinos. portanto teoricamente 'seriam' 1/4 de tempo cada

15 horas atrás, aphawk disse:

i multiplex de 1/8 do tempo ficar bom

mas.. mígos... aquilo lá não está multiplexado. Está direto um a um mesmo ok? Perceba na outra simulação https://i.imgur.com/5poG925.mp4 com pot que o estado dos pinos fica fixo quando paro de mexer no pot. Com isso em mente, o máximo que poderia ocorrer é que no momento Z haveria fuga e um led

15 horas atrás, aphawk disse:

de alto brilho

meio que poderia sentir vontade acender mas mesmo assim deve ficar totalmente apagado, ok?

18 horas atrás, aphawk disse:

na prática os Leds que não deveriam acender  ficarão mesmo totalmente apagados, sem ficar com aquele fundinho iluminado de leve

 

Já com interrupt - que não é aquele caso - de fato o que faço é apagar todos os leds antes de acender outro padrão. Se não apagar fica a 'sombra' do dado anterior o que causa mesmo  o efeito mencionado pelo Paulão.  To com preguiça mas se procurar deve achar uma publicação com hc595 que mencionei lém cima. Nela aplico esta técnica.

 

Na prática já multiplexei 8 displays 7seg com ela e com sucesso. Acho que foi com 50 ... 100Hz mesmo.

 

16 horas atrás, Sérgio Lembo disse:

para multiplexar isso daí

e fazer um controle individual dos leds - p.ex. espelhando seus bits em 2 bytes - exige um pouco + de ginástica que ainda vou ver se vale o esforço mental. A não ser que você duvide que eu consiga...😁

 

22 horas atrás, .if disse:

o fonte...

#include <pic.h>
__CONFIG(CP_OFF & MCLRE_OFF & FOSC_INTOSCIO & PWRTE_ON & WDTE_OFF & BOREN_ON); 
//***************************************************
//....................................................
//12 leds
unsigned char const port[13]=
{
0b000000,
0b111011,
0b011111,
0b111101,
0b111011,
0b111110,
0b111101,
0b111101,
0b011111,
0b111110,
0b111011,
0b111110,
0b011111
};
//....................................................
unsigned char const tris[13]=
{
0b011000,
0b011011,
0b011011,
0b111001,
0b111001,
0b111100,
0b111100,
0b011101,
0b011101,
0b111010,
0b111010,
0b011110,
0b011110
};


//***************************************************
unsigned char adc_read()//unsigned char channel)
{
//ADCON0 = (channel << 2) | 0x03;  // res. 8 bits em ADRESH enable ADC, fosc/32 , referência=vdd
ADCON0 = (3<<2)|0x03; //fixo só no canal 3
while(GO_DONE);
return ADRESH;
}
//***************************************************
void main()
{
unsigned char i;
OPTION_REG = 0b10000000 ; //pullup disable
CMCON0 = 0b111 ;//tudo digital
ANSEL = 0b01101000;//fosc/64, GPIO3=entrada analógica
TRISIO = 0b011000;//GPIO4=entrada analógica, GPIO5,2,1,0=leds
for(;;)
{
i=adc_read()/20;//255/12leds ~...~20.. pra acionar último led
TRISIO=tris[i];//|0b00010000; //GPIO4=entrada analógica
GPIO=port[i];
}
}

Dei uma enxugadinha com adc_read() com canal fixo. Está com mais leds mas ainda com menos de 100bytes. E algo me diz que vou reduzir ainda +. Não porque precisa mas por autodesafio apenas. O caminho: a 'palavra' ou word de instrução deste mc é de 14 bits portanto numa palavra cabem 2 padrões de 7 bits.

 

edit... numa rápida pesquisa vi que este mc não tem como ler sua própria flash em palavra de 14bits... 😢 Mas nem tudo está perdido... Ele possui eeprom e posso usá-la pra alimentar a tabela..🙃.

 

De novo, apesar de praticamente desnecessário, a ideia é apenas registrar/compartilhar conhecimento além claro de tentar manter o tico e teco não muito atrofiados 😁

  • Obrigado 2
Link para o comentário
Compartilhar em outros sites

@.if ,

 

Tá ficando cada vez melhor isso kkkk

 

Eu sei que o programa, como está, acende um Led de cada vez, e é o tal modo PONTO., claro que sei que não tem nada de multiplex e nem interrupção.

 

O que eu gostaria de ver é ele trabalhar no modo BARRA, isto é, em vez de o Led que indica o nível do sinal, ficariam acesos todos os leds inferiores ao nível atual do sinal, numa velocidade tal, que desse a impressão de uma barra de Leds com vários acesos ao mesmo tempo, o que só podemos fazer usando multiplexação e comutando os leds na sequência correta.

 

Claro que é para aprendizado, mas são coisas que hoje não se ensinam mais nas faculdades!

Mesmo da maneira que está, com 100 bytes já tirou muito leite de pedra!

 

Paulo

 

 

  • Curtir 3
Link para o comentário
Compartilhar em outros sites

Quem sabe se inverter a lógica de acionamento do leds de forma que o padrão seja todos acesos e, na medida em que a resistência do pot diminuísse, aí seria só apagar de cima para baixo... ou não, se fizesse dessa forma, o que correria para cima e para baixo seria um ponto apagado mas, ainda assim, apenas um ponto? Ou não... inverter será que ajuda?

 

Não consigo visualizar solução sem usar uns IFs, aí. É que são da natureza do problema as condicionais... "se led1 está aceso, led0 - seja qual for a R no pot - também estará aceso...

 

Assim para fazer a barra, dois fatores concorrem para acender (ou apagar) um led:

1 - a tensão na saída do pot

2 - a condição do led anterior (ou posterior)

 

O termo "anterior" sugere leds em sequência e não independentes...

 

Será que ajudei ou atrapalhei? A intenção foi ajudar...

Link para o comentário
Compartilhar em outros sites

40 minutos atrás, rmlazzari58 disse:

Não consigo visualizar solução sem usar uns IFs, aí. É que são da natureza do problema as condicionais... "se led1 está aceso, led0 - seja qual for a R no pot - também estará aceso...

 

Isso funciona bem se cada led tiver o seu pino. Pra isso precisa de um uC maior. 

 

Aqui estão usando um uC de 8 pinos pra acender 12 leds. 

Então, leds que parecem estar acesos ao mesmo tempo, na verdade não estão. 

  • Curtir 1
  • Haha 1
Link para o comentário
Compartilhar em outros sites

  • Membro VIP
6 horas atrás, rmlazzari58 disse:

apagar de cima para baixo...

 

6 horas atrás, rmlazzari58 disse:

apenas um ponto?

 

6 horas atrás, rmlazzari58 disse:

inverter será que ajuda?

Não amigo, Perceba leds em antiparalelo, ou seja numa visão 'normal'

Em 28/03/2024 às 08:24, .if disse:

Veja que há leds em antiparalelo, neste caso jamais acenderiam simultaneamente.

Perceba também que se consegue acender no máximo 2 ao mesmo tempo com saídas em 1010, 0101 o que não é muito útil. Pra fazer a barra é de fato uma 'barra' ... há de se lançar mão do recurso da já mencionada interrupt e fazer a varredura pra controlar 1 led por vez ou a cada passada pela interrupt. Há de se varrer 12 vezes o que pode causar cintilação se a freq for baixa ou acendimento fraco se alta... ou não: só o físico vai dizer. A princípio pode-se reduzir pra 6 se aproveitar o fato de que consegue-se acender 2 ao mesmo tempo mas a tabela e o algoritmo deve ficar complexo d+ pro tico e teco...

 

6 horas atrás, rmlazzari58 disse:

Não consigo visualizar solução sem usar uns IFs

Existe soluções menos amadoras (sem ofensas ok?) sim amigo. . veja p.ex. a por este ser proposta com 0 if's. To quase sentindo vontade complementar com a barra. ou soltar + um barro.😁

9 horas atrás, aphawk disse:

o que só podemos fazer usando multiplexação e comutando os leds na sequência correta.

É isso aí amigo.. ou quase... No caso acima não chegaria a ser uma multiplexação literal. Eu (eu) chamaria de 'multi-indexação' - inventei isso agora. Já que se aplicaria padrões de acendimentos apropriados a cada interrupt.. Avaliá-lo-ei .😁

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Membro VIP
Em 29/03/2024 às 22:41, aphawk disse:

eu gostaria de ver é ele trabalhar no modo BARRA

Seu pedido é uma ordem😁

Tentei ajustar a freq de interrupt pra melhorar o visual da simulação bem como mudei os leds pra 'analog'... o menos ruim foi isso daí. E o osc e gerador estão fora da simulação.

Na prática fica em torno de 100Hz. Se algum dia alguém montar isso - to quase com vontade - a gente ajusta.

O fonte minimalista como sempre...

#include <pic.h>
__CONFIG(CP_OFF & MCLRE_OFF & FOSC_INTOSCIO & PWRTE_ON & WDTE_OFF & BOREN_ON); 
//***************************************************
//....................................................
#define _tmr1h 0xfa //só pra simulação. 0xfb=>o correto para 100hz 
#define _tmr1l 0x1d //0x1d
//12 leds
unsigned char const port[13]=
{
0b000000,
0b111011,
0b011111,
0b111101,
0b111011,
0b111110,
0b111101,
0b111101,
0b011111,
0b111110,
0b111011,
0b111110,
0b011111
};
//....................................................
unsigned char const tris[13]=
{
0b011000,
0b011011,
0b011011,
0b111001,
0b111001,
0b111100,
0b111100,
0b011101,
0b011101,
0b111010,
0b111010,
0b011110,
0b011110
};
unsigned char an,i;
//******************************************************
static void interrupt
timer1_int(void)
{
TMR1H=_tmr1h;TMR1L=_tmr1l; // 100Hz
TMR1IF=0;
TRISIO=tris[i];
GPIO=port[i];
i++;
if (i>an) i=0;
if (i>12) i=0;//fim de curso
}

//***************************************************
unsigned char adc_read()//unsigned char channel)
{
//ADCON0 = (channel << 2) | 0x03;  // res. 8 bits em ADRESH enable ADC, fosc/32 , referência=vdd
ADCON0 = (3<<2)|0x03; //fixo só no canal 3
while(GO_DONE);
return ADRESH;
}
//***************************************************
void main()
{
OPTION_REG = 0b10000000 ; //pullup disable
CMCON0 = 0b111 ;//tudo digital
ANSEL = 0b01101000;//fosc/64, GPIO3=entrada analógica
TRISIO = 0b011000;//GPIO4=entrada analógica, GPIO5,2,1,0=leds
T1CON=0b00110001;
TMR1H=_tmr1h;TMR1L=_tmr1l; // 100Hz
PIE1=GIE=PEIE=1; //hab. int. timer1
for(;;)
{
an=adc_read()/20;//255/12leds ~...~20.. pra acionar último led
}
  
}

edit...

Tentativa de simulação da "persistência ótica capacitiva" do olho humano. Inventei isso agora...

Em tempo.. você consegue ver se um display de led está multiplexado. Olhe pra ele e chacoalhe a cabeça.. vai ver riscos e traços. Faça isso p.ex. com seu antigo rádio relógio.

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

3 horas atrás, .if disse:

Seu pedido é uma ordem😁

Tentei ajustar a freq de interrupt pra melhorar o visual da simulação bem como mudei os leds pra 'analog'... o menos ruim foi isso daí. E o osc e gerador estão fora da simulação.

Na prática fica em torno de 100Hz. Se algum dia alguém montar isso - to quase com vontade - a gente ajusta.

O fonte minimalista como sempre...

#include <pic.h>
__CONFIG(CP_OFF & MCLRE_OFF & FOSC_INTOSCIO & PWRTE_ON & WDTE_OFF & BOREN_ON); 
//***************************************************
//....................................................
#define _tmr1h 0xfa //só pra simulação. 0xfb=>o correto para 100hz 
#define _tmr1l 0x1d //0x1d
//12 leds
unsigned char const port[13]=
{
0b000000,
0b111011,
0b011111,
0b111101,
0b111011,
0b111110,
0b111101,
0b111101,
0b011111,
0b111110,
0b111011,
0b111110,
0b011111
};
//....................................................
unsigned char const tris[13]=
{
0b011000,
0b011011,
0b011011,
0b111001,
0b111001,
0b111100,
0b111100,
0b011101,
0b011101,
0b111010,
0b111010,
0b011110,
0b011110
};
unsigned char an,i;
//******************************************************
static void interrupt
timer1_int(void)
{
TMR1H=_tmr1h;TMR1L=_tmr1l; // 100Hz
TMR1IF=0;
TRISIO=tris[i];
GPIO=port[i];
i++;
if (i>an) i=0;
if (i>12) i=0;//fim de curso
}

//***************************************************
unsigned char adc_read()//unsigned char channel)
{
//ADCON0 = (channel << 2) | 0x03;  // res. 8 bits em ADRESH enable ADC, fosc/32 , referência=vdd
ADCON0 = (3<<2)|0x03; //fixo só no canal 3
while(GO_DONE);
return ADRESH;
}
//***************************************************
void main()
{
OPTION_REG = 0b10000000 ; //pullup disable
CMCON0 = 0b111 ;//tudo digital
ANSEL = 0b01101000;//fosc/64, GPIO3=entrada analógica
TRISIO = 0b011000;//GPIO4=entrada analógica, GPIO5,2,1,0=leds
T1CON=0b00110001;
TMR1H=_tmr1h;TMR1L=_tmr1l; // 100Hz
PIE1=GIE=PEIE=1; //hab. int. timer1
for(;;)
{
an=adc_read()/20;//255/12leds ~...~20.. pra acionar último led
}
  
}

 

Uia! "Não sabendo que era impossível de fazer, foi lá e fez", rs...

 

 

********************

 

Bem... e humildemente apresento o resultado da comparação entre os LM3914/5/6, usando os manuais da National.

Tenho a impressão de que o 4 é linear, o 5 é logarítmico e o 6 é... o que?

NSrvayL.jpeg

 

Para quem quiser, os manuais e a planilha estão aqui:

https://*****/folder/QcgWABTI#GoOlfmPR7CI5RVQ60faJQA

 

 

Na planilha, a coluna Ω são os valores de resistência da cadeia de resistores entre as não-inversoras de cada comparador; Σ é a somatória desses valores; a coluna Σ / Ω é a razão entre a somatória e a resistência e a coluna P é a razão entre entre Σ / Ω e Σ / Ω anterior. A coluna P é um tipo de passo... não sei dizer melhor que isso: se a somatória é velocidade, a P é aceleração. Ou algo assim...

Link para o comentário
Compartilhar em outros sites

@.if ,

 

Agora sim ficou como eu falei, e o programa minúsculo ficou ainda melhor kkkk

É muito legal ver o pessoal comentando, e assim aprendendo, e vendo o que se pode fazer mesmo com um microcontrolador minúsculo !

Isso é a função da Engenharia, bolar soluções para os problemas mais complexos usando as coisas mais simples possíveis.

Eu propus esse exercício com esse intuito, de fazer as pessoas pensarem em como fazer isso, afinal a tabelinha de eventos enche um pouco o saco, mas são claramente visíveis no programa do @.if , que é uma pequena obra prima de simplicidade !

estou quase montando isso também para ver , usando um Attiny85 ....

 

Paulo

 

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Em 30/03/2024 às 13:46, rmlazzari58 disse:

Tenho a impressão de que o 4 é linear, o 5 é logarítmico e o 6 é... o que?

 

O LM3915 é escala logarítmica, mas calibrada em 3db/step , igual a um VU antigo. é o que foi usado no QRT5500 da Quasar.

O LM3916 é igual ao LM3914, linear, mas com a opção de se fazer um display do tipo BARRA ou PONTO através de uma chave.

Foi do uso dele no meu passado distante na Quasar que eu tirei a ideia de se fazer um display tipo BARRA com o microcontrolador de poucos pinos, coisa que o @.if fez em poucas linhas !

 

Paulo

 

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!