Moduł sterowania oświetleniem 230V

Sterownik ten jest urządzeniem w pełni autonomicznym, może działać całkowicie samodzielnie, pełniąc rolę ośmiu przekaźników bistabilnych. Ma osiem niezależnych kanałów, każdy z nich załączany/wyłączany zwarciem wejścia do masy, od rzędu ośmiu przekaźników bistabilnych odróżniają to urządzenie jednak pewne funkcje dodatkowe:

  • wyjścia mogą być załączane czasowo, decyzja, czy wyjście ma być „czasowe”, czy „zwykłe”, czy może jeszcze inne to kwestia prostej podmianki fragmentu kodu w sofcie.
  • rozróżnianie czasu pobudzenia wejścia (wciśnięcia doń podłączonego przycisku). Wciśnięcie przycisku na dłuższą chwilę (>1s) może np. włączać wyjście czasowe na stałe, gasić wszystkie aktywne wyjścia (wygodne przy wychodzeniu z pomieszczenia z dużą ilością punktów świetlnych, przytrzymując dowolny klawisz gasimy wszystko jednym ruchem). Zwarcie wejścia na stałe (>5s) jest sygnalizowane jako awaria linii.
  • możliwość prostego budowania zależności między kanałami.
  • sterowanie przez szynę RS485

Wygląd gotowego urządzenia zaraz po montażu w tablicy (opisówki jeszcze od starych przekaźników, które urządzenie zastąpiło):

Kanał 1 włączony na stałe, 3 i 5 odliczają sobie zaś czas do wyłączenia, na trójce zostało jeszcze 70% czasu, na 5 – 80% 🙂

Wnętrze urządzenia:

 

Schemat urządzenia (tu obrazek, bardziej szczegółową dokumentację podlinkuję na dole strony):

2015-10-09_13-47-36

Jak widać, od strony układowej nie ma tu żadnych szczególnych wodotrysków, procesor z niezbędnymi peryferiami, osiem wyjść zbudowanych w oparciu o zespół triak+optotriak, osiem wejść zabezpieczonych transoptorami, nadajnik/odbiornik linii do obsługi RS485 oraz wyświetlacz LCD. I tyle. Cała reszta to szaleństwa programisty 🙂

Kilka uwag co do układu:

  • zasilacz: nie jest to nieśmiertelny 7805, tylko mała przetwornica. Ponieważ urządzenie ma działać non stop 24h/d, stwierdziłem, że nie ma co podgrzewać atmosfery i warto choć te 2W zaoszczędzić z pobieranej przez ustrojstwo mocy.
  • Driver RS485 ma na stałe dołączony rezystor terminujący i podciągające zasilanie. To urządzenie jest moim historycznie pierwszym klockiem obsługującym ten interfejs, więc ono właśnie dostało te elementy włączone permanentnie, niemniej warto mieć to przemyślane i w razie potrzeby można elementów R1, R2 i R3 nie montować.
  • Dioda świecąca LD1  sygnalizująca komunikację po RS485 – w pierwotnym projekcie był to po prostu jednobarwny LED podłączony do jednego portu procesora, w trakcie prac nad urządzeniem jednak potrzebne mi było rozróżnienie, czy interfejs aktualnie nadaje, czy odbiera. Ponieważ płytkę wyświetlacza i tak musiałem przerabiać, wstawiłem tam diodę dwubarwną, a jej dodatkową nogę podłączam do procesora „na wariata”, wykorzystując jeden z wolnych interfejsów. Jeśliby ktoś kopiował to urządzenie i miał ochotę na przeróbki, można to zrobić porządnie, rozszerzając złącze SL10/14 o jedno oczko w prawo.
  • Przyciski – do układu są dodane „bo tak”. Na płytce są przewidziane dwa, wmontowany jest jeden, używanych – zero 🙂 Ale w czasie pisania i testowania softu przydawał się.

Tyle o układzie. Kompletnego softu, jak pisałem we wstępie do całego działu, nie chcę podawać, jednak kilka ogólnych uwag dorzucę:

Obsługa wyjść: odbywa się w przerwaniu, wywoływanym timerem co 100ms. W ramach obsługi przerwania wykonywanych jest osiem zestawów komend, jak poniżej:

1
2
3
4
5
6
7
8
9
10
11
   If T(1) <> 0 Then                                        'jeśli t(x) niezerowy to
      Reset Out_1                                           'załącz out_x
      If T(1) = 65535 Then Lamp(1) = 2                      'kod do wysłania po RS485 do monitora
      If T(1) < 65535 Then                                  'i jeśli t(x)nie jest ustawiony na max
         Lamp(1) = 3
         Decr T(1)                                          'odliczaj czas w dół (co 100ms)
      End If
   Else                                                     'a jeśli t(x) zerowy
      Lamp(1) = 0
      Set Out_1                                             'wyłącz out_x
   End If

W ramach zasadniczego programu każde wyjście programuje się ustawiając zmienną T(x), gdzie X-numer wyjścia. T(x)=0 to wyjście wyłączone, T(x)=65535 to wyjście włączone na stałe, każda zaś inna wartość to czas włączenia wyjścia wyrażony w setkach milisekund i odliczany samoczynnie w ramach obsługi przerwania. Dodatkowo występuje tu zmienna Lamp(x), za pośrednictwem której są przekazywane informacje o aktualnym stanie wyjścia, dane te są następnie transmitowane po RS485 do innego urządzenia (monitorka pokazującego stan oświetlenia zewnętrznego).

Obsługa wejść: w pętli głównej programu są po kolei sprawdzane wszystkie wejścia, typowo wygląda to tak:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
'obsługa wejścia 1  (oświetlenie "ścieżka")
   If In_1 = 0 Then                                         'jeśli przycisk wciśnięty
      Do
         Incr A                                             'licz w pętli czas wciśnięcia
         Waitms 25
      Loop Until In_1 = 1 Or A > 200                        'póki nie zostanie puszczony przycisk bądź przekroczony czas
      Select Case A                                         'zbyt krótkie wciśniecia ignoruj
         Case 2 To 29 :                                     'jeśli było choć 50ms
            If T(1) = 0 Then                                'i jeśli zgaszone
               T(1) = Tmax(1)                               'to zapal na ustawiony czas
            Else                                            'a jesli się świeciło
               T(1) = 0                                     'to je zgaś
            End If
         Case 30 To 200 :                                   'przy wciśnięciu powyżej sekundy
            T(1) = 65535                                    'zapal na stałe
         Case Is > 200 :                                    'a jesli wciąnięte było dłużej, niż 5 sekund
            Komunikat = "Zwarcie na Wej.1"                  'wywal komunikat o zwarciu na linii
            Tkom = 50                                       'na pięć sekund
      End Select
      A = 0
   End If

Komentarze w kodzie w zasadzie powinny wystarczyć, dodam tylko, że zmienna „komunikat” wraz z towarzyszącą zmienną „Tkom” służą do przekazywania informacji do wywalenia na wyświetlacz. Normalnie wyświetlacz pokazuje stan linii (jak na zdjęciu powyżej), jednak po zauważeniu niepustego stringu „Komunikat”, wrzuca go na ekran na zadany czas.

Wysyłanie informacji po RS485: tu przykład pokazujący przekazywanie stanu dwóch wejść do osobnego urządzenia stanowiącego zamontowany w kuchni monitor oświetlenia zewnętrznego. Zmienna Lamp(x) była opisana wyżej, jest do niej wpisywany stan lampek monitora, który chcemy na monitorze ustawić. Tu pojawia się dodatkowa zmienna Lamp_ack, służąca do tego, żeby nie wysyłać informacji w kółko, a jedynie wtedy, gdy zaistnieje zmiana. Jeśli stan zmiennej Lamp zostanie zmieniony (bo ktoś zapalił światło), zostaje wysłany w interfejs ciąg znaków: „@8”, czyli do urządzenia o adresie 8 (monitor), „1” – lampka 1 oraz Str(Lamp(x)), czyli znak odpowiadający stanowi zmiennej lamp(x). Na końcu jest jeszcze dokładane zero – miała tu być suma kontrolna, ale ponieważ póki co sieć działa bezbłędnie, sum kontrolnych jeszcze nie zrobiłem. Zrobię, jak będą potrzebne, póki co jest wysyłane zero, żeby zarezerwować miejsce w ramce. Wszystkie te znaki są składane w jeden ciąg znajdujący się w zmiennej Wyraz po czym za pośrednictwem podprogramu Write_rs wysyłane w interfejs.
Samo wysyłanie odbywa się w sposób książkowy, opisany w helpie od Bascoma: blokujemy przerwania (bo przerwanie w połowie wysyłania raczej by rozłożyło transmisję na łopatki), włączamy nadawanie, czekamy doświadczalnie dobraną pauzę dla uniknięcia stanów nieustalonych w linii, wysyłamy w linię to, co jest do wysłania, znów pauza, przełączamy interfejs na odbiór, włączamy przerwania.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  If Lamp(1) <> Lamp_ack(1) Then                            'jeśli ustawiono nowy stan lampki
     Wyraz = "@81" + Str(lamp(1)) + "0"                     'wyślij nowy stan do monitora
     Write_rs Wyraz
     Lamp_ack(1) = Lamp(1)                                  'zapamiętaj nowy stan
  End If
  If Lamp(3) <> Lamp_ack(3) Then                            'jeśli ustawiono nowy stan lampki
     Wyraz = "@83" + Str(lamp(3)) + "0"                     'wyślij nowy stan do monitora
     Write_rs Wyraz
     Lamp_ack(3) = Lamp(3)                                  'zapamiętaj nowy stan
  End If
 
Sub Write_rs(byval Komenda As String)
   Disable Interrupts
   Set R_w                                                  'przelaczenie konwertera rs485 na nadajnik
   Set Rs_r                                                  'zapalenie kontrolki RS485 na czerwono
   Waitus 900                                                'pauza
   Print Komenda                                            'wyślij kod 
   Waitms 10
   Reset R_w                                                'przełączenie konwertera rs485 na odbiornik
   Reset Rs_r                                                'zgaszenie kontrolki
   Enable Interrupts
End Sub

Odczyt interfejsu RS485: w poniższym przykładzie jest pokazany odbiór informacji z monitora: jeśli coś zostało odebrane, zaczyna się od adresu urządzenia 8 oraz znaku „>” (bo tak), program uznaje, że słucha tego, co trzeba i dalej przyjmuje właściwy kod rozkazu, który następnie jest dekodowany już do konkretnych zastosowań, czyli odpowiednio zmienia zmienną T(x), zarządzającą nam wyjściami sterownika 🙂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
'odczyt interfejsu RS485
  A = Ischarwaiting()                                       'jeśli coś zostało odebrane (wtedy A jest ustawiane na 1)
  If A = 1 Then
     Set Rs_g                                               'zapal kontrolkę transmisji RS, kolor zielony
     B = Inkey()
     If B = 56 Then                                         'i jeśli to coś zaczyna się od znaku "8"
        B = Waitkey()
        If B = 62 Then                                      'i dalej ma " > "
           Inputbin Odbierz(1)                              'pobierz pozostałe bajty rozkazu
           'chksum=                                           'oblicz sume kontrolną
 
           If Odbierz(1) = 49 Then                          'klawisz 1 "ścieżka"
              Select Case Odbierz(2)
              Case 107
                 If T(1) = 0 Then
                    T(1) = Tmax(1)
                 Else
                    T(1) = 0
                 End If
              Case 100
                 T(1) = 65535
              End Select
           End If
 
           If Odbierz(1) = 51 Then                          'klawisz 3 "górne FULL"
              Select Case Odbierz(2)
              Case 107
                 If T(3) = 0 Then
                    T(3) = Tmax(3)
                 Else
                    T(3) = 0
                 End If
              Case 100
                 T(3) = 65535
              End Select
           End If
 
        End If
     End If
 
     Waitms 10
     Reset Rs_g                                            'zgaś kontrolkę RS
  End If

Na koniec obiecany schemat wraz z płytką, w formacie Eagle:

 

email
Sterownik 230V
Sterownik 230V
Sterownik-230V.rar
134.7 KiB
60 Downloads
Szczegóły

5 Responses to Moduł sterowania oświetleniem 230V

Q1: jak są połączone diody na panelu? Bo nie widać żeby z płytki wystawały
Q2: RS485 nie jest obsługiwany w przerwaniach?
Q3: oprogramowanie pozwala wysyłać sterownikowi komendy tym z zewnątrz?
Q4: po schemacie i wyglądzie wtyczek domyślam się że i sterownik i wszystkie lampy zewnętrzne zasilane są z tej samej fazy. Nie myślałeś o jakiejś separacji? Np żeby sterownik chociaż zasilać z gwarantowanego.

Ogólnie bardzo mi się podoba ta „kanapka” 🙂

A1: Zdjęcie przedstawia wcześniejszą wersję panela, względem docelowej obróconą o 180 stopni, więc na tym zdjęciu diody powinny być z drugiej strony wyświetlacza, tu na zdjęciu ich nie widać, bo najprawdopodobniej nie są jeszcze wlutowane, nie tylko one zresztą 🙂 Te diody zresztą mieszczą się tutaj mocno na wcisk, one są lutowane na długich końcówkach i wyginane tak, żeby minąć krawędź płytki wyświetlacza i jeszcze wejść na swoje miejsce w obudowie. Niestety nie mam zdjęcia… Ale jeśli masz Eagle, wypakuj sobie pcb z załączonych materiałów.

A2: ano nie. Tak, wiem, że przerwanie zgłaszane przez przychodzącą transmisję RS byłoby eleganckie, ale w sumie nie ma takiej potrzeby. Interfejs szeregowy i tak pracuje sobie samodzielnie w tle, przychodzące komunikaty trzyma w buforze, a Bascom ma tutaj wygodną funkcję ischarwaiting, która przyjmuje niezerową wartość, jeśli bufor coś zawiera. W pętli głównej programu po prostu sprawdzam co jakiś czas tą funckję i jeśli trzeba, obsługuję odbiór komunikatu.

A3: No tak, o tym piszę w punkcie „wysyłanie informacji po RS, podając jako przykład wysyłanie informacji do monitorka, ale dokładnie tak samo są wysyłane i inne. Chyba, że nie zrozumiałem pytania?

A4: tu – nie. Całość oświetlenia zewnętrznego i tak wisi u mnie na jednej różnicówce, a zasilanie oświetlenia zewn. z napięcia gwarantowanego? Bezcelowe wg mnie. Taki ficzer jest natomiast uwzględniony w sterowniku odbiorników 12V, który sobie właśnie programuję obecnie (pokazywałem niedawno płytkę w normalnych, blogowych wpisach), tam faktycznie mam rozdzielone wyjścia na dwie grupy, z możliwością ich zasilenia z dwóch osobnych linii.

Kanapka efektownie wygląda, ale nakląłem się nią. W takiej formie to powstało, bo nie było szans, żeby to inaczej upchać w typowej obudowie na szynę DIN, a nie mam w rozdzielni miejsca na obudowy nietypowe.

pit_i_mat
Commented:  11 stycznia 2017 at 18:52

Hej,
Super projekt, gratuluję 😉
Czy jest szansa aby dostać źródła kodu? Głównie chodzi mi o obsługę RS485.
Próbuję zrobić coś podobnego, ale całkowicie poległem na RS485, a Ty mówisz, że u Ciebie wszystko działa jak należy 😉

    Dzięki 😉

    Kodu wolałbym nie udostępniać, ale to, co Cię interesuje, czyli obsługa RS485 masz w treści opisu podane właściwie w całości, w samym kodzie nie ma tu nic więcej, może poza wstępnymi deklaracjami typu prędkość transmisji.
    Pamiętaj, że szyna RS485 musi mieć na końcach terminatory, a jeśli chcesz mieć możliwość wygodnej diagnostyki, to zorganizuj sobie konwerter RS485 na RS232 (do zrobienia, schematy są w necie, ja to zrobiłem bodajże na bazie jakiegoś projektu AVT) i wtedy możesz swoją transmisję wygodnie podglądać na pececie w jakimkolwiek programie terminalowym począwszy od nieśmiertelnego putty. Oczywiście Pecet wyposażony w RS232 albo konwerter RS232/USB potrzebny 🙂

      pit_i_mat
      Commented:  12 stycznia 2017 at 02:45

      Dzięki za odpowiedź…
      Ja u siebie w sumie mam wszystko uruchomione, ale właśnie RS485 kuleje i szukam sposobu aby to poprawić 🙁
      Mogę jakoś się z Tobą skontaktować poprzez e-mail? Podeślę co mam to może podpowiesz co źle robię i da się to jakoś poprawić.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

Przejdź do paska narzędzi