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 | } |