Domowy system sterujący

Projekty użytkowników forum zarówno sprzętowe, jak i związane z programowaniem w dowolnym języku.
Awatar użytkownika
gaweł
Geek
Geek
Posty: 1321
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Domowy system sterujący

Postautor: gaweł » środa 27 gru 2017, 00:12

Idea

Koncepcja domowego systemu sterującego (w skrócie HCS) narodziła się jeszcze w latach 90-tych ubiegłego wieku. Z biegiem lat ulegała modyfikacjom i rozrastała się, taka elektroniczna ewolucja naturalna. Z czasem projekt urósł do poważnych rozmiarów i obecnie sprawia wrażenie dość rozbudowanego. Jego zadaniem jest sterowanie wszystkiego co się da (i nawet tego, czego się nie da). Poszczególne elementy całości zostały tak pomyślane, by pozwalały na pracę niejako autonomiczną oraz by mogły stać się elementami bardziej złożonej infrastruktury. Wręcz naturalnym elementem rozwiązania poszczególnych sterowników jest wykorzystanie mikrokontrolerów. Całość generalnie jest oparta o mikrokontrolery AVR oraz ARM. Nie jest istotny wybór rodziny mikrokontrolerów a w tym przypadku był on podyktowany dostępnością procesorów zawierających wymagane funkcjonalne zespoły (dotyczy procesorów AVR bo w tamtych czasach nie było większej alternatywy i tak jakoś zostało). Początkowo stosowane były procki z rodziny C51, ale miały one dość poważną wadę, mianowicie tylko jeden kontroler transmisji szeregowej UART no i mizerne zasoby pamięci RAM, z którą co prawda można sobie jakoś poradzić ale kosztem redukcji pinów portów do sterowania). Z racji, że cała komunikacja oparta jest o transmisję szeregową, często konieczne jest użycie takich mikrokontrolerów, które mają więcej niż jeden szeregowy kanał komunikacyjny.
Wspomniałem o komunikacji między poszczególnymi elementami całości i że jest oparta o transmisję szeregową. W całości wykorzystane są dwie „technologie komunikacyjne” RS232 oraz RS485. Cechą charakterystyczną standardu RS232 jest brak możliwości równoległego łączenia interfejsów ale z drugiej strony pozwala to na większe przepływy danych (z racji stosowania filozofii transmisji w pełnym dupleksie). Z przypadku interfejsu RS485 w układzie jednoparopwym można równolegle łączyć wiele interfejsów, czyli uzyskać na jednym kanale komunikacyjnym możliwość wymiany informacji w wieloma urządzeniami. Jednak taka technologia ma pewne swoje ograniczenie, które wynikają z jednoparowości → transmisja półdupleksowa. Oznacza to, że w danej chwili czasowej mikrokontroler może jedynie nadawać albo odbierać dane (nie może wystąpić jednoczesna transmisja w obu kierunkach). O problemach występujących w obsłudze komunikacji szeregowej z wykorzystaniem półdupleksowej transmisji RS485 będę pisał później.
Nie powinno dziwić, że spięcie kilkudziesięciu sterowników różnej maści i przeznaczenia, które w sumie mają trafić do jednego komputera, wygeneruje konieczność zastosowania kompa mającego bardzo wiele portów szeregowych. Na tym poziomie została przewidziana technologia ethernetowa. Każda gałąź sterowników jest widziana dla warstwy hierarchicznie wyższej jako pojedynczy kanał szeregowy RS232. Z poziomu komputera PC wszystkie sterowniki są widziane jako urządzenia o określonym adresie IP. Koncepcja zakłada techniczną możliwość przesłania danych pomiędzy dowolnymi sterownikami wpiętymi gdziekolwiek. Narzuca to jednocześnie dla „węzłowych” sterowników konieczność realizacji podstawowych funkcji dotyczących przekierowywania danych (routing danych). Z kolei funkcjonalność przekierowywania danych wymaga zawarcia w transmitowanych danych niezbędnych informacji pozwalających na jej realizację.
Na koniec można zadać dość istotne pytanie: po co to wszystko? A odpowiedź... bo to fajna zabawa. Coś zrobić nie po to by to mieć, lecz by zmierzyć się z wyzwaniem, by doświadczyć trudności związanych z pokonaniem wielu problemów, by na koniec bez żalu z tym się rozstać.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1321
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: Domowy system sterujący

Postautor: gaweł » środa 27 gru 2017, 00:36

Obsługa transmisji półdupleksowej

Obsługa asynchronicznej transmisji szeregowej z wykorzystaniem interfejsu RS232 w mikrokontrolerach nie stanowi żadnego problemu. Jest wiele przykładów ilustrujących odpowiedni algorytm. Pewną specyfikę stanowi obsługa komunikacji szeregowej z wykorzystaniem interfejsu RS485, który pracuje w trybie półdupleksowym (czyli albo nadaje albo odbiera – nie jest możliwe jednoczesne nadawanie oraz odbieranie). Istnieje możliwość wykorzystania interfejsu RS485 pracującego w trybie pełnego dupleksu (możliwa jest jednoczesna praca nadajnika oraz odbiornika, ale to wymaga zastosowania dwóch układów interfejsu RS485 i linia łącząca jest dwuparowa) i w tym układzie nie różni się w żaden sposób, z punktu widzenia oprogramowania, od obsługi programowej dla interfejsu RS232. W tym dokumencie rozważania dotyczyć będą obsługi transmisji z interfejsem RS485 w układzie jednoparowym (półdupleksowym).
rs485.PNG

Ideę takiego rozwiązania wyjaśnia ilustracja 1. Wszystkie linie transmisyjne (linia A i B, czasami występuje pod oznaczeniami T+ i T-) połączone są ze sobą równolegle. Takie rozwiązanie sprawia wrażenie, że w układzie występuje konflikt logiczny, gdyż, jak można się spodziewać, układ interfejsu realizuje funkcję nadawania, czyli ileś wyjść różnych układów jest połączonych ze sobą. Powstaje pytanie, jeżeli każdy z układów próbuje „głosić własną rację”, to „która racja jest istotna” (szczególnie jeżeli są ze sobą sprzeczne)? W rzeczywistości linie A i B są liniami dwukierunkowymi, możliwe jest nadawanie albo odbieranie – niestety nie jest możliwe jednoczesne nadawanie i odbieranie ponieważ elektrony w przewodzie pełniące rolę posłańców z wiadomościami są zdezorientowane i się gubią :). A poważnie, to do właściwego działania interfejsu konieczny jest sygnał określający, czy w danej chwili realizowana jest operacja nadawania czy odbierania. W przypadku nadajnika, gdy nie jest aktywowany odpowiadający mu kierunek przepływu danych, wyjście linii A i B jest w trzecim stanie (ma wysoką impedancję → „udają”, że ich nie ma).
Idea transmisji sprowadza się do następującej koncepcji. Każdy z interfejsów jest wysterowany do odbioru danych, co przy okazji generuje pewien drobny problem sprzętowy, gdyż w przypadku, gdy każdy interfejs odetnie się od wymuszenia na liniach swego stanu logicznego, mają one nieokreślone potencjały, „pływają w chmurach”. Ten problem rozwiązuje się w ten sposób, że jeden, wybrany interfejs rezystorami wymusza określony stan napięć na liniach, tak, że te rezystory „sprowadzają napięcia na przewodach na ziemię i nie bujają już one w obłokach”.
Jeżeli wybrane urządzenie ma ochotę na wysłanie swoich danych, to po prostu przełącza swój interfejs RS485 na nadawanie i realizuje transmisję. Po jej zakończeniu wraca do funkcji odbierania. Ponieważ każdy inny interfejs jest w trybie odbierania informacji, to wysłany pakiet danych dociera do wszystkich urządzeń przyłączonych do wspólnej linii transmisyjnej. Koncepcja niby prosta zawiera w sobie jeden dość istotny problem, mianowicie może zaistnieć taki przypadek, że jednocześnie więcej niż jedno urządzenie będzie miało ochotę na wysyłanie swoich danych i wtedy wystąpi konflikt logiczny, czyli „czyja racja jest ważna”. By temu przeciwdziałać stosuje się wiele różnych rozwiązań i chwytów. Oczywiście w każdym wypadku musi istnieć jakiś mechanizm pozwalający na stwierdzenie, czy przesyłane dane są przeznaczone dla nas (ponieważ dane docierają do wszystkich). Takim identyfikatorem może być przykładowo numer (dla każdego urządzenia inny). Możliwym rozwiązaniem jest technika, którą można określić „krążący żeton”. W takiej minisieci przekazywany jest umowny żeton, który należy interpretować w ten sposób: „jeżeli posiadasz żeton, to możesz wysłać swoje dane i po zakończeniu nadawania przekaż żeton następnemu”. Ostatnie w kolejce urządzenie przekazuje żeton pierwszemu. Niby prosta koncepcja, ale zawiera również pewne pułapki: co będzie, jak żeton się zagubi (choćby w sytuacji, gdy procesor, który posiada żeton na swoje nieszczęście „zwisł” → wszyscy czekają na żeton a jego posiadacz „umarł”) no i oczywiści problem warunków początkowych, czyli kto na dzień dobry posiada żeton. No i oczywiście odwieczny problem: kto jest następnikiem każdego urządzenia (niezbędna jest znajomość topologii sieci). Rzecz jasna na ten problem również można zaproponować kilka koncepcji rozwiązań związanych z automatyczną rekonfiguracją. Przykładowo, jeżeli adresem urządzenia będzie liczba 8-bitowa, co limituje do 256 kombinacji, to możliwe jest rozwiązanie automatyczne. Proces rekonfiguracji, czyli każde urządzenie poszukuje swego następnika, może zostać rozpoczęty od urządzenia o najniższym numerze (każdy identyfikator liczbowy jest na stałe przyporządkowany do urządzenia, tak jak imię na chrzcie). Wystarczy, że dane urządzenie będzie wysyłać jakieś „hello” do kolejnych wyższych identyfikatorów, aż do momentu jak uzyska odpowiedź na swoje hello. Wtedy wiadomo, kto jest następnikiem i jemu przekazać dalszy proces rekonfiguracji. Oczywiście to nie rozwiązuje problemów w przypadku dołączenia kolejnego urządzenia SLAVE już w „biegu”, chociaż i na ten przypadek można znaleźć jakieś lekarstwo.
Można zaproponować wiele rozwiązań związanych z synchronizacją dostępu urządzenia do „druta”. Zastosowane poniżej polega na tym, że jedno wybrane urządzenie jest wyróżnione (na ilustracji 1 nazwane jako MASTER) oraz ileś urządzeń podpiętych do wspólnej magistrali (na ilustracji określone jako SLAVE 1 .. SLAVE N). To taki król i jego poddani. Z powodu pewnej wyjątkowości urządzenia MASTER, zawiera ono rezystory wymuszające określone potencjały na przewodach. By zmniejszyć męki związane z rekonfiguracją każdy "pan" [MASTER] zna listę swoich "poddanych" [SLAVE]. Ta znajomość może być rozwiązana na wiele sposobów. W opisanych sterownikach istnieje możliwość ich konfiguracji poprzez łącze transmisji szeregowej i zapisanie danych w pamięci EEPROM mikrokontrolera. Początkowo używany był do tego typowy program z windozy HyperTerminal. W zamierzeniach jest napisanie jakiegoś specjalizowanego programu do odpowiedniej konfiguracji (z wykorzystaniem Lazarusa).
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1321
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: Domowy system sterujący

Postautor: gaweł » środa 27 gru 2017, 01:35

Protokół komunikacyjny

Protokół komunikacyjny pomiędzy wszystkimi sterownikami jest znakowy (o ile polecenia i odpowiedzi są zawsze znakowe, o tyle liczby również są przesyłane znakowo → konieczna jest konwersja z postaci binarnej na znakową przy operacjach nadawania oraz z postaci znakowej na binarną w operacjach odbierania). Każde przesyłane informacje mają następujący format:
<identyfikator adresata>:<identyfikator nadawcy>:<polecenie>.<parametr><CR>
gdzie:
  • <identyfikator adresata> – identyfikator sterownika będącego miejscem docelowym przesyłanych danych, jest ciągiem liter oraz cyfr
  • <identyfikator nadawcy> – identyfikator sterownika będącego źródłem przesyłanych danych, jest ciągiem liter oraz cyfr
  • <polecenie> - identyfikator polecenia (polecenie jest ciągiem składającym się z liter
  • <parametr> - parametr lub ciąg parametrów rozdzielonych znakiem kropki, w przypadku, gdy polecenia nie zawiera parametrów, część <parametr> nie występuje (łącznie ze znakiem kropki będącej separatorem pomiędzy identyfikatorem polecenia a listą parametrów),
  • <CR> znak kontrolny (CR) o kodzie 0D w zapisie szesnastkowym jako znak kończący całe polecenie.
Jako identyfikatora adresata można użyć „GENERAL” oznaczające „każdy” (taka forma broadcastu do wszystkich). Z racji, że poleceniami wymieniają się sterowniki lub odpowiednie oprogramowanie w komputerze PC, parser poleceń jest wrażliwy na pisownię małymi oraz wielkimi literami (polecenia mają być zapisane tak, jak wymaga tego adresat → we wszystkich przypadkach występuje pisownia wielkimi literami) oraz nie jest zrealizowana funkcjonalność znaku Backspace (prowadząc dialog ze sterownikiem poprzez emulator terminala należy wpisać dane starannie, bez pomyłek).
Każdy sterownik zawiera realizację poleceń związanych z konfiguracją oraz ze swoim działaniem. W przypadku poleceń konfiguracyjnych wymagany jest kontekst zalogowania do sterownika (wraz z podaniem właściwego hasła). Większość poleceń generuje odpowiedzi (przesłanie informacji zwrotnej → zamienione są pola <identyfikator nadawcy> oraz <identyfikator adresata>). Każdy sterownik ma własną listę poleceń, toteż szczegóły poleceń będą opisane razem ze sterownikiem.
Przykład:
GENERAL:C:HELLO
gdzie:
  • GENERAL - identyfikator adresata w trybie rozgłoszeniowym (szczególnie gdy zaginęła gdzieś informacja o identyfikatorze sterownika),
  • C - identyfikator nadawcy → emulator terminala w komputerze,
  • HELLO - polecenie
odpowiedź:
C:KYC1:RHELLO.HCKYC1-keyboard controller
gdzie:
  • C - jest identyfikatorem adresata (emulator terminala w komputerze PC),
  • KYC1 - identyfikator sterownika do obsługi przycisków (o tym później),
  • RHELLO - odpowiedź na HELLO,
  • HCKYC1-keyboard controller - sterownik odpowiedział jak się nazywa (KYC1) i jaką funkcję spełnia - obsługuje pewien rodzaj klawiatury

Przedstawiona filozofia komunikacji wymaga, by każdy sterownik posiadał swój indywidualny, unikalny symbol. Świeży, z taśmy montażowej, ma „wbite” default'owe parametry, które mogą zostać zmienione poprzez użycie emulatora terminala lub odpowiedniego programu konfiguracyjnego (którego jeszcze nie napisałem, pomimo że upłynęło już trochę lat).
Ostatnio zmieniony środa 03 sty 2018, 19:32 przez gaweł, łącznie zmieniany 1 raz.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1321
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: Domowy system sterujący

Postautor: gaweł » środa 27 gru 2017, 14:10

Mikrokontrolery AVR: obsługa asynchonicznego portu szeregowego w przerwaniach
DSCF3157.JPG


W systemach cyfrowych zbudowanych z użyciem mikrokontrolerów popularnym rozwiązaniem jest zastosowanie do komunikacji asynchronicznej transmisji szeregowej. Sam mikrokontroler ma w swej strukturze zintegrowany kontroler transmisji (USART) umożliwiający autonomiczną pracę. Współpraca kontrolera USART z kontrolerem przerwań pozwala na efektywną realizację przesyłania danych. Z technicznego punktu widzenia wymiana danych poprzez kanał szeregowy może być zrealizowana w trybie dupleksowym lub półdupleksowym. Ewentualne ograniczenia do pracy półdupleksowej wynikają jedynie z zastosowanych interfejsów umożliwiających przesyłanie danych na większe odległości. Popularny standard RS232 umożliwia pracę dupleksową i w sposób naturalny pozwala przyłączyć system mikroprocesorowy do komputera PC (no może z wyjątkiem najnowszych laptopów, w których :-) wyginęło złącze RS232 – a szkoda).
Poniższy przykład prezentuje prosty program, który komunikuje się z otoczeniem poprzez kanał USART. Jego obsługa wykorzystuje przerwania (od nadajnika i odbiornika). W mikrokontrolerze AVR są trzy przerwania związane z kontrolerem USART. Są to:
(1) przerwanie od nadajnika generowane w sytuacji, gdy kontroler USART może przyjąć kolejny znak do nadania,
(2) przerwanie od odbiornika generowane w sytuacji, gdy kontroler USART odebrał znak i jest on gotowy do odczytu,
(3) przerwanie od zakończenia nadawania generowane, gdy kontroler USART zakończył wszystkie czynności związane z nadawaniem znaku.

Wśród wymienionych występują dwa przerwania związane z nadajnikiem. Pozornie podobna ich funkcjonalność ma istotne znaczenie w implementacji procedur obsługi przerwań. W przypadku zastosowania transmisji dupleksowej (RS232 lub dwuparowy RS485) wymaga ona obsługi przerwań od nadajnika (1) oraz odbiornika (2).
Środowisko sprzętowe mikrokontrolera AVR (ATMEGA8515) jest następujące:
do pinu 7 portu A przyłączona jest dioda LED,
do pinów 0 i 1 portu D przyłączony jest interfejs RS232.

Obsługa transmisji szeregowej jest zrealizowana w oparciu o dwa bufory cykliczne: jeden przeznaczony na znaki nadawane, drugi na znaki odbierane. Bufor odbiornika, jako prostsza struktura, reprezentowany jest przez typ RXDRecT. Zawiera ona dwa wskaźniki: zapisu i odczytu oraz bufor znakowy przechowujący odebrane znaki. Obsługa każdego przerwania wygenerowanego po odebraniu przez USART znaku odczytuje go i umieszcza go w buforze jednocześnie inkrementując odpowiedni wskaźnik. Porównując wskaźnik odczytu oraz zapisu można stwierdzić, czy w buforze cyklicznym znajdują się ważne dane do odczytu (czy nie jest pusty). Operacja odczytu danych z bufora polega na pobraniu z bufora elementu wskazanego przez wskaźnik odczytu. Po tej operacji wskaźnik jest inkrementowany. Zwiększanie zawartości odpowiednich wskaźników realizowane jest modulo wielkość bufora.
Na podobnej zasadzie działa bufor cykliczny związany z nadawaniem znaków. Dodatkowo zawiera on informację, czy aktualnie nadajnik jest w stanie bezczynności, czy zajęty jest realizacją nadawania znaku. W przypadku, gdy kontroler USART jest w stanie bezczynności, operacja nadania znaku sprowadza się do wpisania go w rejestry kontrolera i zmianie statusu (od tej chwili kontroler jest zajęty realizacją nadawania znaku). Nadanie kolejnego znaku wiąże się z zapisaniem go do bufora z jednoczesną inkrementacją właściwego wskaźnika. Każde przerwanie wynikające z nadania znaku pobiera z bufora kolejny (jednocześnie inkrementuje właściwy wskaźnik) aż do wyczerpania wszystkich tam zawartych znaków. Brak znaków do nadania implikuje zmianę statusu na stan bezczynności.
Po skompilowaniu programu i zaprogramowaniu mikrokontrolera można poprzez kanał transmisji szeregowej komunikować się z programem. W tym celu na PC należy uruchomić program HyperTerminala (lub jakikolwiek inny program umożliwiający odbieranie i wyświetlanie ich na ekranie oraz nadawanie znaków wczytanych z klawiatury) oraz podłączyć odpowiednim przewodem wyjście szeregowe mikrokontrolera z odpowiednim złączem COM w komputerze PC.
DSCF3156.JPG
oraz
hyper.PNG


Załączniki:
  • program prezentujący obsługę UART (RS232)
    avr_p4.zip
  • komentarz do programu prezentującego obsługę UART
    avr_p4.pdf
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1321
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: Domowy system sterujący

Postautor: gaweł » środa 27 gru 2017, 14:43

RS485 - implikacje obsługi w oprogramowaniu

Różnica w obsłudze UART z interfejsem RS485 pracującego w półdupleksie wynika z konieczności sterowania kierunkiem transmisji (zastosowany układ SN75C176 ma nóżkę do sterowania kierunkiem transmisji) poprzez wybrany pin portu mikrokontrolera. W stanie spoczynkowym, układ interfejsu musi być wysterowany do funkcji nasłuchu, czyli odbierania danych. Jedynie w sytuacji, gdy konieczne jest wysłanie danych, należy zmienić dla układu interfejsu kierunek pracy na nadawanie. Po wytransmitowaniu kompletu danych należy powrócić do funkcji nasłuchu. Jest jeszcze dodatkowy szczegół istotny w komunikacji wynikający z podziału na stronę MASTER oraz SLAVE. W tym przypadku zastosowane jest rozwiązanie, w którym strona MASTER "rozdaje karty", czyli przekazuje żeton do wybranego układu SLAVE, który mając "glejt" na dostęp do druta robi swoje, czyli wytransmitowuje swoje dane lub "mówi", że nie ma nic do wytransmitowania. Każde ze stron generując dane do wysłania nie realizuje dostępu do medium (druta) w sposób natychmiastowy (jak typowo robione jest to w przypadku stosowania interfejsu RS232), lecz dane są buforowane. W przypadku strony MASTER, dostęp do medium komunikacyjnego występuje w strumieniu czasu z określoną ziarnistością. Wystąpienie eventu czasowego jest wyzwalaczem do wysłania danych (chociażby przekazania żetonu). W przypadku strony SLAVE, zbuforowane dane muszą czekać do momenty, gdy sterownik uzyska żeton, czyli zezwolenie na wytransmitowanie danych.
W przykładzie występują następujące struktury danych (mikrokontroler ATMEGA162):

Kod: Zaznacz cały

#define IdleState                      0
#define BusyState                      1

#define TXDBuffSize                    32
#define RXDBuffSize                    16

typedef struct { uint8_t CycFr ;
                 uint8_t CycTo ;
                 uint8_t State ;
                 uint8_t Buffer [ TXDBuffSize ] ;
               } TXDRecT ;
typedef struct { uint8_t CycFr ;
                 uint8_t CycTo ;
                 uint8_t Buffer [ RXDBuffSize ] ;
               } RXDRecT ;

static volatile TXDRecT RS485TXDRec ;
static volatile RXDRecT RS485RXDRec ;

Samo odbieranie danych nie odbiega od rozwiązania z interfejsem RS232 (jeżeli interfejs jest wysterowany do funkcji nadawania, to na linii RxD procesora występuje stan pasywny, co implikuje bezczynność odbiornika w fazie nadawania):

Kod: Zaznacz cały

ISR ( USART1_RX_vect )
{
  uint8_t RecCh ;
  /*----------------------------------------------------------------*/
  RecCh = UDR1 ;
  RS485RXDRec . Buffer [ RS485RXDRec . CycTo ] = RecCh ;
  RS485RXDRec . CycTo ++ ;
  if ( RS485RXDRec . CycTo >= RXDBuffSize )
    RS485RXDRec . CycTo = 0 ;
  StartRS485RxTxLED ( ) ;
} /* USART1_RX_vect */

Procedura obsługi przerwania od nadajnika związanego z interfejsem RS485. W stosunku do interfejsu RS232 występuje tu jedna bardzo istotna różnica. Po wysłaniu wszystkich danych zawartych w buforze cyklicznym, należy przestawić interfejs z nadawania na nasłuch. Jak łatwo zauważyć, przestawienie kierunku transmisji w układzie SN75C176 wywołuje skutek natychmiastowy (wywołanie funkcji RS485ReceiveMode). Wysyłając ostatni znak (poprzednie wywołanie funkcji obsługi przerwania), sprzętowe układy kontrolera obsługi transmisji po wykonaniu swego zadania zgłaszają się poprzez przerwanie po kolejny znak (którego już nie ma, gdyż poprzednio został wysłany ostatni). Przestawienie kierunku transmisji „odcina” nadajnik od „druta”. Z eksperymentów wynika, że dane docierają do drugiej stacji bez zniekształcenia, co oznacza, że sam automat sterujący sprzętem nadajnika nie realizuje żadnego kolejkowania znaków, toteż zgłoszenie się po kolejny znak oznacza, że poprzedni już fizycznie wyszedł. W ogólnym algorytmie może zaistnieć przypadek „bardziej inteligentnego” sprzętu sterującego nadajnikiem umożliwiającym kilkubajtowe kolejkowanie nadawanych znaków w samym sprzęcie, wtedy należy posiłkować się przerwaniem od fizycznego opróżnienia nadajnika do zmiany kierunku samego interfejsu SN75C176, gdyż zbyt wczesne jego przełączenie spowoduje urwanie ostatnich znaków (tych, które wg programu zostały wysłane) a „ugrzęzły” w kolejkach FIFO samego sprzętu. Wychodzi, że w prockach AVR nie ma kolejki FIFO :).

Kod: Zaznacz cały

ISR ( USART1_TX_vect )
{
  /*----------------------------------------------------------------*/
  if ( RS485TXDRec . CycFr == RS485TXDRec . CycTo )
  {
    RS485TXDRec . State = IdleState ;
    RS485ReceiveMode ( ) ;                             // <----- istotne
  } /* if ... */
  else
  {
    UDR1 = RS485TXDRec . Buffer [ RS485TXDRec . CycFr ] ;
    RS485TXDRec . CycFr ++ ;
    if ( RS485TXDRec . CycFr >= TXDBuffSize )
      RS485TXDRec . CycFr = 0 ;
    StartRS485RxTxLED ( ) ;
  } /* if ... else */ ;
} /* USART1_TX_vect */

Sterowanie kierunkiem transmisji (przy okazji jest to sygnalizowane poprzez diody LED):

Kod: Zaznacz cały

static void RS485ReceiveMode ( void )
{
  /*----------------------------------------------------------------*/
  RxTxPort &= ~ ( 1 << RxTxDirPin ) ;
  LEDOff ( TransmMLED ) ;
  LEDOn ( RecvMLED ) ;
} /* RS485ReceiveMode */


static void RS485TransmitMode ( void )
{
  /*----------------------------------------------------------------*/
  RxTxPort |= ( 1 << RxTxDirPin ) ;
  LEDOn ( TransmMLED ) ;
  LEDOff ( RecvMLED ) ;
} /* RS485TransmitMode */

Typowa funkcja do wysłania znaku poprzez interfejs RS485. Występuje jedna dość istotna różnica. Domyślnie interfejs RS485 jest ustawiony na nasłuch, więc przed fizycznym wysłaniem znaku należy przestawić interfejs na nadawanie. Każde dalsze nadawanie znaków będzie gromadzone w buforze cyklicznym (z ustawionym układem SN75C176 na nadawanie). Obsługa przerwań od tego nadajnika w sposób naturalny wypróżni kolejkę z bufora cyklicznego i po wysłaniu ostatniego znaku kierunek zostanie przestawiony na odbiór (patrz: ISR ( USART1_TX_vect ).

Kod: Zaznacz cały

static void RS485SendSerial ( uint8_t SerialCh )
{
  uint8_t NextInx ;
  /*----------------------------------------------------------------*/
  cli ( ) ;
  StartRS485RxTxLED ( ) ;
  if ( RS485TXDRec . State == IdleState )
  {
    RS485TransmitMode ( ) ;
    RS485TXDRec . State = BusyState ;
    UDR1 = SerialCh ;
    sei ( ) ;
  } /* if ... */
  else
  {
    for ( ; ; )
    {
      NextInx = RS485TXDRec . CycTo + 1 ;
      if ( NextInx >= TXDBuffSize )
        NextInx = 0 ;
      if ( NextInx != RS485TXDRec . CycFr )
        break ;
      sei ( ) ;
      nop ( ) ;
      nop ( ) ;
      nop ( ) ;
      wdt_reset ( ) ;
      cli ( ) ;
    } /* for */ ;
    RS485TXDRec . Buffer [ RS485TXDRec . CycTo ] = SerialCh ;
    RS485TXDRec . CycTo ++ ;
    if ( RS485TXDRec . CycTo >= TXDBuffSize )
      RS485TXDRec . CycTo = 0 ;
    sei ( ) ;
  } /* if ... else */ ;
} /* RS485SendSerial */

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1321
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: Domowy system sterujący

Postautor: gaweł » środa 27 gru 2017, 17:30

Żyrandol na mikroprocesorach

Jednym z elementów całości jest sterownik przeznaczony do komutacji obwodów w domowej sieci 235VAC 50Hz (generalnie służy do obsługi obciążeń o charakterze czynnym, ale jest możliwość sterowania obciążeniami ze składową bierną → indukcyjnością). Główne zastosowanie to sterowanie oświetleniem w domu. W tym celu został skonstruowany sterownik oznaczony jako PWC2. Wszystkie sterowniki są zasilanie ze źródła napięcia o wartości 12VDC. Schemat pokazują następujące rysunki:
pwc2_il01.png
pwc2_il02.png
pwc2_il03.png
pwc2_il04.png

Do schematu została opracowana płytka PCB.
pwc2_il05.png
pwc2_il06.png
i finale urządzenie:
pwc2_il07.jpg
pwc2_il08.jpg
Elementem wykonawczym sterownika jest:
pwc2_il09.jpg
Sterownik jest zamykany w małej obudowie przeznaczonej do montażu na szynie DIN.
Do współdziałania sterownik potrzebuje włącznika (klawisza) w ścianie, z tym, że wymagany przycisk jest monostabilny (taki, jakie są stosowany do dzwonków i gongów przy drzwiach wejściowych). Jak łatwo zauważyć, na zaciskach ściennego włącznika występuje napięcie o wartości około 5VDC i naciśnięcie go oznacza aktywację wejściowego transoptora U103 (LTV356). Możliwe jest równoległe dołączenie do tego transoptora wielu przycisków w ścianie, co umożliwia utworzenie elastycznej instalacji. Sam sterownik rozpoznaje typowe naciśnięcie przycisku oraz naciśnięcie przycisku z przytrzymaniem, co umożliwia zlecanie sterownikowi dwóch różnych funkcji dysponując jednym przyciskiem. Realizowana funkcja w wyniku naciśnięcia przycisku jest konfigurowalna.
pwc2_il10.jpg
pwc2_il11.JPG
Użycie sterownika:
pwc2_il12.png
W minimalnej konfiguracji sterownik wymaga zasilania +12VDC (właściwie to zakres napięcia zasilającego jest szeroki) oraz przycisku. W standardowym (factory default) wariancie normalne naciśnięcie przycisku oznacza zmianę stanu komutacji fazy na przeciwną (jak było włączone to zostanie wyłączone, jak było wyłączone to będzie włączone). Przyciśnięcie z przytrzymaniem oznacza wyłączenie.
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1321
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: Domowy system sterujący

Postautor: gaweł » środa 27 gru 2017, 17:36

Sterownik w akcji

... w minimalnej konfiguracji (obsługuje piwniczną łazienkę/pralnię). W pomieszczeniu zainstalowane są dwa punkty świetlne → dwa przyciski w ścianie.
IMG_6352.JPG
IMG_6353.JPG
IMG_6354.JPG
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1321
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: Domowy system sterujący

Postautor: gaweł » środa 27 gru 2017, 20:25

Programowalny sterownik do załączania obciążenia 220VAC z komutacją elektroniczną
oprogramowanie i protokół komunikacyjny


Sterownik oznaczony jako PWC2 przeznaczony jest do włączania zasilania 220 VAC do obciążenia o charakterze czynnym lub indukcyjnym z wykorzystaniem komutacji elektronicznej (nie jest zalecany do sterowania silników elektrycznych /wentylatory/ ze względu na potencjalną możliwość generowania wyższych harmonicznych). Sterownik powstał w kilku wersjach sprzętowych różniących się rozwiązaniem stabilizatora napięcia zasilającego mikrokontroler oraz złączem do modułu z diodami LED. Z punktu widzenia oprogramowania wszystkie mutacje sprzętowe są kompatybilne.
Sterownik ma następujące przyłączenia:
  • złącze zasilające, komunikacyjne i sterujące (MICROFIT 6 pin),
    - napięcie zasilające 12VDC (+U, GND),
    - interfejs asynchronicznej transmisji szeregowej RS485 jednoparowy (T-/R-, T+/R+),
    - sterowanie kontrolerem w trybie autonomicznym (KEY).
  • złącze komutujące obciążenie (TERMINAL 2 pin).
Kontroler PWC2 może pracować autonomicznie i być sterowany przez klucz KEY (przycisk NO [normalnie otwarty]). Rozróżniane są dwa tryby pracy przycisku: przyciśnięcie standardowe (czas zwarcia styków do około 2 sek) oraz przyciśnięcie z przytrzymaniem (czas zwarcia styków powyżej 2 sek), gdzie sterownik zareaguje na zaistniałe zdarzenie zgodnie z konfiguracją zapisaną w pamięci nieulotnej.
Generalnie do sterowania kontrolerem PWC2 jest przewidziany interfejs szeregowy RS485 jako jednoparowy (przełączanie kierunku transmisji realizuje sam sterownik). Transmitowane dane mają format tekstowy z protokołem komunikacyjnym opisanym w oddzielnym dokumencie. Limity komunikacyjne w sterowniku PWC2 są następujące:
  • Symbol urządzenia - 8 znaków
  • Symbol polecenia - 16 znaków
  • Parametry polecenia - 32 znaki
Informacje przechowywane w nieulotnej pamięci konfiguracyjnej
    Parametr - Wielkość - Znaczenie - Wartość początkowa
  • Własny identyfikator - Patrz:Symbol urządzenia - Własny identyfikator urządzenia służący do identyfikacji nadawcy oraz adresata w komunikacji szeregowej - PWC2
  • Hasło - 6 znaków - Hasło dla polecenia CONNECT - MAGIC
  • Polecenie SK - Patrz: Symbol polecenia - Polecenie dla sterownika w przypadku naciśnięcia przycisku w trybie standardowym - CHINV
  • Parametr polecenia SK - 1 bajt - Wartość liczbowa (ewentualnie wymagana przez polecenie SK) jako liczba z zakresu 0 .. 255 - 0
  • Polecenie LK - Patrz: Symbol polecenia - Polecenie dla sterownika w przypadku naciśnięcia przycisku w trybie przedłużonym - CHOFF
  • Parametr polecenia LK - 1 bajt - Wartość liczbowa (ewentualnie wymagana przez polecenie LK) jako liczba z zakresu 0 .. 255 - 0
  • Identyfikator nadzorcy - Patrz: Symbol urządzenia - Tabela 4 identyfikatorów urządzeń, które mają być informowane o zmianach wysterowania obciążenia. -
Realizowane polecenia:
  • CONNECT.<hasło> - Autoryzacja modyfikacji parametrów konfiguracyjnych zapisanych w pamięci nieulotnej, przejście do kontekstu <connect>
    Odpowiedź w przypadku błędu: <brak odpowiedzi>
    Odpowiedź w przypadku poprawnym: RCONNECT.<OK>
  • DISCONNECT - Zakończenie pracy w trybie autoryzowanym.
    Odpowiedź (zawsze): RDISCONNECT.<OK>
  • REPLY - Prośba o przesłanie zgromadzonych komunikatów (udzielenie żetonu)
    Odpowiedź (w przypadku braku danych do wysłania): NODATA
    Odpowiedź (w przypadku istnienia kolejki danych do wysłania) zawiera treść tych komunikatów.
  • HELLO - Zapytanie o identyfikację komponentu, z którym realizowana jest komunikacja. Szczególnie przydatne w sytuacji, gdy brak jest szczegółowych danych dotyczących przyłączonego komponentu (zadbać by technicznie był przyłączony jeden komponent i zapytanie kierować w trybie rozgłoszeniowym – w odpowiedzi uzyskany jest jego identyfikator oraz informacje o realizowanej funkcji).
    Odpowiedź (zawsze): RHELLO.HCPWC2-power controller
  • GETVER - Zapytanie o wersję sprzętową i wersję programu sterującego komponentu.
    Odpowiedź zawsze zawiera identyfikację wersji sprzętowej HVER oraz wersji oprogramowania SVER, przykładowo:
    RGETVER.HVER*2_10*V-2013.SVER*1_1*29-01-2015
    wersja sprzętowa numer 2.10 z maja 2013 roku oraz wersja oprogramowania numer 1.1 ze stycznie 2015 roku.
  • GETID - Zapytanie o identyfikator komponentu.
    Odpowiedź zawsze zawiera identyfikator komponentu. Szczególnie przydatne w sytuacji, gdy brak jest danych identyfikacyjnych przyłączonego komponentu (zadbać by technicznie był przyłączony jeden komponent i zapytanie kierować w trybie rozgłoszeniowym – w odpowiedzi uzyskany jest jego identyfikator).
    Odpowiedź zawsze zawiera aktualny identyfikator komponentu, przykładowo: RGETID.PWC2
  • GETEE - (wymagany kontekst CONNECT) Prośba o przesłanie zawartości pamięci nieulotnej w formacie Intel-hex. Przesyłana zawartość pamięci jest podzielona na kolejne bloki (po GETEE przesyłany jest blok pierwszy).
    Odpowiedź (w kontekście <connect>): blok danych w formacie Intel-hex.
    Odpowiedź (w innym kontekście): <brak odpowiedzi>
  • NXPGEE - (wymagany kontekst CONNECT) Prośba o przesłanie kolejnego fragmentu zawartości pamięci nieulotnej w formacie Intel-hex.
    Odpowiedź (w kontekście <connect>): blok danych w formacie Intel-hex.
    Odpowiedź (w innym kontekście): <brak odpowiedzi>
  • REINIT - (wymagany kontekst CONNECT) Ponowny odczyt danych z pamięci nieulotnej (wycofuje zmiany konfiguracyjne do ostatniego zapisanego stanu).
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>: RREINIT.<OK>
  • RESEE - (wymagany kontekst CONNECT) Ustawienie danych konfiguracyjnych do stanu początkowego (nastaw domyślnych), nie zapisuje danych do pamięci nieulotnej (należy dodatkowo użyć polecenia SAVEEE).
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>: RRESEE.<OK>
  • SAVEEE - (wymagany kontekst CONNECT) Zapis aktualnych ustawień do pamięci nieulotnej.
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>: RSAVEEE.<OK>
  • SETMID.<ID> - (wymagany kontekst CONNECT) Określenie nowego identyfikatora dla komponentu (nie jest równoznaczne z zapisem do pamięci nieulotnej).
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>:
    w sytuacji błędnego polecenia: RSETMID.<FA>
    w sytuacji poprawnej: RSETMID.<OK>
  • GETCHNST - Zapytanie o status komutacji obciążenia.
    Odpowiedź w stanie wyłączenia: RGETCHNST.PWC2.CHISOF
    Odpowiedź w stanie włączenia: RGETCHNST.PWC2.CHISON
  • ADDSUP.<ID> - (wymagany kontekst CONNECT) Wprowadzenie identyfikatora komponentu nadrzędnego (<ID> będącego parametrem).
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>:
    w sytuacji poprawnej: RADDSUP.<OK>
    w sytuacji błędnej (błędny format polecenia, wyczerpanie zasobów): RADDSUP.<FA>
  • DELSUP.<ID> - (wymagany kontekst CONNECT) Usunięcie identyfikatora komponentu nadrzędnego (<ID> będącego parametrem).
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>:
    w sytuacji poprawnej: RDELSUP.<OK>
    w sytuacji błędnej (błędny format polecenia, nieznany identyfikator <ID>): RDELSUP.<FA>
  • LISTSUP - Prośba o listę zdefiniowanych komponentów nadrzędnych.
    Odpowiedź (dla listy pustej): RLISTSUP.<EMPTY>
    Odpowiedź w innym przypadku zawiera listę identyfikatorów, przykładowo:
    RLISTSUP.SUPERVIS
  • CSSERVON.<ID> - Prośba o przesyłanie zmian statusu wyjściowego do urządzenia identyfikowanego przez <ID> (obowiązuje do odwołania).
    Odpowiedź w sytuacji poprawnej: RCSSERVON.<OK>
    w sytuacji błędnej (błędny format polecenia, wyczerpanie zasobów): RCSSERVON.<FA>
  • CSSERVOFF.<ID> - Wycofanie prośby o przesyłanie zmian statusu wyjściowego do urządzenia identyfikowanego przez <ID>.
    Odpowiedź w sytuacji poprawnej: RCSSERVOFF.<OK>
    w sytuacji błędnej (błędny format polecenia, nieznany identyfikator): RCSSERVOFF.<FA>
  • CSSERVLIST - Prośba o aktualną listę komponentów nadrzędnych zgłoszonych jako CSSERVON.
    Odpowiedź (dla listy pustej): RCSSERVLIST.<EMPTY>
    Odpowiedź w innym przypadku zawiera listę identyfikatorów, przykładowo:
    RCSSERVLIST.TRACER
  • LISTKC - Prośba o informacje określające reakcję komponentu na naciśnięcie klucza w trybie standardowym i z przytrzymaniem.
    Odpowiedź zawiera wykonywane polecenia przy wystąpieniu określonego zdarzenia, przykładowo:
    RLISTKC.SK0.CHINV
    RLISTKC.LK0.CHOFF
  • ADDKC.<opis> - (wymagany kontekst CONNECT) Wprowadza polecenie reakcji komponentu na naciśnięcie klucza (dla trybu standardowego i z przytrzymaniem niezależnie). Nowe polecenie usuwa dotychczasowe. <opis> zawiera identyfikację trybu pracy klucza, polecenie oraz ewentualne parametry. Nie oznacza, że zmiany zostaną zapisane w pamięci nieulotnej (należy użyć SAVEEE).
    Identyfikacja klucza to:
    SK0 – standardowe naciśnięcie klucza
    LK0 – naciśnięcie klucza z przytrzymaniem.
    Wykonywane polecenie jako jedno z (wraz z ewentualnym parametrem specyficznym dla polecenia):
    - CHON
    - CHOFF
    - CHINV
    - CHPON
    - CHPOFF
    - CHLPON
    - CHLPOFF
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>:
    w sytuacji poprawnej: RADDKC.<OK>
    w sytuacji błędnej (błędny format polecenia): RADDKC.<FA>
  • DELKC.<opis> - (wymagany kontekst CONNECT) Usuwa polecenie reakcji komponentu na naciśnięcie klucza (dla trybu standardowego i z przytrzymaniem niezależnie). <opis> zawiera identyfikację trybu pracy klucza, polecenie oraz ewentualne parametry. Nie oznacza, że zmiany zostaną zapisane w pamięci nieulotnej (należy użyć SAVEEE).
    Identyfikacja klucza to:
    SK0 – standardowe naciśnięcie klucza
    LK0 – naciśnięcie klucza z przytrzymaniem.
    Wykonywane polecenie jako jedno z (wraz z ewentualnym parametrem specyficznym dla polecenia):
    - CHON
    - CHOFF
    - CHINV
    - CHPON
    - CHPOFF
    - CHLPON
    - CHLPOFF
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>:
    w sytuacji poprawnej: RDELKC.<OK>
    w sytuacji błędnej (błędny format polecenia): RDELKC.<FA>
  • NEWPW.<hasło> - (wymagany kontekst CONNECT) Wprowadza nowe hasło do autoryzacji modyfikacji zawartości pamięci konfiguracyjnej. Nie oznacza, że zmiana hasła zostanie zapisana (należy użyć SAVEEE).
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>:
    w sytuacji poprawnej: RNEWPW.<OK>
    w sytuacji błędnej (błędny format polecenia): RNEWPW.<FA>
  • RUNKC.<KEY> - Poleca wykonanie polecenia skojażo0nego z określonym kluczem (symulacja użycia klucza). Klucz <KEY> może być:
    - SK0 – standardowe naciśnięcie klucza
    - LK0 – naciśnięcie klucza z przytrzymaniem.
    Odpowiedź w przypadku niewłaściwego określenia klucza: RRUNKC.<FA>
    W przypadku poprawnie rozpoznanego klucza, odpowiedź jest zależna od realizowanego polecenia.
  • CHON - Poleca włączyć obciążenie.
    Odpowiedź jest uzależniona od listy listy elementów nadzorczych (lista ADDSUP oraz CSSERVON). Jeżeli istnieje jakikolwiek element w tych listach, to do nich wysyłane jest powiadomienie:
    CHISON – kanał jest w stanie włączenia,
    CHISOF – kanał jest w stanie wyłączenia.
  • CHOFF - Poleca wyłączyć obciążenie.
    Odpowiedź jest uzależniona od listy listy elementów nadzorczych (lista ADDSUP oraz CSSERVON). Jeżeli istnieje jakikolwiek element w tych listach, to do nich wysyłane jest powiadomienie:
    CHISON – kanał jest w stanie włączenia,
    CHISOF – kanał jest w stanie wyłączenia.
  • CHINV - Poleca zmienić stan obciążenia na przeciwny.
    Odpowiedź jest uzależniona od listy listy elementów nadzorczych (lista ADDSUP oraz CSSERVON). Jeżeli istnieje jakikolwiek element w tych listach, to do nich wysyłane jest powiadomienie:
    CHISON – kanał jest w stanie włączenia,
    CHISOF – kanał jest w stanie wyłączenia.
  • CHPON.<czas> - Poleca włączyć obciążenie na czas określony przez parametr <czas> (w sekundach).
    Odpowiedź jest uzależniona od listy listy elementów nadzorczych (lista ADDSUP oraz CSSERVON). Jeżeli istnieje jakikolwiek element w tych listach, to do nich wysyłane jest powiadomienie:
    CHISON – kanał jest w stanie włączenia,
    CHISOF – kanał jest w stanie wyłączenia.
  • CHPOFF.<czas> - Poleca wyłączyć obciążenie na czas określony przez parametr <czas> (w sekundach).
    Odpowiedź jest uzależniona od listy listy elementów nadzorczych (lista ADDSUP oraz CSSERVON). Jeżeli istnieje jakikolwiek element w tych listach, to do nich wysyłane jest powiadomienie:
    CHISON – kanał jest w stanie włączenia,
    CHISOF – kanał jest w stanie wyłączenia.
    CHLPON.<czas> - Poleca włączyć obciążenie na czas określony przez parametr <czas> (w minutach).
    Odpowiedź jest uzależniona od listy listy elementów nadzorczych (lista ADDSUP oraz CSSERVON). Jeżeli istnieje jakikolwiek element w tych listach, to do nich wysyłane jest powiadomienie:
    CHISON – kanał jest w stanie włączenia,
    CHISOF – kanał jest w stanie wyłączenia.
  • CHLPOFF.<czas> - Poleca wyłączyć obciążenie na czas określony przez parametr <czas> (w minutach).
    Odpowiedź jest uzależniona od listy listy elementów nadzorczych (lista ADDSUP oraz CSSERVON). Jeżeli istnieje jakikolwiek element w tych listach, to do nich wysyłane jest powiadomienie:
    CHISON – kanał jest w stanie włączenia,
    CHISOF – kanał jest w stanie wyłączenia.

Wszelkie dane konfiguracyjne są zapisane w pamięci EEPROM. Oprogramowanie wykrywa sytuację, gdy pamięć nie ma poprawnej zawartości (jest obliczana suma CRC16 przechowywana w EEPROM razem z blokiem konfiguracyjnym. W początkowych wersjach zawartość pamięci nieulotnej była inicjowana na wartość factory default. Z czasem stałem się trochę leniwy (zamiast wbijać z terminala polecenia konfiguracyjne) i w ramach kompilacji warunkowej zawartość pamięci EEPROM jest inicjowana na odpowiednie wartości wynikające z konkretnego zastosowania (zamiast iść z lapkiem do piwnicy i konfigurować sterownik na miejscu, ta operacja jest realizowana na stole w laboratorium).
Przykładowo:

Kod: Zaznacz cały

/*

        Specyfikacje EEPROM:
        GeneralEEPROM                   - wariant standardowy
        PWC001EEPROM                    - wariant oswietlenia korytarza w piwnicy
        PWC002EEPROM                    - wariant oswietlenia schodów do piwnicy

*/

#define GeneralEEPROM
//#define PWC001EEPROM
//#define PWC002EEPROM

#include "pwc2eeprom.h"
#include <inttypes.h>
#include <avr/pgmspace.h>

#define _KeySmall_

#include "..\common\hc_keycodes.h"

#define null 0

EEPROMBlockDataRecT EEBlock ;

uint8_t ChOnCommand [ ] PROGMEM               = "CHON" ;
uint8_t ChOffCommand [ ] PROGMEM              = "CHOFF" ;
uint8_t ChInvCommand [ ] PROGMEM              = "CHINV" ;
uint8_t ChPulseOnCommand [ ] PROGMEM          = "CHPON" ;
uint8_t ChPulseOffCommand [ ] PROGMEM         = "CHPOFF" ;
uint8_t ChLongPulseOnCommand [ ] PROGMEM      = "CHLPON" ;
uint8_t ChLongPulseOffCommand [ ] PROGMEM     = "CHLPOFF" ;

//********************************************************************
#ifdef GeneralEEPROM
// GeneralEEPROM - wariant standardowy
static uint8_t MyDefaultID [ ] PROGMEM               = "PWC2" ;
static uint8_t SuperiorDeviceID [ ] PROGMEM          = "" ;
static uint8_t GlobalBaseDeviceID [ ] PROGMEM        = "" ;
#endif
//********************************************************************
#ifdef PWC001EEPROM
// PWC001EEPROM - wariant oswietlenia korytarza w piwnicy
static uint8_t MyDefaultID [ ] PROGMEM               = "PWC001" ;
static uint8_t SuperiorDeviceID [ ] PROGMEM          = "KYC001" ;
static uint8_t GlobalBaseDeviceID [ ] PROGMEM        = "HCS" ;
#endif
//********************************************************************
#ifdef PWC002EEPROM
// PWC002EEPROM - wariant oswietlenia schodów do piwnicy
static uint8_t MyDefaultID [ ] PROGMEM               = "PWC002" ;
static uint8_t SuperiorDeviceID [ ] PROGMEM          = "KYC001" ;
static uint8_t GlobalBaseDeviceID [ ] PROGMEM        = "HCS" ;
#endif



static void EEPROMClearBlock ( void *   Destination ,
                               uint16_t Size )
{
  uint16_t Loop ;
  uint8_t * Dst ;
  /*----------------------------------------------------------------*/
  Dst = ( uint8_t * ) Destination ;
  for ( Loop = 0 ; Loop < Size ; Loop ++ )
    * Dst ++ = null ;
} /* EEPROMClearBlock */


static void SetIDFlash ( uint8_t * DeviceID ,
                         uint16_t  String )
{
  uint8_t Data ;
  uint8_t Loop ;
  uint8_t * DestCh ;
  /*----------------------------------------------------------------*/
  DestCh = DeviceID ;
  for ( Loop = 0 ; Loop <= DeviceIDSize ; Loop ++ )
    * DestCh ++ = null ;
  DestCh = DeviceID ;
  for ( Loop = 0 ; Loop < DeviceIDSize ; Loop ++ )
  {
    Data = pgm_read_byte_near ( String ++ ) ;
    if ( Data )
      * DestCh ++ = Data ;
    else
      break ;
  } /* for */ ;
} /* SetIDFlash */


void SetDefaultEEBlock ( void )
{
  /*----------------------------------------------------------------*/
  EEPROMClearBlock ( & EEBlock , sizeof ( EEPROMBlockDataRecT ) ) ;
  EEBlock . EEBlockMetric = StandardSygnature ;
  SetIDFlash ( EEBlock . MyDeviceID , ( uint16_t ) MyDefaultID ) ;
  EEBlock . Password [ 0 ] = 'M' ;
  EEBlock . Password [ 1 ] = 'A' ;
  EEBlock . Password [ 2 ] = 'G' ;
  EEBlock . Password [ 3 ] = 'I' ;
  EEBlock . Password [ 4 ] = 'C' ;
  EEBlock . Password [ 5 ] = null ;
  SetIDFlash ( EEBlock . StandardKeySerrvice . CommandText , ( uint16_t ) ChInvCommand ) ;
  EEBlock . StandardKeySerrvice . ParamValue = 0 ;
  SetIDFlash ( EEBlock . LongKeyService . CommandText , ( uint16_t ) ChOffCommand ) ;
  EEBlock . LongKeyService . ParamValue = 0 ;
  SetIDFlash ( EEBlock . EventDestinDeviceID [ 0 ] , ( uint16_t ) SuperiorDeviceID ) ;
  SetIDFlash ( EEBlock . EventDestinDeviceID [ 1 ] , ( uint16_t ) GlobalBaseDeviceID ) ;
  EEBlock . CRCValue = 0 ;
} /* SetDefaultEEBlock */




Załączniki: wersja źródłowa softu sterownika:
pwc2.zip
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
Ostatnio zmieniony piątek 05 sty 2018, 20:17 przez gaweł, łącznie zmieniany 1 raz.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1321
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: Domowy system sterujący

Postautor: gaweł » czwartek 28 gru 2017, 23:18

Rozszerzona obsługa przycisków

kyc1_ilu00.jpg


Dla sterowników określonych jako PWC2 została skonstruowana warstwa nadrzędna, której zadaniem jest wprowadzenie większej elastyczności w sterowaniu oraz realizacja funkcjonalności typu MASTER dla całej gamy sterowników przyłączonych do interfejsu RS485. Zastosowany mikrokontroler posiada dwa układy transmisji szeregowej (UART), z których jeden via RS485 komunikuje się z całą girlandą sterowników typu SLAVE oraz drugi interfejs via RS232 przewidziany do komunikacji z kolejną warstwą nadrzędną. Pod kontrolą sterownika może być 6 przycisków (włączników) zamontowanych w ścianie (lub jakichkolwiek innych przycisków monostabilnych).
Schemat przedstawiają poniższe rysunki:
Kyc1_ilu01.png
Kyc1_ilu02.png
Kyc1_ilu03.png
Kyc1_ilu04.png
Kyc1_ilu15.png
Kyc1_ilu16.png
Kyc1_ilu07.png
Same przyciski (klawisze) są obsługiwane za pośrednictwem układów transoptorowych, co pozwala na zastosowanie nawet długich przewodów, gdyż połączenie pomiędzy transoptorem a przyciskiem na charakter prądowy i jest odporne na ewentualne zakłócenia (dokładnie takie samo rozwiązanie jest stosowane w sterowniku PWC2). Na rysunkach schematów (ilustracja 7) pokazany jest stabilizator napięcia bazujący na układzie ST1S10 (tak było w oryginalnej wersji). Niestety nie mam dobrych doświadczeń z tym układem, układy padają jak muchy i zamiast tego układu jest „wstawka” z innym stabilizatorem (pisałem o tym w Impulsowy stabilizator napięcia MCP16301).
Do tego jest płytka PCB:
kyc1_ilu08.png
kyc1_ilu09.png
no i finalny układ
kyc1_ilu10.jpg
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1321
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: Domowy system sterujący

Postautor: gaweł » piątek 29 gru 2017, 17:14

Rozszerzone sterowanie modułami PWC
oprogramowanie i protokół komunikacyjny


Sterownik oznaczony jako KYC1 przeznaczony jest do rozszerzonego sterowania modułami komutującymi obciążenie 220VAC (jak przykładowo sterownik PWC2). Sam moduł zarządza 6 przyciskami (włącznikami w ścianie) oraz stanowi funkcjonalność MASTER dla całej gałęzi przyłączonej do interfejsu RS485. Kanał komunikacyjny UART z interfejsem RS232 stanowi łącze do kolejnej warstwy hierarchicznie wyższej.
Sterownik ma następujące przyłączenia:
  • złącze zasilające, komunikacyjne i sterujące (MICROFIT 6 pin identyczne jak w modułach PWC, lecz w miejscu występowania przyłączenia przycisku, piny nie są wykorzystywane),
    - napięcie zasilające 12VDC (+U, GND),
    - interfejs asynchronicznej transmisji szeregowej RS485 jednoparowy (T-/R-, T+/R+),
  • złącze RS232 do warstwy nadrzędnej (typowe złącze DB9),
  • złącze do przyłączenia 6 przycisków (MICROFIT 12 pin).

Stosowane przyciski (w ścianie) są identyczne jak w przypadku sterowania modułu PWC bezpośrednio (przycisk monostabilny). Sam kontroler KYC1 rozróżnia dwa tryby pracy przycisku: przyciśnięcie standardowe (czas zwarcia styków do około 2 sek) oraz przyciśnięcie z przytrzymaniem (czas zwarcia styków powyżej 2 sek) oraz rozpoznawane jest jednoczesne naciśnięcie dwóch dowolnych przycisków również z dwóch trybach (krótkie naciśnięcie i naciśnięcie z przytrzymaniem).
Moduł dane konfiguracyjne przechowuje w swojej pamięci EEPROM. Są to:
  • Parametr - Wielkość - Znaczenie - Wartość początkowa
  • Własny identyfikator - 8 znaków - Własny identyfikator urządzenia służący do identyfikacji nadawcy oraz adresata w komunikacji szeregowej - KYC1
  • Hasło - 6 znaków - Hasło dla polecenia CONNECT - MAGIC
  • Lista SLAVE - 8 identyfikatorów - Tablica identyfikatorów sterowników przyłączonych do RS485 (lista SLAVE)
  • Lista nadrzędnych warstw - 2 identyfikatory - Tablica identyfikatorów sterowników nadrzędnych (przyłączonych od strony RS232), nie muszą być bezpośrednio nadrzędne.
  • Funkcje przycisków - 16-elementowa tablica opisująca rozpoznawalne funkcje przycisków - Tablica zawierająca symbol przycisku oraz polecenie jakie ma zostać wykonane w reakcji na naciśnięcie przycisku (jako tekst polecenia i identyfikator urządzenia SLAVE, do którego jest adresowane polecenie).
  • Tryb wyświetlania - 1 bajt - Określa rodzaj informacji sygnalizowanej na diodach LED. Możliwe jest wyświetlanie statusów (wskaźnik transmisji RS232, RS485, stan CONNECT itp.) lub sygnalizowanie stanu przycisków. - Status
Dopuszczalne symbole przycisków:
SK0, SK1, SK2, SK3, SK4, SK5, SK01, SK02, SK03, SK04, SK05, SK12, SK13, SK14, SK15, SK23, SK24, SK25, SK34, SK35, SK45, LK0, LK1, LK2, LK3, LK4, LK5, LK01, LK02, LK03, LK04, LK05, LK12, LK13, LK14, LK15, LK23, LK24, LK25, LK34, LK35, LK45.
Realizowane polecenia
  • CONNECT.<hasło> - Autoryzacja modyfikacji parametrów konfiguracyjnych zapisanych w pamięci nieulotnej, przejście do kontekstu <connect>
    Odpowiedź w przypadku błędu: <brak odpowiedzi>
    Odpowiedź w przypadku poprawnym: RCONNECT.<OK>
  • DISCONNECT - Zakończenie pracy w trybie autoryzowanym.
    Odpowiedź (zawsze): RDISCONNECT.<OK>
  • HELLO - Zapytanie o identyfikację komponentu, z którym realizowana jest komunikacja. Szczególnie przydatne w sytuacji, gdy brak jest szczegółowych danych dotyczących przyłączonego komponentu (zadbać by technicznie był przyłączony jeden komponent i zapytanie kierować w trybie rozgłoszeniowym – w odpowiedzi uzyskany jest jego identyfikator oraz informacje o realizowanej funkcji).
    Odpowiedź (zawsze): RHELLO.HCKYC1-keyboard controller
  • GETEE - (wymagany kontekst CONNECT), prośba o przesłanie zawartości pamięci nieulotnej w formacie Intel-hex.
    Odpowiedź (w kontekście <connect>): blok danych w formacie Intel-hex.
    Odpowiedź (w innym kontekście): <brak odpowiedzi>
  • SETMID.<ID> (wymagany kontekst CONNECT), określenie nowego identyfikatora dla komponentu (nie jest równoznaczne z zapisem do pamięci nieulotnej).
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>:
    w sytuacji błędnego polecenia: RSETMID.<FA>
    w sytuacji poprawnej: RSETMID.<OK>
  • GETVER - Zapytanie o wersję sprzętową i wersję programu sterującego komponentu.
    Odpowiedź zawsze zawiera identyfikację wersji sprzętowej HVER oraz wersji oprogramowania SVER, przykładowo:
    RGETVER.HVER*1_0*IX-2011.SVER*1_3*XII-2017
    wersja sprzętowa numer 1.00 z września 2011 roku oraz wersja oprogramowania numer 1.3 z grudnia 2017 roku.
  • GETID Zapytanie o identyfikator komponentu.
    Odpowiedź zawsze zawiera identyfikator komponentu. Szczególnie przydatne w sytuacji, gdy brak jest danych identyfikacyjnych przyłączonego komponentu (zadbać by technicznie był przyłączony jeden komponent i zapytanie kierować w trybie rozgłoszeniowym – w odpowiedzi uzyskany jest jego identyfikator).
    Odpowiedź zawsze zawiera aktualny identyfikator komponentu, przykładowo: RGETID.KYC1
  • REINIT (wymagany kontekst CONNECT), ponowny odczyt danych z pamięci nieulotnej (wycofuje zmiany konfiguracyjne do ostatniego zapisanego stanu).
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>: RREINIT.<OK>
  • RESEE (wymagany kontekst CONNECT), Ustawienie danych konfiguracyjnych do stanu początkowego (nastaw domyślnych), nie zapisuje danych do pamięci nieulotnej (należy dodatkowo użyć polecenia SAVEEE).
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>: RRESEE.<OK>
  • SAVEEE (wymagany kontekst CONNECT), Zapis aktualnych ustawień do pamięci nieulotnej.
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>: RSAVEEE.<OK>
  • NEWPW.<password> (wymagany kontekst CONNECT), Wprowadza nowe hasło do autoryzacji modyfikacji zawartości pamięci konfiguracyjnej. Nie oznacza, że zmiana hasła zostanie zapisana (należy użyć SAVEEE).
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>:
    w sytuacji poprawnej: RNEWPW.<OK>
    w sytuacji błędnej (błędny format polecenia): RNEWPW.<FA>
  • RUNKC.<Key> Poleca wykonanie polecenia skojażo0nego z określonym kluczem (symulacja użycia klucza). Klucz <Key> może być jednym z dopuszczalnych symboli przycisku.
    Odpowiedź w przypadku niewłaściwego określenia klucza: RRUNKC.<FA>
    W przypadku poprawnie rozpoznanego klucza, odpowiedź jest zależna od funkcji przycisku.
  • STATDM (wymagany kontekst CONNECT), Poleca sygnalizowanie na diodach LED informacji statusowej.
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>:
    w sytuacji poprawnej: RSTATDM.<OK>
  • KEYBDM (wymagany kontekst CONNECT), Poleca sygnalizowanie na diodach LED informacji o stanie przycisków.
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>:
    w sytuacji poprawnej: RKEYBDM.<OK>
  • LISTSUBD (wymagany kontekst CONNECT), Poleca wyświetlenie listy urządzeń SLAVE.
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>:
    w sytuacji poprawnej przy pustej liście urządzeń: C:KYC1:RLISTSUBD.<EMPTY>
    w sytuacji, gdy lista nie jest pusta zawiera listę: jeden wiersz na jedną pozycję.
  • ADDCH.<name> (wymagany kontekst CONNECT), poleca dodać podaną w parametrach nazwę jako urządzenie SLAVE.
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect> w sytuacji poprawnej: RADDCH.<OK>
    Odpowiedzi w kontekście <connect> w sytuacji błędnej: RADDCH.<FA>
  • DELCH.<name> (wymagany kontekst CONNECT), Poleca usunąć z istniejących podaną w parametrach nazwę jako urządzenie SLAVE.
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect> w sytuacji poprawnej: RDELCH.<OK>
    Odpowiedzi w kontekście <connect> w sytuacji błędnej: RDELCH.<FA>
  • ADDSUP.<name> (wymagany kontekst CONNECT), Poleca dodać podaną nazwę jako adresata nadrzędnego.
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect> w sytuacji poprawnej: RADDSUP.<OK>
    Odpowiedzi w kontekście <connect> w sytuacji błędnej: RADDSUP.<FA>
  • DELSUP.<name> (wymagany kontekst CONNECT), Poleca usunąć podaną nazwę jako adresata nadrzędnego.
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect> w sytuacji poprawnej: RDELSUP.<OK>
    Odpowiedzi w kontekście <connect> w sytuacji błędnej: RDELSUP.<FA>
  • LISTSUPPoleca wyświetlić listę adresatów nadrzędnych.
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>:
    w sytuacji poprawnej przy pustej liście urządzeń: C:KYC1:RLISTSUP.<EMPTY>
    w sytuacji, gdy lista nie jest pusta zawiera listę: jeden wiersz na jedną pozycję.
  • GETCHNST.ALL - Poleca wyświetlić stany wszystkich urządzeń SLAVE (włączone/wyłączone obciążenie).
  • GETCHNST - Jest tożsame jak z parametrem ALL.
  • GETCHNST.<name> - Poleca wyświetlić stan podanego urządzenia SLAVE (włączone/wyłączone obciążenie).
  • ADDKC.<key symb>.<device name>.<command> (wymagany kontekst CONNECT), poleca przyporządkować funkcję dla przycisku (określa polecenie i jego adresata), które jest wysyłane po zdekodowaniu przycisku.
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>:
    w sytuacji poprawnej przy pustej liście urządzeń: C:KYC1:RADDKC.<OK>
    w sytuacji przeciwnej C:KYC1:RADDKC.<FA>
  • ADDKC.<key symb>.<device name>.<command>.<param> (wymagany kontekst CONNECT), poleca przyporządkować funkcję dla przycisku (określa polecenie i jego adresata), które jest wysyłane po zdekodowaniu przycisku.
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>:
    w sytuacji poprawnej przy pustej liście urządzeń: C:KYC1:RADDKC.<OK>
    w sytuacji przeciwnej C:KYC1:RADDKC.<FA>
  • DELKC.<key symb>.<device name>.<command> (wymagany kontekst CONNECT), poleca usunąć przyporządkowanie funkcji dla przycisku, które jest wysyłane po zdekodowaniu przycisku.
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>:
    w sytuacji poprawnej przy pustej liście urządzeń: C:KYC1:RDELKC.<OK>
    w sytuacji przeciwnej C:KYC1:RDELKC.<FA>
  • DELKC.<key symb>.<device name>.<command>.<param> (wymagany kontekst CONNECT), poleca usunąć przyporządkowanie funkcji dla przycisku, które jest wysyłane po zdekodowaniu przycisku.
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>:
    w sytuacji poprawnej przy pustej liście urządzeń: C:KYC1:RDELKC.<OK>
    w sytuacji przeciwnej C:KYC1:RDELKC.<FA>
  • LISTKC (wymagany kontekst CONNECT), Poleca wyświetlić zawartość tablicy przyporządkowanych przyciskom funkcji.
    Odpowiedź (w innym kontekście niż <connect>): <brak odpowiedzi>
    Odpowiedzi w kontekście <connect>:
    w sytuacji poprawnej przy pustej liście urządzeń: C:KYC1:RLISTKC.<EMPTY>
    w sytuacji, gdy lista nie jest pusta zawiera listę: jeden wiersz na jedną pozycję.
  • CSSERVON.<name> - Poleca utworzyć chwilowe dowiązanie (do odwołania CCSERVICEOFF) do informowania o zmianach statusów urządzeń SLAVE.
    Odpowiedź: w sytuacji poprawne: C:KYC1:RCSSERVON.<OK>
    w sytuacji przeciwnej C:KYC1:RCSSERVON.<FA>
  • CSSERVOFF.<name> - Poleca usunąć chwilowe dowiązanie do informowania o zmianach statusów urządzeń SLAVE.
    Odpowiedź: w sytuacji poprawne: C:KYC1:RCSSERVOFF.<OK>
    w sytuacji przeciwnej C:KYC1:RCSSERVOFF.<FA>
  • ECHOON - Włącza echo znaków dla UARTA z interfejsem RS232 (to co jest pisane, przykładowo z terminala, do sterownika wraca na ekran).
  • ECHOOFF - Wyłącza echo znaków dla UARTA z interfejsem RS232 (to co jest pisane, przykładowo z terminala, do sterownika nie wraca).
Załączniki: soft źródłowy:
hc_kyc1.zip
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1321
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: Domowy system sterujący

Postautor: gaweł » piątek 29 gru 2017, 18:26

Rozszerzone sterowanie modułami PWC
Przykład użycia

Kyc1_ilu22.jpg

Rozwiązanie zawiera jeden sterownik KYC1 zarządzający dwoma sterownikami PWC2 i steruje oświetleniem piwnicy oraz schodów prowadzących do piwnicy. Do sterownika KYC1 przyłączonych jest 6 przycisków. Przykładowo:
kyc1_ilu23.jpg
kyc1_ilu24.jpg

Schematycznie wygląda to następująco:
Kyc1_ilu21.PNG

Rzut kondygnacji wygląda następująco:
Kyc1_ilu25.PNG

Wypełnienie pamięci EPROM (zamiast wklepać z laptopa, wbite na stałe do programu: lenistwo wzięło górę)

Kod: Zaznacz cały

void SetDefaultEEBlock ( void )
{
  /*----------------------------------------------------------------*/
  EEClearBlock ( & EEBlock , sizeof ( EEPROMBlockDataRecT ) ) ;
  EEBlock . EEBlockMetric = StandardSygnature ;
  SetIDFlash ( EEBlock . MyDeviceID , ( uint16_t ) MyDefaultID ) ;
  SetIDFlash ( EEBlock . SubDeviceID [ 0 ] , ( uint16_t ) SubDev1ID ) ;   <-    identyfikuje oświetlenie korytarza
  SetIDFlash ( EEBlock . SubDeviceID [ 1 ] , ( uint16_t ) SubDev2ID ) ;   <-    identyfikuje oświetlenie schodów
  SetKeyControl ( & EEBlock . KeyCommTable [ 0 ] , ( uint16_t ) SubDev1ID , StandKey0Code , ChInvCommandCode , 0 ) ;
  SetKeyControl ( & EEBlock . KeyCommTable [ 1 ] , ( uint16_t ) SubDev1ID , StandKey1Code , ChInvCommandCode , 0 ) ;
  SetKeyControl ( & EEBlock . KeyCommTable [ 2 ] , ( uint16_t ) SubDev1ID , StandKey2Code , ChInvCommandCode , 0 ) ;
  SetKeyControl ( & EEBlock . KeyCommTable [ 3 ] , ( uint16_t ) SubDev2ID , StandKey3Code , ChInvCommandCode , 0 ) ;
  SetKeyControl ( & EEBlock . KeyCommTable [ 4 ] , ( uint16_t ) SubDev1ID , LongKey1Code , ChPulseOnCommandCode , 10 ) ;
  SetKeyControl ( & EEBlock . KeyCommTable [ 5 ] , ( uint16_t ) SubDev2ID , LongKey1Code , ChOnCommandCode , 0 ) ;
  SetKeyControl ( & EEBlock . KeyCommTable [ 6 ] , ( uint16_t ) SubDev2ID , StandKey4Code , ChInvCommandCode , 0 ) ;
  SetKeyControl ( & EEBlock . KeyCommTable [ 7 ] , ( uint16_t ) SubDev1ID , StandKey5Code , ChInvCommandCode , 0 ) ;
  SetKeyControl ( & EEBlock . KeyCommTable [ 8 ] , ( uint16_t ) SubDev1ID , LongKey4Code , ChOffCommandCode , 0 ) ;
  SetKeyControl ( & EEBlock . KeyCommTable [ 9 ] , ( uint16_t ) SubDev2ID , LongKey4Code , ChOffCommandCode , 0 ) ;
  SetKeyControl ( & EEBlock . KeyCommTable [ 10 ] , ( uint16_t ) SubDev1ID , LongKey5Code , ChOffCommandCode , 0 ) ;
  SetKeyControl ( & EEBlock . KeyCommTable [ 11 ] , ( uint16_t ) SubDev2ID , LongKey5Code , ChOffCommandCode , 0 ) ;
  EEBlock . DisplayMode = StatusDispMode ;
  EEBlock . Password [ 0 ] = 'M' ;
  EEBlock . Password [ 1 ] = 'A' ;
  EEBlock . Password [ 2 ] = 'G' ;
  EEBlock . Password [ 3 ] = 'I' ;
  EEBlock . Password [ 4 ] = 'C' ;
  EEBlock . Password [ 5 ] = null ;
  EEBlock . CRCValue = 0 ;
} /* SetDefaultEEBlock */

Teraz:
  • Normalne użycie włącznika KEY0 (w centralnym miejscu korytarza) włącza/wyłącza oświetlenie korytarza,
  • Normalne użycie włącznika KEY1 (u zbiegu pralni i kuchni) włącza/wyłącza oświetlenie korytarza,
  • Użycie z przytrzymaniem włącznika KEY1 włącza oświetlenie na 10 sekund oraz oświetlenie schodów na stałe (jak żona bierze miskę z upranymi rzeczami oburącz, to wcześniej używa tej funkcji i idzie... światło zapala się na całej drodze i stopniowo samo się gasi),
  • Normalne użycie włącznika KEY2 (przy początku schodów) włącza/wyłącza oświetlenie korytarza,
  • Normalne użycie włącznika KEY3 (przy początku schodów) włącza/wyłącza oświetlenie schodów,
  • Normalne użycie włącznika KEY4 (przy końcu schodów) włącza/wyłącza oświetlenie schodów,
  • Użycie z przytrzymaniem włącznika KEY4 wyłącza całe oświetlenie (korytarz i schody),
  • Normalne użycie włącznika KEY5 (przy końcu schodów) włącza/wyłącza oświetlenie korytarza,
  • Użycie z przytrzymaniem włącznika KEY5 wyłącza całe oświetlenie (korytarz i schody),

W obrębie jednej gałęzi właściwie można dowolnie sobie kompilować instalację, każdy włącznik przypięty do sterownika KYC1 może wpływać na sterowanie każdego komutatora PWC2 w całej gałęzi sterowników SLAVE wiszących na interfejsie RS485.
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1321
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: Domowy system sterujący

Postautor: gaweł » poniedziałek 08 sty 2018, 12:05

Moduł komunikacyjny PROCO2

Jednym z elementów całości jest moduł komunikacyjny. Jego zadaniem jest przejście z komunikacji via RS232 na komunikację półdupleksową via RS485. Funkcjonalność ta jest wręcz niezbędna w takich sytuacjach jak tworzenie oprogramowania dla sterowników, w których jedynym medium komunikacyjnym jest półdupleksowa transmisja szeregowa (w PC'ach nie występuje taki port, ale daje się nabyć odpowiedni cósik wkładany do portu USB). Moduł ma przewidywane dodatkowe zastosowanie wynikające z konieczności przyłączenia bezpośrednio do płyty PC'ta (tu chodzi mi o wykorzystanie starych płyt komputerowych jako urządzeń dla określonej warstwy całości) całej gałęzi modułów komunikujących się poprzez półdupleksowy RS485.
Schemat przedstawiają poniższe rysunki:
proco2_ilu01.png
proco2_ilu02.png
proco2_ilu03.png
Proco2_ilu04.png
Proco2_ilu05.png
proco2_ilu06.png
proco2_ilu07.png
proco2_ilu08.png
i finale urządzenie.
proco2_ilu09.jpg

Oprogramowanie modułu z przeznaczeniem do testów i konfiguracji innych modułów wykonawczych jest następujące:
proco2.zip

Sama technika obsługi zewnętrznego kontrolera szeregowego opisana jest <tu>.
Moduł ten nie realizuje żadnych poleceń a stanowi jedynie element pośredniczący w komunikacji (konieczna logika związana z „obsługą żetonów” musi być zawarta po stronie „czegoś” przyłączonego do interfejsu RS232. Moduł w akcji:
proco2_ilu10.jpg

Przykładowy dialog komunikacyjny do konfiguracji modułu PWC2 za pomocą emulatora terminala w kompie (transmisja do PWC2, transmisja od PWC2).

HC-PROCO2 - transparetny procesor komunikacyjny

GENERAL:COMP:HELLO
GENERAL:COMP:REPLY

COMP:PWC2:RHELLO.HCPWC2-power controller
GENERAL:COMP:GETID
GENERAL:COMP:REPLY

COMP:PWC2:RGETID.PWC2
GENERAL:COMP:GETVER
GENERAL:COMP:REPLY

COMP:PWC2:RGETVER.HVER*2_00*V-2013.SVER*1_3*09-12-2017
PWC2:COMP:CONNECT.MAGIC
GENERAL:COMP:REPLY

COMP:PWC2:RCONNECT.<OK>
PWC2:COMP:LISTSUP
GENERAL:COMP:REPLY

COMP:PWC2:RLISTSUP.<EMPTY>
PWC2:COMP:ADDSUP.HSC
GENERAL:COMP:REPLY

COMP:PWC2:RADDSUP.<OK>
PWC2:COMP:ADDSUP.COMP
GENERAL:COMP:REPLY

COMP:PWC2:RADDSUP.<OK>
PWC2:COMP:LISTSUP
GENERAL:COMP:REPLY

COMP:PWC2:RLISTSUP.HSC
COMP:PWC2:RLISTSUP.COMP

PWC2:COMP:SETMID.PWC007
GENERAL:COMP:REPLY

COMP:PWC2:RSETMID.<OK>
PWC2:COMP:REPLY
COMP:PWC007:NODATA
PWC007:COMP:SAVEEE
GENERAL:COMP:REPLY

COMP:PWC007:RSAVEEE.<OK>
PWC007:COMP:DISCONNECT
GENERAL:COMP:REPLY

COMP:PWC007:RDISCONNECT.<OK>
PWC007:COMP:RUNKC.SK0
GENERAL:COMP:REPLY

HSC:PWC007:CHISON
COMP:PWC007:CHISON

GENERAL:COMP:REPLY
HSC:PWC007:CHISOF
COMP:PWC007:CHISOF

GENERAL:COMP:REPLY
HSC:PWC007:CHISON
COMP:PWC007:CHISON
HSC:PWC007:CHISOF
COMP:PWC007:CHISOF
HSC:PWC007:CHISON
COMP:PWC007:CHISON
HSC:PWC007:CHISOF
COMP:PWC007:CHISOF

PWC007:COMP:CSSERVON.JAKIS
GENERAL:COMP:REPLY

COMP:PWC007:RCSSERVON.<OK>
GENERAL:COMP:REPLY
HSC:PWC007:CHISON
COMP:PWC007:CHISON
JAKIS:PWC007:CHISON

GENERAL:COMP:REPLY
HSC:PWC007:CHISOF
COMP:PWC007:CHISOF
JAKIS:PWC007:CHISOF

GENERAL:COMP:REPLY
COMP:PWC007:NODATA
PWC007:COMP:CSSERVLIST
GENERAL:COMP:REPLY

COMP:PWC007:RCSSERVLIST.JAKIS
PWC007:COMP:CSSERVOFF.JAKIS

GENERAL:COMP:REPLY
COMP:PWC007:RCSSERVOFF.<OK>
PWC007:COMP:CSSERVLIST
GENERAL:COMP:REPLY

COMP:PWC007:RCSSERVLIST.<EMPTY>
GENERAL:COMP:REPLY
HSC:PWC007:CHISON
COMP:PWC007:CHISON

GENERAL:COMP:REPLY
COMP:PWC007:NODATA
GENERAL:COMP:REPLY
HSC:PWC007:CHISOF
COMP:PWC007:CHISOF
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1321
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: Domowy system sterujący

Postautor: gaweł » poniedziałek 22 sty 2018, 18:17

Zasilanie awaryjne

Każdy system automatyki musi mieć zasilanie. Nie stanowi to żadnego problemu, gdy... Właśnie chodzi o te „gdy”, gdy nie ma prądu, czyli „wcięło fazę”. Bez zasilania żadne urządzenie nie będzie działać. Do przeciwdziałania temu zjawisku zostało przewidziane kiedyś zasilanie awaryjne. Mój wybór wtedy padł na takie urządzenie:
em_ilu01.jpg
em_ilu02.jpg
Ten model może być zasilany z trzech faz (do mego domu dochodzą trzy fazy), co podnosi „szanse” działania przy drobnych awariach energetycznych. Poza tym, jest to „coś”, co może buforować się zespołem zwykłych samochodowych akumulatorów. Przy normalnej pracy urządzenie dba, by akumulatorom nic nie brakowało. W sytuacji awaryjnej, akumulatory stają się ostoją energetyczną. Na wyjściu tej siłowni jest napięcie 48VDC (jak wiele urządzeń z automatyki przemysłowej, szczególnie w telekomunikacji). Oznacza to, że napięcie +48VDC powinno stać się jakimś standardem (przynajmniej częściowym). Jasne jest, że to napięcie nie może być bezpośrednio zastosowane do zasilania procków oraz podobnych układów. Do zasilania konieczne jest zbudowanie odpowiedniej przetwornicy. Rodzi to pewien problem techniczny, gdyż przetwornice impulsowe tolerujące +48V na wlocie nie są układami popularnymi. Powstała koncepcja budowy przetwornicy bazującej na transformatorach impulsowych. Pozwala to dodatkowo na możliwość uzyskania różnych innych napięć. Przedstawiona poniżej konstrukcja przetwornicy generuje na wyjściu +/-5V; +/-12V oraz +5V izolowane (nie mające żadnych punktów wspólnych z wymienionymi napięciami). Do sterowania transformatorem impulsowym wybrany został układ oferowany przez ST o oznaczeniu VIPER50.
em_ilu03.jpg
Przetwornica została tak pomyślana, by stanowiła dość elastyczny element całości. W rzeczywistych zastosowaniach nie muszą być wykorzystane wszystkie napięcia wyjściowe. Dodatkowo sama przetwornica została wyposażona w układ wykrywania zaniku napięcia zasilającego (230VAC), jako element nie związany z przetwornicą. Schemat detektora zaniku fazy jest następujący:
em_ilu04.png
Schemat przetwornicy pokazuje następujący rysunek:
em_ilu05.png
Do tego została opracowana płytka PCB, która jest pokazana na poniższych ilustracjach:
em_ilu06.png
em_ilu07.png
em_ilu08.png
em_ilu09.png
em_ilu10.jpg
Jednym z elementów, które muszą być „cały czas pod parą” jest sterowanie centralnego ogrzewania. Tak się składa, że moja kotłownia oparta jest o piec spalający drewno (bardzo ekologiczne paliwo). Sterowanie to wymaga pomiaru temperatury oraz sterowania silników pompy wymuszającej przepływ wody w kaloryferach. O ile w dawnych czasach stosowane były duże przekroje rur, co pozwalało na stosowanie „napędu grawitacyjnego”. Wystarczyło tylko palić w piecu, a woda sama wiedziała co należy robić. Obecnie, przy mniejszych przekrojach oraz różnych fikuśnych kształtach połączeń mających na celu schowanie rur w ścianach, nie jest to takie proste. Staje się konieczne stosowanie pomp wymuszających przepływ wody. I tu jest właśnie „pies pogrzebany”. Pompy typowo są na 230VAC i w przypadku utraty zasilania, co jest równoznaczne z brakiem odbioru wytwarzanego w piecu ciepła, zagotowanie wody jest kwestią kilku minut.
To stanowi dość istotną cechę dyskwalifikującą (jakoś o tym nie pomyślałem wcześniej) i zastanawiam się nad potencjalną rezygnacją z tego rozwiązania (cóż, czasami trafiają się ślepe zaułki). Na powyższe problemy znalazłem inne rozwiązanie (będzie w innym odcinku), a opisane być może poczeka na swoją szansę (w końcu może być potrzebne gwarantowane zasilanie do czegoś co nie wykorzystuje napięcia sieciowego).
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse


Wróć do „DIY”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 1 gość