Olá.. Eu preciso medir a tensão de uma bateria(do próprio circuito standalone)


Vejam meu raciocínio:

Eu tenho uma bateria de 5v que alimenta o circuito:

5 / 1023 = 0,0048875855327468

Então essa seria minha resolução.

value = analogRead(0);

vbateria = 0,0048875855327468 * value;

Acontece que quando a bateria esta alimentada com 5V ou com 3V o value fica sempre em 1023.

Li algo sobre analogReference. 

Alguem pode me dar uma dica?

Exibições: 5200

Responder esta

Respostas a este tópico

Opa.

 a conta certa seria,

Resolucao=Vcc/1023;

value = analogRead(0);

vbateria =Resolucao* value;

vbateria =(Vcc/1023)* value;

Ou seja, esta correto, realmente ira dar 1023 sempre. Para mudar isso, precisa usar referencia externa para as entradas analógicas.

Att.

Jucelei Freita

Oi!

Rodrigo,

Tem um pino de referencia no Ardunio uno que e AREF.
para estar habilitando o mesmo segue o code. 

No caso a referencia seria sua bateria.

void setup() {
analogReference(EXTERNAL);


}

Eu acho que é possível fazer o arduino medir a tensão do V-in, eu testei alimentando o arduino com uma bateria de 7 volts um potenciômetro e um transistor para variar a tensão do V-in e um display, como na ocasião eu estava sem multimetro, não pude comparar o resultado que via no display com nada, mas tive a impressão de que funcionava.

Vi nesse site: http://www.uespi.br/pesquisa/opala/medir-tensao-da-bateria/

Eu modifiquei alguma coisa no loop do meu que amostrava o resultado em volt 5.00 4.90 4.75... mas agora não me lembro, mas se precisar fala que depois eu te passo, agora eu estou no celular.

Olá Rodrigo.

Pensando nesta proposta montei uma simulação para compreender a seleção das referências para o conversor analógico digital do Arduino. Veja o exemplo:

 Fiz a simulação com o seguinte princípio:

 1) Uma tensão fixa para a leitura dos valores, que no caso está em 1.00V para facilitar as contas.

 2) Alternar entre as referências: DEFAULT  = VCC

                                                INTERNAL = 1.1V para ATMEGA328

                                                EXTERNAL = o que estiver no pino AREF. Coloquei uma tensão de 2.5V neste caso.

Podemos ver que:

 ValorLido DEFAULT = ( 1.00 /  ( 5.00 / 1023) ) = ~205

 ValorLido INTERNAL = ( 1.00 / ( 1.1 / 1023 )) = ~931

 ValorLido EXTERNAL = ( 1.00 / ( 2.5 / 1023 )) = ~410

Então a seleção do ADC é possível, via a função e parametros:

analogReference(DEFAULT);

analogReference(INTERNAL);

analogReference(EXTERNAL);

 

Como queremos ler o VCC e ele não pode ser comparado com ele mesmo, como o Jucelei disse, vamos ter que usar outra referência, que no caso acho melhor ser a interna do próprio microcontrolador.

Agora vem a teoria:

Como a referência interna será de 1.1V, nossa leitura máxima na entrada do pino analógico terá que ser de 1.1V também!!! Para que o valor lido no ADC seja os 1023 no fim da escala.  Tendo isso em mente, teremos que compatibilizar a leitura da alimentação que no máximo tem 5.0V , para o valor de 1.1V.

Isso pode ser feito com amplificadores operacionais, mas é atirar em uma mosca com uma bazuca. rs Então vamos usar um divisor de tensão. No caso farei com valores teóricos, depois tente fazer para valores comerciais.

Vendo a próxima figura será mais fácil:

Temos duas resistências sendo alimentadas por uma fonte, que no nosso caso é a alimentação do Arduino mesmo o VCC, e a tensão Vo que é a tensão de saída do divisor que vai entrar no pino de leitura analógica.

Tendo a fórmula do divisor que é:

Vo = VCC * ( R2 / (R1 + R2))  , vamos fixar alguns valores.

Vo = será no caso 1.1 que é o valor máximo lido pelo ADC nesta configuração.

VCC = será 5.0V que é a tensão máxima na alimentação do Arduino.

R2   = vou fixar em 10Kohm, mas pode ter outros valores. Fixando ele, posso calcular o valor de R1 que será:

R1 = [(5.0V * 10K) - (1.1 * 10K) ] / 1.1

R1 =~ 35,454Ohms ou aproximadamente 35,5KOhm.

Descobrindo isto, montei o seguinte circuito.

E funcionou!!!! 

Perceba que a tensão na entrada do pino não passa de 1.1V. Ela será 1.1V se eu configurar a tensão da bateria para 5V.

No seu caso não precisa desta bateria, apenas ligue diretamente o divisor de tensão ao VCC.

E a precisão das contas ficou boa também, já é possível efetuar qualquer comparação para indicar nível de alimentação baixo.

No software basta compatibilizar o valor lido para descobrir a alimentação do pino, para isto usei a seguinte fórmula.

Valor de tensão = ((Valor lido do Sensor * 5.0) / 1023.0);

Espero ter ajudado. Vou postar em seguida o código. T++.

const int analogInPin = A0;

int sensorValue = 0;
double outputValue = 0;


void setup() {
  Serial.begin(9600);
}

void loop() {
 
   analogReference(INTERNAL);      // 1.1V ATMEGA168 ; 3.3V ATMEGA8
   Serial.print(" INT: ");
   
   sensorValue = analogRead(analogInPin);
   Serial.print(sensorValue);
   
   outputValue = ((sensorValue * 5.0) / 1023.0);
   Serial.print("   ");
   Serial.print(outputValue);
   Serial.println("");
   
   delay(1000);
               
}}

como no momento só tenho o celular com internet, vou ter que escrever em partes, remontei o meu projeto anterior, com a mesma bateria o mesmo display que é um 16x1 sem luz, um potenciômetro e um transistor para variar a tenção de entrada, estou mandando às fotos, tem um joystick porque no arduino ainda estava programado e eu optei por não reprogramar e sem o joy o loop não parte, daqui a pouco posto o programa.
Anexos
O celular não organiza bem o texto quando eu como, estou anexando o txt.

O programa:


long volt = 0; long milivolt = 0;

void setup(){

/*Fim do Setup*/}

void loop(){

milivolt=readVcc(); float volt = milivolt * (1.0 / 1000.0);

// essa parte mostra no lcd o resultado em volt e milivolt

// lcd.clear(); // lcd.setCursor(0, 0); // lcd.print(milivolt); // lcd.setCursor(5, 0); // lcd.print(volt);

// se voce nao tem display no seu sistema modifica para serial // o delay faz parte do meu programa do joystick, se ja tem um delay no loop nao precisa desse aqui.

delay(25);

}

long readVcc() { // Ler referência interna 1.1V // Ajusta a referência ao Vcc e a medição de referência interna para 1.1V #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); // Aguarde ADCSRA |= _BV(ADSC); // Inicia a conversão while (bit_is_set(ADCSRA,ADSC)); // Medindo uint8_t low = ADCL; // Vai ler ADCL primeiro - Então trava ADCH uint8_t high = ADCH; // Desbloqueia long result = (high8) | low; result = 1125300L / result; // Calcular Vcc em milivolts; 1125300 = 1.1*1023*1000 return result; // Vcc em milivolts }
só para constar.. o celular não organiza bem quando eu COLO**
desculpe, não consigo anexar o arquivo txt, se alguém tiver um e-mail para eu mandar o txt e esse por sua vez postar corretamente agradeço...

O

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço