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

[ATmega16][Bascom]Sterownaie 5 halogenami.

Mice 30 Wrz 2009 13:29 2945 14
REKLAMA
  • #1 7074633
    Mice
    Poziom 14  
    Witam.
    Przy okazji drobnego remontu strychu jako oświetlenie chciałbym założyć 5 zwykłych okrągłych lampek halogenowych 50W. Jako że konsumpcja tego układu to ok 250W chciałbym dorobić do tego układ sterowania za pomocą pilota i klawiatury.



    System postawiony na Atmega16 + moc3022 + bt136
    Zero sieci otrzymuje tym genialnym ukłądzikiem

    [ATmega16][Bascom]Sterownaie 5 halogenami.

    Uporałem się już z kodem przyciemniania i rozjaśniania ale tylko pod jedna żarówkę. Chciałbym mieć niezależne sterowanie każdą żaróweczką (przyciemnienie, rozjaśnianie, wyłączenie, załączenie).

    Czy da się to zrealizować na jednym uP???? Ja jakoś teraz nie mam koncepcji na zarys kodu programu.....

    Proszę o pomysły.
  • REKLAMA
  • #2 7074649
    gothye
    Poziom 33  
    ATMEGA16 ma 4 kanały PWM ,wiec możesz jedynie 4 żarówki nie zależnie sterować
  • REKLAMA
  • #3 7074668
    Mice
    Poziom 14  
    Ale ja nie korzystam z pwm, a jeśli nawet to chyba "lekko" musiał bym zmienić sterownie żarówkami;). Chciałbym to mimo wszystko zrealizować na Bt136 + moc3022itp.
    Chodzi mi o palning samego kodu programu.
    Jak wysterować 5 Triaków w zależności o zera sieciowego.
  • #4 7074850
    mirekk36
    Poziom 42  
    Mice --> oczywiście, że da radę i to spokojnie na jedym procku sterować wieloma kanałami tego typu. Oczywiście bez żadnego PWM'a

    .... w czym piszesz soft?

    niedawno gdzieś tu na elektrodzie był temat i przykłady - fragmenty kodu jak sterować w bardzo prosty sposób zarówno w Bascomie jak i w C koledzy podawali. Przy czym - było to na tyle banalne, że przeróbka na kilka kanałów to pikuś

    generalnie już masz zrobione sterowanie 1 kanałem. Prawdopodobnie i u ciebie wygląda to mniej więcej tak, że w przerwaniu INTx masz obsługę ZERA sieci a tam prawdopodobnie wyzwalasz sobie jakiś timer, który odlicza czas do załączenia triaka i też chyba wykorzystujesz przerwanie od tego Timer'a

    Można więc ustawić Timer na odpowiednio małą rozdzielczość, żeby tykał sobie cały czas a w jego procedurze obsługi przerwania - porównujesz tylko za pomocą tylu zmiennych ile chcesz mieć kanałów czy upłynął odpowiedni czas dla danego kanału. Jeśli tak to załączasz odpowiedniego triaka.

    Ja kiedyś zrobiłem na tej zasadzie także w Bascomie sterowanie 2 kanałowe do swojej wytrawiarki - gdzie 1 kanał sterował płynnie mocą pompki powietrza a drugi grzałką - tyle że już dawno nie mam kodu źródłowego gdzieś się zapodział - a i od dawan już w C programuję. Niedługo - podobną rzecz w C będę także robił
  • #5 7074881
    Mice
    Poziom 14  
    Mirekk36
    Co do działania samego programu to trafiłeś w sedno:)
    Na INT0 ma podawaną szpilkę z detektora zera sieci. To przerwanie ustawia wartość w Timer0 i uruchamia go, a po dotarciu do jego przerwania wykonuje się ten kawałek kodu:
    Triac:           'program przerwania Timer0
    Stop Timer0            'zatrzymanie Timer0
    Portb.2 = 1             'wystawienie sygnału na moc3022
    Waitus 40               'przytrzymanie tego sygnału przez ok 40us
    Portb.2 = 0             'wyłącznie sygnału



    Podejrzewam że tą sekcje będę musiał rozbudować. Średnio zrozumiałem ten fragment:
    Cytat:
    Można więc ustawić Timer na odpowiednio małą rozdzielczość, żeby tykał sobie cały czas a w jego procedurze obsługi przerwania - porównujesz tylko za pomocą tylu zmiennych ile chcesz mieć kanałów czy upłynął odpowiedni czas dla danego kanału. Jeśli tak to załączasz odpowiedniego triaka.



    Chodzi o preskaler???tak??? mam teraz ustawiony na 256 czyli musiał bym dać mniej i zamiast ustawiać wartość początkową timera0, zliczać jego pętle i tymi danymi operować???
  • REKLAMA
  • #6 7074905
    mirekk36
    Poziom 42  
    Mice ---> no raczej każdy robi to dosyć podobnie choć widziałem i inne techniki ;) też dosyć ciekawe

    ale dalej to już rozwiń to tak jak mówiłem. Czyli czas przerwania Timera dobierz tak, żeby pozwalał na wybraną rozdzielczość - czyli ilość kroków w czasie trwania jednej połówki. I w tym przerwaniu porównuj zmienne tak jak to się robi przy programowym PWM'ie
  • #7 7074932
    Mice
    Poziom 14  
    Mimo wszystko prosił bym o wytłumaczenie "jak chłop krowie na rowie" bo nie mogę złapać wątku....
  • REKLAMA
  • Pomocny post
    #8 7074982
    mirekk36
    Poziom 42  
    hmmm no ja to robiłem wtedy w Bascomie mniej więcej tak:

    ustawiałem sobie tak któryś Timer, żeby przerwanie wykonywało się powiedzmy 64 albo 128 czy ze 200 razy w ciągu czasu trwania jednej połówki czyli w trakcie ok 10ms tak?

    Gdy pojawiło się przerwanie INTx to odpalałem ten Timer, który zaczynał tykać i wykonywać przerwanie tyle razy ile ustalonych było wcześniej kroków. Jeśli ich było np 200 to sprawdzany był licznik w procedurze obsługi przerwania i po 200 tyknięciach timer sam się wyłączał ale zawsze przed pojawieniem się kolejnego przerwania - to chyba zrozumiałe - mam nadzieję

    no i teraz zdefiniowałem sobie jakieś zmienne globalne typu:

    Kanal1 i Kanal2

    i teraz ustalam sobie gdzieś w pętli głównej, że Kanal1 ma się od razu włączyć - czyli wartość np 1 (żarówa świeci na FULL) a drugi Kanał ma świecić z połową jasności czyli np przy 200 krokach daję mu wartość 100 (oczywiście to zjawisko jest nieliniowe - więc trzeba sobie jeszcze dorobić tabelę typu Lookup - no ale do testów upraszczamy na razie sprawę)

    i teraz gdy odpala się przerwanie Timera to tam cały czas działa ten licznik kroków prawda? teraz wystarczy porównywać wartość tegoż licznika z wartościami zmiennych Kanal1 i Kanal2

    czyli

    gdy licznik >= Kanal1 to włącz Triak1

    gdy licznik >= Kanal2 to włącz Triak2

    itd

    oczywiście gdy ma się w ogóle nie włączyć dany kanał to wartość odpowiedniej zmiennej dajesz powyżej wartości zdeklarowanych kroków.

    to tak na szybko i mniej więcej z pamięci opisuję swoją metodę - która mi działała

    czy teraz troszkę chociaż jaśniej ?
  • #9 7074999
    Mice
    Poziom 14  
    Ok teraz to już wiem:) Dziękuję za cierpliwość i punkciki wędrują na Twoje konto:)
  • #10 7075121
    mirekk36
    Poziom 42  
    Musisz tylko bardzo zwrócić uwagę na to aby MAKSYMALNIE jak tylko się da - napisać jak najkrótszy kod w obsłudze przerwań szczególnie tego Timera - bo w przeciwnym wypadku - może zacząć dochodzić do tak dziwnych sytuacji, że nie będziesz wiedział w ogóle o co chodzi.

    Wiesz? chodzi o to, żeby przerwania Timera pozostawiały jeszcze sporo czasu na działanie pętli głównej i innych przerwań - nie mogą się broń boże nakładać na siebie - jesli będzie zbyt długi kod.

    W tym celu na pewno warto będzie użyć jakiegoś szybkiego taktowania procka jeśli to jest Bascom (może kwarc 16MHz) - bo wiadomo, że sporo on sam dorzuca swoich rzeczy do obsługi przerwania a kodu w asm nie widać więc ciężko wyliczyć ile trwa przerwanie

    Nie wiem czy znasz asm - ale jak coś to zawsze można sobie w całości napisać obsługę takiego przerwania w asemblerze jako wstawkę w Bascomie. Wtedy przy inicjalizacji przerwania można spokojnie zastosować parametr NOSAVE i nie będziesz miał żadnych ale to żadnych problemów aby to zrealizować.

    W ogóle często powtarzam, że jeśli się Bascoma naszprycuje wstawkami asemblerowymi jak dobrą kaszę skwarkami ;) .... to duuużo można w tym języku zrobić ;)
  • #11 7075134
    Mice
    Poziom 14  
    Zdam relacje jak tylko postawie to na nogi:)


    OK pierwsze koty za płoty:)

    Układ zaczął działać, ale...:)mam pytania:)
    O ile moja matematyka jakoś mi wyszła(układ reaguje na zmianę zamiennych i to dosyć sensownie to jednak pojawił się problem z zewnętrzną regulacją zmiennych tzn:

    Na int0 podana szpila bezpośrednio uruchamia ustawiony timer0 na 250 z dzielnikiem 64
    wystartowany timer0 zawija pętle (i wstawia w siebie wartość 250) do 170 razy na jedna połówkę sinusoidy po czym jest zatrzymywany i śpi aż int0 da mu kopa ponownie:).
    Ten przedział wykorzystuje do wyzwalania triaków.
    Program w wersji alpha:)
    $regfile = "m16def.dat"
    $crystal = 8000000                                          '8MHz
    
    
    Dim Up As Byte
    Dim Down As Byte
    Dim Timerdie As Byte
    Config Porta = Input
            Porta = &B11111111
    Config Portb = Output
            Portb = &B00000000
    Config Portc = Input
            Portc = &B11111111
    Config Portd = Input
            Portd = &B11111111
    Dim Pomocnik As Bit
    Dim Kanal1 As Byte
    Dim Kanal2 As Byte
    Dim S2a As Bit
    Dim S1a As Bit
    Enable Interrupts
    Enable Timer0
    Config Timer0 = Timer , Prescale = 64
    On Timer0 Triac
    Enable Int0
    On Int0 Zero
    Timer0 = 250
    Stop Timer0
    Kanal1 = 150
    Kanal2 = 150
    S2a = 1
    Do
    
    
    If Timerdie = Kanal1 Then                                   ' jesli licznik rowna sie zmiennej kanal1 to
    Portb.2 = 1                                                 'uruchama moc3022  i lampke1
    Waitus 10                                                   'przytrzymuje sygnał
    Portb.2 = 0                                                 'wyłącza sygnał
    End If
    
    If Timerdie = Kanal2 Then
    Portb.1 = 1                                                 '-||-
    Waitus 10
    Portb.1 = 0
    End If
    
    
    
    Loop
    
    
    Lampka1:
    Incr Kanal1
    Return
    Lampka2:
    Incr Kanal2
    Return
    
    
    Zero:
    Start Timer0
    Return
    
    
    
    Triac:
    Timer0 = 250
    Incr Timerdie
    If Timerdie = 170 Then
    Timerdie = 1
    Stop Timer0
    End If
    Return


    Jeżeli twardo wpisuje wartości w zmienne kanal1 i kanal2 to wszystko jest cacy ale jak dopisuję komendę debounce żeby zmieniać je to te opóźnienie które ta funkcja powoduje już zaśmieca mi płynną regulacje jasności (lampka mruga w chwili trzymania przycisku itp)
    Pytanie 1. Jak zrealizować wpis do zmiennych bez wykorzystania paskudnego debounce ??
    Pytanie 2. w jaki inny sposób mogę zamienić te WAITUS w procesie uruchamiania moc3022 w pętli głównej.
  • #12 8451611
    adambehnke
    Poziom 24  
    Troszkę odgrzeję temat.Czy Autor tematu uporał się z tymi czterema kanałami? Czy jesli mu się udało to czy zechciał by wkleić kodzik? Też jestem teraz w trakcie walki z czterema kanałami i nie wiem do końca jakich pinów procesora( atmega16) użyć w wersji końcowej.Czy używać PWM-a czy można zrobić to prościej. Dodam że procesor będzie obsługiwał jeszcze LCD z nokii6100 oraz touch screen.
  • #13 8458051
    Mice
    Poziom 14  
    Tak:) Uporałem się i działa to nawet:)
    Program jest banalnie prosty, może lekko zakręcony ale jak czegoś nie będziesz wiedział to pisz:)
    Podpowiem, że ważny jest czas trwania impulsu wyzwalania optrotriaka.
    Może trochę wait-ów za dużo, no ale w efekcie sterowanie działa już z rok bez żadnego serwisu.


    Cytat:
    $regfile = "m16def.dat"
    $lib "mcsbyte.lbx" 'dane
    $crystal = 16000000 '8MHz
    Dim Q1 As Bit ' zmienna pomagajaca przy przyciskach
    Dim Q2 As Bit '-||-
    Dim 4m As Word 'zmienna 4m do zliczania czasu
    Dim 30m As Word '-||-
    Dim Up As Byte 'zmianna up
    Dim Down As Byte 'zmienna down
    Dim Timerdie As Byte 'zmienna timerdie podprogramu do wyłączania timera0
    Config Porta = &B11110000 'konfiguracja portu A jako wejscie podniesione do stanu logicznego 1
    Porta = &B11111111 '
    Config Portb = Output 'konfiguracja portu B jako wyjscie zapiete pod mase
    Portb = &B00000000
    Config Portc = Input ''konfiguracja portu C jako wejscie podniesione do stanu logicznego 1
    Portc = &B11111111
    Config Portd = &B01010000 'konfiguracja portu D jako wejscie poeniesione do stanu logicznego 1
    Portd = &B11111111
    Dim Pomocnik As Bit 'zmienna pomocnicza
    Dim Kanal1 As Byte 'zmienna zaróweczki 1
    Dim Kanal2 As Byte 'zmienna zaroweczki 2
    Dim Kanal3 As Byte
    Dim Kanal4 As Byte
    Dim Kanal5 As Byte
    Dim B As Byte
    Dim Bit1 As Bit
    Dim Bit2 As Bit
    Dim Bit3 As Bit
    Dim Bit4 As Bit
    Dim Bit5 As Bit
    Dim S4a As Bit

    Dim Address As Byte , Command As Byte
    Config Rc5 = Pind.3 [ , Timer = 2]
    Readeeprom Kanal1 , 1
    Readeeprom Kanal2 , 2
    Readeeprom Kanal3 , 3
    Readeeprom Kanal4 , 4
    Readeeprom Kanal5 , 5

    Enable Interrupts 'uruchom przerwania
    Enable Timer0 '
    Config Timer0 = Timer , Prescale = 8
    On Timer0 Triac
    Cls
    Cursor Off

    Enable Int0
    On Int0 Zero

    Stop Timer0
    'Kanal1 = 150
    'Kanal2 = 150
    'Kanal3 = 150
    'Kanal4 = 150
    'Kanal5 = 150
    Bit4 = 0
    Bit5 = 1
    Q1 = 1
    4m = 0
    'Moc = 211
    30m = 0
    Do
    If Bit4 = 1 Then 'START EFEKTU
    Gosub Efekt
    End If
    Getrc5(address , Command)
    If Address = 0 Then
    Command = Command And &B01111111
    End If
    If Address <> 255 Then
    'Locate 1 , 1
    'Lcd "adres:" ; Address
    'Locate 2 , 1
    'Lcd "komand:" ; Command
    End If
    If Command = 13 Then
    S4a = 1
    Else
    If S4a = 1 Then
    S4a = 0
    Writeeeprom Kanal1 , 1
    Writeeeprom Kanal2 , 2
    Writeeeprom Kanal3 , 3
    Writeeeprom Kanal4 , 4
    Writeeeprom Kanal5 , 5
    End If
    End If

    If Kanal1 < 10 Then
    Kanal1 = 10
    End If
    If Kanal1 > 220 Then
    Kanal1 = 220
    End If 'sprawdzenie stanu swiatlosci lampek:)

    If Kanal2 < 10 Then
    Kanal2 = 10
    End If
    If Kanal2 > 220 Then
    Kanal2 = 220
    End If

    If Kanal3 < 10 Then
    Kanal3 = 10
    End If
    If Kanal3 > 220 Then
    Kanal3 = 220
    End If

    If Kanal4 < 10 Then
    Kanal4 = 10
    End If
    If Kanal4 > 220 Then
    Kanal4 = 220
    End If

    If Kanal5 < 10 Then
    Kanal5 = 10
    End If
    If Kanal5 > 220 Then
    Kanal5 = 220
    End If


    If Command = 1 Then
    Bit1 = 0
    Bit2 = 0
    Bit3 = 0
    End If
    If Command = 2 Then
    Bit1 = 1
    Bit2 = 0
    Bit3 = 0
    End If
    If Command = 3 Then
    Bit1 = 0
    Bit2 = 1
    Bit3 = 0
    End If
    If Command = 4 Then
    Bit1 = 0
    Bit2 = 0
    Bit3 = 1
    End If
    If Command = 5 Then
    Bit1 = 0
    Bit2 = 1
    Bit3 = 1
    End If

    If Command = 16 Then
    If Bit1 = 0 And Bit2 = 0 And Bit3 = 0 Then
    Gosub Uplamp1
    Command = 0
    End If
    If Bit1 = 1 And Bit2 = 0 And Bit3 = 0 Then
    Gosub Uplamp2
    Command = 0
    End If
    If Bit1 = 0 And Bit2 = 1 And Bit3 = 0 Then
    Gosub Uplamp3
    Command = 0
    End If
    If Bit1 = 0 And Bit2 = 0 And Bit3 = 1 Then
    Gosub Uplamp4
    Command = 0
    End If
    If Bit1 = 0 And Bit2 = 1 And Bit3 = 1 Then
    Gosub Uplamp5
    Command = 0
    End If
    End If

    If Command = 17 Then
    If Bit1 = 0 And Bit2 = 0 And Bit3 = 0 Then
    Gosub Downlamp1
    Command = 0
    End If
    If Bit1 = 1 And Bit2 = 0 And Bit3 = 0 Then
    Gosub Downlamp2
    Command = 0
    End If
    If Bit1 = 0 And Bit2 = 1 And Bit3 = 0 Then
    Gosub Downlamp3
    Command = 0
    End If
    If Bit1 = 0 And Bit2 = 0 And Bit3 = 1 Then
    Gosub Downlamp4
    Command = 0
    End If
    If Bit1 = 0 And Bit2 = 1 And Bit3 = 1 Then
    Gosub Downlamp5
    Command = 0
    End If
    End If

    Debounce Pina.0 , 0 , Stopint0 , Sub
    Loop

    'KONIEC PETLI GLOWNEJ
    Efekt:
    Do

    Loop


    Return


    Stopint0:
    Disable Int0


    Return


    Uplamp1:

    Kanal1 = Kanal1 - 5
    Return
    Downlamp1:
    Kanal1 = Kanal1 + 5
    Return

    Uplamp2:
    Kanal2 = Kanal2 - 5
    Return
    Downlamp2:
    Kanal2 = Kanal2 + 5
    Return

    Uplamp3:
    Kanal3 = Kanal3 - 5
    Return
    Downlamp3:
    Kanal3 = Kanal3 + 5
    Return

    Uplamp4:
    Kanal4 = Kanal4 - 5
    Return
    Downlamp4:
    Kanal4 = Kanal4 + 5
    Return

    Uplamp5:
    Kanal5 = Kanal5 - 5
    Return
    Downlamp5:
    Kanal5 = Kanal5 + 5
    Return


    Zero:
    Start Timer0

    Return




    Triac:


    Timer0 = 174 '248
    Incr Timerdie
    If Timerdie = 200 Then 'bylo 110
    Timerdie = 1
    Stop Timer0
    End If



    If Timerdie = Kanal1 Then
    Portb.1 = 1 '-||-
    Waitus 20
    Portb.1 = 0
    End If

    If Timerdie = Kanal2 Then ' jesli licznik rowna sie zmiennej kanal1 to
    Portb.2 = 1 'uruchama moc3022 i lampke1
    Waitus 20 'przytrzymuje sygnał
    Portb.2 = 0 'wyłącza sygnał
    End If

    If Timerdie = Kanal3 Then
    Portb.3 = 1 '-||-
    Waitus 20
    Portb.3 = 0
    End If

    If Timerdie = Kanal4 Then
    Portb.4 = 1 '-||-
    Waitus 20
    Portb.4 = 0
    End If


    If Timerdie = Kanal5 Then
    Portb.0 = 1 '-||-
    Waitus 20
    Portb.0 = 0
    End If
    Return

  • #15 8466099
    Mice
    Poziom 14  
    Standard:)
    [ATmega16][Bascom]Sterownaie 5 halogenami.
    Mój kod jest na 5 halogenów tak btw:)
REKLAMA