logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATmega16] Jak zaimplementować programowe PWM dla matrycy LED 8x8 na ATmega16?

radoslav006 07 Sie 2012 11:01 6627 27
  • #1 11183462
    radoslav006
    Poziom 12  
    Poprawiłem tytuł na bardziej oddający problem i zgodny z regulaminem p. 3.1.15.
    LordBlick

    Witam,
    Chciałbym zaprojektować matrycę led 8x8 w której losowe (pseudolosowe) ledy przyciemniały się i rozjaśniały, nawet kilkanaście jednocześnie i żeby wszystkie równo nie przygasały, tylko to przemieszać trochę; tzn. jedna się rozjaśnia, druga się przyciemnia, no w różnych fazach, żeby były.
    Przeglądałem forum i rozumiem, że muszę zastosować multipleksowanie, najprościej chyba ledy do jednego portu, do drugiego portu 8 tranzystorów i z multipleksowaniem będzie ok. Tylko zostaje kwestia kwestia tego pwm-a. No i właśnie tu mam problem, sprzętowe pwm to umiem obsłużyć. Tylko tu będzie potrzeba aż 8 kanałów pwm. Z przeglądania forum wynika, że jakimś rozwiązaniem jest programowe pwm, tylko nie mam pomysłu jak to napisać :/ (piszę w C). Poza tym już samo multipleksowanie wprowadza pewne mruganie, więc powinno się wziąć na to chyba poprawkę przy "mruganiu" pwm-em. Czytałem, że po prostu przy takim zasilaniu ledów spada ich jasność, można zasilać mocniejszymi impulsami, tylko właśnie jakimi, żeby zapewnić długą żywotność tak zasilanego led-a?
    Czyli ogólnie rzecz biorąc gubię się już w tym wszystkim :| Szukam jakiś konkretniejszych wskazówek, pomocy, myślę, że może ktoś już wykonywał podobne układy, raczej to nie jest nic odkrywczego.
    PS. Zastanawiałem się też na uC z 8 kanałami PWM, ale w obudowie DIP nic takiego nie mogę znaleźć, a innych to ja się boję lutować. No, a tak to wystarczyłby chyba dowolny procek z dwoma portami, myślę o ATmega8, bo mam akurat na stanie.
  • #2 11183530
    Konto nie istnieje
    Konto nie istnieje  
  • #3 11185139
    radoslav006
    Poziom 12  
    Dzięki za info, ale ja tylko pod AVR się bawię. PIC nie ogarniam niestety :/ Ciężko się przestawić?
  • #5 11186731
    dondu
    Moderator na urlopie...
    radoslav006 napisał:
    PIC nie ogarniam niestety :/ Ciężko się przestawić?

    Mnie trudno było przebrnąć przez pierwszy datasheet z powodu przyzwyczajenia do Atmeli. Także nieco inna filozofia timerów, itp. Ale po dwóch tygodniach zabawy kłopoty zniknęły :)
  • #6 11187783
    radoslav006
    Poziom 12  
    @dar.El
    Bardzo zaciekawiło mnie takie coś, jednak te "datasheety" jakieś ubogie są :| Albo ja nie ogarniam (może bardziej prawdopodobne). Nie ma jakieś obszerniejszego opisu tych sterowników?
  • #7 11187849
    Cezary_
    Poziom 18  
    radoslav006 napisał:
    Witam,
    Chciałbym zaprojektować matrycę led 8x8 w której losowe (pseudolosowe) ledy przyciemniały się i rozjaśniały, nawet kilkanaście jednocześnie i żeby wszystkie równo nie przygasały, tylko to przemieszać trochę; tzn. jedna się rozjaśnia, druga się przyciemnia, no w różnych fazach, żeby były.


    Sterowanie PWM multipleksowanej matrycy zdaje się być niebanalnym problemem. Przede wszystkim regulacja współczynnika wypełnienia dla pojedynczej LED może w takim układzie zawierać się tylko w granicach 0..1/8. Jeśli jasność miałaby być regulowana przez PWM w czasie, gdy wybrana jest jakaś kolumna matrycy, to częstotliwość PWM musiałaby być znacznie wyższa niż częstotliwość multipleksu dla uniknięcia możliwych interferencji i niezamierzonych migotań. Inne możliwe rozwiązanie, to regulacja czasu włączenia LED podczas cyklu świecenie - tej 1/8 czasu, wynikającej z multipleksowania. W obu rozwiązaniach potrzeba ośmiu wyjść licznikowych, np z jednostek compare/capture.
    Przy szybkim procesorze można by się pokusić o programowe sterowanie w przerwaniach, mając świadomość, że przy np 32 poziomach jasności. multipleksie 1/8 i częstotliwości multipleksu 100Hz takich przerwań będzie 100x8x32 = 25600 w sekundzie (co 40us przerwanie). Przy cyklu rozkazu 1us rzecz do trudna wykonania, ale w szybszym procesorze czemu nie...
  • #8 11187903
    LordBlick
    VIP Zasłużony dla elektroda
    W rachubę wchodzi jeszcze wykorzystanie zewnętrznej pamięci RAM, w której będzie zakodowane na wyjściach wypełnienie każdej LED - dla 32 poziomów jasności będzie to 8 x 32 bajtów.
  • #9 11188145
    radoslav006
    Poziom 12  
    Cezary_ napisał:
    Przede wszystkim regulacja współczynnika wypełnienia dla pojedynczej LED może w takim układzie zawierać się tylko w granicach 0..1/8.

    Mógłbyś rozwinąć tą myśl?
    Cezary_ napisał:
    Inne możliwe rozwiązanie, to regulacja czasu włączenia LED podczas cyklu świecenie - tej 1/8 czasu, wynikającej z multipleksowania.

    Mhm, czyli tak jakby już samo multipleksowanie jest samo w sobie takim "pwm". A gdyby tak przy bardzo szybkim multipleksie, niektóre diody po prostu nie włączać za każdym razem?
    Cezary_ napisał:
    Przy cyklu rozkazu 1us rzecz do trudna wykonania, ale w szybszym procesorze czemu nie...

    Hmm, no właśnie jak policzyć ile na danym procesorze trwa jeden rozkaz? No do atmegi8 można chyba max 16MHz dołączyć.
  • #10 11195613
    Cezary_
    Poziom 18  
    radoslav006 napisał:
    Cezary_ napisał:
    Przede wszystkim regulacja współczynnika wypełnienia dla pojedynczej LED może w takim układzie zawierać się tylko w granicach 0..1/8.

    Mógłbyś rozwinąć tą myśl?

    To wynika z faktu, że każda LED może świecić najwyżej 1/8 czasu - bo przecież sterowanie jest multipleksowe.

    radoslav006 napisał:
    Mhm, czyli tak jakby już samo multipleksowanie jest samo w sobie takim "pwm". A gdyby tak przy bardzo szybkim multipleksie, niektóre diody po prostu nie włączać za każdym razem?

    Można tak to zrobić, ale wtedy częstotliwość multipleskowania mysi być duża. Bo jeśli włączysz diodę co np 32 cykl multipleksowania 1/8, to aby nie było widać jej migotania (zakładając minimalną częstotliwość świecenia np 100Hz), samo multipleksowanie musi się odbywać z częstotliwością 100Hz * 8 * 32, czyli znowu 25600 cykli/sekundę.

    radoslav006 napisał:
    Hmm, no właśnie jak policzyć ile na danym procesorze trwa jeden rozkaz? No do atmegi8 można chyba max 16MHz dołączyć.

    Tę informację znajdziesz w dokumentacji procesora.
  • #11 11200306
    radoslav006
    Poziom 12  
    @ Dzięki Cezary_ za cenne uwagi.
    Cezary_ napisał:
    Można tak to zrobić, ale wtedy częstotliwość multipleskowania mysi być duża.

    Program oprócz sterowania diodami nie ma żadnego innego zajęcia, więc myślę, że procesor dałby radę jakieś duże częstotliwości multipleku osiągnąć, trzeba by było dokładnie policzyć. Jeżeli całość byłaby na 8 tranzystorach to, czy przełączanie ich powoduje jakieś znaczne opóźnienia przy wysokich częstotliwościach? Jeśli pytanie jest głupie to przepraszam, ale tak od strony fizycznej to nie ogarniam za bardzo tych tranzystorów.

    Mam jeszcze takie pytanie, jeśli mam diodę (zieloną) o takiej specyfikacji podanej na stronie sklepu (brak datasheet):
    If : 25mA
    Vf : 2.3-2.5V
    To jak mocne mogę podać impulsy? Jakiej długości to mogą być impulsy? Przykładowo (zostawiając pwm w spokoju na razie) jak mogę osiągnąć pełną jasność przy multipleksowaniu tych diód 8x8?
  • #12 11296803
    radoslav006
    Poziom 12  
    Witam,
    odświeżam temat, piszę dopiero teraz, gdyż ze względu na brak czasu trochę mi zajęło opracowanie mojego kompletnego schematu i programu, w międzyczasie musiałem się też trochę podszkolić i poczytać o niektórych rzeczach. Jest to mój pierwszy samodzielny schemat, więc proszę też o wyrozumiałość, mogą występować typowo "szkolne" błędy ;P Dlatego proszę o sprawdzenie zarówno schematu jak i programu.

    Spróbuję teraz wyjaśnić co i jak mniej więcej przemyślałem.
    uC ma obsługiwać matrycę ledów (8x8) i wyświetlać efekty (przygaszanie i rozświetlanie losowo wybranych diod). Cała matryca zrobiona na tranzystorach ponieważ, żeby w multipleksie dawać pełną jasność chcę dawać impulsy rzędu nawet 160mA lub trochę mniej dla dobra diód (diody są na 20mA, ale dla 8 wierszy świecenie jest tylko przez 1/8 czasu, więc dla pełnej jasności 8*20mA = 160mA). Dla diod dołączony potencjometr montażowy, bo nie wiem, czy od razu wlutuję całe 8 wierszy. Potrzebuję też programowy PWM dla 8 diod, który zrealizowałem przez bardzo szybki multipleks i nie zapalanie wszystkich diód w wierszu za każdym razem; przerwanie od timera ustawione co 928 cykli + czas obsługi przerwania, czyli w sumie przerwanie wyzwalane co ok. 1000 cykli zegara co daje multipleks z częstotliwością ok. 16kHz. Rozdzielczość PWM zaplanowana na 100, więc PWM odbywa się z częstotliwością 160Hz co w zupełności wystarczy dla ludzkiego oka. No mam nadzieję, że jasno to napisałem, po prostu przy zmienianiu wierszy jakąś diodę zapalam przez 60 zmian, a później przy 40 przejściach przez ten wiersz pozostanie ona zgaszona. Wartości pwm z korekcją dla oka ludzkiego podzielone na 25 stopni zapisane są w tablicy pwm_index. W dwuwymiarowej tablicy pwm_led zapisany aktualny index wartości pwm dla każdej diody (z tablicy pwm_index) oraz informacja, czy należy to pwm zmniejszać (przygaszanie), czy zwiększać (rozjaśnianie), czy ma dioda pozostać włączona. Całe kombinacje z PWM zrobione są w main() w na dwóch pętlach for (w pętli głównej while(1)). Sterowanie szybkością efektu odbywa się za pomocą enkodera stykowego, od którego otrzymuję przerwanie na int0. Drgania styków rozwiązane sprzętowo, żeby odciążyć mikrokontroler. To chyba tyle wyjaśnień, jeżeli potrzeba mogę coś wyjaśnić jeszcze naturalnie, żeby ułatwić przejrzenie kodu / schematu.

    Mam też kilka problemów o które chciałbym od razu zapytać:
    1. Nie rozumiem przyczyny błedu kompilacji przy deklaracji "volatile PWM_struct pwm_led[MAX_LINE][8];"
    error: expected '=', ',', ';', 'asm' or '__attribute__' before 'pwm_led'.
    2. Mam wątpliwości co do tych tranzystorów. Nie wiem, czy takie mogę zastosować, może powinienem jakieś inne, albo są tańsze zamienniki. I czy mogę bezpośrednio je pod uC podłączać, czy potrzeba jakieś oporniczki do tego.

    Do postu dołączam plik schematu w Eagle'u oraz kod w C.

    Z góry dziękuję za konstruktywne uwagi i udzieloną pomoc,
    Pozdrawiam.
  • #13 11296877
    dondu
    Moderator na urlopie...
    Ładnie opisane :)

    Na razie uwagi przede wszystkim do schematu:
    1. Wrzucaj pliki w postaci graficznej - nie każdy ma pod ręką Eagle.
    2. Kod wklejaj w znacznikach SYNTAX, a nie w pliku.
    3. Kondensatory przy kwarcach są złej wartości - powinny być około 16-22pF - sprawdź w datasheet.
    4. Daj dwa kondensatory osobno na AVcc i osobno na Vcc: http://mikrokontrolery.blogspot.com/2011/04/zasilanie-mikrokontrolera.html
    5. Tranzystory T9-T16 powinny być PNP, a nie NPN.
    6. Jakieś rezystory na bazach tranzystorów, by się przydały.

    I teraz najważniejsze. Skoro chcesz puszczać przez pojedynczy LED 160mA (mam nadzieję, że sprawdziłeś ich datasheet) i nie stosujesz osobnych rezystorów dla każdej kolumny, to masz problemy, nad którymi powinieneś pomyśleć głębiej:
    - gdy potencjometr będzie miał rezystancję różną od zera, to diody będą świecić mocniej lub słabiej zależnie ile ich jednocześnie zapalisz.
    - gdy potencjometr będzie miał wartość zero:
    -- gdy zapalisz tylko jedną diodę cały prąd poleci przez nią - wytrzyma to?
    -- jaki będzie spadek napięcia na zasilaniu gdy zapalisz 8 diod po 160mA każda, i czy nie zakłóci to pracy mikrokontrolera? Tutaj także dodatkowe pytanie: Czy ten regulator napięcia da Ci tak duży prąd?



    Czy zrozumiale to opisałem?
  • #14 11297912
    radoslav006
    Poziom 12  
    Dzięki za uwagi odnośnie udostępniania plików.
    Przy kwarcu rzeczywiście złe wartości, przez pomyłkę.
    Filtrowanie Vcc i AVcc poprawiłem.
    Punkt 5. - nie rozumiem do końca; czemu tak jest źle?
    Punkt 6. Właśnie tak podejrzewałem. Tylko dokładniej to dlaczego by się przydały i jak obliczyć wartości tych rezystorów?

    Co do samych diod:
    Nie zamierzam zapalać więcej niż jednej kolumny na raz. Czyli nie będzie szeregowego podłączenia diod, wszystkie połączone równolegle.
    Cytat:
    gdy zapalisz tylko jedną diodę cały prąd poleci przez nią - wytrzyma to?

    Tego problemu rzeczywiście nie zauważyłem... Hmm, po prostu chciałem uciec przed stosowaniem 8 potencjometrów. Da się to optymalnie rozwiązać? Bo nie chciałbym się zmuszać do określania liczby kolumn z góry, bo nie wiem do końca ile mi będzie tak naprawdę potrzebne.
    Cytat:
    jaki będzie spadek napięcia na zasilaniu gdy zapalisz 8 diod po 160mA każda, i czy nie zakłóci to pracy mikrokontrolera? Tutaj także dodatkowe pytanie: Czy ten regulator napięcia da Ci tak duży prąd?

    Czy da prąd to liczyłem 8*160mA = 1.28A (same diody), a stabilizator jest na 1.5A, zresztą może dla bezpieczeństwa puszczę raczej 140mA - 150mA. Do DataSheet diod niestety nie mam dostępu, ale zapytam sprzedawcy.
    Niestety nie umiem stwierdzić jaki będzie spadek napięcia na zasilaniu i jak to wpłynie na mikrokontroler. Będzie potrzebny jakiś większy kondensator? Powiem tylko, że układ planowałem zasilać z USB komputera, czytałem, że USB 2.0 może dać do 1.5A, więc powinno pociągnąć mój układ.

    Piszesz zrozumiale, dzięki za odpowiedź ;)
  • #15 11310688
    radoslav006
    Poziom 12  
    Odświeżam temat, gdyż problem jest dla mnie nadal otwarty.
    Dodaję poprawiony schemat (tranzystory, kondensatory, GND przy USB, dodatkowe rezystory przy matrycy led) w wersji graficznej i kod.
    Zdecydowałem się na zastosowanie stałych rezystorów (R4-R11) w każdym wierszu dla wyeliminowania wady jaką opisał dondu.
    Schemat:
    [ATmega16] Jak zaimplementować programowe PWM dla matrycy LED 8x8 na ATmega16?
    Kod programu:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Z góry dzięki za pomoc i pozdrawiam.
  • Pomocny post
    #17 11312856
    Cezary_
    Poziom 18  
    Tak jak napisał dondu - należy dołączyć rezystory pomiędzy bazami tranzystorów i wyjściami procesora. Brak tych rezystorów spowoduje przepływ dużego prądu, bliskiego prądowi zwarcia wyjścia. Może być przekroczona dopuszczalna moc strat w układzie scalonym, jego przegrzanie i zniszczenie.
    Rezystory ograniczające prąd LED umieściłeś od strony anod, zatem by uniknąć różnych prądów w LED i różnych ich jasności, powinieneś matrycą tak sterować, by linie od strony katod były po kolei dołączane do masy, zaś od strony anod należy wybierać które LED mają świecić przy wybraniu danej linii, np: jeśli mają świecić LED4-1, LED7-1 i LED2-2, to przy włączonym T1 muszą być włączone T11 i T14, przy włączonym T2 musi być włączony T9. Piszę o tym, bo jestem przyzwyczajony do odwrotnego układu matrycy (linie anod wspólne), ale faktycznie wybór układu jest tu obojętny.
    Na schemacie masz jeszcze chyba odwrotnie ustawiony IC2 (wejście zamienione z wyjściem), no i ważna jest uwaga dondu o spadku napięcia w stabilizatorze.
    Nie wiem jak duża jasność świecenia LED jest Ci potrzebna, ale mam wrażenie, że wydajne, bardzo jasne LED możesz zasilać wiele mniejszym prądem, dla uzyskania efektu. Uważaj też z prądem impulsowym, bo w kartach katalogowych producentów, ten prąd jest najwyżej 3 razy większy od prądu ciągłego (przy wypełnieniu 1/10). Dla rezystorów ograniczających 20 omów prąd może osiągać wartość chwilową ponad 100mA, czyli LED, mające prąd maksymalny 20mA będą przeciążone.
    Kodu programu nie analizowałem, na pierwszy rzut oka wydaje mi się, że zbyt skomplikowane obliczenia robisz w obsłudze przerwania. Raczej należy w przerwaniu ograniczyć się do odczytania poprzez wskaźnik kolejnej komórki tablicy, sterującej matrycą, przesunięciem linii sterowanej na kolejny bit i wysłaniem tych wartości do portu. Skomplikowane obliczenia przenieś do tej części programu, która zajmuje się przygotowywaniem danych do wyświetlania. Przerwanie wykonywane jest często, więc należy dążyć do skrócenia czasu jego wykonania, wpisywanie danych jest robione znacznie rzadziej, więc można jego czas wysłużyć.
  • #18 11313619
    radoslav006
    Poziom 12  
    Ok, dzięki wam za odpowiedzi i sugestie :)
    Czyli do zastanowienia pozostaje mi kwestia prądu diod (skoro Cezary_ tak sugerujesz to rzeczywiście zmniejszę sporo ten prąd i tak w sumie w górnych granicach zasilania diody oko nie widzi takiej dużej różnicy). To moje przerwanie jeszcze też przemyślę, chociaż nie przeszkadza mi to za bardzo w pętli głównej programu, że przerwanie zajmuje trochę czasu.
    No i to nieszczęsne zasilanie. Czytam dondu Twój blog, tylko po prostu widziałem schemat na którym było USB + 7805, sądziłem, że to jakoś zadziała. Na Twoim blogu piszesz też, że są stabilizatory o bardzo małych wartościach Dropout Voltage, tylko nie mogę znaleźć na allegro ani MCP1727, ani innego stabilizatora ldo 5V/1.5A. Jakaś podpowiedź? Bo wolałbym naprawdę nie rezygnować z zasilania usb.
    Czyli już powoli mogę się brać za projektowanie PCB :)
  • #20 11314405
    dondu
    Moderator na urlopie...
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Zmienne opóźnienia: http://mikrokontrolery.blogspot.com/2011/04/gcc-avr-funkcje-opoznienia-delay.html

    radoslav006 napisał:
    To moje przerwanie jeszcze też przemyślę, chociaż nie przeszkadza mi to za bardzo w pętli głównej programu, że przerwanie zajmuje trochę czasu.

    ISR_NOBLOCK - w jakim celu?


    radoslav006 napisał:
    No i to nieszczęsne zasilanie. Czytam dondu Twój blog, tylko po prostu widziałem schemat na którym było USB + 7805, sądziłem, że to jakoś zadziała.

    Możesz wskazać gdzie konkretnie?


    radoslav006 napisał:
    Na Twoim blogu piszesz też, że są stabilizatory o bardzo małych wartościach Dropout Voltage, tylko nie mogę znaleźć na allegro ani MCP1727, ani innego stabilizatora ldo 5V/1.5A. Jakaś podpowiedź?

    Do szukania warto wykorzystywać wyszukiwarkę Farnell: http://pl.farnell.com/regulatory-napiecia-ldo
  • #21 11316781
    radoslav006
    Poziom 12  
    Cezary_ napisał:
    Przy zasilaniu tylko z USB stabilizator jest zbędny, bo USB dostarcza stabilizowanego napięcia +5V.

    Aha, to super w ogóle. W takim razie wywalę go w ogóle. A jakieś kondensatory dodać mimo wszystko?
    dondu napisał:

    Rozumiem, nie czytałem o tym wcześniej.
    dondu napisał:
    ISR_NOBLOCK - w jakim celu?

    A tak dałem, bo pomyślałem, żeby przerwanie od INT0 na pewno się wykonało. No zresztą krótkie (INT0) jest.
    dondu napisał:
    Możesz wskazać gdzie konkretnie?

    Tzn, żeby nie było porozumień, bo trochę niejednoznacznie to napisałem - nie było to oczywiście na Twoim blogu. Nie pamiętam gdzie. Albo coś już sam przekręciłem, nie jestem już pewien skoro to taki szkolny błąd.

    Mam jeszcze takie pytanie odnośnie tej linijki w kodzie:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Czemu wyrzuca mi w tym miejscu błąd kompilacji? Nie potrafię zrozumieć tego.
  • #22 11318007
    dondu
    Moderator na urlopie...
    radoslav006 napisał:
    Aha, to super w ogóle. W takim razie wywalę go w ogóle. A jakieś kondensatory dodać mimo wszystko?

    Tak, 100nF do każdej nóżki zasilającej każdego układu scalonego i na wejściu z USB jakiś elektrolit np. 100µF.
    Możesz także dać dodatkowo z 10µF w pobliżu mikrokontrolera (zależnie jak rozwiążesz ścieżki na PCB).
    Może wtedy warto będzie dodać także w pobliży matrycy jakiś 470µF.


    radoslav006 napisał:
    dondu napisał:
    ISR_NOBLOCK - w jakim celu?

    A tak dałem, bo pomyślałem, żeby przerwanie od INT0 na pewno się wykonało. No zresztą krótkie (INT0) jest.

    INT0 i tak się wykona, bo flaga raz zapalona musi zostać obsłużona lub zgaszona programowo, dlatego wyrzuć to ISR_NOBLOCK.

    radoslav006 napisał:
    dondu napisał:
    Możesz wskazać gdzie konkretnie?

    Tzn, żeby nie było porozumień, bo trochę niejednoznacznie to napisałem - nie było to oczywiście na Twoim blogu. Nie pamiętam gdzie. Albo coś już sam przekręciłem, nie jestem już pewien skoro to taki szkolny błąd.

    OK, wyjaśnione.
  • #23 11318735
    radoslav006
    Poziom 12  
    dondu napisał:
    Tak, 100nF do każdej nóżki zasilającej każdego układu scalonego i na wejściu z USB jakiś elektrolit np. 100µF.
    Możesz także dać dodatkowo z 10µF w pobliżu mikrokontrolera (zależnie jak rozwiążesz ścieżki na PCB).
    Może wtedy warto będzie dodać także w pobliży matrycy jakiś 470µF.

    No to sprawa zasilania wyjaśniona (przynajmniej na razie :P).

    W ogóle myślę, żeby zamiast enkodera zastosować przełącznik 6 pozycyjny ( w Eagle'u jest to "Rotary Switches Type 01", mam przecież sporo pinów wolnych, a i elementów dodatkowych nie trzeba by było, no i obyło by się też bez przerwania wtedy w ogóle. Tak od razu enkoder na schemat wrzuciłem, bo chciałem go gdzieś zastosować już od jakiegoś czasu. No, ale to się jeszcze zobaczy.

    Ale nadal nie wiem co zrobić z tym błędem kompilacji :/
  • #24 11318808
    dondu
    Moderator na urlopie...
    radoslav006 napisał:
    W ogóle myślę, żeby zamiast enkodera zastosować przełącznik 6 pozycyjny ( w Eagle'u jest to "Rotary Switches Type 01", mam przecież sporo pinów wolnych, a i elementów dodatkowych nie trzeba by było, no i obyło by się też bez przerwania wtedy w ogóle. Tak od razu enkoder na schemat wrzuciłem, bo chciałem go gdzieś zastosować już od jakiegoś czasu. No, ale to się jeszcze zobaczy.

    Ale możesz, to potraktować jak naukę obsługi enkodera - może warto jednak nie rezygnować?


    radoslav006 napisał:
    Ale nadal nie wiem co zrobić z tym błędem kompilacji :/

    Nie podałeś jaki, to i odpowiedzi nie ma :)
    + dodatkowo załącz cały program po poprawkach.
  • #25 11319929
    radoslav006
    Poziom 12  
    dondu napisał:
    Ale możesz, to potraktować jak naukę obsługi enkodera - może warto jednak nie rezygnować?

    No też tak chyba do tego podejdę. To była taka luźna uwaga z mojej strony powiedzmy :P
    dondu napisał:
    Nie podałeś jaki, to i odpowiedzi nie ma

    Post nr 12, 21 i 23 :P
    dondu napisał:
    + dodatkowo załącz cały program po poprawkach.

    Oto poprawiony kod:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Przy okazji zapytam jeszcze dla pewności, czy bez problemu mogę zamienić w moim układzie BC327 na BC556A (podawane impulsy zmniejszę do rzędu 70-80 mA) oraz BC338 na BC337-16. Wydaje mi się, że tak, tylko po prostu to mój pierwszy "samodzielny" (dziękuję wszystkim za pomoc) układ i wolę zapytać niż później dochodzić do tego co jest nie tak :P
  • #26 11328708
    dondu
    Moderator na urlopie...
    To problem podstawowy leży tutaj:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    dodatkowo:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Ale teraz wyskoczy Ci sporo warningów dot typów zmiennych, które używasz jako indeksy tablic. Ponieważ line oraz index są typu char, a indeksy w tablicach powinny być typu int.

    Możesz to rozwiązać na dwa sposoby:


    Sposób 1.

    zmieniając typy line oraz index na int

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    otrzymasz:

    Program: 1976 bytes (12.1% Full)
    (.text + .data + .bootloader)

    Data: 225 bytes (22.0% Full)
    (.data + .bss + .noinit)


    Build succeeded with 0 Warnings...




    Sposób 2.
    zostawiając zmienne line oraz index jako char
    ale wymuszając jawnym rzutowaniem konwersję w każdej linii tego wymagającej


    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    a wtedy otrzymasz:

    Program: 1776 bytes (10.8% Full)
    (.text + .data + .bootloader)

    Data: 160 bytes (15.6% Full)
    (.data + .bss + .noinit)


    Build succeeded with 0 Warnings...



    Sam wybierz, czy wolisz czytelniejszy kod bez rzutowania, czy zyski w pamięci programu i danych :)
  • #27 11330818
    radoslav006
    Poziom 12  
    Aaaaaj, ale ze mnie idiota.... Po prostu tam gdzie mogę zawsze robię chary (ze względu na pamięć) i nie wziąłem pod uwagę, ze char nie może być indeksem tablicy.

    Zrobię jeszcze kilka kosmetycznych zmian i udostępnię później gotowy schemat i kod, może komuś się przyda. No i zostanie jeszcze kwestia PCB.

    Dzięki za pomoc ;)
  • #28 11339392
    radoslav006
    Poziom 12  
    Ostatecznie mój schemat wygląda tak:
    [ATmega16] Jak zaimplementować programowe PWM dla matrycy LED 8x8 na ATmega16?
    Uwagi: Zdecydowałem się na 6 kolumn. Prąd dla diody w impulsie ~70mA. Element Encoder_E16 robiony samodzielnie, gdyż brakowało w bibliotekach takiego o odpowiadających mi pinach. uC planuję trochę przetaktować z maksymalnych 16MHz do 20MHz. To chyba wszystko.

    Kod w C:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Uwagi: 10 poziomów szybkości efektu.. Rozdzielczość pwm zmniejszona do 50. Progów korekcyjnych pwm (przystosowanych dla ludzkiego oka) dla diody: 20 (jeżeli rozjaśnianie/przyciemnianie nie będzie płynne trzeba będzie zwiększyć ewentualnie). Wszelkie czasy myślę, że będą wymagały drobnej, eksperymentalnej korekcji, tym bardziej, ze zmieniam bardzo szybko kolumny i nie wziąłem pod uwagę np. czasu reakcji diody, nie wiem, czy diodki będą wyrabiać :P

    Na razie to tyle. PCB prawie skończone, zamieszczę wkrótce w osobnym temacie do sprawdzenia. Tylko nie mogę się zdecydować na razie, czy wszystko na jednej płytce zrobić, czy matrycę z diodami dać na osobnej płytce + goldpiny + kable łączące płytki. Najprawdopodobniej zamieszczę dwie wersje w wyżej wspomnianym temacie, link zamieszczę jeszcze tutaj wkrótce. Temat

    Jeszcze raz chciałbym wszystkim podziękować za pomoc :) Pozdrawiam.
REKLAMA