Sprawdzanie niezajętości torów z użyciem modułu detektora

Ten wpis dotyczy kolejowych modułów Arduino. Dowiesz się z niego:

Wprowadzenie

Do tego przykładu wykorzystam moduł detektora niezajętości odcinków oznaczonego kodem 0204. To urządzenie umożliwia sprawdzanie obecności taboru na 4 odcinkach torów.

Zaczniemy od tego jak odczytać dane, a potem zastosujemy to w konkretnym przykładzie.

O tym jak podłączyć moduł do torów i innych urządzeń możesz przeczytać w tym artykule.

Stan zajętości torów

Z punktu widzenia prowadzenia ruchu pociągów, ważne jest uzyskaniu potwierdzenia, że tor na który chcemy skierować pociąg jest pusty i nie dojdzie to zderzenia. Stąd też mówimy o detekcji niezajętości torów.

Definicja niezajętości toru w kodzie biblioteki przewiduje kilka możliwych wartości:

C++
enum TrackUnoccupancy{
  TRACK_UNOCCUPANCY_UNKNOWN = 0,
  TRACK_OCCUPIED = 1,
  TRACK_UNOCCUPIED = 2
};

Stan TRACK_OCCUPIED oznacza, że tor jest zajęty przez tabor.
Stan TRACK_UNOCCUPIED oznacza, że tor nie jest zajęty przez tabor.
Stan TRACK_UNOCCUPANCY_UNKNOWN wykazywany jest, gdy nie można jednoznacznie określić stanu niezajętości toru lub odczyt informacji nie był możliwy.

Sprawdzanie stanu niezajętości toru

Sprawdzanie stanu niezajętości wybranego odcinka toru odbywa się poprzez wysłanie do modułu detektora odpowiedniej ramki danych. Możesz to zrobić z wykorzystaniem programu w urządzeniu do którego podłączony jest sterownik (np. płytki typu Arduino z własnym kodem) lub gotowego kontrolera segmentu.

Aby wysłać ramkę danych do odczytu stanu zajętości toru wykonujemy polecenie checkObjectState, podając jako argument wybrany detektor niezajętości:

C++
TrackOccupancyDetectorRef track1 = new TrackOccupancyDetector(30, 1, "Track 1);
TrackOccupancy result = modules->checkObjectState(track1);

Jest na to też inny sposób, który pokaże Ci w przykładzie.

Przykład

W tym przykładzie wykorzystamy płytkę z podłączonymi sterownikami i czujnikami. Do napisania programu sterującego semaforem i odczytem danych z czujnika wykorzystamy bibliotekę trainbrains SDK. W tym celu należy pobrać bibliotekę i dołączyć ją do projektu. Zależnie od środowiska programistycznego (IDE) będzie się to odbywało nieco inaczej. Możesz obejrzeć to w materiale wideo.

Pełny kod do tego przykładu możesz pobrać z repozytorium trainbrains.

Projekt

Załóżmy, że budujemy makietę z 1 semaforem i jednym czujnikiem niezajętości. Wykorzystamy więc różne 2 moduły:

Nasze urządzenia przytorowe są podłączone do sterowników w następujący sposób:

  • Model semafora świetlnego A jest podłączony do sterownika pod adresem 10, kanał 1;
  • Tor 1 jest podłączony do czujnika niezajętości pod adresem 30, kanał 4.

Cel

Celem programu niech będzie samoczynne podawanie sygnału zezwalającego na jazdę, gdy odcinek za semaforem jest wolny, oraz sygnału “Stój!” gdy odcinek jest zajęty.

Będzie to w dużym uproszczeniu przypominać sytuację jaką możemy obserwować gdy tabor zajmuje odcinki toru na linii wyposażonej w Samoczynną Blokadę Liniową (choć naprawdę działa ona inaczej).

Krok 1. Deklaracja użytych urządzeń przytorowych

Deklarujemy w kodzie programu jakimi urządzeniami przytorowymi będziemy sterować. Można to zrobić na przykład w ten sposób:

C++
#include <Arduino.h>
#include "TrainbrainsModules.h"

TrainbrainsModulesRef modules = new TrainbrainsModules();
TrackUnoccupancyDetectorRef track1 = new TrackUnoccupancyDetector(30, 1, "Track 1");
LightSignalRef signalA = new LightSignal(10, "Signal A");

void setup()
{
  modules->init();
  modules->use(track1);
  modules->use(signalA);  
}

Domyślnym numerem kanału jest 1. W tym przypadku nie trzeba podawać go ręcznie

Krok 2. Reagujemy na zajmowanie toru

Zmianę sygnału na semaforze powiążemy bezpośrednio ze zdarzeniem zajęcia i zwolnienia toru:

C++
void setup()
{
  modules->init();
  modules->use(track1);
  modules->use(signalA);  

  track1->whenTrackOccupied([](TrackUnoccupancyDetectorRef detector){ modules->setSignalAspect(signalA, PKPSignalAspect::Stop); });
  track1->whenTrackReleased([](TrackUnoccupancyDetectorRef detector){ modules->setSignalAspect(signalA, PKPSignalAspect::Clear); });
}

A następnie, w pętli głównej programu wykonamy cykliczne sprawdzanie stanu wszystkich wykorzystywanych obiektów:

C++
void loop()
{
    modules->checkUsedObjectsState();
}

Cała reszta zadzieje się samoczynnie. Gdy w trakcie sprawdzania zajętości toru stwierdzona zostanie zmiana na stan “zajęty”, wówczas wykonane zostanie polecenie skojarzone z tym zdarzeniem, czy podanie na semaforze sygnału “Stój!”. W odwrotnej sytuacji, wykonane zostanie drugie skojarzone polecenie.

Pełny kod tego przykładu możesz pobrać tutaj.

To już prawie wszystko

Hej!

Mam nadzieję, że ten wpis jest dla Ciebie wartościowy. Może chcesz pomóc w rozwoju tych materiałów? Wystarczy, że zostawisz poniżej komentarz co o nim myślisz, czego Ci zabrakło lub co Twoim zdaniem trzeba poprawić albo dasz mu łapkę w gorę 👍

Otrzymuj informacje o nowych ciekawych materiałach. Dołącz do newslettera trainbrains!

Leave a Reply