collapse

* Posts Recentes

Amplificador - Rockboard HA 1 In-Ear por almamater
[Ontem às 19:13]


O que é isto ? por KammutierSpule
[26 de Março de 2024, 19:35]


Bateria - Portátil por almamater
[25 de Março de 2024, 22:14]


Emulador NES em ESP32 por dropes
[13 de Março de 2024, 21:19]


Escolher Osciloscópio por jm_araujo
[06 de Fevereiro de 2024, 23:07]


TP4056 - Dúvida por dropes
[31 de Janeiro de 2024, 14:13]


Leitura de dados por Porta Serie por jm_araujo
[22 de Janeiro de 2024, 14:00]


Distancia Cabo por jm_araujo
[08 de Janeiro de 2024, 16:30]


Meu novo robô por josecarlos
[06 de Janeiro de 2024, 16:46]


Laser Engraver - Alguém tem? por almamater
[16 de Dezembro de 2023, 14:23]

Autor Tópico: leitura de voltagens com o analogRead(A0)  (Lida 26322 vezes)

0 Membros e 1 Visitante estão a ver este tópico.

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #45 em: 28 de Outubro de 2018, 16:30 »
Já li tantas vezes a parte do ADC da datasheet que acho que vou imprimir e mandar encadernar... :-)

Acho que não perceberam o que eu estava a perguntar.

Essa função, que é usada para ler o Vcc do arduino usa a ref.interna de 1.1v.  ->  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);

Logo, como é possível que:

a) Leia corretamente valores acima de 1.1 V, já testei com USB e dá 4.7 V e com 5V diretos ao pino +5V dá 5.1V

b) Como é que, depois de terminar, não deixa o arduino configurado na ref. de 1.1V ?
Stupid men are often capable of things the clever wouldn't dare to contemplate.

Offline jm_araujo

  • Mini Robot
  • *
  • Mensagens: 2.947
  • NERD!
Re: leitura de voltagens com o analogRead(A0)
« Responder #46 em: 28 de Outubro de 2018, 16:40 »
Pelo que entendi, acho que percebeste mal essa leitura.
O que faz é ler os 1.1V com a referência do Vcc. Faz a operação invertida ao  que dizes. Por isso quando acaba deixa a referência como Vcc e não como 1.1V

Agora estou no telemóvel e é difícil fazer explicações mais longas, mas se não fui claro diz qq coisa que logo tento desenvolver (se não aparecer ninguém primeiro)
 

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: leitura de voltagens com o analogRead(A0)
« Responder #47 em: 28 de Outubro de 2018, 16:45 »
Tu é que ainda não percebeste, Vasco :)
A função usa a alimentação do AVR como Vref (REFS[1:0] = 01b = "AVCC with external capacitor at AREF pin", tabela 28-3 da datasheet), e está a medir e Vref interna de 1.1V, pois uma das entradas do MUX (MUX[3:0] = 1110b = "1.1V (VBG)"*, tabela 28-4) está ligada a ela e permite lê-la. Ou seja, o ADC tem uma Vref de 5V (estás a alimentar o AVR a 5V, acho) e está a ler um valor que anda em torno de 1.1V, portanto não há problema nenhum.

Citar
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);

Isto faz REFS[1:0] = 01b e MUX[3:0] = 1110b


*VBG = Vbandgap

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #48 em: 28 de Outubro de 2018, 19:00 »
Daaaaa...



Vou continuar a ler... eventualmente chego lá.... jezzzzzusss...

« Última modificação: 28 de Outubro de 2018, 19:06 por vasco »
Stupid men are often capable of things the clever wouldn't dare to contemplate.

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: leitura de voltagens com o analogRead(A0)
« Responder #49 em: 28 de Outubro de 2018, 20:36 »
Assim.

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #50 em: 29 de Outubro de 2018, 14:45 »
Realmente estava a ver a coisa ao contrário, achei que estavam a usar a ref de 1.1V para ler o AVcc. É escarafunchoso fazer a coisa desta maneira. Mas, obviamente é uma solução válida.

Entretanto tentei criar a minha própria referência para poder compensar as diferenças entre diferentes arduinos Nano. Usei uma referência LT-1004-2.5 e duas resistências de 100K em paralelo (porque raio não fazem resistências de 50 K ????) e nas várias situações que testei tenho sempre o mesmo valor.
No entanto, o facto é que não sei como usar esta referência para calibração.
Tentei simplesmente ler o seu valor, que numa situação ideal deveria retornar 512 e usar o valor lido para obter um offset que depois seria adicionado a todas as medições. Mas não vejo quaisquer melhoras relativamente à exatidão dos valores que estou a obter.

E faz sentido colocar um condensador de 10nF entre o AREF e o GND ?
O valor do condensador não vem na datasheet, mas encontrei varias threads sobre isso no AVRfreaks. Mas parece-me evidente que estão a falar de coisas muito mais hardcore do que aquilo que eu estou a fazer.
Stupid men are often capable of things the clever wouldn't dare to contemplate.

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: leitura de voltagens com o analogRead(A0)
« Responder #51 em: 29 de Outubro de 2018, 15:31 »
Não sei se escarafunchoso é a palavra certa, mas não é uma forma nada precisa, por causa da variação da precisão da Vref interna de 1V1, a não ser que se meça essa Vref (chip a chip) e se use o valor "exacto" nas contas.

A melhor estratégia é sempre a de calibrar o sistema como um todo, como indiquei naquele post da interpolação linear. Mas se quiseres mesmo fazer contas com a Vref interna, um DMM tem muito melhor precisão que ela, por isso podes usá-lo para fazer uma "calibração manual". Configuras o ADC para usar a "Vref interna com um cap no pino AREF", e depois medes a tensão no AREF - essa é a tensão da Vref interna. Usas o valor no teu código. Esta calibração é válida para o chip que usaste (qualquer calibração, baseada na Vref interna, o é).

Em alternativa podes automatizar um pouco mais a calibração, usando uma tensão de referência externa de maior precisão, como esse LT1004-2.5 (espero que seja muito barato, pois 20mV de erro não é nada de especial). Aí ligas essa referência a um pino entrada de ADC e fazes a leitura com a Vref interna. Sabendo tu a tensão que estás a medir, resolves a equação em ordem à Vref interna, que então usas nas contas (eu costumo fazer um programa para calibrar, que guarda o valor da Vref na EEPROM, e depois o"programa principal" lê-o de lá).

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: leitura de voltagens com o analogRead(A0)
« Responder #52 em: 29 de Outubro de 2018, 16:23 »
Ah, em relação ao condensador no AREF, eu costumo meter 100nF, mas acho que 10nF tb deve servir.

O condensador serve para ajudar a estabilizar ainda mais a Vref, isto é importante para reduzir os erros na conversão. A Vref dos ADC deve ser "rock solid", ou seja, ter um valor o mais estável possível.

Agora, se o deves fazer ou não, depende. Há um detalhe. Quanto maior for a capacitância, maior é o tempo que demora a mudar a Vref do ADC (por exemplo de AVcc para Vref interna ou vice-versa). Se usas sempre a mesma Vref no teu programa isto não é um problema, mas se tens que trocar de Vref então tens que ter isso em conta.
« Última modificação: 29 de Outubro de 2018, 16:25 por Njay »

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #53 em: 29 de Outubro de 2018, 18:59 »
10nF ou 100nF não me faz diferença, embora num estágio mais avançado possa pensar mudar para a refª de 1.1 quando tiver que medir uma voltagem abaixo de 1 V (como faz o Transistor Tester) para esta aplicação não tenho qualquer problema em esperar que a referência estabilize.
Um LT-1004-2.5 custa cerca de 1.5€, provavelmente haveria maneiras mais baratas mas eu já tenho confusão que chegue dentro da cabeça.
Gostaria de conseguir automatizar a calibração o mais possível, para a coisa poder funcionar com qualquer Nano, entre dois que tenho por aqui que são claramente de fornadas diferentes até o valor do Vcc (quando ligados por USB na mesma porta e com o mesmo cabo) muda significativamente.
Stupid men are often capable of things the clever wouldn't dare to contemplate.

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: leitura de voltagens com o analogRead(A0)
« Responder #54 em: 29 de Outubro de 2018, 19:50 »
Eu utilizava uma ferrite e um condensador de 1uF , está na datasheet algures.
Avr fanboy

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #55 em: 29 de Outubro de 2018, 22:40 »
Encontro na figura 28-9 "ADC Power connections" que o pino AVCC teria um condensador de 100nF ao GND e ligação ao VCC via uma bobine de 10uH... Será isto a que te referes ?
Stupid men are often capable of things the clever wouldn't dare to contemplate.

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: leitura de voltagens com o analogRead(A0)
« Responder #56 em: 29 de Outubro de 2018, 22:55 »
Trabalhas em Lx Vasco? Posso emprestar-te por uns tempos uma cena para calibrares os teus aparelhos/chips, é de 1.8V -/+1mV. Contacta-me por MP se interessado.

Não me lembro da ferrite nem cap de 1u na datasheet. Isso que o Vasco fala é relacionado com o ADC mas não é do que o senso está a falar.
« Última modificação: 29 de Outubro de 2018, 22:57 por Njay »

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: leitura de voltagens com o analogRead(A0)
« Responder #57 em: 30 de Outubro de 2018, 00:00 »
Oh, estão a falar do AREF e não do AVCC.

1uF X7r no AREF, 1uF+100nF+BLM31PG121SN1L ou 81-BLM15BB221SN1D, funciona que nem ginjas quando tinha as atxmega/atmegaRFA/RFR pendurados em reguladores comutados, e melhor ainda com LDO's.

Se bem que depois apanhei o hábito de utilizar LM4040 de 2.048 em sistemas 3.3v ou de 4.096v em sistemas 5v, é baratissimo comparado com a limpeza que dá em arredondamentos.
Avr fanboy

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #58 em: 30 de Outubro de 2018, 00:25 »
Em alternativa podes automatizar um pouco mais a calibração, usando uma tensão de referência externa de maior precisão, como esse LT1004-2.5 (espero que seja muito barato, pois 20mV de erro não é nada de especial). Aí ligas essa referência a um pino entrada de ADC e fazes a leitura com a Vref interna. Sabendo tu a tensão que estás a medir, resolves a equação em ordem à Vref interna, que então usas nas contas (eu costumo fazer um programa para calibrar, que guarda o valor da Vref na EEPROM, e depois o"programa principal" lê-o de lá).

Era essa a minha ideia e foi assim que liguei o lt1004.

Tentei calcular o Vcc com base na ref de 2.485V no pino A1, mas falhei miseravelmente... :-(
Dá-me 7.657V de Vcc
Julgo que   ADMUX = _BV(REFS0) | (A1 & 7); quer dizer para ler o pino A1 usando Vcc como referência, certo ?

Código: [Seleccione]
long readVcc_25() {
  long result;
  // Read 2.485V reference in pin A1 against AVcc
  ADMUX = _BV(REFS0) | (A1 & 7);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = (2.485*1023*1000) / result; // Back-calculate AVcc in mV    <===== WRONG !!!!!
  return(result);
}

Nota: o 1023 em vez de 1024 vem da função original onde 1125300 = 1.1*1023*1000
Nota2: Grande referência para o ADC - http://www.gammon.com.au/adc
« Última modificação: 30 de Outubro de 2018, 00:29 por vasco »
Stupid men are often capable of things the clever wouldn't dare to contemplate.

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: leitura de voltagens com o analogRead(A0)
« Responder #59 em: 30 de Outubro de 2018, 00:55 »
Tentei calcular o Vcc com base na ref de 2.485V no pino A1, mas falhei miseravelmente... :-(
Dá-me 7.657V de Vcc
Julgo que   ADMUX = _BV(REFS0) | (A1 & 7); quer dizer para ler o pino A1 usando Vcc como referência, certo ?

A1? Onde foste buscar isso? Estás a misturar coisas de Arduino, parece-me... Os nomes dos bits para selecionar a entrada do multiplexer analógico no registo ADMUX são MUX0 a MUX3 (datasheet... e é o que está a ser usado no código original e é o que temos estado a usar), e tens que converter o número do bit (é o que as macros de nomes de bits num registo são) numa bitmask, com a _BV (Bit Value) por exemplo.

Depois tens que ADCcounts = Vpin * 2ADCbits / Vref daí que Vref = Vpin * 2ADCbits / ADCcounts .
Em mV é multiplicar o resultado por 1000, ou melhor, multiplicar antes de dividir pelo ADCcounts e somar ADCcounts/2 também antes de dividir para melhorar a precisão. Como vês, Vpin * 2ADCbits * 1000, na tua aplicação é uma constante.
« Última modificação: 30 de Outubro de 2018, 01:08 por Njay »