Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Całkowanie sygnalu w AVR/C Atmega 128

27 Lis 2010 23:27 5243 43
  • Poziom 16  
    Witam wszystkich pracuje nad sterownikiem SZR i chciałbym scałkować dodatnie połówki napięcia (sinusa) metoda prostokątów bo nie potrzebuje dokładnego pomiaru ale mam problem czy można wartość bezpośrednio z ADC dodawać do siebie i w następnej kolejności dzielić przez liczbę próbek.Dodam że przetwornik jest ustawiony w trybie przerwania ISR[ADC].czyli w przerwaniu zatrzymuje przetwornik odczytuje wartość do zmiennej przełączam kanał uruchamiam ADC i tak w kółko.Wartość napięcia chce wyświetlać na LCD Graf oraz badać kierunek wirowania faz. Ilość próbek na daną fazę(kanał) to 230. Rozdzielczość przetwornika 1024.
  • Moderator Mikrokontrolery Projektowanie
    Można tak zrobić, tylko musisz zapewnić odpowiednią ilość "miejsca" na próbki. ADC ma 10 bitów, dla zmiennej uint16_t pozostaje ci więc miejsce na max 2^6 próbek, czyli 64, a ty chcesz 230, musisz więc zastosować zmienną o typie uint32_t.
  • Poziom 16  
    W c programuje od niedawna i nie wiem co oznaczają skróty uint_16t niektórzy nawet w programie używają tego rodzaju skróty ja zastosowałem do sumowania zmienną unsigned long int
  • Moderator Mikrokontrolery Projektowanie
    ulong będzie ok - to właśnie odpowiednik uint32_t. Różnica jest taka, że ulong ma różną długość w zależności od platformy sprzętowej, uint32_t ma zawsze 32 bity. Stąd dużo osób preferuje tego typu definicje, zamiast int, short, long itd.
  • Poziom 14  
    Witam. 230 na kanal przy pomiarze sinusa ? Moze kolega wyjasnic dokladniej ?
    Jesli kolega chce zatrzymac 230 x 3 (3 fazy) x 16 bit danych to nie wystarczy pamieci w samym AVR.Jesli to tylko 1 faza to zostanie jeszcze polowa pamieci na pozostale operacje .Mysle ze w tym 1 przypadku należałoby podzielic obliczenia na etapy , po wczytaniu np 115 pomiarow dokonac obliczen ,wczytac nastepne i dokonczyc obliczenia uwzgledniajac wczesniejsze.Poza tym o jaki rodzaj usrednienia chodzi ? W jakim czasie jest ono potrzebne ? Moze zastosowac bufor kołowy dla prubek , ostatnio budowalem uklad gdzie wlasnie do usrednienia pomiarow zastosowalem takie rozwiazanie . Czy napewno istnieje potrzeba zachowania w pamieci tak dużej ilosci pomiarow?
  • Poziom 16  
    Jak może nie wystarczyć pamięci Jedna zmienna long int dajmy na to o nazwie L1 i do niej zapisywane wartości z ADC no można za każdym razem formatować tą wartość do postaci faktycznej próbki napięcia i scałkować już same próbki a póżniej policzyć jeszcze pierwiastek w celu uzyskania wartości skutecznej a nie szczytowej. I tak do zbadania ma jeszcze dwie fazy L2i L3 wykrycie kolejności wirowania faz czyli sprawdzanie na którym kanale pojawi się wartość zerowa albo też bliska zeru bo nie wiem czy trafie dokładnie w 0
  • Poziom 14  
    No tak . To po co piszesz o jakis 230 prubkach ? :) Zasugerowales w ten sposób ze chcesz miec tyle w pamieci stad taka moja odpowiedz.W takim razie mozesz dodawac , mnozyc i dzielic do woli , na ile Swięty Mhz ci pozwoli.Pozdrawiam.
  • Poziom 16  
    Mam jeszcze jedno pytanie a mianowicie wzór na całkowanie jest taki C=[i=0..N]{y[i]*TS } przy czym Ts=const =x[N+1]-x[n] i teraz za TS mam podstawić czas próbkowanie czyli w moim przypadku jest to cały okres=0,02s?
  • Poziom 38  
    Nie, to jest czas między dwiema próbkami i w tym przypadku będzie zależał od częstotliwości próbkowania ADC. Zerknij do wzoru na całkę oznaczoną Riemanna, jest to suma pól prostokątów, na które dzielisz pole pod wykresem jakiejś funkcji.

    W Twoim wzorze tak właśnie jest, masz N próbek sygnału i liczysz pola prostokątów, TS to długość na osi x, y[i] to wysokość na osi y i dodajesz pola takich prostokątów. Są dokładniejsze metody, chociażby metoda trapezów, która wygląda analogicznie, tylko, że nie traktujesz całki sygnału jako sumy pól prostokątów, tylko trapezów. Metod właściwie jest mnóstwo, ale nie o to pytałeś :P
  • Poziom 16  
    No tak w moim przypadku procek jest taktowany 8MHz i preskaler jest ustawiony na 16 więc jeden takt równa się 0,0002s razy 13 taktów tyle trwa konwersja przetwornika więc próbkowanie wyniesie 0,00028s czyli 3,5kHz Czy jestem na dobrze myślę panowie.
  • Poziom 38  
    Czas konwersji nie ma nić wspólnego z częstotliwością próbkowania.
    Po prostu wyniki będzie miał opóźnione o te 13 taktów względem wymuszenia przetwarzania. Sumowania możesz dokonywać na bieżąco a dopiero po zebraniu całego zestawu próbek dokonać pozostałych obliczeń. W dodatku skoro chcesz korzystać z kilku kanałów należy pamiętać, że 1 próbka po przełączeniu kanały jest niepoprawna. Dla 3 kanałów musisz wybrać 6x większa częstotliwość próbkowania.
  • Poziom 16  
    Czyli reasumując mam przykładowo 200 próbek każdą co przerwanie dodaje do siebie w zmiennej a pożniej muszę pomnożyć przez ilość danych próbek
  • Poziom 38  
    i razy okres próbkowania (czas pomiędzy próbkami). I Przeanalizuj jakiego typu dane są ci potrzebne. Suma pewnie będzie 4 bajtowa. A współczynnik przez który będziesz mnożył?
  • Poziom 38  
    Przez okres próbkowania*VREF/1024 i ewentualnie pierwiastek z tego
  • Poziom 16  
    Ale nie do końca wiem jak jest z tym czasem działania przetwornika wydaje mi się ze czas taktowania wpływa na czas konwersji i co za tym idzie na częstotliwość próbkowania Ja zrobiłem tak okres przebiegu sinusa wynosi 0,02 Założyłem ze podczas startu przetwornika zacznie on próbkować w nie wiadomo w jakim punkcie sinusa dlatego czas próbkowania musiał by wynieść 20ms za cały okres tylko nie wiem jak obliczyć zmienna która co przerwanie będe odejmował. Więc żeby dobrać odpowiednia liczbę w zmiennej licznikowej muszę obliczyć co jaki czas będzie wykonywane przerwanie od ADC
  • Poziom 38  
    Mógłbyś jakimś wzorem zarzucić bo nie wiem co Ty tam tworzysz ? i zerknąć do DS ?

    Jak masz zegar 16MHz i wybierzesz preskaler 128, to ADC jest taktowany zegarem o częstotliwości 125kHz --> 8 µs

    Konwersja trwa 13 cykli zegarowych ADC więc 8*13µs = 104µs i to też masz wpisać jako czas między dwoma próbkami.

    btw, nie wiem czy wiesz, ale $$\int_0^{2\pi} \sin{x}dx = 0$$ :)
  • Poziom 15  
    Trochę się pogubiłem. Rozumiem że masz 3 fazy puszczasz je przez diody.
    Następnie chcesz scałkować, żeby poznać wartość skuteczną.

    Ja bym próbkował w przerwaniach od jakiegoś timer'a np. co 0,1ms.
    W danym przerwaniu próbkuje osobno 1,2,3 kanał oraz wykonuję sumę
    Llicz++
    k1=k1+ADC
    k2=k2+ADC
    k3=k3+ADC
    Dodatkowo zliczam impulsy od przerwań i przy 200 wykonuje obliczenia czyli sumę
    dziele przez 100 bo druga połówka obcięta
    k1=k1/100
    ...
    ...
    Następnie mnożę przez współczynnik wynikający z VRef oraz dzielnika przez jaki puszczasz dane do ADC i masz elegancką wartość skuteczną napięcia każdej fazy.

    Następnie zeruje wszystko i zapodaje na nowo.

    Oczywiście możesz dodać bieżące sprawdzanie wielkości k1 k2 k3 i na tej podstawie stwierdzić kolejność.
  • Poziom 38  
    galusz napisał:

    Ja bym próbkował w przerwaniach od jakiegoś timer'a np. co 0,1ms.


    W atmega128 jest chyba wyzwolenie przetworzenia timera na ovf/CC timera
  • Poziom 16  
    Kwarc do celowo zakładam że będzie 16MHz ale póki co nie chce mi działać na 16 MHz coś jest w Fusebitach co przestawiam na Ext. High Crystal Rezonator to się wysypuje trzeba wracać do 8MHz . Co do próbkowania połówki sygnału sinusa to chciałem wykorzystać przerwania od ADC bo jak kolega napisał przerwania od Timera co 1ms jest to za wolno tym bardziej że docelowo ma do sprawdzenia 2 linie trójfazowe jedna napięcia w sieci a drugą napięcia z agregatu, czyli razem 6 kanałów. Buduje sterownik SZR na prace Inż. W przerwaniu zatrzymuje przetwornik przepisuje do zmiennej wartości rejestrów ADCL i ADCH potem chciałem dodawać w zmiennej te próbki i po zliczeniu 200 przerwań od ADC bo tyle przeliczyłem że wyniesie czas20ms czyli okres. Na końcu reszta obliczeń Sprawdzenie w moim przypadku napięć na trzech fazach nie musi odbywać sie ciągle może to być odstęp co 200ms sprawdzenie 6 napięć i 200ms przerwy.Ale że przedtem programowałem w Bascomie to teraz trochę mi ciężko idzie.

    Dodano po 2 [minuty]:

    A dodam jeszcze że próbkuje tylko jeden kanał cały czas resztę załatwia multiplekser analogowy CD4051 za jego sprawą przełączam kanały.
  • Poziom 15  
    Nie napisałem, że co 1ms tylko co 0.1ms. A poza tym nie zauważyłem, że mowa o 128 :)
    Natomiast z takim problemem to spokojnie Atmega8 na Bascomie sobie poradzi i to bez multiplekserów i na zegarze wew..
    Nie bawiłem się 128 więc nie podpowiem dokładnie co i jak.
  • Poziom 16  
    Witam z samymi obliczeniami atmega8 oczywiście że da rade tylko ja steruję jeszcze innymi rzeczami i chodziło o liczbę IO sam wyświetlacz połyka 14 a gdzie reszta będę jednak robił to w przerwaniach od ADC.
  • Poziom 26  
    Nie wiem czy wiecie, ale RMS to pierwiastek kwadratowy z całki KWADRATU napięcia....
  • Poziom 16  
    Witam ponownie mam pytanie do kolegów a mianowicie nie działa mi funkcja dekodująca liczbę na kod BCD Mam funkcje
    void DZIES_BCD(int a)
    {

    volatile signed char i;
    volatile char buffer[6];

    for(i=0,buffer[5]=0; a; a/=10,i++)
    {
    buffer[i]= a%10 + '0';
    pozycja=i;
    }
    for(; i<=6; i++)

    {
    buffer[i] = ' ';
    }

    i teraz jak wywołam funkcje i za "a" podam liczbę 6547 to jest wszystko dobrze a jeśli będzie to liczba 65535 to już funkcja się wysypuje. Dokładnie to nie wiem co jest w pierwsze pętli for warunek zakończenia.
  • Poziom 38  
    To napisz taką funkcję sam :) Warunkiem zakończenia pierwszego fora jest a > 0
  • Poziom 16  
    To nic nie kapuje z tego for(i=0,bufer[5]=0; to jest zerowanie tablicy i nadanie początkowej wartości póżniej jest kosmiczna część; a;a/=10;no dzielimy a przez 10 ale samo "a" co znaczy no i na końcu inkręmentacja.
  • Poziom 16  
    Nie wiem w czym tkwi problem bo jak dekoduje liczbę 4 cyfrową to jest wszystko w porządku w przypadku liczby 5 cyfrowej 16bitowej jest już problem po pierwszym obiegu pętli a przecież a>0 .
  • Poziom 38  
    gaskoin napisał:
    To napisz taką funkcję sam :)
  • Poziom 16  
    Witam temat wraca jak bumerang z całkowaniem już sobie poradziłem ale teraz szukam sposobu jak sprawdzać kierunek wirowania faz. Mój okres próbkowania na 3fazach wynosi 20ms nie ważne w jakim momencie przetwornik zaczyna próbkować.Szukam sposobu ażeby sprawdzać w którym momencie na jednej z faz w zmiennej przechowującej wartość próbki pojawi się wartość równa 0. W tym momencie chciałem wystawić flagę z tym że póżniej jest kłopot z określeniem w którym momencie jaka flaga była pierwsza czy od fazy L1 czy L2 Czy L3
  • Użytkownik usunął konto  
  • Poziom 16  
    Trochę kiepskie rozwiązanie bo jeśli trafię w inny punkt Sinusoidy to wszystko się posypie sprawa jest dość skąplikowana. Póki co szukam rozwiązania w zależnościach czasowych ale nie doszłem do niczego