Jindra Fučík

LocoNet rozhraní pro zpětný ohlas

Zpětný ohlas, nebo také detekce obsazení koleje je celkem důležitá součást provozu kolejiště, zejména pro případy řízení kolejiště pomocí počítače, ale také pro provoz těch částí kolejiště, kam uživatel běžně nevidí. Nějaký popis problematiky jsem již v dávné minulosti popsal v tomto dokumentu, docela pěkné vymezení pojmů provedl také Martin na své stránce lokopin.
Nemám v plánu se v tomto článku zabývat tím, proč je potřeba zpětný ohlas a ani jak realizovat detekované úseky. Dokonce když použiji Martinovu terminologii, nehodlám příliš moc řešit konstrukci DO (Detektoru Obsazení), prostě a jednoduše budu předpokládat, že si každý poradí a že detektory které použije jsou vybavené opto oddělovačem, jako například tyto.
Budu se zde zabývat prostým KZH (kodérem zpětného hlášení), který reportuje pouze stavy "obsazeno" a nebo "volno", ačkoli LocoNet je schopen přenášet i další informace - například identifikaci lokomotivy případně další informace, které se dají číst například prostřednictvím RailCom. Tyto informace jsou trochu nejistě popsány například v dokumentu "Digitrax Transponding with BDL168 & RX4 Application Note".

Primární zájem je soustředit se na jednoduché KZH, které jsou podporované většinou programů pro ovládání kolejišť a jejichž konstrukce je jednoduchá pro domácí stavbu. Bohužel pozvolna narážíme na "lidovou tvořivost" o které jsem již několikrát v souvislosti s LocoNetem psal. Proto zde uvedu dva druhy KZH. Jeden extra jednoduchý, který má svou parametrizaci provedenou přímo v programu a druhý, který používá Uhlenbrock LNCV (v podstatě kopie Uhlenbrock 63340).

Hardware

Hardware je v zásadě dost jednoduchý - připojení LocoNet a pak využít všechny dostupné vývody jako vstupy pro detekci obsazení. Možná by stálo za úvahu udělat vstup například pro S88n, ale nemá cenu se pouštět do větších komplikací. Mnohem užitečnější se mi zdá se držet jednoduchého konceptu, který bude snadno použitelný pro výuku.
Pro použití LNCV je nutné, aby modul byl vybaven programovacím tlačítkem a alespoň jednou LED pro signalizaci programování. Pro tyto dvě zařízení se mi zdá jako užitečné použít vývody D0 a D1 (většinou využívané spíš jako Rx(0) a Tx(1) pro sériovou komunikaci). Vzhledem k tomu, že přetěžujeme sériový port a modul ho pro svůj provoz nepoužívá, jeví se jako dobrý nápad použít Arduino Pro Mini, které nemá žádný převodník. Tuto volbu trochu kazí fakt, že právě tato deska má poněkud nejednotně vyvedené vývody A4/18 a A5/19. Byla by pochopitelně škoda tyto piny nepoužít pro vstup. Já tyto vývody většinou řeším tak, že je osadím 90° pinovou lištou a do desky nepájivého pole je připojuji pomocí vodičů M/F. Druhá možnost 90° dutinkovou lištou a připojovat je pomocí klasických vodičů. Pochopitelně pokud si bude uživatel chtít udělat vlastní desku tištěných spojů, musí si dát pozor na to, kde jsou na konkrétním Arduinu vyvedeny tyto vývody, neboť zde panuje určitá nejednotnost. Návrh podle sparkfun má tyto vývody nad vývody A2,A3,Vcc, zatímco velmi levné čínské modely mají tyto vývody před tlačítkem reset a tím zavádí vývody po všech čtyřech stranách. Pro osazování do desky tištěných spojů se mi zdá lepší čínský model, ale znamená úpravu použité patice pomocí žiletkové pilky. Tyto moduly také používám, proto mám ve schématu zakreslené vstupy A4 a A5 na horní straně.

Na schématu nejsou zakreslené vlastní DO (detektory obsazení), jen jeden čárkovaně jako příklad. Jak jsem již napsal, předpokládám, že budou použity 4ks těchto modulů a celková kapacita tak bude 16 vstupů.

Software

Software je celkem jednoduchý, v podstatě jediné co dělá je kontrolování vstupů a při zjištění změny zavolá funkci sendSensor(int Adr, boolean state);. Tato funkce sestaví čtyřbajtový paket který používá opcode OPC_INPUT_REP (0xB2 - General sensor input codes) <IN1> <IN2> <CKSUM>, kde:
IN1 = adresa sensoru 0,A6,A5,A4,A3,A2,A1,A0 (pro detekci obsazení 0,A7,A6,A5,A4,A3,A2,A1)
IN2 = adresa senzoru a jeho status 0,X,I,L,A10,A9,A8,A7 (pro detekci obsazení 0,0,A0,State,A11,A10,A9,A8)

Software existuje ve dvou verzích, první je velice jednoduchá, spíš experimentální. Definuje si dvě pole, jedno se seznamem vstupů (všechny vstupy jsou používány jako digitální, proto jsou používána čísla větší než 13, podívejte se například na TENTO popis vývodů) a druhé s jejich adresou vstupu.:
int dPin[dAnz] = {2, 3, 4, 5, 6, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
int dAdr[dAnz] = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 4096};
To je model, který bude předpokládám pro celou řadu lidí dostatečně funkční. U této zjednodušené verze pozor na jednu drobnost - vznikala jako testovací, takže obsahuje hodně testovacích a debug výstupů na sériový port, takže pokud jí budete používat v provozní praxi, tak si je odstraňte. Na druhou stranu tato verze nepoužívá LED a tlačítko, takže si můžete tyto výpisy nechat aktivní a pomocí sériového portu sledovat komunikaci.

Druhá verze je trochu rozsáhlejší, pokouší se napodobit Uhlenbrock 63340, takže podporuje dva režimy programování. Oba tyto režimy se aktivují stiskem tlačítka (signalizováno LED). Pokud po stisku tlačítka přijde informace o přehození výhybky callback funkce void notifySwitchRequest( uint16_t Address, uint8_t Output, uint8_t Direction ), potom zařízení použije adresu této výhybky jako adresu prvního vstupu (ostatní vstupy se seřadí za tuto adresu) a nastaví default hodnoty ostatních parametrů. Druhý režim je s použitím LNCV programování:
int8_t notifyLNCVprogrammingStart(uint16_t & ArtNr, uint16_t & ModuleAddress)
int8_t notifyLNCVread(uint16_t ArtNr, uint16_t lncvAddress, uint16_t, uint16_t & lncvValue)
int8_t notifyLNCVwrite(uint16_t ArtNr, uint16_t lncvAddress,uint16_t lncvValue)
void notifyLNCVprogrammingStop(uint16_t ArtNr, uint16_t ModuleAddress)
Tyto funkce slouží k ovládání LNCV registrů. Jejich pojmenování je doufám dostatečně popisné, takže není nutné jej nijak vysvětlovat.

V kódu si všimněte jednoho neduhu, se kterým se u Arduina setkáváme poměrně často - v programu je sice definovaný výchozí stav eeprom pomocí direktivy EEMEM unsigned int EEMEM ee_adr = 1;, ale Arduino IDE jej nenahraje do procesoru. Ale nezoufejte, před několika lety vznikl záznam o chybě #1318, tak snad se v brzké době dočkáme zlepšení.
Každopádně jsem pro jistotu udělal vlastí opravu táto chyby. Popis například ZDE.

Použití

Pozor: Vzhledem k existenci chyby #1318 se příliš nedá spoléhat na výchozí hodnoty. Proto velmi doporučuji před začátkem používání tohoto modulu nejprve použít "Zjednodušené programování", které výchozí hodnoty celkem slušně nastaví.

Modul podporuje dva režimi programování: Zjednodušený a komplexní.
Zjednodušený režim slouží k základnímu nastavení a lze jej použít na jakémkoli LocoNet systému. Stačí stisknout tlačítko na modulu, tím dojde k rozblikání LED a modul je připraven k nastavení. Nyní si na libovolném ovladači připojeném ke stejnému LocoNetu zvolte režim ovládání příslušenství, zvolte adresu výhybky takovou, jaká má být adresa prvního vstupu na modulu (bez ohledu na to, jestli je výhybka přítomna či nikoli). Tuto výhybku přehoďte. Tím dojde k nastavení adresy modulu a adresy prvního vstupu. Ostatní vstupy mají adresy jdoucí za sebou. Takže pokud jste například přehodili výhybku číslo 10, pak je adresa modulu = 10 a zároveň první vstup má adresu 10, druhý vstup má adresu 11, třetí 12 a tak dále. Zároveň dojde k nastavení výchozí hodnoty pro "falling time"=0, "rising time"=200 a "report address"=1017 (viz výchozí hodnoty v seznamu LNCV).

Komplexní režim umožňuje změnit každý parametr samostatně. K této změně se používá programovací režim LNCV, Tento režim vytvořil Uhlenbrock a podporují jej systémy které jsou od Uhlenbrock odvozené (zase lidová tvořivost). Tento programovací režim je také dostupný z počítače, ale zatím jsem zjistil, že jej podporuje pouze Rocrail a možná některé jednoúčelové programy k centrálám.
Pro konfiguraci je nutné zadat model. Toto zařízení používá modelové číslo 63340 (zadává se jen 6334, u některých ovladačů poslední 0 svítí vždy a nejde upravovat).
Po zadání modelu (ArtNum, česky: ArtČíslo ) je potřeba zadat ještě adresu modulu. Výchozí adresa je 1, ale při použití zjednodušeného programování se nastaví stejná, jako adresa prvního vstupu. Zařízení reaguje také na všeobecnou adresu 65535. Platí stejné podmínky jako u jiných modulů - používejte pouze pokud je modul jediný na sběrnici; modul pak vrátí svou adresu a ta se na ovladači správně zobrazí. Podle definice je adresa modulu uložená v LNCV0. Při komplexním programování je možné změnit adresu modulu a také je možné nastavit adresy vstupů individuálně tak, že žádný vstup nemá stejné číslo jako je adresa modulu. Následující obrázky ukazují programování za použití ovladače Daisy II.

Následující tabulka popisuje všechna dostupná LNCV. Tento modul se snaží kopírovat stejná LNCV jako Uhlenbrock 63340.
LNCVVýchozí hodnotaVýznam
01Adresa modulu
11Adresa prvního vstupu
22Adresa druhého vstupu
......
1616Adresa šestnáctého vstupu
171017Adresa pro zopakování stavů (report address)
210Čas pro ukončení obsazení (falling time)
41200Čas pro zahájení obsazení (rising time)
Je poměrně dobrou praxí si na moduly psát jejich adresu, protože vyhledávání modulů není v LNCV úplně jednoduché (potřeba připojovat modul jako jediný a podobně). Jedna z jednodušších cest je nové nastavení adresy přes zjednodušené programování.
Adresa vstupů může být v rozsahu 1-4096, v systému se nikde nekontroluje, jestli neexistují dva vstupy se stejnou adresou. Pokud se vám podaří tento stav nastavit, pak dostanete velmi zmatený stav při přejíždění vlaků. Pokud zadáte číslo mimo tento rozsah, bude upraveno do rozsahu.
Hodnota pro opakování znamená číslo výhybky, kterou když "přehodíte" z jiného ovladače na stejném LocoNetu, tak modul zopakuje stavy všech svých vstupů. To může být celkem nebezpečné v případě, že větší množství modulů používá stejnou hodnotu, pak při opakování všech vstupů mohou na docela dlouhou dobu zaneprázdnit sběrnici.
Hodnoty pro zahájení a ukončení obsazení slouží k pro případy, kdy lokomotiva poskakuje po kolejích, takže než se pošle informace o změně až po té, kdy stav trvá nějakou dobu (čas je v milisekundách)