Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki

KURS HOME ASSISTANT

Chcesz zautomatyzować swój dom bez skomplikowanego kodowania?
Zastanawiasz się nad wyborem sprzętu, oprogramowania i aplikacji?
Od czego zacząć przygodę z HA? Co będzie najlepsze na start?

Nasz kurs Home Assistant nauczy Cię krok po kroku, jak łatwo zautomatyzować swój dom i oszczędzić na rachunkach za prąd i ogrzewanie. Bez chmur, bez zbędnych abonamentów. Twoja przygoda z Home Assistant zaczyna się tutaj!

↓↓↓

    Szanujemy Twoją prywatność. Możesz wypisać się w dowolnym momencie.




    Teraz jest 29 maja 2025, o 06:50


    Strefa czasowa: UTC + 1





    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 7 ] 
    Autor Wiadomość
    PostNapisane: 21 lis 2017, o 15:00 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 31 sty 2013
    Posty: 435
    Lokalizacja: Rybnik
    Pomógł: 6

    Witam,

    Mam pytanie odnośnie PWM'a programowego.

    Wszystko działa tak jak chcę Diody ładnie się zapalają od 0 do 255. Ale chciałbym mieć możliwość zwiększenia szybkości zaplania się ich. I tutaj mam problem nie wiem jak zmienić kod. Wartość szybkości chciałbym wysyłać po uarcie. Ale nie wiem co zmieniać..

    Składnia: [ Pobierz ] [ Ukryj ] [ Zaznacz wszystko ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Proszę o pomoc :)



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 21 lis 2017, o 17:51 
    Offline
    Użytkownik

    Dołączył(a): 07 cze 2016
    Posty: 563
    Pomógł: 143

    Nie napisałeś, jaki mikrokontroler, ale bity WGM10 i WGM11 są raczej zwykle w rejestrze TCCR1A, a nie TCCR1B. Poza tym ich ustawienie to raczej nie tryb CTC, a Phase Correct 10-bit, więc wprowadzanie jakiejkolwiek wartości do OCR1A nie wpłynie na szybkość generowania przerwań. Dodatkowo ustawienie bitów CS10 i CS12 w TCCR1B to raczej nie jest preskaler 1, jak masz napisane w komentarzach, ale to bym na razie zostawił.

    Skonfiguruj porządnie ten timer na odpowiedni tryb (CTC) zgodnie dokumentacją techniczną właściwego mikrokontrolera. Zamiast bitów WGM10 i WGM11 trzeba będzie prawdopodobnie ustawić tylko bit WGM12 w rejestrze TCCR1B. Ustaw wstępnie wartość OCR!A na ok. 2000 (powinieneś uzyskać podobną częstotliwość migania jak przed poprawkami), a później reguluj za pomocą zmiany wartości OCR1A, ewentualnie możesz też zmienić preskaler na mniejszą wartość. Nie wiem, jaki efekt dokładnie chcesz uzyskać, więc musisz sam dobrać odpowiedni preskaler, przy czym nie przesadź z szybkością, bo wykonanie procedury obsługi przerwania trochę trwa, a mikrokontroler ma do wykonania również inne zadania, więc trzeba zapewnić odpowiednie odstępy czasu pomiędzy przerwaniami.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 21 lis 2017, o 20:07 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 23 paź 2014
    Posty: 1035
    Lokalizacja: Trójmiasto
    Pomógł: 190

    Jeśli dobrze zrozumiałem kolega chce zwiększyć prędkość z jaką diody się zapalają więc gmeranie przy tajmerach raczej nie będzie rozwiązaniem.

    Aby zwiększyć szybkość zapalania się lub gaszenia musisz przyśpieszyć wykonywanie sekcji która zwiększa lub zmniejsza wartości PWM dla poszczególnych ledów. Czyli w Twoim przypadku odpowiedzialne za to są delaye w funkcji "led". Większe delaye to wolniejsze wykonywanie się pętli for a co za tym idzie wolniejsze inkrementowanie bądź dekrementowanie wartości PWM. Gdy zmniejszysz te delaye szybkość wykonywania się pętli wzrośnie więc i diody szybciej będą się rozjaśniać bądź ściemniać.
    Innym sposobem na przyśpieszenie procesu będzie inkrementacja o większą liczbę czyli musiałbyś przerobić warunek w pętli z i++ na np. i+=2 tylko musisz przypilnować by warunek kończący pętlę miał szanse zaistnieć (nie wiem jakiego typu jest "i" bo w Twoim kodzie tego zabrakło, jeśli typu int to będzie dobrze ale jeśli uint8_t to już pętla się nie zakończy bo gdy i będzie 254 i przy następnym obiegu zostanie zwiększone o 2 to z powodu ograniczenia 8 - bitowego taka operacja da znów zero czyli warunek prawdziwy i pętla się nie przerwie) - tylko takie rozwiązanie spowoduje spadek płynności rozjaśniania.


    Autor postu otrzymał pochwałę


    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 21 lis 2017, o 20:38 
    Offline
    Użytkownik

    Dołączył(a): 07 cze 2016
    Posty: 563
    Pomógł: 143

    Kolego xentis, jak teraz na to spoglądam, to muszę przyznać Ci rację. Przyznaję, że z pośpiechu nie przeanalizowałem dokładnie kodu (mea culpa) ;)

    Nie zmienia to jednak faktu, że timer nie jest skonfigurowany zgodnie z założeniami podanymi w komentarzach, choć faktycznie raczej nie będzie to miało wpływu na szybkość zmian jasności diod.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 21 lis 2017, o 21:59 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 23 paź 2014
    Posty: 1035
    Lokalizacja: Trójmiasto
    Pomógł: 190

    Hehe ja z kolei wogule nie zagłębiałem się w konfigurację timera bo autor pisał że mu to działa więc z analizie poddałem meritum problemu ;)



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 22 lis 2017, o 11:26 
    Offline
    Użytkownik

    Dołączył(a): 07 cze 2016
    Posty: 563
    Pomógł: 143

    Wprawdzie zbyt pobieżnie przeanalizowałem kod i konfiguracja timera nie ma wpływu na szybkość zapalania (zmiany jasności) diod, jednak ogólnie dla działania programu nie jest to całkiem bez znaczenia. Konfiguracja timera będzie miała wpływ na częstotliwość generowania przerwań i pośrednio na częstotliwość PWM. Jeśli częstotliwość ta będzie zbyt mała, może być widoczne migotanie diod. Jeśli będzie zbyt duża, mikrokontroler może nie nadążać z obsługą pozostałej części programu. W tej chwili nie wiadomo, jaka właściwie ta częstotliwość jest, a to, że w tej chwili działa, nie musi oznaczać, że będzie działać po rozbudowaniu programu, kiedy dojdzie obsługa UART, parsowanie i nie wiadomo co jeszcze. Dobrze byłoby więc mieć ten timer pod kontrolą.

    Trzeba pamiętać, że przy programowym PWM o częstotliwości 100Hz i rozdzielczości 256 dla F_CPU=16MHz przerwania muszą występować co 625 taktów zegara, z czego sama procedura obsługi tego przerwania w tym konkretnym przypadku zajmie ok. 100 taktów, czyli ponad 15% czasu procesora. Czy to dużo czy mało to zależy od stopnia rozbudowania programu, prędkości transmisji UART, optymalności kodu, ogólnej konstrukcji programu itp.

    Inna sprawa, jaka mi się rzuciła w oczy, to używanie funkcji delay() w programie, który korzysta z przerwań. Czas obsługi przerwań jest doliczany do czasów opóźnień generowanych przez funkcje delay(). Procedury obsługi przerwań nie zawsze trwają tyle samo czasu (bo nie zawsze te same warunki są spełnione lub nie), nie zawsze występują w równych odstępach czasu, więc czasy opóźnień mogą być niedokładne i niestabilne. Tutaj może te opóźnienia nie muszą być jakoś szczególnie dokładne i być może efekty niedokładnych i nierównych opóźnień nie są jakoś szczególnie widoczne, ale nie wiadomo co będzie przy dalszej rozbudowie programu, szczególnie kiedy dojdzie obsługa przerwań od UART, która występuje w przypadkowych momentach, a nie tak jak w przypadku timera regularnie.

    Osobiście zamiast użyć funkcji led() w pętli głównej programu zrobiłbym to na przerwaniach, ale ja taki jestem czasami zbyt drobiazgowy i się czepiam ;) Jeśli tam będzie tylko transmisja UART i obsługa prostej klawiatury, to pewnie będzie działać tak jak jest. Dlatego już się nie będę tutaj wymądrzał. Życzę powodzenia :)


    Autor postu otrzymał pochwałę


    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 22 lis 2017, o 19:18 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 31 sty 2013
    Posty: 435
    Lokalizacja: Rybnik
    Pomógł: 6

    Witam Was,

    Oczywiście macie rację, w kodzie który podałem, źle był skonfigurowany Timer, a to dlatego, że próbowałem wpisywać różne wartości żeby sprawdzić reakcje. Ostatecznie Timer jest ustawiony na preskaler 1 i do rejestru OCRA wpisuje wartość 1300 korzystając z trybu CTC i taktowania procesora 20MHz.

    Zdecydowałem się na zmianę wartości w funkcji _delay

    Stosując taki zapis:

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    do zmiennej "szybkość" która jest tyupu uint8_t wpisywana jest wartość, która nadlatuje z Uart'a. Natomiast funkcja delay_ms wygląda następująco

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Może nie jest to zbyt eleganckie rozwiązanie.. które blokuje pętle główną, ale w moim przypadku sprawdza się i zdaje egzamin. Dziękuję za zainteresowanie i pomoc :)

    Pozdrawiam
    Miłego wieczoru



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    Wyświetl posty nie starsze niż:  Sortuj wg  
    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 7 ] 

    Strefa czasowa: UTC + 1


    Kto przegląda forum

    Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 5 gości


    Nie możesz rozpoczynać nowych wątków
    Nie możesz odpowiadać w wątkach
    Nie możesz edytować swoich postów
    Nie możesz usuwać swoich postów
    Nie możesz dodawać załączników

    Szukaj:
    Skocz do:  
    Sitemap
    Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
    phpBB SEO