(25-01-2016, 00:47)kamil2234 napisał(a): Poprawiłem kod dla ESP8266-12 - można go oczywiście stosować również na Arduino 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
Pozdrawiam serdecznie!
Łukasz