calculo de AD

Software e Hardware para linha ARM

Moderadores: 51, guest2003, Renie, gpenga

calculo de AD

Mensagempor cortex » 25 Fev 2011 09:50

Caros colegas, estou montando um voltimetro para ler tensões em milivolts, acontece que tensões acima de 70mV estou tendo um erro danado devido ao meu calculo utilizado, segue o trecho do codigo se alguém puder da um pitaco na caca que estou fazendo eu ficaria muito grato!!



LPC_ADC->ADCR |= (1<<24);
while (!(LPC_ADC->ADGDR & (1UL<<31)));
val1[0] = ((LPC_ADC->ADGDR >> 4) & 0xFFF);
LPC_ADC->ADCR &= ~(7<<24);

va1[0] = val1[0];
va1[0] = ((float)((va1[0])*100)/0x00000FFF) *3.3;
Value1[0]=(unsigned char)(va1[0]/100%10);
Value1[1]=(unsigned char)(va1[0]/10%10);
Value1[2]=(unsigned char)(va1[0]%10);

o problema está aqui, nesta multiplicação que estou fazendo, não tenho idéia se a multiplicação está correta!

va1[0] = ((float)((va1[0])*100)/0x00000FFF) *3.3;

obrigado!
cortex
Byte
 
Mensagens: 121
Registrado em: 27 Out 2010 10:32

Mensagempor fabim » 25 Fev 2011 10:38

tististsit...

float data;
short adc,resu;
char string[5];

adc= ((LPC_ADC->ADGDR >> 4) & 0xFFF);


data =(float)adc * (3300.00/1024); //para 10 bits
//suponha que o resultado do adc é 512 = 1.650V.
//3300.00/1024 = 3.22265625 float.
//3.22265625 * 512 = 1650.00 float isso melhora o range.
//sprintf(string,"voltagem: %0.1f",data);


Agora se quiser que fique 1.650 em float.

data =(float)adc * (3.300/1024); //para 10 bits
//3300.00/1024 = 0.00322265625 float.
//ele só vai pegar isso 0.00322265 o final 625 ele perde
//0.00322265 * 512 = 1.6499968 não gosto desse resultado
//sprintf(string,"voltagem: %0.3f",data);

//esse comando do sprintf %0.3f, diz ao conversor que é pra jogar 3 casas
//depois do ponto em float para a string.


mas como eu sou bixo HOMI, eu não uso float pra essas coisinhas bestas. hehe
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor cortex » 25 Fev 2011 15:01

valew fabim! funfou!! o que tava cagando é q tava dividindo por 12bits!!
cortex
Byte
 
Mensagens: 121
Registrado em: 27 Out 2010 10:32

Mensagempor cortex » 28 Fev 2011 23:04

como eu sei que estou utilizando referência externa ou interna no cortex 1768?

em meu circuito liguei o Vrefp e o Vrefn isolados do circuito, vindo direto do regulador, mas meu regulador é tabajara com zener 3v3, alguma alteração na leitura se eu mandar mais de 3.3V nestas referências? no caso uma oscilação de tensão vai alterar minha leitura ad?
cortex
Byte
 
Mensagens: 121
Registrado em: 27 Out 2010 10:32

Mensagempor barboza » 01 Mar 2011 11:43

fabim escreveu:
data =(float)adc * (3300.00/1024); //para 10 bits



O ideal é multiplicar antes de dividir.

Código: Selecionar todos
data = (float) (((float) adc * 3300.00) / 1024); //para 10 bits
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor fabim » 01 Mar 2011 12:31

barboza escreveu:
fabim escreveu:
data =(float)adc * (3300.00/1024); //para 10 bits



O ideal é multiplicar antes de dividir.

Código: Selecionar todos
data = (float) (((float) adc * 3300.00) / 1024); //para 10 bits


poha, tu ainda diz que dois casting seguidos é o ideal ?

ta loco eim.

bom, não resisti.
Sem contar que aqui.

data =(float)adc * (3300.00/1024);
Qualquer IDE substitui o (3300.00/1024), por 3.2226562..
ou seja, ele pega o ADC e mult resul.. isso ja em float.

Enquanto aqui.
data = (float) (((float) adc * 3300.00) / 1024); //para 10 bits
Ele faz ADC mult 3300.00
depois
div em casting por 1024;
depois casting para data;

Vai demorar umas 4 a 5 vezes mais pra dar o resultado...
Editado pela última vez por fabim em 01 Mar 2011 12:45, em um total de 1 vez.
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor barboza » 01 Mar 2011 12:40

fabim escreveu:
barboza escreveu:
fabim escreveu:
data =(float)adc * (3300.00/1024); //para 10 bits



O ideal é multiplicar antes de dividir.

Código: Selecionar todos
data = (float) (((float) adc * 3300.00) / 1024); //para 10 bits


poha, tu ainda diz que dois casting seguidos é o ideal ?

ta loco eim.


barboza escreveu:O ideal é multiplicar antes de dividir.
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor fabim » 01 Mar 2011 14:29

barboza escreveu:
fabim escreveu:
barboza escreveu:
fabim escreveu:
data =(float)adc * (3300.00/1024); //para 10 bits



O ideal é multiplicar antes de dividir.

Código: Selecionar todos
data = (float) (((float) adc * 3300.00) / 1024); //para 10 bits


poha, tu ainda diz que dois casting seguidos é o ideal ?

ta loco eim.


barboza escreveu:O ideal é multiplicar antes de dividir.


fabim escreveu:
data = (float) (((float) adc * 3300.00) / 1024); //para 10 bits
Isso demora de mais

data =(float)adc * (3300.00/1024); //para 10 bits
Isso não demora nada




#define float_quociente 3300.00/1024

data = (float)adc * float_quociente;
Isso tambem ta errado ?

Se a constante é estatica/constante/fixa, e não dinamica.
Pra que usar a libc pra fazer dois calculos e perder n ciclos de maquina ?

Barboza não to brigando não eim, veja bem. Eu só estou colocando a melhor forma. E a correta.

A melhor forma de se fazer algo, é aquela que tem o melhor resultado no menor tempo.
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor barboza » 01 Mar 2011 15:04

fabim escreveu:
barboza escreveu:
fabim escreveu:
barboza escreveu:
fabim escreveu:
data =(float)adc * (3300.00/1024); //para 10 bits



O ideal é multiplicar antes de dividir.

Código: Selecionar todos
data = (float) (((float) adc * 3300.00) / 1024); //para 10 bits


poha, tu ainda diz que dois casting seguidos é o ideal ?

ta loco eim.


barboza escreveu:O ideal é multiplicar antes de dividir.


fabim escreveu:
data = (float) (((float) adc * 3300.00) / 1024); //para 10 bits
Isso demora de mais

data =(float)adc * (3300.00/1024); //para 10 bits
Isso não demora nada




#define float_quociente 3300.00/1024

data = (float)adc * float_quociente;
Isso tambem ta errado ?

Se a constante é estatica/constante/fixa, e não dinamica.
Pra que usar a libc pra fazer dois calculos e perder n ciclos de maquina ?

Barboza não to brigando não eim, veja bem. Eu só estou colocando a melhor forma. E a correta.

A melhor forma de se fazer algo, é aquela que tem o melhor resultado no menor tempo.


Quem disse que estou brigando????? Já correu sangue ai???? hehehe.

Com certeza o melhor é o certo e mais rápido.

O meu recado foi sobre problemas de arrendondamentos e truncamento. Problemas com calculos numericos.
Dois castings iguais seguidos não creio que faz diferença. O compilador sabe o que deve fazer ou não. Com certeza, duas operações levará mais tempo que uma, mas o resultado poderá ser bem diferente, principalmente se o valor do adc for pequeno, e não na meia escala, como seu exemplo.


Agora cuidado, que

fabim escreveu:#define float_quociente 3300.00/1024


É diferente que:

Código: Selecionar todos
#define  float_quociente    (3300.00/1024)


Já perdi uma semana com algo assim, pois o compilador irá expandir a macro (nao constante) e você terá resultados diferentes.
Minhas macros ou constantes, sempre defino entre (), mas editei uma já declarada e me ferrei.



p.s. Ahh, obrigado por editar a sua msg com algo que não havia quando fiz o meu comentario. rs.
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor barboza » 01 Mar 2011 15:08

fabim escreveu:
barboza escreveu:
fabim escreveu:
barboza escreveu:
fabim escreveu:
data =(float)adc * (3300.00/1024); //para 10 bits



O ideal é multiplicar antes de dividir.

Código: Selecionar todos
data = (float) (((float) adc * 3300.00) / 1024); //para 10 bits


poha, tu ainda diz que dois casting seguidos é o ideal ?

ta loco eim.


barboza escreveu:O ideal é multiplicar antes de dividir.


fabim escreveu:
data = (float) (((float) adc * 3300.00) / 1024); //para 10 bits
Isso demora de mais

data =(float)adc * (3300.00/1024); //para 10 bits
Isso não demora nada




#define float_quociente 3300.00/1024

data = (float)adc * float_quociente;
Isso tambem ta errado ?

Se a constante é estatica/constante/fixa, e não dinamica.
Pra que usar a libc pra fazer dois calculos e perder n ciclos de maquina ?

Barboza não to brigando não eim, veja bem. Eu só estou colocando a melhor forma. E a correta.

A melhor forma de se fazer algo, é aquela que tem o melhor resultado no menor tempo.


Quem disse que estou brigando????? Já correu sangue ai???? hehehe.

Com certeza o melhor é o certo e mais rápido.

O meu recado foi sobre problemas de arrendondamentos e truncamento. Problemas com calculos numericos.
Dois castings iguais seguidos não creio que faz diferença. O compilador sabe o que deve fazer ou não. Com certeza, duas operações levará mais tempo que uma, mas o resultado poderá ser bem diferente, principalmente se o valor do adc for pequeno, e não na meia escala, como seu exemplo.


Agora cuidado, que

fabim escreveu:#define float_quociente 3300.00/1024


É diferente que:

Código: Selecionar todos
#define  float_quociente    (3300.00/1024)


Já perdi uma semana com algo assim, pois o compilador irá expandir a macro (nao constante) e você terá resultados diferentes.
Minhas macros ou constantes, sempre defino entre (), mas editei uma já declarada e me ferrei.



p.s. Ahh, obrigado por editar a sua msg com algo que não havia quando fiz o meu comentario. rs.
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor cortex » 02 Mar 2011 08:01

[quote="cortex"]como eu sei que estou utilizando referência externa ou interna no cortex 1768?

em meu circuito liguei o Vrefp e o Vrefn isolados do circuito, vindo direto do regulador, mas meu regulador é tabajara com zener 3v3, alguma alteração na leitura se eu mandar mais de 3.3V nestas referências? no caso uma oscilação de tensão vai alterar minha leitura ad?[/quote]

brigas a parte, i u meu? alguem dá um pitaco!
cortex
Byte
 
Mensagens: 121
Registrado em: 27 Out 2010 10:32

Mensagempor fabim » 02 Mar 2011 10:38

cortex escreveu:
cortex escreveu:como eu sei que estou utilizando referência externa ou interna no cortex 1768?

em meu circuito liguei o Vrefp e o Vrefn isolados do circuito, vindo direto do regulador, mas meu regulador é tabajara com zener 3v3, alguma alteração na leitura se eu mandar mais de 3.3V nestas referências? no caso uma oscilação de tensão vai alterar minha leitura ad?


brigas a parte, i u meu? alguem dá um pitaco!


maximo DDP entre VREF+ e VREF- <= potencial aplicado no micro controlador...
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor cortex » 02 Mar 2011 10:52

valew fabim!
cortex
Byte
 
Mensagens: 121
Registrado em: 27 Out 2010 10:32


Voltar para ARM

Quem está online

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

cron

x