• 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
PWM - Sygnały przesunięte w fazie
#11
Tak jak es2 napisał, dla trybu phase correct, można bardzo dokładnie ustawić częstotliwość PWM.

Ja zrobiłem to tak, że dałem ICR1=400 dla preskalera = 1.
Dla kryształu 16MHz wychodzi równiutko 20kHz.
Wykorzystałem dwa kanały timera 1, przy czym TCCR1B ustawiłem w przeciwnej fazie.

W setupie ustawiamy zegar:

Kod:
    TCCR1A = 0;
    TCCR1B = 0;
    TCNT1  = 0;
    TCCR1A = (1<<COM1A1) | (1<<COM1B1) | (1<<COM1B0) | (1<<WGM11);
    TCCR1B = (1<<WGM13) | (1<<CS10);
    ICR1   = 400;                      
    
    pinMode( 9, OUTPUT);
    pinMode(10, OUTPUT);
Napisałem sobie taką funkcję ustawiająca wypełnienie.
Kod:
void PWM(int wypelnienie) //od 0% do 100%
{
    wypelnienie = map (wypelnienie, 0, 100, 0, 400);
    OCR1A = wypelnienie; // pin9
    OCR1B = 400-wypelnienie; // pin 10
}

Wypełnienie jest mapowane 100 --> 400, żeby podawać je do funkcji w procentach, ale jak ktoś chce, to można to wywalić i wysyłać od 0 do 400. Będzie precyzyjniej.
Kod spełnia oczekiwania autora wątku, przynajmniej tak wnioskuję z załączonej grafiki.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#12
Dzięki Robson, Twój kod jest lepszą odpowiedzią do założeń posta, ja korzystałem z Timera2 z podobnie deklarowanymi rejestrami "wypełnień" OCR2A i OCR2B wyjść UNO 3 i 11. Ale i tak chyba bardziej byliśmy zainteresowani rozwiązaniem niż autor posta.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#13
Dziękuję bardzo za wszystkie odpowiedzi, odpowiadam dopiero teraz bo wcześniej brakowało czasu żeby przetestować podawane tu pomysły.
Po pierwszych próbach wydaje mi się, ze rozwiązanie podane przez Robsona rzeczywiście może rozwiązać mój problem (dlatego tez szczególne podziękowania kieruję do Ciebie). Miałbym jeszcze kilka pytań odnośnie tego zagadnienia.

1. Czy regulacja częstotliwości odbywa się tylko poprzez zmianę wartości IRC1?

2. Nie do końca rozumiem w jaki sposób regulować wypełnieniem. Standardowo zmieniałem je w zakresie 0-255 w funkcji AnalogWrite, jeśli dobrze rozumiem to teraz zmiana powinna odbywać się podobnie, tyle ze w zakresie 0-400 (pomijając funkcje void PWM). Zastanawia mnie fakt, że w okolicach wypełnienia 200 wartość napięcia jest prawdopodobnie największa, natomiast w miarę zmieniania wypełnienia bliżej wartości skrajnych to napięcie jest niższe. 
     
Wyjątkiem który zauważyłem jest domyślna wartość graniczna czyli 255 przy której sygnał przyjmuje wartość w okolicach zera.
   
Prosiłbym o odpowiedź, czy dobrze zrozumiałem regulację, albo informację gdzie popełniam błąd.

3. Czy jest jakiś "domowy" sposób na sprawdzenie uzyskiwanego sygnału gdy nie mam możliwości testu z wykorzystaniem oscyloskopu? Posiadam program Virtins Sound Card Oscilloscope, dzięki któremu po podaniu sygnału z Arduino na dzielnik napięcia i dalej na wejście mikrofonowe karty dźwiękowej jestem w stanie uzyskać przebiegi, jednak maksymalna częstotliwość próbkowania to 96000Hz, przez co przy sygnale 20kHz zmiany stopnia wypełnienia widoczne są tylko poprzez zmianę wartości napięcia, natomiast zmiany w osi czasu nie są widoczne. Znacie może jakieś inne narzędzia które pozwoliłoby mi zobaczyć dokładniejsze przebiegi sygnałów?
 
Odpowiedź
#14
(21-07-2018, 22:54)akudom napisał(a): 3. Czy jest jakiś "domowy" sposób na sprawdzenie uzyskiwanego sygnału gdy nie mam możliwości testu z wykorzystaniem oscyloskopu?

Analizator logiczny za cenę flaszki. To nie oscyloskop, to coś co go uzupełnia. Sensowny oscyloskop, kupisz za 300..500zł, tyle niektóry wydaja na papierosy czy paliwo do motoru, który zbliża ich do śmierci.


PS
(21-07-2018, 22:54)akudom napisał(a): ze rozwiązanie podane przez Robsona rzeczywiście może rozwiązać mój problem
Polski język jest ubogi?
 
Odpowiedź
#15
(21-07-2018, 22:54)akudom napisał(a): 1. Czy regulacja częstotliwości odbywa się tylko poprzez zmianę wartości IRC1?

Nie tylko. Jest jeszcze preskaler.

(21-07-2018, 22:54)akudom napisał(a): 2. Nie do końca rozumiem w jaki sposób regulować wypełnieniem. Standardowo zmieniałem je w zakresie 0-255 w funkcji AnalogWrite, jeśli dobrze rozumiem to teraz zmiana powinna odbywać się podobnie, tyle ze w zakresie 0-400 (pomijając funkcje void PWM).

Tą funkcję, to sobie napisałem, aby ułatwić ustawianie wypełnienia na dwóch kanałach jednocześnie. Skoro przesunięcie ma być o 180°, to po co kombinować?
Funkcja analogWrite jest tak napisana, że jej licznik przepełnia się przy 255, więc wypełnienie zmieniałeś w zakresie 0-255.
Nie wiem w czym masz problem z zakresem 0-400, albo 0-100???
NIe musisz kożystać z tej funkcji, możesz pisać (dla wypełnienia powiedzmy 25%):


Kod:
OCR1A = 100;
OCR1B = 300;


(21-07-2018, 22:54)akudom napisał(a): Zastanawia mnie fakt, że w okolicach wypełnienia 200 wartość napięcia jest prawdopodobnie największa, natomiast w miarę zmieniania wypełnienia bliżej wartości skrajnych to napięcie jest niższe. 
 
Wyjątkiem który zauważyłem jest domyślna wartość graniczna czyli 255 przy której sygnał przyjmuje wartość w okolicach zera.
 
Prosiłbym o odpowiedź, czy dobrze zrozumiałem regulację, albo informację gdzie popełniam błąd.

Wartość napięcia jest stała i wynosi 5V.
Twój sposób pomiaru jest taki, że wynikiem jest wartość skuteczna napięcia (Vrms).
Wartość skuteczna jest równa wartości maksymalnej pomnożonej przez pierwiastek wypełnienia Vrms = V*sqrt(D/100%)
U mnie jest tak:



Masz po prawo wyświetlane wartości napięć. Zauważ jak zmienia się Vrms w zależności od wypełnienia.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#16
(21-07-2018, 22:54)akudom napisał(a): Znacie może jakieś inne narzędzia które pozwoliłoby mi zobaczyć dokładniejsze przebiegi sygnałów?

Tak, jest takie narzędzie o nazwie oscyloskop.
Kupiłem kiedyś Mini Kombajn Pomiarowy z AVT. Aktualnie kosztuje 170PLN. Podłączyłem pod niego moje Arduino, a na ekranie takie coś:



Wniosek z tego taki, że możesz zbudować sobie oscyloskop na Arduino, bo MKP też jest 8 Bit.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#17
Dziękuję za wszystkie odpowiedzi. Miałbym jeszcze jedną prośbę.

(19-07-2018, 22:06)Robson Kerman napisał(a): Tak jak es2 napisał, dla trybu phase correct, można bardzo dokładnie ustawić częstotliwość PWM.

Ja zrobiłem to tak, że dałem ICR1=400 dla preskalera = 1.
Dla kryształu 16MHz wychodzi równiutko 20kHz.
Wykorzystałem dwa kanały timera 1, przy czym TCCR1B ustawiłem w przeciwnej fazie.

W setupie ustawiamy zegar:

Kod:
    TCCR1A = 0;
    TCCR1B = 0;
    TCNT1  = 0;
    TCCR1A = (1<<COM1A1) | (1<<COM1B1) | (1<<COM1B0) | (1<<WGM11);
    TCCR1B = (1<<WGM13) | (1<<CS10);
    ICR1   = 400;                      
    
    pinMode( 9, OUTPUT);
    pinMode(10, OUTPUT);

Czy mógłbyś mi wyjaśnić jakie dokładnie zmiany powodują te modyfikacje rejestrów które wprowadziłeś? Poczytałem nieco na ich temat, ale nie jestem w stanie rozszyfrować i zrozumieć całości. Przepraszam, że tak się o to dopytuję, ale nie należę do zaawansowanych użytkowników Arduino a że Twój przykładowy kod wydaje się działać poprawnie to chciałbym zrozumieć dlaczego.
 
Odpowiedź
#18
Licznik/zegar jest taktowany zewnętrznie, lub poprzez układ preskalera i w zależności od jego ustawienia, tiknięcie dla licznika jest co 8, 64, 256 i 1024 impulsów zegara, albo 8, 32, 64, 128, 256 i 1024, albo jeszcze inaczej.
Licznik 8bit liczy do 256, a 16bit do 65535, albo można też ustawić do jakiej liczby ma maksymalnie liczyć nasz licznik (TOP), oraz od jakiej liczy zacząć liczenie (BOTTOM).
Jeśli więc ustawimy preskaler na przykład na 256, to dla kwarcu 16MHz, nasz licznik policzy w ciągu sekundy do 62500. I już z góry widać, że licznik ośmiobitowy przepełni się i restartuje 244.14 razy na sekundę. Takie przepełnienie może wywołać przerwanie i zmienić stan wyjścia zegara.
Ale to już pewnie wiesz.

TCCR1 - rejestr kontrolny (Timer/Counter Control Register), jest rejestrem szesnastobitowym. Oznacza to, że ma szesnaście bitów kontrolnych. Szesnaście przełączników ustawiających różne tryby naszego licznika/zegara.
Podzielony jest na dwa ośmiobitowe rejestry TCCR1A i TCCR1B. 

TCCR1A = (1<<COM1A1) | (1<<COM1B1) | (1<<COM1B0) | (1<<WGM11); 
Bierzemy sobie datasheet i w tabeli COMPARE OUTPUT MODE czytamy:
COM1A1 - startujemy ze stanu wysokiego, a gdy licznik osiągnie wartość wpisaną do OCR1A ustawiamy stan niski.
COM1B1 i COM1B0 - to samo co dla kanału A, tylko że odwrócona faza. Starujemy ze stanu niskiego.

WGM11 - WGM mode 2.

TCCR1B = (1<<WGM13) | (1<<CS10); 
WGM13 - WGM mode 8. To było mi potrzebne, aby ustawić TOP na ICR1.
CS10 - preskaler ustawiony na 1.

ICR1   = 400; - no właśnie TOP jest ustawiony na ICR1, więc jak licznik doliczy do TOP to zmienia się OC1x.

Przesunięcie fazy jest realizowane w taki sposób:
OCR1A = X;
OCR1B = ICR1 - X;


Nie wiem, czy dobrze to wytłumaczyłem, nie mam talentu pedagogicznego.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#19
(22-07-2018, 12:50)Robson Kerman napisał(a): Wniosek z tego taki, że możesz zbudować sobie oscyloskop na Arduino, bo MKP też jest 8 Bit.
MKP ma Xmega a nie Memga, który jest najczęściej spotykany w Arduino.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości