Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Medição da Tensão Vcc do Arduino ATmega328 - Gustavo Murta 01/ago/2015 - Rev Lekobh 01/ago/2015
- // http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/
- // https://code.google.com/p/tinkerit/wiki/SecretVoltmeter
- #define ACS712x05B // Usar para sensor 5 Amperes
- //#define ACS712x20A // Usar para sensor 20 Amperes
- //#define ACS712x30A // Usar para sensor 30 Amperes
- void setup() {
- Serial.begin(9600);
- }
- void loop() {
- Serial.print("Vcc = " );
- Serial.print( readVcc(), DEC );
- Serial.print(" mV" );
- float tensao = scalaACS(analogRead(A0), readVcc());
- Serial.print(", VA0 = " );
- Serial.print( tensao );
- Serial.print(" mV" );
- float corrente = converteI(tensao);
- Serial.print(", IA0 = " );
- Serial.print( corrente, DEC );
- Serial.println(" mV" );
- float leitura = captura();
- corrente = converteI(leitura);
- Serial.print(", IRMS=" );
- Serial.print( corrente, 2 );
- Serial.println(" A" );
- delay(100);
- }
- //--------------------------------------------------------------------------------------------
- long readVcc() {
- // Lê o valor da referencia de 1.1V comparado com o AVcc
- // Coloca a referência em VCC e mede o valor da referencia interna de 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
- unsigned int media = 0;
- delay(2); // Espera estabilizar a referência
- //despresa a primeira leitura
- ADCSRA |= _BV(ADSC); // Inicia conversão
- while (bit_is_set(ADCSRA,ADSC)); // Aguarda o termino da conversão
- for (int i = 0; i<100; i++) { //loop para usar uma media dos valores
- ADCSRA |= _BV(ADSC); // Inicia conversão
- while (bit_is_set(ADCSRA,ADSC)); // Aguarda o termino da conversão
- uint8_t low = ADCL; // Tem que ler primeiro o Low - ele trava o valor de ADCH
- uint8_t high = ADCH; // Destrava os dois
- long result = (high<<8) | low; // pega valor do conversor
- media += result; // soma a media
- }
- long result = 112530000L / media; // Calcula Vcc (em mV); 1125300 = 1.1*1023*1000*100(amostras)
- return result; // Vcc in millivolts
- }
- //--------------------------------------------------------------------------------------------
- float scalaACS (long valor, long vcc) {
- float Viout = float (25000.00*valor)/vcc; // retorna o valor do acs como ajustado para 5v
- return Viout; // retorna o valor equivalente VIout para 5 V em millivolts
- }
- //--------------------------------------------------------------------------------------------
- float converteI (float valor) {
- #if defined (ACS712x05B)
- int Sens = 185; //mv por A;
- #elif defined (ACS712x20A)
- int Sens = 104; //mv por A;
- #elif defined (ACS712x30A)
- int Sens = 69; //mv por A;
- #else
- int Sens = 0;
- #endif
- float Iout = (valor*1000)/Sens; // retorna o valor do acs como ajustado para 5v
- return Iout; // retorna o valor equivalente VIout para 5 V em millivolts
- }
- //--------------------------------------------------------------------------------------------
- //Aguarda passagem por zero
- void passagem () {
- boolean st=false; //an indicator to exit the while loop
- unsigned long start = millis(); //Guarda tempó para timuot segurança.
- while(st==false) //the while loop...
- {
- int startV = analogRead(A0); //le o valor de A0
- if ((startV < (1024*0.55)) && (startV > (1024*0.45))) st=true; //check its within range
- if ((millis()-start)>2000) st = true;
- }
- }
- //--------------------------------------------------------------------------------------------
- float captura () {
- #define amost 500 //numero de amostras do sinal
- int amostras[amost];
- for (int i = 0; i<amost; i++) { //loop aguardar os valores sem interferencias ou delays
- amostras[i] = analogRead(A0);
- }
- long int mediacap = 0;
- int maximo = 0;
- int minimo = 1023;
- int borda = 0;
- //Serial.println("borda= " );
- for (int i = 0; i<amost; i++) { //loop aguardar os valores
- // mediacap += amostras[i];
- maximo = max(maximo, amostras[i]);
- minimo = min(minimo, amostras[i]);
- if ( ((amostras[i] > amostras[0]) && (amostras[i+1] <= amostras[0])) || ((amostras[i] < amostras[0]) && (amostras[i+1] >= amostras[0]))){
- if (i < amost-2) borda = i;
- // Serial.print( borda );
- // Serial.print(", " );
- }
- }
- float vpp = float((maximo-minimo) * (5.0 / 1023.0));//valor de tensao pico a pico
- float vmin = float(minimo * (5.0 / 1023.0));// valor de tensao minimo
- float vrefpp = float(vmin + vpp/2); //referencia p sumir com a componente continua do sinal
- mediacap = 0;
- float rms = 0.00;
- for (int i = 0; i<borda; i++) { //loop ate o valor da ultima borda (passagem por zero)
- float vrms =(float( amostras[i] * (5.0 / 1023.0)))-vrefpp;// rms componente alternada
- rms += (vrms*vrms);
- mediacap += amostras[i];
- }
- rms = sqrt(rms/borda);
- float vrms =rms;//float( rms * (5.0 / 1023.0));
- mediacap = mediacap/(borda);
- float vmediacap = float(mediacap * (5.0 / 1023.0));
- float rmsa = vrms; // componente alternada RMS
- float rmsc = vmediacap-5.00/2; //componente continua RMS
- vrms += rmsc;// soma componentes alternadas + continuas
- float vmulti = float((vpp/2)* 0.707);
- Serial.print("media=" );
- Serial.print( vmediacap, DEC );
- Serial.print(", RMSC=" );
- Serial.print( rmsc );
- Serial.print(", RMSA=" );
- Serial.print( rmsa );
- Serial.print(", rms=" );
- Serial.println( vrms );
- Serial.print(", vpp=" );
- Serial.println( vpp );
- Serial.print(", vmultimetro=" );
- Serial.println( vmulti );
- return vrms; // retorna o valor rms alternado + continuo
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement