Advertisement
lekobh

Teste RMS

Aug 1st, 2015
270
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.32 KB | None | 0 0
  1. // Medição da Tensão Vcc do Arduino ATmega328 - Gustavo Murta 01/ago/2015 - Rev Lekobh 01/ago/2015
  2. // http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/
  3. // https://code.google.com/p/tinkerit/wiki/SecretVoltmeter
  4.  
  5.  #define ACS712x05B // Usar para sensor 5 Amperes
  6.  //#define ACS712x20A // Usar para sensor 20 Amperes
  7.  //#define ACS712x30A // Usar para sensor 30 Amperes
  8.  
  9.  
  10.  
  11.  void setup() {
  12.   Serial.begin(9600);
  13.  
  14. }
  15. void loop() {
  16.   Serial.print("Vcc = " );
  17.   Serial.print( readVcc(), DEC );
  18.   Serial.print(" mV" );
  19.  
  20.   float tensao = scalaACS(analogRead(A0), readVcc());
  21.   Serial.print(",   VA0 = " );
  22.   Serial.print( tensao );
  23.   Serial.print(" mV" );
  24.  
  25.   float corrente = converteI(tensao);
  26.  
  27.   Serial.print(",   IA0 = " );
  28.   Serial.print( corrente, DEC );
  29.   Serial.println(" mV" );
  30.  
  31.   float leitura = captura();
  32.   corrente = converteI(leitura);
  33.   Serial.print(", IRMS=" );
  34.   Serial.print( corrente, 2 );
  35.   Serial.println(" A" );  
  36.  
  37.   delay(100);
  38. }
  39.  
  40.  
  41. //--------------------------------------------------------------------------------------------
  42. long readVcc() {
  43.   // Lê o valor da referencia de  1.1V comparado com o AVcc
  44.   // Coloca a referência em VCC e mede o valor da referencia interna de 1.1V
  45.   #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  46.     ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  47.   #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
  48.     ADMUX = _BV(MUX5) | _BV(MUX0);
  49.   #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
  50.     ADMUX = _BV(MUX3) | _BV(MUX2);
  51.   #else
  52.     ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  53.   #endif  
  54.   unsigned int media = 0;
  55.  
  56.  
  57.   delay(2); // Espera estabilizar a referência
  58.  
  59.  //despresa a primeira leitura
  60.        ADCSRA |= _BV(ADSC); // Inicia conversão
  61.        while (bit_is_set(ADCSRA,ADSC)); // Aguarda o termino da conversão
  62.  
  63.   for (int i = 0; i<100; i++) { //loop para usar uma media dos valores
  64.        ADCSRA |= _BV(ADSC); // Inicia conversão
  65.        while (bit_is_set(ADCSRA,ADSC)); // Aguarda o termino da conversão
  66.  
  67.        uint8_t low  = ADCL; // Tem que ler primeiro o Low - ele trava o valor de ADCH  
  68.        uint8_t high = ADCH; // Destrava os dois
  69.  
  70.        long result = (high<<8) | low; // pega valor do conversor
  71.        media += result; // soma a media
  72.      }
  73.  
  74.   long result = 112530000L / media; // Calcula Vcc (em mV); 1125300 = 1.1*1023*1000*100(amostras)
  75.   return result; // Vcc in millivolts
  76. }
  77.  
  78. //--------------------------------------------------------------------------------------------
  79.  
  80. float scalaACS (long valor, long vcc) {
  81.  
  82.   float Viout = float (25000.00*valor)/vcc; // retorna o valor do acs como ajustado para 5v
  83.  
  84.   return Viout; // retorna o valor equivalente VIout para 5 V em millivolts
  85.  
  86. }
  87.  
  88. //--------------------------------------------------------------------------------------------
  89.  
  90. float converteI (float valor) {
  91.  
  92.   #if defined (ACS712x05B)
  93.     int Sens = 185; //mv por A;
  94.   #elif defined (ACS712x20A)
  95.     int Sens = 104; //mv por A;
  96.   #elif defined (ACS712x30A)
  97.     int Sens = 69; //mv por A;
  98.   #else
  99.     int Sens = 0;
  100.   #endif  
  101.  
  102.   float Iout = (valor*1000)/Sens; // retorna o valor do acs como ajustado para 5v
  103.  
  104.   return Iout; // retorna o valor equivalente VIout para 5 V em millivolts
  105.  
  106. }
  107.  
  108. //--------------------------------------------------------------------------------------------
  109. //Aguarda passagem por zero
  110.  
  111.  
  112. void passagem () {
  113.  boolean st=false;                                  //an indicator to exit the while loop
  114.  
  115.   unsigned long start = millis();    //Guarda tempó para timuot segurança.
  116.  
  117.   while(st==false)                                   //the while loop...
  118.   {
  119.     int startV = analogRead(A0);                    //le o valor de A0
  120.      if ((startV < (1024*0.55)) && (startV > (1024*0.45))) st=true;  //check its within range
  121.      if ((millis()-start)>2000) st = true;
  122.   }
  123.  
  124.  
  125. }
  126.  
  127. //--------------------------------------------------------------------------------------------
  128.  
  129.  
  130. float captura () {
  131. #define amost 500 //numero de amostras do sinal
  132.  
  133.   int amostras[amost];
  134.  
  135.   for (int i = 0; i<amost; i++) { //loop aguardar os valores sem interferencias ou delays
  136.     amostras[i] = analogRead(A0);
  137.   }
  138.  
  139.   long int mediacap = 0;
  140.   int maximo = 0;
  141.   int minimo = 1023;
  142.   int borda = 0;
  143.          //Serial.println("borda= " );
  144.      
  145.   for (int i = 0; i<amost; i++) { //loop aguardar os valores
  146.      // mediacap += amostras[i];
  147.       maximo = max(maximo, amostras[i]);
  148.       minimo = min(minimo, amostras[i]);
  149.       if ( ((amostras[i] > amostras[0]) && (amostras[i+1] <= amostras[0])) || ((amostras[i] < amostras[0]) && (amostras[i+1] >= amostras[0]))){
  150.             if (i < amost-2) borda = i;
  151.           //   Serial.print( borda );
  152.           //   Serial.print(", " );
  153.      
  154.       }
  155.   }
  156.   float vpp = float((maximo-minimo) * (5.0 / 1023.0));//valor de tensao pico a pico
  157.   float vmin = float(minimo * (5.0 / 1023.0));// valor de tensao minimo
  158.   float vrefpp = float(vmin + vpp/2); //referencia p sumir com a componente continua do sinal
  159.   mediacap = 0;
  160.   float rms = 0.00;
  161.   for (int i = 0; i<borda; i++) { //loop ate o valor da ultima borda (passagem por zero)
  162.       float vrms =(float( amostras[i] * (5.0 / 1023.0)))-vrefpp;// rms componente alternada
  163.       rms += (vrms*vrms);
  164.       mediacap += amostras[i];
  165.       }
  166.   rms =  sqrt(rms/borda);
  167.   float vrms =rms;//float( rms * (5.0 / 1023.0));
  168.  
  169.   mediacap = mediacap/(borda);    
  170.   float vmediacap = float(mediacap * (5.0 / 1023.0));
  171.   float rmsa = vrms; // componente alternada RMS
  172.   float rmsc = vmediacap-5.00/2; //componente continua RMS
  173.   vrms += rmsc;// soma componentes alternadas + continuas
  174.  
  175.  
  176.   float vmulti = float((vpp/2)* 0.707);
  177.  
  178.   Serial.print("media=" );
  179.   Serial.print( vmediacap, DEC );
  180.  
  181.   Serial.print(", RMSC=" );
  182.   Serial.print( rmsc );
  183.  
  184.  
  185.   Serial.print(", RMSA=" );
  186.   Serial.print( rmsa );
  187.      
  188.   Serial.print(", rms=" );
  189.   Serial.println( vrms );
  190.      
  191.   Serial.print(", vpp=" );
  192.   Serial.println( vpp );    
  193.    
  194.  
  195.    
  196.   Serial.print(", vmultimetro=" );
  197.   Serial.println( vmulti );  
  198.  
  199.   return vrms; // retorna o valor rms alternado + continuo
  200.  
  201.  
  202.  }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement