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 26360 vezes)

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

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
leitura de voltagens com o analogRead(A0)
« em: 23 de Agosto de 2018, 00:43 »
Boa noite,

Costumo tentar evitar o cross posting, mas desde esta tarde que não consigo aceder ao forum.arduino.cc onde coloquei uma pergunta sobre este assunto.
Não entrando muito nos detalhes do que estou a fazer (um ohmimetro, sou um tanto ou quanto daltónico e não consigo ler as barras, e o multímetro nunca está à mão e é lixado medir com as pontas de prova), gostava só de pedir que me explicassem qual é a ideia do uso do analogRead para ler uma voltagem.

Estou a usar um Nano, portanto o ADC é de 10 bits.
Pelo que percebo, quando se faz um leitura deve-se receber 0 se o valor for 0V e 1023 se o valor for 5V, sendo que 2.5V dariam 511, etc...
No muito que já li sobre o assunto dei com alguém a dizer que usava a referência interna de 1.1V para obter melhor precisão.

Realmente existe a instrução analogReference(INTERNAL1V1);
Mas, e isto aqui é que gostaria que me explicassem, fico limitado a medir valores abaixo de 1.1V? É que os valores que medi com com esta referência ativa não fazem sentido. Mas no contexto em que dizem isto também não faz sentido nenhum que não se possam ler valores acima de 1.1V...  :o
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 #1 em: 23 de Agosto de 2018, 01:05 »
Se Vin for a tensão de entrada, no pino, o número lido do ADC, adc, a que chamamos "contagem", é

adc = Vin / Vref * 210

O expoente 10 é o número de bits do ADC. Por omissão, no Arduino Vref = Vcc = 5V, ou melhor, ~5V, porque a precisão (quão perto dos 5V absolutos) e a estabilidade (a estabilidade face a alterações da temperatura e outras) dependem da "qualidade" da fonte de alimentação que gera esses 5V.

Pela expressão já vês que só consegues medir tensões até Vref - Vref / 210, ou seja Vref - "uma contagem" (também conhecido como "1 LSB") . Para valores de tensão acima disso, a contagem é sempre o valor máximo (1023 no caso de um ADC de 10 bits), diz-se que "satura" (nos 1023, neste caso).

A referência interna de tensão de 1.1V é uma fonte de maior estabilidade do que o tipico regulador de 5V (como o 7805), ou seja, o valor dela varia com a temperatura/Vcc/consumo/etc dentro de certos limites mais apertados (indicados na datasheet do AVR), mas a sua precisão é má, pois pode ser um valor qualquer entre 1 e 1.2V (ver datasheet) para cada chip que sai da fábrica, 1.1V é um valor nominal (acho que até o 7805 tem melhor precisão :D). Para a usar para medir valores absolutos de tensão, tens que medi-la 1º e depois usar esse valor nos cálculos (tipicamente guarda-se na EEPROM e o código faz uso disso).

Ao usares uma Vref mais baixa, estás a aumentar a resolução, à custa de perder gama dinâmica (o intervalo possível de leitura). Com Vref = 5V o passo do ADC, ou, dito de outra forma, a menor variação "garantida" que consegues medir, é

Vref / 210 ~ 4.88 mV

já com Vref = 1.1V é ~ 1.07 mV.

Podes sempre ler valores acima de Vref, se reduzires a tensão de entrada para ser < Vref e tiveres isso em conta no código...

Perguntas?
« Última modificação: 30 de Agosto de 2018, 22:12 por Njay »

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #2 em: 24 de Agosto de 2018, 20:41 »
Ok, então afinal é mesmo como eu pensava, só se pode medir voltagens abaixo da vref.
Faz sentido quando não se pode garantir a vcc a 5V (baterias por exemplo).

Tenho estado a olhar para alternativas ao ohm meter via x resistências de teste, e parece que ninguém se arrisca a fazer outra coisa com o arduino.
Na vossa opinião, pare medir um range entre 1 ohm (ok 10 ohms) e 1 M qual será o conjunto de resistências de teste apropriado ? Dividir o mais possível pela range toda ou há alguma nuance ?

O método dos 4 pontos (kelvin) parece-me viável, tenho algures um sensor de corrente, mas tenho que investigar para ver se mede gramas ou arrobas.

Estou meio tentado a meter uma caixita com material no meio da roupa das férias, mas é capaz de ser um bocado perigoso... ;-) Portanto acho que não vou fazer mais nada até Setembro.

abraços e obrigado
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 #3 em: 24 de Agosto de 2018, 23:33 »
Já deste uma vista de olhos ao "trasistortester": https://github.com/svn2github/transistortester

Só precisa de uma referência externa e um punhado de resistências (o resto é para alimentação e UI), e compra-se tão barato que pode servir de base para outros projetos.

Não tem problemas em ler resistências dos valores que pretendes, e no manual descreve como é feito o cálculo, página 74 do manual aqui: https://raw.githubusercontent.com/svn2github/transistortester/master/Doku/tags/english/ttester_eng112k.pdf


Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #4 em: 30 de Agosto de 2018, 18:46 »
Como costume, excelente sugestão, vou investigar.

Obrigado
Stupid men are often capable of things the clever wouldn't dare to contemplate.

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #5 em: 05 de Setembro de 2018, 18:42 »
Tenho estado a estudar o esquema e vou ver se construo uma versão "abreviada" só com o necessário para medir resistências.
Ainda não consegui compreender qual é o método que usam, apenas têm duas resistências de referência, não estou a ver para já como é que conseguem a exatidão que dizem que conseguem, e já comprovei que pelo menos a versão que eu tenho dá resultados aceitáveis, portanto haverá algum truque. O código também não é exatamente muito simples... tsk... analogRead() é para maricas... :-D
É um pet project giro, vou andar de volta disto mais uns tempos :-)
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 #6 em: 07 de Setembro de 2018, 11:40 »
Estive a ler sobre o método por curiosidade e para ver se dava uma ajuda, e acho que entendi:
Esquema:


O que fazem é ativar primeiro a Out 1 (Out 2 em tri-state, a flutuar),é um divisor de tensão, e medem o valor com a ADC, usando como referência do ADC os 5V da alimentação. Se o valor de resistência for muito baixo dá valores muito perto dos 0V, e nesse caso mudam a referência da ADC  para a interna de 1.1V para aumentar a resolução. Se o valor for muito alto, mudam do Out1 para o Out2, fica um divisor com os 470kOhm e já puxa os valores da ADC para baixo. Não fiz as contas, mas pode ser necessário para valores de resistência na zona de transição entre os 680 e os 470k usar também a referência interna de 1.1V.

Depois é só fazer as contas  para converter a tensão do ADC para a resistência, mas não é nada de muito complicado, é sempre um divisor de tensão.


A "confusão" do esquema original é porque permite ler resistências (e outros componentes) entre quaisquer 3 pinos, e é preciso fazer mais medidas, mas para o teu caso é desnecessário complicar.




« Última modificação: 07 de Setembro de 2018, 11:44 por jm_araujo »

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #7 em: 07 de Setembro de 2018, 15:05 »
Ok, parece fazer algum sentido.
Julgo que o esquema original usa uma referencia externa de 2.5V e não os 5V do VCC, não tenho aquela referência mas tenho um modulozinho que pode dar 2.5, 5.0, 7.5 e 10V
Vou tentar ensaiar com ela e com  a interna de 1.1V da maneira que sugeriste.

https://www.ebay.com/itm/331725573000

tks.
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 #8 em: 07 de Setembro de 2018, 15:27 »
No transistortester a referência externa é usada para calibração e não como referência:
Citar
The additional 2.5V precision voltage reference connected at pin PC4 (ADC4) can be used to
check and calibrate the VCC voltage, but is not required

Assim conseguem ter a gama completa dos 5V para converter.

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #9 em: 07 de Setembro de 2018, 21:32 »
OK, não tinha compreendido isso.
Mas então fico com duas incógnitas, não sei nem a que voltagem o Nano coloca o pino quando o ponho em HIGH nem sei a que voltagem está a referência de 5V quando alimento o Nano via USB.

Bom, vou ligar uns pinos segundo o teu esquema e já vejo que resultados tenho.
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 #10 em: 07 de Setembro de 2018, 21:53 »
Mete o pino á voltagem que tem no Vcc, se for 5v, mete 5v, se for 3.3v, mete 3.3v no pino.

A referência de 5v, supostamente estará a 5v se for do tipo shunt, ou a 0v se não tiver headroom para funcionar.
Avr fanboy

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #11 em: 07 de Setembro de 2018, 22:24 »
É um nano, portanto são 5V.
O problema é que nunca são MESMO 5v, tal como o VCC vindo do USB também nunca são MESMO 5v. E pelo que consegui medir até agora com a minha limitada "aparelhagem", não são mesmo NADA 5V, são mais 4.5v

Mas bom, como a minha resistência de 680 ohm tem na verdade 546 ohm e a de 470k tem 4773 ohms devo estar a preocupar-me com coisas parvas... :-)
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 #12 em: 07 de Setembro de 2018, 22:53 »
Se tens 4.5v no USB algo de errado se passa com o teu ou o teu hub..

Avr fanboy

Offline jm_araujo

  • Mini Robot
  • *
  • Mensagens: 2.947
  • NERD!
Re: leitura de voltagens com o analogRead(A0)
« Responder #13 em: 08 de Setembro de 2018, 10:15 »
É um divisor resistivo e o ADC tem a mesma referência. Se a alimentação variar o resultado da conversão deve manter-se constante.

Eu preocupava-me mais era se tiveres de usar a referência interna, que já não varia em simultâneo. Não estive a ver o diagrama, talvez dê para converter o valor dessa referência e descobrir a sua relação com a alimentação.

Offline vasco

  • Mini Robot
  • *
  • Mensagens: 444
Re: leitura de voltagens com o analogRead(A0)
« Responder #14 em: 08 de Setembro de 2018, 11:00 »
Se tens 4.5v no USB algo de errado se passa com o teu ou o teu hub..

Não estou a usar um hub externo, estou a ligar numa porta frontal de um desktop, a voltagem à saída sem nada ligado é 5.01v mas desce para 4.97 quando lhe ligo o Nano, mas nota que esta medida é feita não com o DMM mas com um daqueles testers USB, portanto os valores podem não ser exactos, mas existe uma variação.

Com o Nano ligado, e medindo entre o shield da tomada mini usb (no Nano) tenho

pino 5V e pino AREF: 4.641V (sim, sei que o AREF é para ligar uma referencia externa, fui só ver o que lá estava)
pino VIN: 4.222 (também sei que este pino é usado para alimentar o nano sem passar pelos reguladores, fui só ver o que lá estava)
pino 3.3V: 3.245
pino a que foi feito um pinMode(x, OUTPUT); digitalWrite(x, HIGH);: 4.607V <== deverei usar este valor para Vin, penso eu de que...

Tenho que medir no shield da tomada, não vou tentar medir nos contactos do board á saida da tomada, era curto-circuito certo.

Sempre vi este comportamento nos Nanos (chineses de várias origens) achei que era mesmo assim, daí estar a pensar que uma referencia externa fazia sentido.

Usando uma função maluca que anda por aí para medir o VCC (feita para usar quando a alimentação vem de baterias), quando está ligado via USB meço 4.5V que bate mais ou menos certo com o que meço com o DMM.

Fica aqui para referência a função que mede o VCC, não é minha, julgo que já a vi algures no código do transistor tester, mas não tenho a certeza da origem.

Código: [Seleccione]
long readVcc() {
  // Read 1.1V reference against AVcc
  // set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
  ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
  ADMUX = _BV(MUX3) | _BV(MUX2);
#else
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif

  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Start conversion
  while (bit_is_set(ADCSRA, ADSC)); // measuring

  uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
  uint8_t high = ADCH; // unlocks both

  long result = (high << 8) | low;

  result = (1125300L / result); // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
  return result; // Vcc in millivolts
}
Stupid men are often capable of things the clever wouldn't dare to contemplate.