Teljesítmény mérés 230V-os hálózaton

A meglévő hardware eszközök fejlesztési lehetőségei, módosítások, illetve új eszközök bevezetése
Válasz küldése
Avatar
csabeszq
Bitfaragó
Hozzászólások: 678
Csatlakozott: 2012. szeptember 5. szerda, 6:00

Teljesítmény mérés 230V-os hálózaton

Hozzászólás Szerző: csabeszq »

Egy algoritmust osztanék meg, amivel egész jó pontossággal mértem teljesítményt.

Öntöző-rendszert automatizálok, ehhez a szivattyú teljesítményét ismerni kell.
- ha sokáig megy üres járásban, akkor le kell kapcsolni
- ha megszorul, akkor is

Mivel mérek:
- a hálózaton feltételezem, hogy 230V van
- a szivattyú áramát mérem 1:2000-es áramváltóval (tekercs, amin átdugom a 230V-os kábelt)

Algoritmus:
- legyen megbízható és foglaljon kevés helyet (sajnos nem csak ezzel foglalkozik az Arduino)
- ESP8266-tal van összekötve, ez sokmindent elmond az ADC táp stabilitásáról, finoman szólva is zajos a rendszer

Min-max kísérlet
- 50 Hz-nél egy periódus 192 mérést igényel (free running, 128-as előosztás)
- ebből kiveszem a min-max értékeket
- min-max-ból meghatározom a teljesítményt
A kísérlet meglehetősen kudarcos lett, mert igazából elég látványos zajt produkált a rendszer. Finoman szólva is 20% ugrálás volt, ami a vezérléshez használhatatlan volt.

Effektív érték számítás:
- az algoritmus úgy működött, hogy a 192 mintavételt memória takarékosság végett felosztottam 8x24 részre
- beolvasok 8 ADC értéket, átlagolom, tárolom az első pozíción, beolvasom a második 8 értéket, az átlagát a második pozíción tárolom,..
- a tárolás 2x24 byte-ot vesz igénybe
- amint kész vagyok a mintavételezéssel, a 24 mintás puffer átlagát kiszámolom
- ebből effektív értéket számolok: négyzetgyök((szumma ((mérés(x) - átlag)^2)) / 24)
Megdöbbenéssel vettem észre, hogy zajos rendszerben is mennyire pontos volt a függvény alatti terület számítása. Egy szinusz periódusból néhány százalék pontossággal megállapította a teljesítményt (áramot) és 50 bájtot sem foglalt a RAM-ból az egész logika.
Avatar
winnerbt
Elektronbűvölő
Hozzászólások: 907
Csatlakozott: 2007. március 25. vasárnap, 6:00

Re: Teljesítmény mérés 230V-os hálózaton

Hozzászólás Szerző: winnerbt »

Az áramváltó szekundere hogyan csatlakozik a uC-hez? Féltápra van húzva?
Avatar
csabeszq
Bitfaragó
Hozzászólások: 678
Csatlakozott: 2012. szeptember 5. szerda, 6:00

Re: Teljesítmény mérés 230V-os hálózaton

Hozzászólás Szerző: csabeszq »

A kapcsolás egyszerű:

Fogtam egy 1k-s ellenállást, a piros és a kék vezetékre kötöttem. Amikor áram folyik a tekercsen, akkor feszültség keletkezik az ellenálláson.

Fogtam egy trimmert (1k) és beállítottam középre. A trimmert hozzá kötöttem az áramváltós ellenállás egyik végéhez, az ADC-t a másik végéhez.

Kép:
Kép

Kapcsolás valami ilyesmi:
Kép
Avatar
winnerbt
Elektronbűvölő
Hozzászólások: 907
Csatlakozott: 2007. március 25. vasárnap, 6:00

Re: Teljesítmény mérés 230V-os hálózaton

Hozzászólás Szerző: winnerbt »

Az osztó közepe miért van analóg bejáraton?
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: Teljesítmény mérés 230V-os hálózaton

Hozzászólás Szerző: kapu48 »

Gondolom, hogy tudjon referenciát mérni?
Avatar
winnerbt
Elektronbűvölő
Hozzászólások: 907
Csatlakozott: 2007. március 25. vasárnap, 6:00

Re: Teljesítmény mérés 230V-os hálózaton

Hozzászólás Szerző: winnerbt »

Ja, hogy az osztó pontatlanságából adódó nullponthibát. Lehet...
Avatar
csabeszq
Bitfaragó
Hozzászólások: 678
Csatlakozott: 2012. szeptember 5. szerda, 6:00

Re: Teljesítmény mérés 230V-os hálózaton

Hozzászólás Szerző: csabeszq »

A képen van, én nem használtam. Megmértem egy teljes periódust, abból számoltam ki.
Avatar
winnerbt
Elektronbűvölő
Hozzászólások: 907
Csatlakozott: 2007. március 25. vasárnap, 6:00

Re: Teljesítmény mérés 230V-os hálózaton

Hozzászólás Szerző: winnerbt »

Nem baj, én akkor is belemagyaráztam a dolgot :)
Pont most akarok összedobni egy árammérőt, majd könyörgök a rutinért :)
Avatar
csabeszq
Bitfaragó
Hozzászólások: 678
Csatlakozott: 2012. szeptember 5. szerda, 6:00

Re: Teljesítmény mérés 230V-os hálózaton

Hozzászólás Szerző: csabeszq »

Oké, majd küldöm. Az uint32 sqrt a legneccesebb rész. Mindenféle matematikusok kieszelték, hogy hogyan lehet egész számokon gyököt vonni. Iszonyú gyors az algoritmus és lebegőpontos aritmetika sem kell.
Avatar
csabeszq
Bitfaragó
Hozzászólások: 678
Csatlakozott: 2012. szeptember 5. szerda, 6:00

Re: Teljesítmény mérés 230V-os hálózaton

Hozzászólás Szerző: csabeszq »

A kód ADC-t érintő részeit csatolom. Nem túl igényes, de megy.
Remélem segít, bár díjnyertes nem lesz szépségben.

Kód: Egész kijelölése


// minták száma
#define POWER_SAMPLES     192
// ennyi mintát kell átlagolni
#define AVG_SAMPLE          8

// ha kész vagyunk a mintavételezéssel
#define POWER_SAMPLE_DONE 0xFF

uint16_t avg_sample;
uint32_t stat_power = 0;

volatile uint8_t  power_cnt = 0;

#define ADC_BUF_SIZE (POWER_SAMPLES/AVG_SAMPLE)

// ADC puffer, 24 szóból
volatile uint16_t adc_buf[ADC_BUF_SIZE];

// ADC interruptot használok
ISR(ADC_vect)
{
  // pontosan 192-t mintavételezünk
  if( power_cnt < POWER_SAMPLES )
  {
    uint16_t adc = ADCL;
    adc |= ((uint16_t)ADCH << 8);

    avg_sample += adc;

    // ez a rész átlagot számít, amikor a mutató elérné AVG_SAMPLE-t
    // beírja a pufferbe
    // a pufferbe 24 szó kerül (192/8). 8-asával átlagolok
    switch( power_cnt & (AVG_SAMPLE-1) )
    {
      case 0:
        avg_sample = adc;
        break;
      case AVG_SAMPLE-1:
        adc_buf[power_cnt/AVG_SAMPLE] = avg_sample / AVG_SAMPLE;
        break;
    }

    // ha megvan a 192 minta leállunk
    if( ++power_cnt == POWER_SAMPLES )
    {
      ADCSRA = 0;
      ADCSRB = 0;

      power_cnt = POWER_SAMPLE_DONE;
    }
  }
}

// ezzel indítjuk a 192 mintavétezést. 50 Hz az 192 minta 128-as előosztásnál
void adcStart()
{
  power_cnt = 0;
  ADCSRA = 0;
  ADCSRB = 0;
  ADMUX  = (1<<REFS0) | (1<<MUX2)| (1<<MUX1);    // Ref. = AVCC
  ADCSRA = (1<<ADEN)|(1<<ADIE)|(1<<ADATE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADIF);
  ADCSRA |= (1<<ADSC);
}


void getPowerConsumption()
{
  return stat_power;
}

void setup()
{
  adcStart();
}

// uint32 négyzetgyök-vonás
uint32_t isqrt(uint32_t n)
{
  uint32_t root = 0, bit, trial;
  bit = (n >= 0x10000) ? (uint32_t)1<<30 : (uint32_t)1<<14;
  do
  {
     trial = root+bit;
     if (n >= trial)
     {
        n -= trial;
        root = trial+bit;
     }
     root >>= 1;
     bit >>= 2;
  } while (bit);
  return root;
}

void loop()
{
  // mintavételezés befejeződött?
  if( power_cnt == POWER_SAMPLE_DONE )
  {
    // kiszámoljuk az átlagot egy teljes periódusra
    uint16_t avg = 0;
    for(uint8_t i=0; i < ADC_BUF_SIZE; i++ )
      avg += adc_buf[i];
    avg /= ADC_BUF_SIZE;

    // effektív érték számítás az átlag alapján
    // sqrt( summa( (ADC-AVG)^2 ) / N )
    uint32_t eff = 0;
    for(uint8_t i=0; i < ADC_BUF_SIZE; i++ )
    {
      int16_t diff = (int16_t)adc_buf[i] - (int16_t)avg;
      eff += diff * diff;
    }
    eff /= ADC_BUF_SIZE;
    eff = isqrt( eff );

    // a 36/10 egy konstans az áramváltóra.
    // megmértem multiméterrel és ennyivel kellett szorozni az ADC-t, hogy a fogyasztás jöjjön ki
    stat_power = eff * 36 / 10;
    
    // mérés újraindítása
    adcStart();
  }
}
Avatar
winnerbt
Elektronbűvölő
Hozzászólások: 907
Csatlakozott: 2007. március 25. vasárnap, 6:00

Re: Teljesítmény mérés 230V-os hálózaton

Hozzászólás Szerző: winnerbt »

Köszi, mentettem.
Majd kiagyalom, hogyan működik (nekem bascomban van a programom)
Én ACS758-al mérnék felvett áramot, de most egy kicsit megakadt a dolog, a megrendelő köddé vált...
Attól még megcsinálom, ha másnak nem, magamnak.
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: Teljesítmény mérés 230V-os hálózaton

Hozzászólás Szerző: kapu48 »

Sajnos a Megrendelők többsége abban a hitben él, hogy minden kívánság megvan a fiókban!
És lökjük nekik azonnal, Ingyen!
Avatar
csabeszq
Bitfaragó
Hozzászólások: 678
Csatlakozott: 2012. szeptember 5. szerda, 6:00

Re: Teljesítmény mérés 230V-os hálózaton

Hozzászólás Szerző: csabeszq »

A lényeget leírom:

- 16MHz-es Arduino-nál, 128-as ADC prescaler mellett egy 50 Hz-es periódus durván 192 minta.
Magyarul: veszel 192 mintát, az jó közelítéssel lefed 1 teljes periódust.

- 192 ADC minta tárolása 384 bájtot igényel, amit nem feltétlen szeretünk Arduino alatt, mert kevés a RAM

- a tárhely csökkentése érdekében minden 8 minta átlagát mentjük el, 192/8 = 24 mintát, azaz 48 bájtot. A szinusz függvényt szépen lehet átlaggal is közelíteni

- ezek után megmarad 24 mintavételed egy teljes periódusra
- kiszámolod az átlagát
- az átlag segítségével kiszámolod az effektív értéket sqrt((sum ((avg-sample)^2))/N)
- az így kiszámolt érték áram (ADC kvantumokban), amit egy multiméter segítségével kalibrálhatsz
- ha 230V-tal megszorzod, akkor durván a teljesítményt kapod
Avatar
csabeszq
Bitfaragó
Hozzászólások: 678
Csatlakozott: 2012. szeptember 5. szerda, 6:00

Re: Teljesítmény mérés 230V-os hálózaton

Hozzászólás Szerző: csabeszq »

Az előző hozzászólásom nem kicsit sántít. Sajnos DC-n edződött jómagamnak fogalmam sincs mi az az AC.
- ha 230V-tal megszorzod, akkor durván a teljesítményt kapod
Ezt annyiban pontosítanám, hogy a legritkább esetben lehet a teljesítményt kiszámolni az áram 230V-os szorzatával.
A kérdés, hogy mekkora az eltolás az áram és a feszültség között.

Nem szeretném a műszert túlkomplikálni, de valahol tudni kellene, hogy hol kezdődik a szinusz periódus.

Arra gondoltam, hogy 2x22k-val és egy 230V-os diódával rákötök egy optocsatolót a hálózatra, amikor a csatoló bekapcsol, akkor kezdődik a periódus.
Ez után durván számolhatom a szinuszt, amivel már hellyel közzel lehetne teljesítményt mérni.

Ismerem: az áramváltó kimenetén az áramot, tudom, hogy 230V a hálózati feszültség, észlelem a periódus kezdetét, ebből elvileg közelíthető lenne a teljesítmény, de szóljatok, ha tévedek.
Válasz küldése