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

bascom - sterowanie led pwm

BIGJack 06 Lis 2012 10:35 4236 18
  • #1 06 Lis 2012 10:35
    BIGJack
    Poziom 16  

    Mam problem ze sterowaniem PWM w moim projekcie.
    Załączam fragment kodu który ma powoli rozjaśniać i ściemniac żarówkę
    led jednak rozjasnienie działa zgodnie z założeniem czyli powoli i płynnie a gaszenie w mgnieniu oka tzn. bardzo szybko.
    Jeżeli te procedurki połącze w jedna to prawidłowo rozjasnia i gasi?
    Jaka jest przyczyna?

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod
    [/code]

    0 18
  • Deimic Smart Home
  • #2 06 Lis 2012 13:16
    Mundi1970
    Poziom 24  

    Podprogramy wywołuje się instrukcją Gosub, a nie Goto.

    0
  • #3 06 Lis 2012 15:14
    BIGJack
    Poziom 16  

    Kolego nowynom Twój poprawiony kod również nie zawiera etykiet :) aczkolwiek wygląda można powiedzieć wzorowo :)

    Cytat:
    A tak nawiasem, czy nie łaska sprawdzić na symulatorze ?

    Napisałem tego posta w akcie desperacji po lekturze helpa, innych postów i
    wygooglowaniu wszystkiego co możliwe. Mam podpięty układ pod kompa i przelewam moje wypociny na bieżąco do procka.

    Cytat:
    O toto Kolega nie wie, co to są ETYKIETY

    Oczywiście że wiem aczkolwiek nie jestem biegły w bascomie i robiąc mój mały bałagan w prostym kodzie etykiety mi tylko przeszkadzają. Oczywiście jak wstawiam fragment kodu na elektrodę to byłyby wskazane aczkolwiek przy tych kilku linijkach chyba się obędziemy bez nich :)

    Jest to fragment kodu celowo zawężony do minimum niezbędnego do analizy moich błędów w pisaniu programu. Celowo zrobiłem nieskończoną pętlę.

    Całość ma sterować iluminacją dekoracyjną i oświetleniem miejsca roboczego w kuchni. Czujnik podczerwieni rozjaśnia w miarę szybko i odlicza czas do wyłączenia jednak jeżeli podczas odliczania wykryje ruch to zeruje czas i odlicza od początku po czym płynnie powoli wygasza światło. Oto kod który napisałem do tej pory.
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    ps pomijając fakt że zastosowałem goto zamiast gosub dlaczego jedna procedura jest wykonywana według oczekiwań a druga nie?
    kolego nowynom Twój kod działa ładnie w symulatorze ale w moim układzie brak reakcji. hmmm

    0
  • #4 06 Lis 2012 16:23
    30402
    Użytkownik usunął konto  
  • #5 06 Lis 2012 17:09
    BIGJack
    Poziom 16  

    Saabotaz ;

    Cytat:
    1) Robisz "Goto Rozjasnij" i "Goto Sciemnij", a potem próbujesz wrócić Returnem. Wywalasz program.

    Wcześniej przed pętlą do-loop dla sprawdzenia ustawiłem aby dioda migała i faktycznie co rozjaśnienie migała - wniosek, masz rację program się wywalał.

    Cytat:
    2) Czemu ci działa Rozjaśnienie, a Ściemnianie nie? No bo skok do rozjasnienia przez Goto, program rozjaśni jak należy, powrót returnem i wywala się program. Cud że po tym ściemnianie jeszcze ci działa

    Racja.

    Cytat:
    3) Już ci poradzili że problem jest z GOTO, a powinieneś wstawić GOSUB, ty jednak znów wklejasz program z GOTO.

    Nie jestem uparty i zrozumiałem mój błąd, wstawiłem po prostu cały kod a nie tylko jego zmodyfikowany fragment. Oczywiście zmienię goto na gosub.

    nowynom, zwłoka to zadeklarowana pozostałość po wcześniejszym podejściu do tego projektu :-) zastąpiona została zmienną czas. Natomiast co do 15 to miał być czas świecenia w tymczasowy czas świecenia led-a. Pętla zaś miała być spowolniona poleceniem wait 1 . Czy jeżeli nie zależy mi na precyzyjnym odmierzaniu czasu muszę opóźnienie robić na timerze?

    0
  • Deimic Smart Home
  • Pomocny post
    #6 06 Lis 2012 17:18
    1537339
    Użytkownik usunął konto  
  • #7 11 Mar 2013 12:46
    gustawm2
    Poziom 10  

    Witam,

    ostatnimi czasy potrzebowałem wykonać projekcik do sterowania jasnością diody.
    Przeczesałem elektrodę, kawałek polskiego internetu i książkę do Bascoma.

    Układ, który wykonałem działa poprawnie, ale gorzej jest z softem.
    Niestety nie bardzo wiem gdzie szukać rozwiązania problemu.

    Attiny2113 działa na wewnętrznym oscylatorze.
    Oto mój kod.

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Jeżeli w ciało ifa if Pind.0/1 = 0 wpiszę kod
    Code:

    For A = 0 To 250 Step 10
        Pwm1a = A
        Waitms 5
    Next I


    to ten fragment działa poprawnie.
    W zasadzie zależy mi na zmienianiu Pwm1a w granicach 0 - 250 po naciśnięciu jednego lub drugiego przycisku.

    Wiem, że kod można znacznie uprościć, ale na razie to jestem zamotany najważniejszą na tę chwilę funkcją - zmianą pwm.

    Nie wiem czemu po odpaleniu programu działa tylko jedno naciśnięcie guzika w danym kierunku, drugie naciśnięcie nie powoduje wejścia w ifa - zmianę stanu pb0 i pwm.

    Czy problemem jest typ zadeklarowanej zmiennej A?

    0
  • #8 11 Mar 2013 13:17
    30402
    Użytkownik usunął konto  
  • #9 11 Mar 2013 17:04
    gustawm2
    Poziom 10  

    Saabotaz napisał:
    Wszystko działa dobrze, dokładnie tak jak napisałeś :-)

    Syfy w programie:

    1) A jako integer, powinno być jako byte (pwm 8 bit) lub word (16 bit). Tutaj to nie powoduje błędu ale dobrze by było nie używać zmiennych mogących być ujemnymi, ponieważ PWM może mieć wartości tylko 0 lub dodatnie.

    2) Enable Timer 1 - nie jest potrzebne bo nie używasz przerwań, raczej przydałoby się Start Timer 1 ale Bascom automatycznie startuje Timer podczas configu

    3) If A < 250, potem robisz A+10 co daje wartość 260 i przekręcenie się wartości. No bo przecież 8 bit nie może mieć więcej niż 255, a zobacz że ty wpisujesz tam max 260. Popraw na If A < 241 (czemu 241, a nie 240? Bo dając 240 uzyskasz max pwm 240, dając 241 max będzie 250, pomyśl czemu)

    4) If A > 0, potem robisz A-10 co ci daje -10 czyli przekręcenie się wartości w pwm (bo on może być tylko 0 lub dodatni). Zmień na If A > 9 (pomyśl czemu >10 nie zadziała zbyt dobrze)

    5) Pamiętaj że program działa błyskawicznie, w ułamku sekundy od przyciśnięcia przycisku, jego if wykona się z pewnością kilka tysięcy razy na sekundę. Dlatego przed każdym end if wstaw np. waitms 200


    Dzięki za podpowiedź.
    Okazało się, że największym problemem jest pkt 5 - niestety zawodowym programistą uC nie zostanę, wolę skrypczenie w mniej wysublimowanych językach.

    Ad. 3 i 4) Jeżeli chodzi o warunki z A to było to pisane na kolanie i rzeczywiście przekręcały się liczniki, ale w pewnym zakresie nie miało to znaczenia - dzięki za wytknięcie

    Ad. 1 - Rzeczywiście Integer tu lekko nie pasuje, ale w tym przypadku nie ma to większego znaczenia gdyż w programie nie ma innych funkcji, które mogłyby operować na tej zmiennej.

    Przerobiłem fragment książki o Bascomie, a wraz z tym program ciut się zmienił,
    w zasadzie robi prawie to samo co wcześniej.

    Generalnie kod zrobił się czytelniejszy i przy testach z diodą i buzzerem wypadł pomyślnie.
    Teraz pozostaje mi zgłębić (czyt. zrozumieć) do końca temat pwm i poprawić program tak, aby zadziałał w "środowisku produkcyjnym".

    Oto obecny kod:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    0
  • #10 11 Mar 2013 17:19
    30402
    Użytkownik usunął konto  
  • #11 11 Mar 2013 19:45
    emarcus
    Poziom 35  

    Saabotaz napisał:
    Wszystko działa dobrze, dokładnie tak jak napisałeś :-)

    Syfy w programie:

    3) If A < 250, potem robisz A+10 co daje wartość 260 i przekręcenie się wartości. No bo przecież 8 bit nie może mieć więcej niż 255, a zobacz że ty wpisujesz tam max 260. Popraw na If A < 241 (czemu 241, a nie 240? Bo dając 240 uzyskasz max pwm 240, dając 241 max będzie 250, pomyśl czemu)


    Tu akurat w wyjaśnieniu wkradła sie pewna nieścisłośc.
    Po przekroczeniu wartości A>255 lub 260 nie nastąpi "przekręcenie się wartości" [?]
    Zarówno zmienna A przyjmie taką wartośc (integer przyjmie max 32767) jak też rejestr Pwm1a bez problemu taką wartośc zaakceptuje bo jest to rejestr 16 bitowy (OCR1A). Problemem w tym wypadku jest wyjście poza zakres kontroli 'pola' 8-bitowych wartości.
    Co nie zmienia faktu że żródłem problemu jest autor wymiarując pośrednią zmienną A jako integer, co prowadzi do wyraźniejszego konfliktu na drugim końcu regulacji (przy decrementacji wartości Pwm1a).
    Jeżeli pozostawimy zmienną "A as word" wtedy należloby przed wpisem do Pwm1a wstawic ograniczenia;
    od góry(przy incrementacji):
    ............
    if A >= 255 then
    A = 255

    oraz od dołu (przy decremantacji):
    ............
    if A >255 then
    A=0

    e marcus

    0
  • #12 12 Mar 2013 01:09
    gustawm2
    Poziom 10  

    Dzięki wielkie za sugestie.
    Program poprawiłem, wszystko działa tak jak chcę.

    Zabrałem się za kolejną rzecz i utknąłem na timerach i książce do bascoma.

    Generalnie to mam problem z PWM - potrzebuję wygenerować impulsy o zadanej długości w taktowaniu pomiędzy x Hz

    Na razie siedzę i próbuję wymyślić jak to zrobić.

    Dodano po 3 [godziny] 4 [minuty]:

    Poczytałem o PWM i nie wiem czy do końca dobrze rozumiem.

    Zakładając, że poterzbuję wygenerować impuls o długości od 1000us do 2000us z częstotliwością dowolną pomiędzy 50Hz a 400Hz to... tak sobie policzyłem
    Przyjąłem częstotliwość 245Hz
    1000000/8/510 =~ 245Hz
    Dalej:
    1sek = 1000000us
    1000000us/245Hz =~ 4018us na okres, w którym będziemy wypełniać PWM

    Jeżeli okres wynosi 4018us, do wygenerowania są impulsy o długości od 1000us do 2000us:
    DC1 = (1000us/4018us)* 100% = 24,88%
    DC2 = (2000us/4018us)* 100% = 49,77%

    zakładając, że nasz rejestr pwm jest 8 bitowy to 25% z 256 = 64 , a 50% = 128
    więc powinienem tak sterować układem, aby zapisując do rejestru pwm1a poruszać się pomiędzy tymi wartościami.

    Proszę o sprostowanie jeżeli coś pominąłem lub coś pokiełbasiłem :-)

    0
  • #13 12 Mar 2013 22:43
    emarcus
    Poziom 35  

    gustawm2 napisał:


    Zabrałem się za kolejną rzecz i utknąłem na timerach i książce do bascoma.

    Generalnie to mam problem z PWM - potrzebuję wygenerować impulsy o zadanej długości w taktowaniu pomiędzy x Hz


    Zakładając, że poterzbuję wygenerować impuls o długości od 1000us do 2000us z częstotliwością dowolną pomiędzy 50Hz a 400Hz to... tak sobie policzyłem
    Przyjąłem częstotliwość 245Hz
    1000000/8/510 =~ 245Hz
    Dalej:
    1sek = 1000000us
    1000000us/245Hz =~ 4018us na okres, w którym będziemy wypełniać PWM

    Jeżeli okres wynosi 4018us, do wygenerowania są impulsy o długości od 1000us do 2000us:
    DC1 = (1000us/4018us)* 100% = 24,88%
    DC2 = (2000us/4018us)* 100% = 49,77%

    zakładając, że nasz rejestr pwm jest 8 bitowy to 25% z 256 = 64 , a 50% = 128
    więc powinienem tak sterować układem, aby zapisując do rejestru pwm1a poruszać się pomiędzy tymi wartościami.

    Proszę o sprostowanie jeżeli coś pominąłem lub coś pokiełbasiłem :-)


    Nie najlepiej to kombinujesz.
    Jeżeli pracujesz nad Att2313 to temat Timera1i jego trybów pracy a w szczególności PWM najłatwiej poznasz studiując Datasheet rozdział:

    16-bit Timer/Counter1>Modes of Operation
    Po zapopznaniu się (z grubsza) z treścią wszystkich trybów pracy timera, zatrzymaj się na dłużej na tabeli 46 str. 110, w której znajdziesz wszystkie możliwe tryby (Mode) pracy timera1 (od 0 do 15).
    Zauważ, że za każdy tryb pracy odpowiedzialne są ustawienia tylko czterech bitów (wymienione w kolejnych czterech kolummach)_WGM1 3:0 - niefortunnie są one rozrzucone w różnych rejestrach Timera1- do tego dojdziesz później jezeli jeszcze nie połapałeś.
    Popatrz na kolumnę z nagłówkiem "TOP"; jeżeli w tej kolumnie występuje konkretna wartośc (w HEX-notation), - to ten tryb pracy ma już określoną częstotliwośc pracy i wpisy do rejestru pwm1a mogą kontrolowac tylko wypełnienie.
    Jeżeli zakładasz 8-bit PWM to jak doszedłeś do ustalenia częstotliwości pracy 245Hz ?
    Popatrz na tabelę poniżęj;

    bascom - sterowanie led pwm

    Owszem, możesz użyc pwm1a do kontrolo częstotliwości w innych trybach ale wtedy nie masz kontroli nad regulacją wpełnienia, które pozostanie na poziomie 50%.
    Nie znaczy to że nie ma możlowości kontroli obydwóch parametrów; oczywiście jest taka możliwośc ale to wymaga nieco innego rozważenia niż przjąłeś w swoich obliczeniach powyżej.
    Timer1 ma dwa kanały PWM; A i B na których możesz generowac dwa rózne sygnały PWM o tejsamej częstotliwosci określonej przez prescaler a wypełnienie kontrolwane przez pwm1a oraz pwm1b dla odpowiednich kanałów.
    Aby kontrolowac oba parametry musisz zrezygnowac z jednego kanału PWM wtedy masz możliwośc jedną wartością np: pwm1a kontrololwac częstotliwośc a pwm1b kontrollwałby wypełnienie dla jednego tylko sygnału PWM.
    Zatem najpierw musisz zacząc od wybrania trybu pracy timera i pod ten tryb prowadzic dalsze obliczenia dla przyjętej częstotliwości.


    e marcus

    0
  • #14 12 Mar 2013 23:10
    gustawm2
    Poziom 10  

    Hej.

    Dzięki za odpowiedź.
    Będę musiał jeszcze nad tym przysiedzieć bo coś mi się to wszystko rozjeżdża.

    Ustaliłem częstotliwość PWM z następującego wzoru - częstotliwość rezonatora/preskaler/510(w przypadku pwm 8bit)

    Pogubiłem się totalnie w tych timerach i ustawieniach.
    Jutro po pracy wezmę się jeszcze raz za książkę i poczytam - może się coś rozjaśni; później przeczytam datasheeta i mam nadzieję, że się wszystko wyklaruje.

    0
  • #15 13 Mar 2013 11:23
    30402
    Użytkownik usunął konto  
  • #16 13 Mar 2013 12:18
    gustawm2
    Poziom 10  

    Witam,

    ale kiedy właśnie zależy mi na tym, żeby to skumać... wynik na oko uzyskałem taki jak oczekiwałęm, teraz chcę iść dalej.
    Potrzebuję wygenerować impulsy o długości od 1000 do 2000us z zadanym taktowaniem - w zasadzie dowolnym pomiędzy 50-400Hz

    0
  • #17 13 Mar 2013 14:00
    emarcus
    Poziom 35  

    gustawm2 napisał:
    Witam,

    ale kiedy właśnie zależy mi na tym, żeby to skumać... wynik na oko uzyskałem taki jak oczekiwałęm, teraz chcę iść dalej.
    Potrzebuję wygenerować impulsy o długości od 1000 do 2000us z zadanym taktowaniem - w zasadzie dowolnym pomiędzy 50-400Hz


    No to wybierz swoją częstotliwośc z tabeli, ktorą ci podałem i pod ten odpowiedni tryb skonfiguruj timer, a w programie głównym pozostanie ci manipulacja wypełnienia poprzez zmiany wartości pwm1a. Process tej zmiany może byc dokonany na wiele różnych sposobów. Cały program nie powinien zając więcej niż kika linii kodu.

    e marcus

    0
  • #18 13 Mar 2013 15:29
    30402
    Użytkownik usunął konto  
  • #19 13 Mar 2013 16:47
    emarcus
    Poziom 35  

    Saabotaz napisał:
    Jeśli chcesz mieć kontrolę nad długością impulsu PWM i długością całego okresu (np generowanie prostokąta o określonej częstotliwości) to zazwyczaj używa się timera w trybie CTC.
    .


    Eh... Sabot,
    Mącisz mu w głowie okropnie......
    Przecież w CTC nie ma możliwości nad kontrolą obydwóch parametrów; częstotliwości i wypełnienia niezależnie.
    Praktycznie reguluje się tylko wypełnienie (dokładniej czas trwania impulsu), co w konsekwencj staje się wypełnieniem w przypadku generowania fali poprzez 'toggle OCF1A - stanu logicznego wyjścia.
    Oczywiście wypełnienie w tej sytuacj będzie zawsze 50% (konskwencja procesu toggle). Częstotliwośc (okres) takiej 'pseudo PWM' fali będzie funkcją wypełnienia.

    Autor potrzebuje zmieniac wypełnienie przy wybranej i ustalonej częstotliwości czego tryb CTC mu nie daje, więc musi 'sięgnąc' do innych trybów configuracji timera gdzie taka niezależna kontrola jest możliwa.

    e marcus

    0