• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Pomiar prądu zmiennego z gniazdka (230v) czujnikiem acs712 na Arduino Leonardo
#9
(25-01-2016, 00:47)kamil2234 napisał(a): Poprawiłem kod dla ESP8266-12 - można go oczywiście stosować również na Arduino Smile  Udaje się już mierzyć prąd powyżej 30-40 Watt.

Stwierdziłem, że będę wycinać to coś u dołu lub u góry poprzez określenie PERCENTYLA.  Zanim zacząłem to pisać pobawiłem się wykresami w excelu, aby sprawdzić czy funkcja będzie odporna na duże zniekształcenia.  Akurat w moim wypadku nie było ich tak dużo więc postanowiłem każdy pomiar przekraczający PERCENTYL górny lub dolny zmienić na aktualną wartość środka osi po której porusza się amplituda przebiegu prądu w danym momencie.  Dodatkowo,  aby nie wycinać wszystkiego z górnego pasma i dolnego pasma zostawiłem marines o wartości 5. Margines ma na celu ograniczenie wycinania chwilowych nieznacznych skoków.  

Nie wiem czy prawidłowo (jestem początkujący) ale mam zamiar go jeszcze udoskonalić jak przestudiuje wzory na przebiegi prądu, zniekształcenia harmoniczne etc. 

  
Kod:
#include <stdio.h>
#include <stdlib.h>

int lo = 1000 ;
int PinId =A0;
int SensorAnalogValue = 0;
int array[1000];
int tablica[1000];
float AggregateReadingInTime = 0;
double CurrentValue = 0;
float relation = 0.004887586;
//float relation = 0.003921569;
float Srednia = 0;
int percentyl_top, percentyl_lower;

float resolution = 0.100;
int voltage = 233;
float srednia = 0 ;

void setup() {


Serial.begin(9600);
pinMode(PinId, INPUT);


}

void loop() {



 for(int i=1;  i<=lo; i++){
 
   array[i] = analogRead(PinId);
   tablica[i] = array[i];
 //  SensorAnalogValue = SensorAnalogValue - 404;
 // funckja pow podniesienie do potęgi drugiej
   //AggregateReadingInTime += pow(SensorAnalogValue,2);
   delay(1);
 }


percentyl_lower = mypercentile(array,0.05, lo);
Serial.print("percentyl_lower: ");
Serial.print(percentyl_lower);
Serial.print(" percentyl_top: ");
percentyl_top  = mypercentile(array,0.95, lo);
Serial.println(percentyl_top);

srednia  =  (percentyl_top+percentyl_lower)/2;
Serial.print("Srednia: ");
Serial.println( srednia);

 
for(int i=1;  i<=lo; i++){

 if ( tablica[i] > percentyl_top +5 ) {
       tablica[i] = srednia  ;
   }

 if ( tablica[i] < percentyl_lower  -5 ) {
      tablica[i] = srednia ;
     // Serial.println(tablica[i]);
      // delay(100);
   }

  //Serial.println(tablica[i]);
   
    tablica[i] = tablica[i] - srednia;


   
  AggregateReadingInTime += pow(tablica[i],2);
 //delay(100);
 }

 

 //funkcja sqrt pierwiastek drugiego stopnia

 AggregateReadingInTime = (sqrt(AggregateReadingInTime/lo)) ;

 Serial.print("WS : ");
 Serial.print(AggregateReadingInTime);
 
 AggregateReadingInTime = AggregateReadingInTime * relation;

 CurrentValue = (AggregateReadingInTime/resolution);

 
 
 Serial.print(" Current : ");
 Serial.print(CurrentValue);
 Serial.print(" A ");



 Serial.print("Energy:");
 Serial.print(CurrentValue * voltage);
 Serial.println(" Watt ");

/* */



 


 delay(1500);

}

int mypercentile(int data[], float percentile, int count){
 float p, allindex;
 int result = 0;
   if((0 < percentile) && (percentile < 1 )) {
       p = percentile;
   }else if( 1 < percentile && percentile <= 100 ) {
       p = percentile * .01;
   }else {
       
       return(result);
   }
 
   //Serial.print("count drugi: ");
  // Serial.println(count);

   allindex = (count-1)*p;
    int intvalindex = (int)(allindex);
   float floatval = allindex - intvalindex;
   sort(data, count);


    //Serial.print("  floatval: ");
   //Serial.println(  floatval);

   if((floatval- (long int)floatval) == 0){
       result = data[intvalindex];
   }else {
       if(count > intvalindex+1)
           result = floatval*(data[intvalindex+1] - data[intvalindex]) + data[intvalindex];
       else
           result = data[intvalindex];
   }
 
  return(result);

   

}

void sort(int a[], int size) {
   for(int i=0; i<(size-1); i++) {
       for(int o=0; o<(size-(i+1)); o++) {
               if(a[o] > a[o+1]) {
                   int t = a[o];
                   a[o] = a[o+1];
                   a[o+1] = t;
               }
       }
   }
}

Cześć,
Twój kod działa prawie doskonale. Prawie, bo o ile całkiem ładnie mierzy pobór prądu, o tyle czasami wyrzuca jakieś przekłamania. Rzuć proszę okiem na te pomiary (bez podłączonego żadnego obciążenia):

Kod:
Srednia: 521.00; WS: 31.97 Current: 1.25 A Energy: 288.36 W
Srednia: 489.00; WS: 2.10 Current: 0.08 A Energy: 18.90 W
Srednia: 489.00; WS: 2.30 Current: 0.09 A Energy: 20.75 W
Srednia: 485.00; WS: 2.65 Current: 0.10 A Energy: 23.87 W
Srednia: 490.00; WS: 1.89 Current: 0.07 A Energy: 17.03 W
Srednia: 521.00; WS: 31.81 Current: 1.25 A Energy: 286.91 W
Srednia: 490.00; WS: 1.80 Current: 0.07 A Energy: 16.27 W
Srednia: 520.00; WS: 31.78 Current: 1.25 A Energy: 286.60 W
Srednia: 490.00; WS: 2.50 Current: 0.10 A Energy: 22.55 W
Srednia: 489.00; WS: 2.24 Current: 0.09 A Energy: 20.24 W
Srednia: 490.00; WS: 2.04 Current: 0.08 A Energy: 18.40 W
Srednia: 521.00; WS: 31.34 Current: 1.23 A Energy: 282.70 W
Srednia: 521.00; WS: 28.66 Current: 1.12 A Energy: 258.53 W
Srednia: 522.00; WS: 29.15 Current: 1.14 A Energy: 262.96 W
Srednia: 494.00; WS: 2.27 Current: 0.09 A Energy: 20.50 W
Srednia: 493.00; WS: 2.06 Current: 0.08 A Energy: 18.63 W
Srednia: 493.00; WS: 1.95 Current: 0.08 A Energy: 17.63 W
Srednia: 521.00; WS: 31.95 Current: 1.25 A Energy: 288.20 W
Srednia: 521.00; WS: 31.05 Current: 1.22 A Energy: 280.04 W
Srednia: 490.00; WS: 2.32 Current: 0.09 A Energy: 20.94 W
Srednia: 492.00; WS: 1.78 Current: 0.07 A Energy: 16.08 W
Srednia: 490.00; WS: 2.09 Current: 0.08 A Energy: 18.90 W
Srednia: 492.00; WS: 1.93 Current: 0.08 A Energy: 17.38 W
Srednia: 522.00; WS: 29.96 Current: 1.17 A Energy: 270.21 W
Srednia: 491.00; WS: 2.32 Current: 0.09 A Energy: 20.95 W
Srednia: 491.00; WS: 2.06 Current: 0.08 A Energy: 18.60 W
Srednia: 491.00; WS: 1.88 Current: 0.07 A Energy: 16.98 W
Srednia: 490.00; WS: 2.07 Current: 0.08 A Energy: 18.66 W
Srednia: 522.00; WS: 31.05 Current: 1.22 A Energy: 280.04 W
Srednia: 524.00; WS: 29.97 Current: 1.18 A Energy: 270.36 W
Srednia: 494.00; WS: 2.01 Current: 0.08 A Energy: 18.12 W
Srednia: 494.00; WS: 1.94 Current: 0.08 A Energy: 17.46 W
Srednia: 495.00; WS: 1.99 Current: 0.08 A Energy: 17.99 W
Srednia: 522.00; WS: 30.97 Current: 1.21 A Energy: 279.36 W
Srednia: 522.00; WS: 30.57 Current: 1.20 A Energy: 275.76 W
Srednia: 521.00; WS: 29.99 Current: 1.18 A Energy: 270.51 W

Masz może pomysł, skąd się mogą brać te przekłamania? ESP zasilam z przetwornicy, która daje ładne i stabilne napięcie, więc samo zasilanie nie powinno być problemem...

Będę wdzięczny za jakąkolwiek pomoc.

--
EDIT

Zmieniłem wartości w tych dwóch liniach (z 0.05 i 0.95) i chyba jest już ok:
Kod:
percentyl_lower = mypercentile(array,0.10, lo);
percentyl_top  = mypercentile(array,0.90, lo);

Działa, ale nadal nie rozumiem dlaczego i w czym tkwi problem Wink

Pozdrawiam serdecznie!
Łukasz
 
Odpowiedź
  


Wiadomości w tym wątku
RE: Pomiar prądu zmiennego z gniazdka (230v) czujnikiem acs712 na Arduino Leonardo - przez Maruder - 25-04-2016, 14:03

Skocz do:


Przeglądający: 2 gości