Como eu posso medir tensão com pic e max7221

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Como eu posso medir tensão com pic e max7221

Mensagempor rosiley » 25 Set 2015 19:36

Boa noite pessoal, antes de mais nada quero agradecer a ajuda que tenho recebido neste forum e que está sendo de grande importância para o meu aprendizado e os meus projetos, mais vamos lá.

Estou desenhando um voltimetro com pic e display de 7 segmentos sendo multiplexado pelo max 7221, este projeto vai ler dois canais analógicos onde será mostrado em 8 display, sendo 4 para um canal e 4 para outro canal como segue o código abaixo. Fazer com que o processador acesse o display eu consigo, mais fazer com que o mesmo mostre o valor é ai que o bicho pega.

cpp code
#include <16f877.h>          //Inclui arquivo header do PIC 16F877
#device ADC = 10 //Define 10 bits para o resultado da conversão AD

#include <stdio.h> // inclusão de SPRINTF
#include <string.h> // inclusão de STRLEN

#use delay (clock=20000000) /*Definição da frequência do cristal para cálculo
..dos delays*/
#fuses HS, NOWDT, PUT,BROWNOUT, NOLVP //Configuração dos bits de controle

//Definições para a comunicação serial
#use RS232 (Baud=9600, xmit = PIN_C6, rcv = PIN_C7)

//variáveis para armazenamento da conversão

int32 ad0,ADC0; // AN0
int32 ad1,ADC1; // AN1
int32 ad2,ADC2; // AN2
//int32 ad3,ADC3; // AN4

#INT_TIMER0 //Diretiva de indetificação da int. do Timer 0

void PiscaLED()
{
static boolean PiscaLed; //para piscar o led.
static int contador; //para contar o tempo de 1 segundo.
set_timer0(131-get_timer0());
contador++;
if(contador == 125) //Se contou 125 (1 segundo).
{
contador=0; //zera contagem.
PiscaLed = !PiscaLed; //Inverte bit;
output_bit(pin_C0, PiscaLed); //Liga/desliga LED.
}
}

//Formato do protocolo = AN0:0000:AN1:0000:00000000
void escreve_serial() //Função de envio do protocolo para a serial
{
printf("AN0:%04lu",ad0);//Envia dados de conversão A/D1
printf(";"); //Controle do protocolo
printf("AN1:%04lu",ad1); //Envia dados de conversão A/D2
printf(";"); //Controle do protocolo
printf("AN2:%04lu",ad2); //Envia dados de conversão A/D3
printf(";"); //Controle do protocolo
}

#define N_MAX 2
#define MAX_DIN PIN_B4
#define MAX_CS PIN_B3
#define MAX_CLK PIN_B2
#include <MAX72xx.c>

char a,b,c,d,e,f;
char g,h,i,j,k,l;

void main()
{
//Configura as entradas analógicas AN0 a AN4
SETUP_ADC_PORTS(AN0_AN1_AN2_AN4_VSS_VREF);
//Utiliza o clock interno para tempo de aquisição
SETUP_ADC(ADC_CLOCK_Internal);
//Habilita interrupção global
Enable_Interrupts(GLOBAL);
//Habilita interrupção por recepção de dados na serial
Enable_Interrupts(INT_RDA);
//Habilita interrupção pelo overflow do Timer 0
ENABLE_INTERRUPTS(INT_TIMER0);
/*Configura Timer 0 para incremento pelo ciclo de máquina Prescaler de 1:256 e
modo de operação em 8 bits*/
SETUP_TIMER_0(RTCC_INTERNAL | RTCC_DIV_256 | RTCC_8_BIT);
//Inicia o Timer 0 com o valor 61 - Interrupção a cada 25ms
SET_TIMER0(61);

Iniciar_MAX72xx(0xFF); //Ativa o decodificador
Comandos_MAX72xx(0x0A,0X08); //Itensidade minima

while(true)
{

SET_ADC_CHANNEL(0); //Configura o canal de leitura 0
delay_ms(10); //Tempo de ajuste do canal (necessário)
ad0 = READ_ADC(); //Faz a conversão AD e a salva na variável ad0

SET_ADC_CHANNEL(1); //Configura o canal de leitura 1
delay_ms(10); //Tempo de ajuste do canal (necessário)
ad1 = READ_ADC(); //Faz a conversão AD e a salva na variável ad0

SET_ADC_CHANNEL(4); //Configura o canal de leitura 1
delay_ms(10); //Tempo de ajuste do canal (necessário)
ad2 = READ_ADC(); //Faz a conversão AD e a salva na variável ad0

ADC0 = (ad0 * 500) /1023;
ADC1 = (ad1 * 500) /1023;
ADC2 = (ad2 * 500) /1023;


for(a=0;a<10;a++)
for(b=0;b<10;b++)
for(c=0;c<10;c++)
for(d=0;d<10;d++)
for(e=0;e<10;e++)
for(f=0;f<10;f++)

for(g=0;g<10;g++)
for(h=0;h<10;h++)
for(i=0;i<10;i++)
for(j=0;j<10;j++)
for(k=0;k<10;k++)
for(l=0;l<10;l++)
{
Enviar_MAX72xx(1,1,a);// Primeiro display, Posição no display, valor no display
Enviar_MAX72xx(1,2,b);
Enviar_MAX72xx(1,3,c);
Enviar_MAX72xx(1,4,d);
Enviar_MAX72xx(1,5,e);
Enviar_MAX72xx(1,6,f);

Enviar_MAX72xx(2,1,g);// Segundo display, Posição no display, valor no display
Enviar_MAX72xx(2,2,h);
Enviar_MAX72xx(2,3,i);
Enviar_MAX72xx(2,4,j);
Enviar_MAX72xx(2,5,k);
Enviar_MAX72xx(2,6,l);
delay_ms(100);
}

}
}
rosiley
Nibble
 
Mensagens: 51
Registrado em: 01 Jul 2008 19:38
Localização: rio das ostras

Re: Como eu posso medir tensão com pic e max7221

Mensagempor andre_luis » 26 Set 2015 22:39

ok, mas não ficou claro o que está acontecendo e o que deveria acontecer...
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Como eu posso medir tensão com pic e max7221

Mensagempor rosiley » 26 Set 2015 23:58

Boa noite, o circuito está funcionando ou seja está enviando os valores para o pc via rs232, mais eu não estou conseguindo fazer com que o display mostre os valores.
rosiley
Nibble
 
Mensagens: 51
Registrado em: 01 Jul 2008 19:38
Localização: rio das ostras

Re: Como eu posso medir tensão com pic e max7221

Mensagempor andre_luis » 27 Set 2015 11:09

Voce não está instanciando a função escreve_serial() em nenhum lugar do seu programa...
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Como eu posso medir tensão com pic e max7221

Mensagempor Djalma Toledo Rodrigues » 27 Set 2015 12:12

'
Crítica ao C

Detesto essas Sintaxes idiotas. Começa pelo nome C

A Intel havia patenteado os mnemônicos
Aí, no impedimento, em vez de "Inc x" ==> "X++"

? E para decrementar em C ? "X+-" ? conf. que não sei

Mas, voltando ao caso
Isso em Assembler seria tão mais simples.

* Depois coloco o jeito meu de ter os Mnemônicos disponíveis na Ide ao Programar.

Dj. (Se sentindo clítico, como dizem no Face.)
Editado pela última vez por Djalma Toledo Rodrigues em 27 Set 2015 15:39, em um total de 1 vez.
Avatar do usuário
Djalma Toledo Rodrigues
Dword
 
Mensagens: 2334
Registrado em: 03 Ago 2008 13:22

Re: Como eu posso medir tensão com pic e max7221

Mensagempor Djalma Toledo Rodrigues » 27 Set 2015 15:36

'
Mas, me parece que há um equivoco na Concepção do Programa
é o Display Led que deve ser multiplexado e não os seguimentos.

Verifique.

Dj.
Avatar do usuário
Djalma Toledo Rodrigues
Dword
 
Mensagens: 2334
Registrado em: 03 Ago 2008 13:22

Re: Como eu posso medir tensão com pic e max7221

Mensagempor ze » 28 Set 2015 12:00

Permita-me também alguns olhares críticos
-pra este mc e este propósito, não é necessário o tal max (que nunca vi na vida). Este mc tem muitas portas que podem podem com relativa facilidade multiplexar 8 dígitos de 8 segmentos numa interrupçao qualquer de timer (quase dá pra digitar o fonte on line aqui agora). Pra isso tem que lançar mão de algum conhecimento básico do hw do pic.
-concordo com o equívoco do dj. Publique seu esquema. Mais fácil pra ver 'o que que há. O que está se passando por sua cabeça' (fábio júnior, anos 80)
-discordo do c ser menos simples do que o asm (mas isso nada a ver)
-Se insistir no max, 1ª mente veja como ele funciona (não vi) e envie um dado qualquer pra ele. Use simulador
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Re: Como eu posso medir tensão com pic e max7221

Mensagempor rosiley » 28 Set 2015 13:11

Segue o desenho para análise e um link onde eu estou tentando fazer igual.


https://www.youtube.com/watch?v=ikgQyHx_yB0

https://www.youtube.com/watch?v=g91CJSjKz18
Você não está autorizado a ver ou baixar esse anexo.
rosiley
Nibble
 
Mensagens: 51
Registrado em: 01 Jul 2008 19:38
Localização: rio das ostras

Re: Como eu posso medir tensão com pic e max7221

Mensagempor andre_luis » 28 Set 2015 13:28

Onde está declarada a função Enviar_MAX72xx() ?
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Como eu posso medir tensão com pic e max7221

Mensagempor ze » 28 Set 2015 14:50

Mesmo aumentando o número de displays desde o 1º post, eu ainda evitaria o max (que pode estar pirando a cabeça). Talvez alguns 74hc164, hc595 da vida .
Não vi video. Se for 6 displays por canal ad, acho que está sobrando coisa pois 10bits = 1023 no máximo 4 displays mas eu usaria só 3 (ou 2) pra medir de 0 a 5V
Mais coisa sobrando é int32 num mc de 8 bits. Neste caso nem precisa (talvez nem deva)
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Re: Como eu posso medir tensão com pic e max7221

Mensagempor rosiley » 04 Nov 2015 19:37

Boa noite pessoal, pesquisando na net encontrei este código que começou a clarear a minha visão e comecei implementando ao meu projeto mas estou com uma dúvida no que diz aos valores.

1° Os digitos visualizados no display o primeiro digito sempre mostra 0 ;
2° Como faço para fazer com que o segundo max7219 mostre outro valor. Segue o código para análise.

cpp code
#include <12f683.h> 
#fuses intrc_io,noput,nowdt,noprotect,nomclr,nobrownout,noieso,nofcmen
#device adc=10
#use delay(clock=4M)
#use fast_io(a)
#use spi(do=pin_a0,clk=pin_a2,bits=16,load_active=1,load=pin_a1,idle=1)
//We have to write this directive, you can add stream and change the pin do, clk, load
//I've used bits 16 'cause max7219 needs 16 bits =)
//The idle is 1, if you put 0, nothing will appear on your displays <- this is really important


int address, data, adqnum, digit[4]; //address, data max's variables
//adqnum for 100 samples
//digit[4] this array keeps 4 digits used in this project
int16 packetmax, result; //packetmax goes to the max7219
//result keeps the value used to obtain digits
int32 adcvalue=0; //this variable keep the adc value read 100 times
float calculus; //variable used for (adcvalue * (5/1023))

void maxsend(){ //routine for max7219 just
packetmax=make16(address,data); //make a 16 bit variable address byte high, data byte low
spi_xfer(packetmax); //transfer using spi software
} //just 5 lines including #use spi. It's really simple right?

void maxsetup(){ //configure properly
address=0x09, data=0xff, maxsend(); //it's up to you
address=0x0a, data=0x01, maxsend(); //just read a minute the datasheet
address=0x0b, data=0x03, maxsend(); //it's easy and fast.
address=0x0f, data=0x00, maxsend();
address=0x0c, data=0x01, maxsend();
}

void algebra_digits(){
calculus=adcvalue*0.4887585533; //500 is the max value, 500=5.00V, but it's float
result=calculus; //transfer the correct value to int result
//if you want to measure a higher voltage just change the float value
//and don't forget using resistors as needed.

//the following 4 lines are used to obtain digits
digit[0]=result-((result/10)*10); //units place
digit[1]=(result/10)-((result/100)*10); //tens place
digit[2]=(result/100)-((result/1000)*100); //hundreds place
digit[3]=result/1000; //thousands place
}

void main(){
setup_comparator(nc_nc_nc_nc); //no comparator module
setup_adc(adc_clock_div_16); //Tad = 4.0us
setup_adc_ports(an3_analog); //gpio4 as analog input, u can choose your favorite pin
set_adc_channel(3); //select channel 3 =gpio4
set_tris_a(0b00011000); //set port
delay_ms(1000); //wait just for relaxing =), this line is not that important
maxsetup(); //

while(1){
for(adqnum=1;adqnum<=100;adqnum++){ //collect 100 samples, I usually do this, u can use your favorite method
adcvalue=adcvalue+read_adc(); //for acquisition.
delay_us(20);
}
adcvalue=adcvalue/100;
algebra_digits(); //call algebra routine to get each digit
address=0x01, data=digit[0], maxsend();
address=0x02, data=digit[1], maxsend();
address=0x03, data=(digit[2] | 0b10000000), maxsend(); //use OR for adding decimal point
address=0x04, data=digit[3], maxsend();
adcvalue=0; //clean adcvalue
}
}
rosiley
Nibble
 
Mensagens: 51
Registrado em: 01 Jul 2008 19:38
Localização: rio das ostras

Re: Como eu posso medir tensão com pic e max7221

Mensagempor rosiley » 30 Abr 2016 11:35

Obrigado a todos que me ajudaram e informo que consegui resolver o problema, o meu projeto já lê os canais corretamente nas duas linhas de display, agora tenho outra missão. Fazer com que a segunda linha de display leia os valores dos canais 2, 4 e 5 do conversor ad controlado atraves de uma chave.
rosiley
Nibble
 
Mensagens: 51
Registrado em: 01 Jul 2008 19:38
Localização: rio das ostras


Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

cron

x