FAÇA UM VOLTÍMETRO DE 3 DÍGITOS COM PIC16F628A

1

Gostaria de montar um voltímetro digital para a sua fonte de alimentação? Ou controlar a tensão de algum processo, de uma forma barata? Então, você desejará saber mais…

Veja o esquema abaixo:

O circuito proposto trata-se de um voltímetro digital de 3 digitos, construido com a técnica de conversão Delta_Sigma, própria para microcontroladores que não dispõem de conversor analógico/digital internos. Os displays são multiplexados, usando a rotina do timer 0 para orquestrar esta multiplexação.

A TÉCNICA DELTA-SIGMA

Para iniciar, note nos pinos 17 e 18, a presença de uma malha resistiva/capacitiva (RC). Ela visa atuar como um integrador da tensão a ser medida. Veja que no terminal do capacitor de 0,22 microfarads , recebe a soma da tensão de entrada com a tensão fornecida pelo modulador de 1 bit (fornece somente ‘0’ ou ‘5’ volts), através do resistor de 47k ligado ao pino 17 (porta,0).
Pelo pino 18 (porta,1) é comparado a tensão presente nele com a tensão de refêrencia (2,5 volts). Se a tensão de referência for maior, aciona o pino 17 para nivel ‘1’, decrementa contador de resolução (CICLO1/CICLO) e começa a carregar o capacitor até que a tensão seja maior que a de referência. Nesta ocasião, após a comparação, se a tensão de entrada do integrador for maior que a de referência, a saída do pino 17 se torna ‘0’, descarregando o capacitor e incrementando nesta ocasião, o resultado em C1/C0 e decrementando o contador de resolução. Isto continua até terminar o número de conversões determinado pelo contador de resolução. Mais detalhes desta técnica poderá ser visto na Note Application AN700 da Microchip.

O CÓDIGO ASM

O programa começa realizando a configuração de portas e registradores. O comparador é ligado para funcionar apenas um dos dois comparadores no chip. A voltagem de referência interna também é ligada e ajustada para 2,5 volts, ligando sua saída para o pino 1 (porta,2). Depois, o programa entra no loop principal, fazendo a leitura da entrada e dando um atraso entre a próxima leitura, em um ciclo infinito. O timer 0 é ligado com prescaller e interrupção, que é usada na rotina de multiplexação dos display de 7 seguimentos de ânodo comum. O ponto é fixo, sendo ligado junto a saída ‘k1’.

UTILIDADES

A idéia veio da necessidade de construir um voltímetro para uma fonte de bancada, mas que fosse com o PIC 16F628a. Mas, nada impede de outros usos para este voltímetro. Vai da sua necessidade e criatividade!
Pode ser usado para medir de 0 a 25 volts , com segurança. Para outras tensões, deverá mudar os resistores de entrada.

CALIBRAÇÃO

Para calibrar de forma simples, apenas ligue o ponto de teste ‘PT1’ Ao Vcc (+5 volts). Ajuste o trimpot para ler exatos ‘5.0 volts’. Pronto! Caso queira mais facilidade no ajuste, coloque um trimpot ‘multivoltas’, pois o ajuste é um pouco sensivel.
Obs. Este material foi montado e testado apenas em placa de protoboard, podendo ter bugs ainda não identificados. Esta sendo fornecido o arquivo ASM, que poderá ser alterado segundo as necessidades dos hobistas.

Segue o arquivo ASM:

PIC_VOLT_628_ASM

Segue o arquivo HEX:

PIC_VOLT_628_HEX

Adicionalmente, em 31/12/2014, acrescentei esta versão em código “C”:

PIC_VOLT_C

Manuais:
AN700 – Conversor Delta-sigma
Pic 16F628A

Curiosidades:
Conceito equilibrado sobre o trabalho
Histórias de sobreviventes do tsunami do Japão
O rei dos relógios
O desafio da longitude para os navegadores do passado
Os melhores brinquedos
O mistério de Cahokia
Quais são alguns dos avanços no campo da energia
Por que tantos crimes violentos?
Como vai a sua Tireóide?
Matemática para todos
Beneficios da amamentação na Inteligência das criança
A glória das estrelas
Al_Jazari – ‘pai da robótica’?
O ‘pim’ – confirma relato biblico

Outros assuntos:
Como sobreviver ao primeiro ano de casamento
Quando um dos conjuges tem necessidades especiais
Como lidar com dívidas
Como resolver diferenças no casamento
Como tratar o conjuge com respeito
Como evitar ferir com palavras
Ensine seus filhos bons principios com atividades de colorir
Como posso ter ânimo para exercitar
Como posso controlar meu peso?
Entrevista com um bioquímico
Como você encontra tempo para deveres escolares?

Até o próximo artigo!!!

1

32 comentários sobre “FAÇA UM VOLTÍMETRO DE 3 DÍGITOS COM PIC16F628A

  1. 0

    claudio tenho uma ideia pra dar uma nova versao a esse super projeto eu ja motei ele pelo menos 4 veses uso ele em som automotivo para monitorar a bateria no pic sobraram 3 pinos a ideia é fazer um remote modo para desligar o modulo de audio quando a bateria atingir uma tensao muito baixa por exemplo 10v. O funcionamento ficaria assim, o autoradio envia o sinal do remote ao voltimentro 12v converte-se em 5v o voltimetro so ia ligar o display quando tivesse esse 5v presente no seu pino sendo que o voltimetro ficava ligado direto na bateria,entao acionado ele passa a monitorar a bateria se ele checar que tem mais de 10v ele faz um pino ir para o estado alto 5v este 5v é convertido em 12v e entregue ao modulo que passa a ser acionado a corrente necessaria para acionar o modulo é na ordem de 0,01A acho que bem menos que isso.por quer deixar o voltimetro ligado direto? pra nao ter que estar fazendo o reset.nao sei se é possivel o empremento mais se for fica turbinado o sistema 😉 desde agradeço a atençao.

    1. 0

      Olá Morais!
      Um remoto para ligar o display e um detetor de nível de bateria baixo, tudo junto.
      Parece uma ideia bem interessante! Vou analisar sua sugestão.
      Muito obrigado!
      Claudio

    2. 0

      Olá Morais!
      Com respeito a sua sugestão de “incrementar” o voltímetro com uma função adicional de cortar a saída de som quando estiver com tensão limite, gostaria de saber o seguinte:
      O fio que vem do autoradio (remote), se o mesmo estiver desligado fará que a saída para o amplificador seja também desligada?
      Eu imagino da seguinte forma:
      Se o autoradio estiver ligado, ligará o display e a saída de som através de um relé (por ex.), mas se a bateria chegar ao valor limite desligará o relé, mesmo se o autoradio continuar ligado.
      Se desligar o autoradio, desliga também este relé e o display.
      Quando cortar o relé, necessitará desligar o autoradio (remote = 0), para poder rearmar.
      Seria mais ou menos isto que pensou também?

      Cláudio

  2. 0

    Olá Claudio,
    Eu estou fazendo um termostato para cerca de 1000 graus Celsius, usando um K. termopar
    E eu projetei o amplificador e obter 10 mV / ° C (compensação de temperatura ambiente), eu quero adicionar um metro, e quer usar seu design, mas com um display de 4 dígitos, para me dar 000 ° a 999 °.
    Obrigado por compartilhar o seu conhecimento.
    Saudações.

    Hola Claudio,
    Estoy haciendo un termostato para aproximadamente 1000 grados centigrados, usando un termopar K.
    Ya diseñé el amplificador y obtengo 10 mV/°C (con compensacion de temperatura ambiente), le quiero agregar un medidor, y deseo usar tu diseño pero con un display de 4 digitos, que me diera de 000° a 999°.
    Gracias por compartir sus conocimientos.
    Saludos.

    1. 0

      Olá Jandos!
      Muito interessante este seu projeto! Mas creio que você necessitará de um voltímetro bem preciso e com muitas escalas para abranger a sua medição. Você não conseguirá boa precisão com o método delta-sigma. Melhor usar talvez um outro projeto, que use conversor analógico/digital de pelo menos 10 bits (mais melhor) e com algum software para escalas automáticas, para melhorar a precisão na escala baixa de 0 a 10 graus.
      Cláudio

      1. 0

        Olá Claudio,
        Muito obrigado pela sua sugestão, eu vou lidar com o ICL7107 e ICL7106.
        Saudações.

        Hola Claudio,
        Muchas gracias por tu sugerencia, voy a tratar con el ICL7107 y el ICL7106.
        Saludos.

  3. 0

    GRANDE AMIGO, DESCULPE INCOMODAR, MAS SEI QUE VOCÊ É PROFISSIONAL EM ASSEMBLY, QUERIA QUE VERIFICASSE PARA MIM, PORQUE NÃO QUER FUNCIONAR CORRETAMENTE ESSE MULTIMETRO COM 4 LEDS, NÃO SEI COMO USAR OS 10 BITS, E COM 8 FUNCIONA, MAS ACENDE TODOS LEDS COM 2,5V TEM COMO ME AJUDAR:

    LIST P= 12F675;

    __CONFIG B’11000110010100′; H’3194′

    COUNTER EQU H’23’;
    ADC_READ EQU H’24’;
    LED1ON_COMP EQU H’25’;
    LED2ON_COMP EQU H’26’;
    LED4ON_COMP EQU H’27’;
    LED5ON_COMP EQU H’28’;
    WORK_SAVE EQU H’29’;
    STATUS_SAVE EQU H’30’;
    #DEFINE BANK0 BCF H’03’, 0X05;
    #DEFINE BANK1 BSF H’03’, 0X05;

    ORG 0x000;

    GOTO MAIN;

    ORG 0x004;
    MOVWF WORK_SAVE ;SALVA ‘W’
    SWAPF H’03’, 0X00; ;SALVA ‘STATUS’
    MOVWF STATUS_SAVE;
    INCF COUNTER;
    BCF H’0B’, 0X2;
    SWAPF STATUS_SAVE, 0X00; ;RECUPERA ‘STATUS’
    MOVWF H’03’;
    MOVFW WORK_SAVE ;RECUPERA ‘W’
    RETFIE;

    MAIN
    BANK0;
    MOVLW B’11100000′;
    MOVWF H’0B’;
    MOVLW B’00000111′; 0x07;
    MOVWF H’19’;
    BANK1;
    MOVLW B’11000101′;
    MOVWF H’81’;
    MOVLW B’00010001′;
    MOVWF H’9F’;
    MOVLW B’00001001′;
    MOVWF H’85’;
    BANK0;
    MOVLW B’10000001′;
    MOVWF H’1F’;
    MOVLW B’00000000′;
    MOVWF H’05’;
    MOVLW D’60’;
    MOVWF LED1ON_COMP;
    MOVLW D’100′;
    MOVWF LED2ON_COMP;
    MOVLW D’200′;
    MOVWF LED4ON_COMP;
    MOVLW D’255′;
    MOVWF LED5ON_COMP;

    CLRF COUNTER;

    LOOP:
    CALL DELAYL;
    CALL GETADC;
    CALL DELAY;
    CALL DELAY;
    CALL DELAY;
    CALL DELAY;
    GOTO LOOP;

    DELAY:
    CLRF COUNTER;
    BTFSS COUNTER, 0X3;
    GOTO $-1;
    CLRF COUNTER;
    RETURN;

    DELAYL:
    CLRF COUNTER;
    BTFSS COUNTER, 0X0;
    GOTO $-1;
    CLRF COUNTER;
    RETURN;

    GETADC:
    BANK0;
    BSF H’1F’, 0X1;
    BTFSC H’1F’, 0X1;
    GOTO $-1;
    BANK1;
    MOVF H’9E’, 0X00;
    MOVWF ADC_READ;
    CALL TEST_ADC;
    RETURN;

    TEST_ADC:
    FIRST_TEST:
    BANK0;
    MOVF LED1ON_COMP,0X00;
    SUBWF ADC_READ,0X00;
    BTFSC H’03’, 0X00;
    GOTO LED1ON;
    GOTO LED10FF;

    SECOND_TEST:
    BANK0;
    MOVF LED2ON_COMP,0X00;
    SUBWF ADC_READ,0X00;
    BTFSC H’03’, 0X00;
    GOTO LED2ON;
    GOTO LED20FF;

    FOURTH_TEST:
    BANK0;
    MOVF LED4ON_COMP,0X00;
    SUBWF ADC_READ,0X00;
    BTFSC H’03’, 0X00;
    GOTO LED4ON;
    GOTO LED4OFF;

    FIFTH_TEST:
    BANK0;
    MOVF LED5ON_COMP,0X00;
    SUBWF ADC_READ,0X00;
    BTFSC H’03’, 0X00;
    GOTO LED5ON;
    GOTO LED5OFF;

    END_TEST:
    RETURN;

    LED1ON:
    BANK0;
    BSF H’05’, 0X01;
    GOTO SECOND_TEST;

    LED10FF:
    BANK0;
    BCF H’05’, 0X01;
    GOTO SECOND_TEST;

    LED2ON:
    BANK0;
    BSF H’05’, 0X02;
    GOTO FOURTH_TEST;

    LED20FF:
    BANK0;
    BCF H’05’, 0X02;
    GOTO FOURTH_TEST;

    LED4ON:
    BANK0;
    BSF H’05’, 0X04;
    GOTO FIFTH_TEST;

    LED4OFF:
    BANK0;
    BCF H’05’, 0X04;
    GOTO FIFTH_TEST;

    LED5ON:
    BANK0;
    BSF H’05’, 0X05;
    GOTO END_TEST;

    LED5OFF:
    BANK0;
    BCF H’05’, 0X05;
    GOTO END_TEST;

    END;

    1. 0

      Olá Paulo!
      Infelizmente não sou especialista como você diz. Quem me dera! Mas no código acima, o valor da conversão está sendo pego apenas do registrador ADRESL (0x9E), portanto, apenas 8 bits. Na comparação o mesmo ocorre, usando apenas 8 bits. Para usar 10 bits teria que usar o registrador ADRESH (0x1E) também. Talvez você possa contornar a situação reduzindo a entrada de sinal com um trimpot de 10 k ohms, onde o curso fica na entrada do pic e um lado ao gnd, e o outro lado para a tensão a ser medida. Ajuste a tensão para sair 1/4 do valor da entrada e você terá o circuito funcionando do jeito correto, mesmo com 8 bits. O código é seu? Tem o esquema que possa compartilhar e o uso prático?
      Claudio

      1. 0

        Olá, Muito obrigado pela explicação, eu consegui fazer esse projeto funcionar mudando o alinhamento a esquerda, e pegando o ADRESH (0X1E), O CÓDIGO FUI EM QUEM DESENVOLVI, COMO TINHA DITO EU FIZ UM CURSINHO DE ASSEMBLY, AINDA TOU FAZENDO, AÍ JÁ GOSTO DE IR DESENVOLVENDO OS MEUS CÓDIGO, APESAR QUE DEVE TÁ MUITO MAL FEITO ESSE CÓDIGO NÉ? TENHO TAMBÉM O ESQUEMA NO PROTEUS, E FUNCIONOU LEGAL NO PROTEUS, SERÁ QUE NA PRATICA FUNCIONARIA? MAIS UMA PERGUNTA, SERÁ QUE SE EU USASSE UMA MARIX DE LEDS NO CASO 16 LEDS, DARIA PARA FAZER ELES FUNCIONAR USANDO 16 EM VEZ DE 4? DESDE JÁ OBRIGADO PELA RESPOSTA. ATT. PAULO

        1. 0

          Olá Paulo!
          Muito bom que tenha encontrado por você mesmo uma solução! Verá que em situações parecidas haverá muitas opções tanto no software como no hardware. Quanto a funcionar, creio que não terá problemas na prática, visto que funcionou no simulador Proteus, bem confiável. Com o uso de 16 leds, necessitará de 4 saída do pic para fazer esta matriz. Os intervalos ficarão mais apertados
          sendo necessário comparar ambos registradores do ADC (ADRESL/ADRESH). Sendo 1024 bits /16 = 64, assim, cada degrau seria 64 bits acima até chegar em 1024. Quanto a matriz, ela é meio complicada porque terá que acionar tanto a saída como o sentido da saída, para que somente um led fique aceso por vez. Mas acredito que você possa fazer se persistir.
          Claudio

    1. 0

      Olá Marcos!
      Obrigado por sua sugestão! A maior dificuldade é o elemento sensor, no caso, um resistor de baixo valor, sobre o qual será medido uma pequena tensão proporcional a corrente que circula por ele.
      Sempre necessita outros amplificadores operacionais para aumentar o ganho, e por isto tenho evitado esta montagem.
      Cláudio

  4. 0

    Boa tarde Claudio
    Tem um link aqui de um Temporizador usando o comparador do PIC16F628A mas o link tá dando um erro assim.
    Sorry, but you don’t have access to this forum
    Gostaria de saber como fazer para ver o link do Temporizador.
    obrigado.

    1. 0

      Olá Florisvaldo! Tem que se registrar para usar esta seção do blog. Mas não tem um artigo específico de temporizador nesta seção, apesar do tema sugerir.
      Cláudio

    1. 0

      Olá Florisvaldo! Este código foi originalmente escrito em ASM, porque nesta época ainda não estava familiarizado com a linguagem “C”. Quem sabe mais para frente, possa reescreve-lo em “C” tanto este como outros postados em ASM.
      Cláudio

  5. 0

    Caro Claudio, boa tarde.
    Tudo muito bem entendido.
    Grato por sua gentileza; valeu de verdade.
    Um abração e bom fim de semana.
    Att,
    João.

  6. 0

    Caro Claudio, bom dia.
    Ok, entendi. Mantenho os 3 transistores NPN com os catodos dos displays ligados aos coletores e os emissores aterrados. As bases permanecem conforme o circuito.
    Uma Dúvida: Os pontos será que vão acender? Se os catodos vão estar aterrados quando a base dos NPN for alimentada, de onde virá alimentação para os pontos? Não será preciso modificar, também, o transistor NPN dos pontos? Pensei o seguinte: alimentar o coletor com 5 volts e o emissor via resistor de 270R ligar ao ponto. Solicito por gentileza analisar este detalhe.
    Att,
    João.

    1. 0

      Olá João! Isto mesmo. Desculpe-me, pois esqueci deste detalhe. Poderá fazer desta forma que você mencionou ou simplesmente ligar um resistor de 270 ohms do pino 12 ao ‘ponto’.
      Cláudio

  7. 0

    Caro Claudio, boa noite.
    O resistor de 47K ligado ao pino 17 do PIC está recebendo tensão do zener 5 volts ou passa direto?
    Caso use display catodo comun que mudanças preciso fazer?
    Os resistores de 47K 1% (um por cento) é facilmente encontrado no comércio?
    Att,
    João.

    1. 0

      Olá João! Por favor, coloque um ‘ponto’ no capacitor de 220 nf (no extremo oposto ao gnd). Os resistores de 47k se tocam neste ponto com o capacitor de 220nf. Já para usar display de catodo comum você terá que inverter a polaridade dos seguimentos. Para isto apenas comente a instrução ‘COMF DIGX ‘ onde x será 2,1 ou 0.
      veja abaixo:
      ;===============================================================================================
      ;CONVERTE PARA 7 SEGUIMENTOS E COLOCA NOS BUFFERS (DIG2 A 0) DO MULTIPLEX PARA APRESENTAÇÃO
      CD7S
      SWAPF BR1,W ;CONVERTE TERCEIRO DIGITO PARA 7 SEGUIMENTOS
      ANDLW 0X0F
      ADDLW .0
      BTFSS STATUS,Z
      GOTO PR1
      CLRF DIG2
      ; COMF DIG2,F ;comente aqui
      GOTO V_DIG1
      PR1
      CALL SEG7
      MOVWF DIG2
      COMF DIG2,F
      V_DIG1
      MOVFW BR1 ;CONVERTE SEGUNDO DIGITO PARA 7 SEGMENTOS
      ANDLW 0X0F
      CALL SEG7
      MOVWF DIG1
      ; COMF DIG1,F ;comente aqui
      V_DIG0
      SWAPF BR0,W ;CONVERTE PRIMEIRO DIGITO PARA 7 SEGMENTOS
      ANDLW 0X0F
      CALL SEG7
      MOVWF DIG0
      ; COMF DIG0,F ;comente aqui
      RETURN

      Quanto aos catodos dos displays, ligue cada catodo ao coletor de um transistor (npn) e seus emissores ao gnd., mantendo a base como está.
      Cláudio

  8. 0

    Boa tarde claudio gostaria de testar esse circuito no Proteus mais o arq. hex tah em bloco de notas como posso usa-lo no pic compiler?

    1. 0

      Olá Darllan! Tente salvar o bloco de notas com terminação ‘.hex’. Se não funcionar, abra o arquivo ( bloco de notas) com o WinPIc, lembrando de colocar o filtro do ‘tipo’ em modo ‘.’. Depois salve como arquivo ‘.hex’ em uma pasta que desejar. Quanto a programas em ‘c’, não é minha praia, pois sou apenas hobista, e não programador. Mas se algum colega do blog puder ajudar…
      Cláudio

      1. 0

        obrigado Claudio…vo tentar aki …mais uma otra duvida …qdo eu for fazer a gravaçao no pic eu utilizo a .hex ou a .asm?

        1. 0

          Olá Darllan! Você deverá usar o arquivo Hex para gravar no Pic. Este é o resultado da compilação do arquivo ASM no Mplab_ide. Veja na Internet, que tem varios tutoriais que ensinam a programar um pic com bastante facilidade. Você necessitará de um gravador de Pic (hardware), que pode ser um comercial, ou um caseiro, como o ‘simples programador de pic‘ deste blog. Também necessitará de um programador rodando no PC (software), que poderá ser o WinPic800 . E por ultimo, precisará de um arquivo Hex a ser transferido para o Pic. Alguns PC, usando o Widowns, não permite o acesso direto da porta serial. Se tiver problemas com isto, use o programa USERPORT , e para instalação dele veja o video. Para programar Atmel Avr, você deverá usar outro Hardware, como o sugerido neste blog como ‘simples programador avr’, e outro programa no PC, o PonyProg.
          Cláudio

      2. 0

        Claudio to meio com duvidas em usar o winPic…sera q vc poderia me mandar ele no winPic fazendo um grande favor no meu email?

    1. 0

      Olá Saulo! Esta rotina já é conhecida e foi adaptada para as necessidades do circuito. Consiste em deslocar para a esquerda os registradores com o valor hexa a converter para dentro dos registradores de resultados decimais . Após cada deslocamento , soma-se 3 a cada nibble (conjunto de 4 bits do byte) dos registradores de resultado. Porque 3? Por que será feito o deslocamento para a esquerda, que equivale a multiplicar por 2 , então 3×2=6 , que é diferença entre o hexa e o decimal). Continuando, após somar 3 ao nibble, testamos se o bit MSB foi para 1. Se foi, mantemos a soma, senão, desfazemos a soma (não é repassada ao registrador). Fazemos isto para cada nibble e repetimos o loop pelo número de bits de resultado desejado.
      O resultado seria equivalente a decrementar o número a converter e a cada vez que fizesse isto, incrementar um registrador que poderíamos chamar de ‘unidade’ do registrador de resultado. Quando a unidade chegasse a 10, seria zerada e incrementaria o registrador de ‘centena’, e assim sucessivamente, pelo numero de bits de conversão desejado.
      Claudio

Os comentários estão fechados.