Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Arduino DUE - Programowe filtrowanie szumów sinus podczas odczytu z ADC

DarekMich 01 Feb 2016 20:10 1692 3
Tespol
  • #1
    DarekMich
    Level 15  
    Witam, mam takie pytanie, ostatnimi czasy pracowałem nad pomiarem energii kWh jakie z powodzeniem utylizuje u siebie w domu, ale za pomocą raspberry pi[C] i ADC MCP3208 [12 bit]. Udaje mi się przy pomocy tego zestawu osiągnąć około 120-180 pomiarów na/Sinus, całość już działała jakiś czas dobrze, zdecydowałem sie jednak na upgrade.

    Moje zainteresowanie padło na maksymalną prostotę, i zakupiłem w tym celu arduino DUE. po kilku H spędzonych w internecie i czytania na temat możliwości tego urządzenia skończyłem z programem który osiąga następujące efekty w trybie freerun dla 2 ADC

    tylko 12 bit [0-4095]:
    pomiar 1 sinusoidy napięcie/prąd to około 5300 próbek
    (1 pomiar do tablicy to 1 odczyt z ADC)


    "oversampling" 13 bit[0-8191]:
    pomiar 1 sinusoidy napięcie/prąd to około 1350 próbek (4x mniej)
    (1 pomiar do tablicy to 4^1 odczytów podzielone przez 2^1 - w praktyce sumujemy 4 pomiarów ze sobą i następnie dzielimy je przez 2 dla 1 dodatkowego bita)

    "oversampling" 14 bit[0-16383]:
    pomiar 1 sinusoidy napięcie/prąd to około 350 próbek (16x mniej)
    (1 pomiar do tablicy to 4^2 odczytów podzielone przez 2^2 - w praktyce sumujemy 16 pomiarów ze sobą i następnie dzielimy je przez 4 dla 2 dodatkowych bitów)

    W obu przypadkach tracimy na ilosci próbek, ale zyskujemy na rozdzielczości.

    W związku z tym ma 2 pytania.
    Overampling wydaje się działać i dawać pośrednio zadowalające efekty. Chciałbym sie zapytać jak wy byście się do tego faktu odnieśli.

    I drugie pytanie odnosi się do samych pomiarów, niezależnie od rozdzielczości.
    Problemem jednak są zakłócenia. Zdaję sobię sprawę, ze stosowanie zwykłych przewodów dla tego typu płytek nie jest najlepszym pomysłem (z tąd mogą się brać widoczne zakłócenia). tak samo jak ze wzrostem rozdzielczości wzrasta również poziom zakłóceń.

    Przy 12 bitach, napięciu odniesienia 3.3V i czujniku typu SCT-013-000 pomiar prądu zużywanego przez urządzenia o niskich mocach (np 30/50W) jest praktycznie niemożliwy, przy 14 bitach i jest już możliwy taki pomiar, gdzie przy podłączonej zwykłej żarowej żarówce 45W z P=U*I wychodzi mi ~38W, problemem są właśnie te zakłucenia.

    Znacie może jakiś sprawdzony sposób na programowy filtr gotowej tablicy zawierającej takie próbki, bądź dokonywania obliczeń na bieżąco w trakcie pomiaru?

    Próbowałem z pętlą która liczyła średnią z 2 pomiarów z każdego parzystego pomiaru w tablicy (numer porządkowy) ale nie jestem zadowolony z efektu.

    Zdaję sobię sprawę, że pomimo wyeliminowania wszelkich zakłóceń i szczelności ekranowej układu pomiarowego po mojej stronie i tak zostają kilometry kabla zarówno w ziemi jak i na liniach napowietrznych i te zakłócenia zawsze będą występować, na dodatek stosowanie oversamplingu również nie polepsza tutaj sprawy.

    Nie chodzi mi o gotowy kod na "gładką" sinusoidę, chodzi mi o pozbycie sie z niej tych wszystkich dodatkowych "strzępów" w rozważaniu teoretycznym.

    W chwili obecnej chwili "noise" sprawia błąd pomiaru w szczytowych okolicach 0.08-0.12A RMS(co i tak nie jest tragiczne przy 100 A czujniku tego typu) jednak wystarczy żeby pomiar mocy żarówki 45W wahał się od 25-55W.

    Ewentualne obejście problemu to zastosowanie 3 pomiarów jednocześnie, przy czym 1 pomiar napięcie i 2 pomiarów z 2 różnych sensorów, gdzie 100A wpięty będzie na stałe i jeżeli pomiar będzie mniejszy niż np 10A program podłączy 30A (czulszy model) i będzie jego uwzględniał w pomiarach zamiast 100A.


    ----------- EDIT -------------


    Jako ciekawostka, kod który stosuję, Wartość ADC z A0 oraz A1 znajują się pod AN0 i AN1 po wywołaniu funkcji read_adc():

    Po przetestowaniu poniższego programu wyniki sa następujące dla pomiarów o łącznym czasie trwania 20,5 ms (nieco ponad 1 okres 50Hz) przy odczycie 2 ADC:

    12 bitów - 6821 próbek
    13 bitów - 1706 próbek
    14 bitów - 427 próbek
    15 bitów - 107 próbek
    16 bitów - 27 próbek
    17 bitów - 7 próbek

    oczywiście 15,16,17 tutaj występują jako ciekawostka, przydatne, keidy chcemy mierzyć dosyć dokładnie napięcie/prąd stałe z wyjścia czujnika lub baterii.

    Kod podaję, gdyż nie tak łatwo znaleźć informacje w internecie jak to fajnie poskładać żeby osiągnąć te 1MS/s w arduino due.

    Ilość sampli/s spada tyle razy ile ADC chcemy odczytywać na raz, czyli:
    1 adc około 1MS/s
    2 adc około 500 kS/S
    itd

    Code: c
    Log in, to see the code


    Z góry dzięki za wszelkie rady.
    Do you have a problem with Arduino? Ask question. Visit our forum Arduino.
  • Tespol
  • #2
    michcior
    Level 30  
    Podstawowe pytanie, wiesz co to jest moc czynna/bierna?
    No więc, płacimy za moc czynną, acz ciekawe jest też znać moc bierną.
    Pomiar mocy czynnej czy biernej to banał, mnożymy próbki prądu i próbki napięcia i mamy moc czynną,
    mnożymy próbki prądu przesunięte o 90stopni z napięciem i mamy moc bierną. Mnożymy próbki a potem dopiero sumujemy co nam daje moc.

    A gładką sinusoidę uzyskasz robiąc prostą filtracje FIR, czyli splot z sinusem 50Hz. Tyle, że na funkcję splotową trzeba nałożyć okno (Hamminga/Bartleta czy jakieś tam) żeby trochę rozmyć widmo filtru. Taka filtracja nawet ta najprostsza to temat na cały wykład niestety.
    Pytanie, czy trzeba stosować taką filtrację, bo przebieg napięcia w naszej sieci odbiega od sinusoidy, odfiltrujesz też wszystkie stany nieustalone w przebiegu prądu a to nie jest dobrze, bo wiele odbiorników przełącza się szybko. Raczej podrasuj część analogową, zadbaj o stabilność próbkowania i filtry częstotliwości Nyquista.
  • Tespol
  • #3
    DarekMich
    Level 15  
    Tak, wiem na czym polega liczenie mocy i energii. tutaj pomiar był jedynie żarówki żarowej, i dlatego mogłem sobie pozwolić na uproszczenie. Nie chcę rozlewać wywodu ani wymuszać dyskusji która w tym miejscu nie jest jeszcze potrzebna (by moze po osiągnięciu celu powstanie włąściwy temat). Upraszczajać, jestem świadomy blędu obliczeniowego stosując tak proste obliczenia. Wszyscy wiemy, że nie wiadomo jak "lepiej" dokonam pomiaru od licznika jaki założył mi zakłąd elektryczny i tak nie wskuram, do wglądu poglądowego to będzie aż nadto skąplikowany program, ale zbyt prosty do profesjonalnego zastosowania.
    (wiem, że krztałt sinus prądu potrafi być lekko mówiąc "zniekrztałcony").

    Nie chcę też wymuszać na siłe wyników z tablicypomiarowej żeby przypominały sinus, chodzi mi jedynie o złagodzenie tych wyników. nie żeby patrząc na wykres wygenerowany w arkuszu kalkulacyjnym widzieć piłę. Problem nie dotyczy napięcia, ale pomiarów małych (tutaj bardzo małych) prądów.

    Jutro mogę wrzucić wykre pomiaru prądu (wstaję do pracy wczesnie więc końćze na dziś), teraz samo napięcie na wyjściu z transformatora podane na dzielnik napięcia nastepnie z przesuniętą masą tak by możńa było mierzyć dodatnią i ujemną połówkę sinusidy, chodzi o to, żeby załagodzić tę piłe (wykres całego sinusa i tylko wierzchołka):

    Arduino DUE - Programowe filtrowanie szumów sinus podczas odczytu z ADC Arduino DUE - Programowe filtrowanie szumów sinus podczas odczytu z ADC
  • #4
    DarekMich
    Level 15  
    Witam, troszeczkę czasu minęło i program udało sie po małej przerwie w końcu dokończyć (tzn. żeby osiągnąć tzw minimum jakie było zakładane).

    Zmianie uległo dosyć sporo, odszedłem od sposobu pomiaru Sinus prądu i Sinus napięcie, oraz wyliczania Cos Fi między nimi, ze względu na fakt, że faktycznie kształt sinus prądu i napięcia są krótko mówiąc dosyć dalekie od idealnych, a właśnie takie jedynie nadają się do wzoru: P=U * I * cos fi;

    Zamiast tego po prostu dokonuje pomiarów chwilowych przez całą tablice i następnie uśredniam wynik.
    Aktualnie program spełnia następujące założenia:
    - pomiar RMS Napięcia,
    - pomiar RMS prądu,
    - pomiar aktualnie pobieranej chwilowej mocy rzeczywistej,
    - pomiar aktualnie pobieranej chwilowej mocy pozornej,
    - pomiar częstotliwości napięcia sieci,
    - pomiar energii rzeczywistej w czasie zebranych próbek jakie są w tablicy (wartość pomnożona 1000000 razy)
    - pomiar energii pozornej w czasie zebranych próbek jakie są w tablicy (wartość pomnożona 1000000 razy),
    Suma pobranej energii rzeczywistej oraz pozornej od chwili uruchomienia układu.

    Najmniejszy możliwy pomiar to ~5W mocy rzeczywistej (przy oversamplingu ADC do 14 bitów ~420 próbek na sinus) poniżej już niestety szumy.

    Przykład pomiar czajnika ~3kW daje pomiar na poziomie 2700-2850W w zależności od chwilowego napięcia sieci

    pomiar 45W żarówki żarowej daje pomiar 45-46W (przy 14 bitach, w przypadku 12 bitów dokładność spada to 55-60W dla 45W żarówki)

    Poniżej załączam program, w jego nagłówku znajdują się wszystkie niezbędne wartości konfiguracjii, aby program działał w danej aplikacji.

    Przed podaniem napięcia na ADC z transformatora zarówno dla prądu i napięcia należy zastosować rezystory 1:1 (najlepiej 5-10k każdy) aby wytworzyć dzielnik napięcia i uzyskać jego połowę, następnie transformator jak i sensor prądu wpinamy pomiędzy punkt środka napięcia 3.3 a nasze wejście ADC.

    Wykorzystane wejścia to
    A0 - dla pomiaru prądu
    A1 - GND
    A2 - dla pomiaru napięcia
    A3 - GND
    A4 - A5 - niepodłączone.

    Załączam również kalkulator użyty w openoffice do obliczenia rezystora dla sensora prądu, wybór mój padł na 21,7 Ohm który pozwala mierzyć prądy o wartości do 107A (75A RMS). Pola żółte są komórkami które należy zmienić wg własnego uznania, pole pomarańczowe są to wyniki.


    Oto cały program:
    Code: c
    Log in, to see the code


    Wyniki jakie daje program są dosyć łatwe do odczytania:
    Code:
    Initializing...
    
    Ready
    Vrms=239.93V Irms=0.28 Freq=49.96Hz Ireal=0.01A S=2.82W  P=66.28W Factor S/P=0.04 Es=0.00kWh  Est=0.78289kWs Ep=0.00VAh Ept=18.40997VAs
    Vrms=239.87V Irms=0.27 Freq=49.96Hz Ireal=0.01A S=3.20W  P=65.38W Factor S/P=0.05 Es=0.00kWh  Est=1.15397kWs Ep=0.00VAh Ept=18.11487VAs
    ...



    Powyższy kod wysyła co 1s w pętli linie informującą nas o zebranych danych.
    powyższy wynik jest widoczny bezpośrednio po uruchomieniu układu.

    Irms=0.28 Ireal=0.01A S=2.82W P=66.28W

    Co najciekawsze w przewodzie przy którym znajduje się czujnik prądu nie płynie żaden prąd. Z tąd poprzednie moje pytanie odnośnie filtracji sinusoidy, okazuje się, że wszystkie przewody użyte w ukłądzie zachowują się jak antena, wykres minimalnych prądów w przypadku obciążenia żarówką żarową o mocy 45W są następujące:

    Code:
    Vrms=240.48V Irms=0.28 Freq=50.32Hz Ireal=0.01A S=2.63W  P=66.74W Factor S/P=0.04 Es=0.01kWh  Est=1.06281kWs Ep=0.11VAh Ept=18.57274VAs
    
    Vrms=240.51V Irms=0.28 Freq=50.20Hz Ireal=0.01A S=3.28W  P=67.76W Factor S/P=0.05 Es=0.01kWh  Est=0.77063kWs Ep=0.11VAh Ept=18.57880VAs
    Vrms=239.76V Irms=0.27 Freq=50.20Hz Ireal=0.01A S=2.53W  P=63.96W Factor S/P=0.04 Es=0.01kWh  Est=0.87477kWs Ep=0.11VAh Ept=18.18164VAs
    Vrms=240.30V Irms=0.35 Freq=50.20Hz Ireal=0.20A S=48.68W  P=83.34W Factor S/P=0.58 Es=0.01kWh  Est=11.52740kWs Ep=0.11VAh Ept=22.36589VAs
    Vrms=240.22V Irms=0.35 Freq=50.20Hz Ireal=0.20A S=47.44W  P=82.94W Factor S/P=0.57 Es=0.01kWh  Est=13.33910kWs Ep=0.11VAh Ept=23.38149VAs
    Vrms=240.29V Irms=0.33 Freq=50.20Hz Ireal=0.19A S=46.43W  P=80.38W Factor S/P=0.58 Es=0.01kWh  Est=13.27906kWs Ep=0.11VAh Ept=23.09661VAs


    Tutaj widać moment włączenia żarówki, nie jest ona idealna. Najtańsza żarówka kupiona za 50 pensów (~2.50 PLN) więc o jej dokładnie zadeklarowanej mocy możemy zapomnieć.

    Im wyższa moc jest pobierana tym mniej zakłócenia mają wpływ na wyniki.

    poprzednio widzieliście wykres SINUS napięcia, teraz wykres prądu dla 45W żarówki:

    Arduino DUE - Programowe filtrowanie szumów sinus podczas odczytu z ADC

    Program wstawiam, gdyż łatwiej będzie iść w te ślady niż odkrywać wszystko od nowa. Choć osobiście wiem, że znajduje się wiele gotowych bibliotek (emonlib - przykład).

    Dalsza część programu zostanie zintegrowana w większy projekt.
    Pozdrawiam