Advertisement
jgustavoam

ACS712-30A Medições com Carga

Aug 1st, 2015
308
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Medições de tensão Vout com carga -  sensor ACS712-30A com Arduino ATmega328 - Gustavo Murta 01/ago/2015
  2. // http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/
  3. // https://code.google.com/p/tinkerit/wiki/SecretVoltmeter
  4. // https://github.com/openenergymonitor/EmonLib
  5.  
  6.     //--------------------------------------------------------------------------------------
  7.     // Variable declaration for emon_calc procedure
  8.     //--------------------------------------------------------------------------------------
  9.     int sampleV;                 //sample_ holds the raw analog read value
  10.     //int sampleI;                
  11.  
  12.     double lastFilteredV,filteredV;          //Filtered_ is the raw analog value minus the DC offset
  13.     // double filteredI;                  
  14.     double offsetV;                          //Low-pass filter output
  15.     // double offsetI;                       //Low-pass filter output              
  16.  
  17.     double phaseShiftedV;                    //Holds the calibrated phase shifted voltage.
  18.  
  19.     double sqV,sumV,sqI,sumI,instP,sumP;     //sq = squared, sum = Sum, inst = instantaneous
  20.  
  21.     int startV;                              //Instantaneous voltage at start of sample window.
  22.  
  23.     boolean lastVCross, checkVCross;         //Used to measure number of times threshold is crossed.
  24.  
  25. long readVcc() {
  26.   // Leitura da tensão de Referencia de 1.1V para calcular  AVcc
  27.   // Configura Referencia do ADC para Vcc
  28.      
  29.     ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  30.    
  31.   delay(2);                         // Aguarda estabilização da Tensão Vref
  32.   ADCSRA |= _BV(ADSC);              // Inicia a conversão ADC
  33.   while (bit_is_set(ADCSRA,ADSC));  // Começa a leitura
  34.  
  35.   uint8_t low  = ADCL;              // Lê primeiro o registrador ADCL e depois o ADCH  
  36.   uint8_t high = ADCH;              // destrava os dois registradores
  37.  
  38.   long result = (high<<8) | low;    // Formata o resultado
  39.  
  40.   // Conversor ADC do Arduino já calibrado
  41.   // Primeiro ReadVcc = 1.1 * 1023 * 1000 > Vcc = 4957 mV
  42.   // Com Multimetro Vcc = 5000 mV e Vref = 2500 mV
  43.   // Com Arduino    Vcc = 5000 mV e Vout = 2497 mV
  44.  
  45.   result = 1135061L / result;        // Cálculo do Vcc (em mV) 1135061 = 1.109542*1023*1000
  46.   return result;                     // Vcc em millivolts
  47.   }
  48.  
  49.   unsigned int crossCount = 0;       // Usado para determinar a quantidade de passagens por zero
  50.   unsigned int numberOfSamples = 0;  // Quantidade de amostragens
  51.   unsigned int crossings = 20;       // quantidade de semiciclos da senoide
  52.   int timeout = 2000 ;
  53.   define ADC_BITS    10
  54.   define ADC_COUNTS  (1<<ADC_BITS)
  55.  
  56.   //-------------------------------------------------------------------------------------------------------------------------
  57.   // 1) Waits for the waveform to be close to 'zero' (mid-scale adc) part in sin curve.
  58.   //-------------------------------------------------------------------------------------------------------------------------
  59.   boolean st=false;                  //an indicator to exit the while loop
  60.  
  61.   unsigned long start = millis();    //millis()-start makes sure it doesnt get stuck in the loop if there is an error.
  62.  
  63.   while(st==false)                   //the while loop...
  64.   {
  65.      startV = analogRead(A2);        //using the voltage waveform
  66.      if ((startV < (ADC_COUNTS*0.55)) && (startV > (ADC_COUNTS*0.45))) st=true;      //check its within range
  67.      if ((millis()-start)>timeout) st = true;
  68.   }
  69.  
  70.   //-------------------------------------------------------------------------------------------------------------------------
  71.   // 2) Main measurement loop
  72.   //-------------------------------------------------------------------------------------------------------------------------
  73.   start = millis();
  74.  
  75.   while ((crossCount < crossings) && ((millis()-start)<timeout))
  76.   {
  77.     numberOfSamples++;                       // Incrementa o número de amostragens
  78.     //lastFilteredV = filteredV;             // Used for delay/phase compensation
  79.    
  80.     //-----------------------------------------------------------------------------
  81.     // A) Medições de Tensões  no pino A2 do Conversor ADC
  82.     //-----------------------------------------------------------------------------
  83.     sampleV = analogRead(A2);                 //Read in raw voltage signal
  84.  
  85.     //-----------------------------------------------------------------------------
  86.     // B) Apply digital low pass filters to extract the 2.5 V or 1.65 V dc offset,
  87.     //     then subtract this - signal is now centred on 0 counts.
  88.     //-----------------------------------------------------------------------------
  89.     offsetV = offsetV + ((sampleV-offsetV)/1024);
  90.     filteredV = sampleV - offsetV;
  91.        
  92.     //-----------------------------------------------------------------------------
  93.     // C) Root-mean-square method voltage
  94.     //-----------------------------------------------------------------------------  
  95.     sqV= filteredV * filteredV;                 //1) square voltage values
  96.     sumV += sqV;                                //2) sum
  97.    
  98.     //-----------------------------------------------------------------------------
  99.     // D) Phase calibration
  100.     //-----------------------------------------------------------------------------
  101.     //phaseShiftedV = lastFilteredV + PHASECAL * (filteredV - lastFilteredV);
  102.    
  103.     //-----------------------------------------------------------------------------
  104.     // E) Instantaneous power calc
  105.     //-----------------------------------------------------------------------------  
  106.     //instP = phaseShiftedV * filteredI;          //Instantaneous Power
  107.     //sumP +=instP;                               //Sum  
  108.    
  109.     //-----------------------------------------------------------------------------
  110.     // F) Find the number of times the voltage has crossed the initial voltage
  111.     //    - every 2 crosses we will have sampled 1 wavelength
  112.     //    - so this method allows us to sample an integer number of half wavelengths which increases accuracy
  113.     //-----------------------------------------------------------------------------      
  114.     lastVCross = checkVCross;                    
  115.     if (sampleV > startV) checkVCross = true;
  116.                      else checkVCross = false;
  117.     if (numberOfSamples==1) lastVCross = checkVCross;                  
  118.                      
  119.     if (lastVCross != checkVCross) crossCount++;
  120.   }
  121.    
  122.   //-------------------------------------------------------------------------------------------------------------------------
  123.   // 3) Post loop calculations
  124.   //-------------------------------------------------------------------------------------------------------------------------
  125.   //Calculation of the root of the mean of the voltage and current squared (rms)
  126.   //Calibration coefficients applied.
  127.  
  128.   double V_RATIO = VCAL *((SupplyVoltage/1000.0) / (ADC_COUNTS));
  129.   Vrms = V_RATIO * sqrt(sumV / numberOfSamples);
  130.  
  131.   //double I_RATIO = ICAL *((SupplyVoltage/1000.0) / (ADC_COUNTS));
  132.   //Irms = I_RATIO * sqrt(sumI / numberOfSamples);
  133.  
  134.   //Calculation power values
  135.   //realPower = V_RATIO * I_RATIO * sumP / numberOfSamples;
  136.   //apparentPower = Vrms * Irms;
  137.   //powerFactor=realPower / apparentPower;
  138.  
  139.   //Reset accumulators
  140.   sumV = 0;
  141.   //sumI = 0;
  142.   //sumP = 0;
  143.  //--------------------------------------------------------------------------------------      
  144. }
  145.  
  146.  void setup() {
  147.   Serial.begin(9600);
  148. }
  149. void loop() {
  150.   long Vcc = (readVcc());
  151.   Serial.print("Vcc = " );
  152.   Serial.print(Vcc);
  153.   Serial.println(" mV" );
  154.  
  155.   int Vin = analogRead(A2)+1 ;        // leitura da tensão no pino A2 + LSB
  156.   long Vout = (Vin * Vcc) / 1023;
  157.   Serial.print("Vout = " );  
  158.   Serial.print( Vout );              // Vout do sensor ACS712-30A
  159.   Serial.println(" mV" );
  160.   Serial.println ();
  161.  
  162.   Serial.print('Vrms = ');  
  163.   Serial.print(Vrms);
  164.   Serial.println(' mV ');
  165.  
  166.   delay(1000);
  167. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement