Kolejna część artykułu o budowie systemu sterowania ruchem kolejowym na stacji Wysoka jest uzupełnieniem i podsumowaniem naszych dotychczasowych działań. Mamy już kompletną część elektroniczną oraz wiemy jak wygląda kod dla segmentu nr 1. Zanim przejdziemy do zgłębiania tajników tego kodu i jego modyfikacji, chciałbym nieco szerzej opisać sposób postępowania z przygotowanym już kodem, aby można było „wsadzić go” do procesora znajdującego się na płytce Arduino. Proces taki nazywa się „kompilacją” i polega na przetłumaczeniu stworzonego kodu w języku C++ do postaci zrozumiałej przez mikrokontroler czy tzw. kodu maszynowego (zapisu w postaci zer i jedynek
Co należy zrobić? Trzeba uruchomić środowisko Arduino IDE i w zakładce PLIK wybrać opcję OTWÓRZ wskazując odpowiedni plik (np. Wysoka_segment_1.ino). Na ekranie edytora pojawi się wówczas cały kod wybranego pliku. Następnie musimy wybrać rodzaj płytki, do której będziemy wgrywać program. Wybieramy, zatem, zakładkę NARZĘDZIA, a następnie menu PŁYTKA, z którego z kolei wybieramy odpowiednią pozycję (np. Arduino Nano).
Teraz możemy kontrolnie zweryfikować poprawność kodu klikając w komendę ZWERYFIKUJ znajdującą się na górnym pasku. Jeśli weryfikacja przebiegnie pomyślnie (brak błędów) możemy przejść do kompilowania kodu. Jeśli natomiast pojawią się jakieś błędy w kodzie, to należy je usunąć. Może się również zdarzyć, że nowo zainstalowane środowisko nie będzie posiadało zainstalowanych potrzebnych bibliotek użytych w naszym kodzie (np. Servo.h). Wtedy trzeba taką bibliotekę pobrać z Internetu (lub z zapisów dostępnych poniżej) w formie pliku zip, w zakładce SZKIC wybrać opcję DOŁĄCZ BIBLIOTEKĘ, a następnie DODAJ BIBLIOTEKĘ ZIP i wybrać odpowiedni plik biblioteki. Teraz możemy już podłączyć płytkę Arduino do komputera poprzez port USB i wybrać w zakładce NARZĘDZIA pozycję PORT i zaznaczyć port „aktywny”.
Gdy płytka jest podłączona, kod zweryfikowany oraz skonfigurowany jest port komunikacyjny to możemy przystąpić do kompilowania naszego programu. Wystarczy wtedy wcisnąć przycisk WGRAJ z górnego paska i poczekać aż kompilator wykona całą pracę.
Proces ten powinien zakończyć się komunikatem:
avrdude done. Tank you. – widocznym w oknie kompilatora (na samym dole ekranu).
W ten oto sposób zaprogramowaliśmy nasze Arduino, które może teraz rozpocząć działanie. Jeśli proces kompilacji się nie powiódł, a weryfikacja przebiegła pomyślnie to najprawdopodobniej port komunikacyjny jest niewłaściwie skonfigurowany i komputer „nie „widzi płytki Arduino. Jest to częsty błąd podczas początkowych działań z Arduino.
Pora na zgłębienie kilku tajników naszego kodu.
Wydaje się, że najtrudniejszą sprawą jest obsługa rozjazdów na naszej makiecie (w sensie programowym oczywiście), zatem wracamy do fragmentu kodu odpowiedzialnego za obsługę serwomechanizmu. Przypomnijmy go:
Jeśli do naszego mikrokontrolera trafi kod „1011” if (data == 1011) to program wykona poniższy blok ujęty znakami { … }, czyli przełoży zwrotnicę rozjazdu do położenia plus (na wprost).
Jako pierwszy jest sprawdzany warunek: czy serwomechanizm jest w pozycji > lub = 98, czyli czy napęd zwrotnicy rozjazdu znajduje się w położeniu minus (na bok). Jeśli tak jest, to można przystąpić do zmiany pozycji.
Kolejna instrukcja – to pętla:
którą można przetłumaczyć następująco:
Rozpoczynając pętlę dla pozycji serwa = 100; kończąc na pozycji serwa >=20; zmniejszaj wartość pozycji serwa o 1.
Po każdym takim zmniejszeniu pozycji następują instrukcje zawarte w bloku, czyli:
– ustaw serwo_1 do obecnej pozycji;
– czekaj 10 milisekund.
Mamy również w tym bloku warunek: jeśli pozycja serwa < 60 (czyli jeśli przekroczymy połowę ruchu napędu) to wyłączamy przekaźnik (służący do polaryzacji krzyżownicy) oraz drugi warunek – o wysłaniu informacji zwrotnej: jeśli serwo osiąga wartość końcową (pozycja serwa < 22).
Wyróżnić można, zatem, kilka parametrów określających nam ruch i zakres tego ruchu oraz prędkość z jaką obrót serwomechanizmu następuje:
- 100 – pozycja początkowa, z której zaczynamy zmianę położenia napędu
- 20 – pozycja końcowa
- 60 – pozycja środkowa (gdy nastąpi zmiana polaryzacji krzyżownicy)
- delay (10) przerwa pomiędzy kolejnymi krokami ruchu
- 1 – wartość pojedynczego kroku
Możemy te wartości zmienić, co spowoduje, że ruch napędu będzie szybszy lub wolniejszy. Również możemy zmienić zakres tego ruchu. Większość serwomechanizmów porusza się w zakresie od 0 do 180 (stopni) i takie wartości możemy wpisać. Proponuję poeksperymentować i poszukać odpowiedniego zakresu ruchu zanim zamontujemy napęd do rozjazdu lub wykolejnicy. A co zrobić, gdy zamiast modelarskich serwomechanizmów chcemy zastosować innego rodzaju napędy – na przykład siłowniki od zamka samochodowego? Otóż, jeśli chcemy sterować jakimś fabrycznym napędem z wyłącznikiem krańcowym, to powinniśmy użyć modułu przekaźnika. Na początku programu należy zdefiniować (czyli nazwać) konkretne wyjście mikrokontrolera, które będzie ten przekaźnik przełączać – na przykład:
w bloku setup()
w bloku odczyt_seriala()
Zastępujemy, zatem, fragmenty programu dotyczące obsługi serwomechanizmów na odpowiednie komendy służące obsłudze przekaźnika.
Napęd z przekaźnikiem łączymy w następujący sposób:
Większość „fabrycznych” napędów rozjazdowych musi być zasilana napięciem od 9 V do 16 V, potrzebujemy zatem dodatkowego źródła zasilania, które poda do nich odpowiednie wyższe napięcie. W tej sytuacji konieczne jest prowadzenie dodatkowego (piątego) przewodu w magistrali pomiędzy segmentami makiety lub – dysponując odpowiednio wydajnym zasilaczem 5V, który zasila naszą magistralę – pokusić się o wykorzystanie przetwornic podwyższających napięcie do np. 12V na potrzeby zasilania takich napędów do zwrotnic rozjazdów. W sytuacji, w której korzystamy z takich napędów nie używamy przekaźnika do polaryzacji rozjazdów, gdyż taki znajduje się wewnątrz napędu. Z tego wynika, że fragment programu odnoszący się do przekaźnika można po prostu… skasować.
Kilka zdań należy poświęcić również samym modułom przekaźników jakie są dostępne na naszym rynku.
Mamy dwa rodzaje takich modułów:
1. wyzwalane stanem wysokim HIGH (5V);
2. wyzwalane stanem niskim LOW (0V).
Nie ma większego znaczenia, które z nich zastosujemy, gdyż w zależności od rodzaju modułu wystarczy tylko odpowiednio podpiąć styki polaryzacji krzyżownicy lub styki napędu.
Trochę inaczej jest w przypadku semaforów sterowanych stanem niskim (LOW). Należy wówczas niejako „odwrotnie” opisać je w programie, czyli tam, gdzie normalnie było HIGH zamienić opis na LOW i odwrotnie.
Na przykład dla sygnału S1 na semaforze A będzie to:
Pamiętajmy, że to samo musimy wykonać na początku programu w bloku setup().
Widać, zatem, że adaptacja programu do nieco innej sytuacji związanej na przykład ze sterowaniem innymi urządzeniami – na przykład napędami do semaforów kształtowych lub napędami do zwrotnic rozjazdów nie będących serwomechanizmami nie jest sprawą skomplikowaną. Wystarczy tylko we właściwym bloku programu pozamieniać odpowiednie parametry nie zmieniając pozostałej reszty.
Podobnie rzecz będzie się miała, jeśli zechcemy rozbudować „system” na przykład dodając do systemu sterowania systemy sterowania oświetleniem budynków czy latarniami zewnętrznymi. Wystarczy wtedy podpiąć się do wolnego wyjścia mikrokontrolera, zadeklarować to wyjście i nadać mu stan początkowy, a w bloku odczyt_seriala dołożyć odpowiednią komendę sterującą tym wyjściem. Pamiętać należy o ograniczeniu prądowym każdego wyjścia mikrokontrolera i w przypadku większych obciążeń stosować moduły przekaźników lub tranzystory.
Mogą pojawić się wówczas pytania: Co zrobić, gdy nie mamy już wolnego wyjścia mikrokontrolera na danym segmencie, a chcemy dołączyć do niego jeszcze jakieś urządzenia? Istnieje kilka opcji. Najprostszą jest zastosowanie płytki Arduino o większej ilości wyjść lub dołożenie drugiej, która obsłuży dodatkowe elementy. Są oczywiście dostępne „ekspandery” wyprowadzeń, ale nie polecam ich stosowania, gdyż obciążalność prądowa tych ekspanderów jest bardzo mała, co czyni problematycznym ich używanie jako wyjść zasilających akcesoria makiety.
Osobiście polecam (i sam stosuję) dostawianie kolejnych płytek Arduino NANO – głównie ze względu na ich niewielkie wymiary oraz (co bardzo ważne) z uwagi na to, że wszystkie płytki w segmentach makiety są jednakowe, a to pozwala na unifikację instalacji, zaś w przypadku uszkodzenia którejś płytki wystarcza posiadanie jednego, zapasowego modułu, który pasuje do wszystkich segmentów makiety.
Pamiętajcie, że tworząc KAŻDY system sterowania należy przewidzieć, iż jego elementy mogą ulec uszkodzeniu (np. z powodu wilgoci, dużych różnic temperatury, czy też przez błąd ludzki), dlatego warto stosować powtarzalne moduły – czy to płytek sterujących, czy przekaźników, czy też rodzaje napędów rozjazdów, wykolejnic itp. Mając pod makietą elementy jednego rodzaju mamy sytuację, w której zapasowy moduł pasuje do wszystkich segmentów, a co za tym idzie występuje łatwość i szybkość wymiany uszkodzonego elementu i możliwość usunięcia usterki w sterowaniu nawet podczas trwania wystawy lub imprezy modelarskiej.
Na koniec jeszcze kilka słów o tym – co dalej?
Następną cześć artykułu poświęcę pulpitowi, czyli sercu systemu. Będzie dokładna analiza kodu pulpitu oraz gotowy plik do pobrania i stosowania na własnych makietach.
Zapraszam do lektury kolejnych odcinków, a przede wszystkim do wyposażenia swoich makiet kolejowych w zależnościowe systemy sterowania urządzeniami srk, będące jednym z kluczowych elementów charakteryzujących prawdziwą kolej.