View difference between Paste ID: LdNAWM3K and w4k9wfcL
SHOW: | | - or go back to the newest paste.
1-
// teste do Vout do sensor ACS712-30A com Arduino ATmega328 - Gustavo Murta 01/ago/2015
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-
  while (bit_is_set(ADCSRA,ADSC));  // Comeca a leitura 
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-
  // Com Sketch     Vcc = 5000 mV e Vout = 2497 mV 
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
}