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.

Ściemniacz 230V na Atmedze328P

16 Maj 2012 08:20 2545 6
  • Poziom 12  
    Witam
    Zrobiłem dwu kanałową płytkę do ściamniacza żarówek na 230V z wykorzystaniem triaka (oczywiśie dwóch, po jednym na kanał). Schemat znalazem na formu, wykorzystywany jest układ detekcji przejścia przez zero, triak jest sterowany przez MOC3021, itd.

    Układ detekcji przejścia przez zero jest podłączony do przerwania INT0, wyzwalanie triaktów do wyjść PD5 i PD6.
    Problem jest następujący, program nie potrafi wysterować wyjściami PD5 i PD6, stan portu D zmiania się natomiast nie zmienia się stan triaka.
    Płytka jest OK (tak mi się wydaję) ponieważ zmieniająć w przerwaniu INT0 obsługę potru zamiast włączać to wyłączam to triak nie pracuje, tzn żarówka nie świeci się.
    Jeżeli w przerwaniu INT0 zamiast wyłączania ustawię włączanie to żarówka świeci się na max, przerwanie od licznika TIMER1_COMPA/B_vect generuje się i zmienia się stan portu ale nie ma to wpływu na triaka.
    Docztytałem że ustawiając bity COMXX w rejestrach timera odłacza się sterowanie portami IO poprzez rejestry PORTX, wtedy wyjściami steruje timer ale w moim przypadku nie ustawiam tych bitów. Licznik TIMER1 pracuje w trybie normalnym. Porty do jakich są podłączone traki to porty PD5 -> OC0B, PD6 -> OC0A ale to są wyjścia TIMER0 którego nie wykorzystuje.
    Walcze z problemem od dwóch dni i nic nie mogę wywalczyć.

    uC pracuje na kwarcu 11059200 Hz, w konfiguacji projektu jest to wpisane.

    Poniej przytaczam część kodu programu odpowiedzialnego za strowanie.

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Zawartość pliku Dimmer_230V.h

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Proszę poprawić treść wiadomości - 3.1.13. Zabronione jest publikowanie wpisów naruszających zasady pisowni języka polskiego, niedbałych i niezrozumiałych.
    [zumek]
  • Pomocny post

    Poziom 28  
    Po wykryciu przejścia przez zero załączasz triak a po upływie pewnego czasu go wyłączasz. Tak to nigdy nie zadziała stabilnie. Steruj w następujący sposób:
    - wykryj przejście przez zero
    - rozpocznij odliczanie opóźnienia
    - po upływie tego czasu wystaw stan wysoki (wystarczy krótki impuls)
    - przy kolejnym przejściu przez zero triak wyłączy się samoczynnie

    Przy okazji:
    - wywal te printf'y z przerwania
    - w przerwaniu ustawiaj stan jakiejś flagi (np zmienna bool)
    - wywal opóźnienie w main
    - w main sprawdzaj flagę i jeśli jest ustawiona to wysyłaj sobie dane gdzie chcesz :) (no i skasuj flagę rzecz jasna)

    Inna uwaga:
    - jeżeli połówkę okresu sinusoidy podzielisz na równe czasowo przedziały to w rezultacie otrzymasz regulację której charakterystyka będzie cosinusem
    Można temu zaradzić.
    Aby uzyskać liniową charakterystykę regulacji przedziały nie mogą być sobie równe. Jest taki fajny wzorek całkowy z którego po przekształceniach wyznacza się dolną granicę całki - jest to czas o jaki należy opóźnić załączenie triaka. Wyniki obliczeń najprościej jest wpisać do tabeli umieszczonej w pamięci programu i do liczników wczytywać gotowe wartości.
    Przypomnij się wieczorem to podeślę Ci odpowiednie wzory i gotowy arkusz w excelu. Mam też dobrze pokomentowany kod w C na mikrokontroler PIC. Są różnice w obsłudze sprzętowej, ale zasada działania algorytmu będzie taka sama dla AVR.

    Jeszcze inna uwaga: kod pisałem dla firmy produkującej sprzęt medyczny. Firma ma ogromnie wyśrubowane wymagania dot. bezpieczeństwa urządzeń. Stąd optotriak nie jest sterowany bezpośrednio stanem portu tylko jest do portu dołączony poprzez kondensator. Na port (na czas trwania żądanego pobudzenia triaka) podawany jest sygnał prostokątny. Dzięki temu w przypadku awarii portu jest całkowita pewność, że triak nie zostanie włączony w niekontrolowany sposób - jak pisałem wcześniej, wyłączy się samoczynnie przy najbliższym przejściu przez zero.

    Powodzenia :)
  • Pomocny post
    Poziom 16  
    Kolego, troszkę źle się do tego przybierasz.
    Po pierwsze od przerwania wyzwolonego detekcją zera uruchamiasz timer. Przerwanie od tego timera dopiero uruchamia triak. W kolejnym przejściu przez zero triak samoczynnie się wyłącza.

    Zobacz mój ściemniacz. Działa w 100% poprawnie:
    https://www.elektroda.pl/rtvforum/viewtopic.ph...rk=topic&sid=098576f31ecd99a54e4f64e2250b6481
  • Poziom 12  
    Dzięki tehaceole za uwagi.
    Zapomniałem w sumie że trika wyzwala się impulsem :)
    Poprawię to.
    Poprawię też żeby triak na początku był wyłaczony.
    TIMER0 jest startowany w przerwaniu INT0, przez "TCNT1=0;"

    Poźnienie i printy zostały po debugu :)

    Kondensator co wspominasz o nim to jes podłączony rozumiem do masy jednym biegunem a drugim do portu ?

    Dodano po 2 [minuty]:

    Dzięki aaadamw
    Przyjże się Twojemu ściemniaczowi.

    Ja startuje timer w przerwaniu, jak pisałem w poście wyżej:

    ISR(INT0_vect)
    {
    TCNT1=0;
    .....

    }

    Generalnie poprawię kod, zobaczymy co wyjdzie, dzięki.

    Dodano po 5 [godziny] 24 [minuty]:

    tehaceole
    Jeżeli chodzi o zmianę jasności świecenie z cosinusoidy na liniową to już przygotowałem sobie dane.
    Zastanawiam się tylko jak takie dane umieścić programie, nie chciałbym żeby
    były one w RAM'ie.
    Czy jest jakiś sposób żeby załadować je do pamięci razem z programem ?

    Pozdrawiam
    mumin_80
  • Pomocny post

    Poziom 28  
    mumin_80 napisał:
    Kondensator co wspominasz o nim to jes podłączony rozumiem do masy jednym biegunem a drugim do portu ?
    NIE NIE NIE ABSOLUTNI NIE! Kondensator wpięty jest szeregowo pomiędzy portem a diodą nadawczą optotriaka. Dlatego na porcie musi być wystawiany sygnał prostokątny a nie stan wysoki lub niski. Ale dzięki temu zyskujesz 100% pewności na wypadek awarii portu.

    mumin_80 napisał:
    Jeżeli chodzi o zmianę jasności świecenie z cosinusoidy na liniową to już przygotowałem sobie dane.
    W załączniku masz program i formuły w Open Office.
    mumin_80 napisał:
    Zastanawiam się tylko jak takie dane umieścić programie, nie chciałbym żeby
    były one w RAM'ie.

    A więc na przykładzie zmiennej typu string, która de facto jest tablicą:
    - definiujesz sobie tablicę z parametrem PROGMEM
    Kod: C
    Zaloguj się, aby zobaczyć kod

    - w programie do odczytu danych umieszczonych w pamięci programu musisz podejść troszkę inaczej niż do operowania na tablicy w RAM:
    na przykładzie funkcji wyświetlającej na LCD
    Kod: C
    Zaloguj się, aby zobaczyć kod

    ciało funkcji:
    Kod: C
    Zaloguj się, aby zobaczyć kod


    Prościej:
    Tworzysz tablicę "n" elementów (z parametrem PROGMEM) zawierającą predefiniowane wpisy zawartości rejestrów timera. Tworzysz zmienną indeksującą tę tablicę.
    Dane odczytujesz tak:
    Kod: C
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    Poziom 34  
    tehaceole napisał:
    Po wykryciu przejścia przez zero załączasz triak a po upływie pewnego czasu go wyłączasz. Tak to nigdy nie zadziała stabilnie.


    Hmm. To NIGDY nie zadziała!

    Przypomnę tylko, że triaka można jedynie załączyć. Obniżenie napięcia na bramce triaka nie powoduje jego wyłączenia. Aby triak się wyłączył to napięcie na nim musi osiągnąć ZERO.
  • Poziom 12  
    Dzięki wszystkim,
    Działa :)

    Wątek można uznać za zamnięty.
    Pozdrawiam
    mumin_80