Junien/asemien seuraaminen Arduinon ja NodeJS-palvelimen avulla

81 views
Skip to first unread message

Jere Vainionpää

unread,
May 8, 2019, 1:41:47 PM5/8/19
to rata.digitraffic.fi
Moi!

Meillä oli lukiossa mahdollisuus osallistua Lappeenrannan teknillisen yliopiston elektroniikkakurssille, johon kuului itse toteutettava Arduino-projekti. Toteutin sitten laitteen, jolla pystyy seuraamaan junan kulkua (varautunut raideosuus, liikennepaikka ja saapumisen/lähdön ennuste sekä nopeus) tai tietylle liikennepaikalle seuraavaksi saapuvaa tai sieltä lähtevää junaa Digitrafficin APIn avulla. Projekti oli vähän ns. kokeilu, koska mitään käytännön arvoahan (kokemusten ja leikkikaluna olemisen lisäksi) tällaisella härvelillä ei liene - netissä on jo paljon sovelluksia, joilla saa samat tiedot hienommassa muodossa kätevämmin kännykän selaimella. Ajattelin kuitenkin ilmoittaa täällä tällaisenkin toteutuksen olevan mahdollista. Ehkä joku saa siitä hienon idean uudelle sovellukselle...

Käytännössä Arduinolla ei pysty kuitenkaan tekemään kovin monimutkaista "datamurskausta", joten Arduino yhdistää läppärillä pyörivään NodeJS-palvelimeen, joka hoitaa yhteydet Digitrafficin ja tietokannan välillä. Lisäksi Arduinoon on liitetty keypad käyttäjän syötettä varten sekä LCD-näyttö ja piezo-kaiutin ulostuloina. Keypadi on vähän huono asemien syöttämisessä, koska siitä ei löydy ollenkaan kirjaimia, enkä lähtenyt koodaamaan jotain näppäinpuhelimille tyypillistä ominaisuutta, joten haluttu asema syötetään sen UIC-koodilla. Kyllä niitä muutaman pystyy opettelemaan ulkoa - jonkinlainen pikavalinta olisi itse asiassa hyvä kehitysidea.

Tein laitteesta projektiraporttivideon YouTubeen, laitteen demot löytyvät alkaen kohdasta 8:51: https://www.youtube.com/watch?v=pZB0i_n1jmY
Projektin lähdekoodit ja ohjeet käynnistämiseen ovat Github-repositoryssa: https://github.com/junapelaaja/arduino-traintracker (koodin laatu ei ehkä ole parasta - tätä ei ole millään tavalla optimoitu tuotantokäyttöön)
server.js sisältää palvelimella suoritettavan skriptin ja traintracker.ino Arduinolle ladattavan koodin.

Jere

Teemu Sirkiä

unread,
May 8, 2019, 2:04:35 PM5/8/19
to rata.digitraffic.fi
Mielenkiintoinen projekti! Ja mukava esittely videomuodossa lopputuloksesta. Tuon voisi toteuttaa myös Raspberry PI:llä, jossa olisi vähän enemmän tehoa suurikokoisten vastausten käsittelyyn, mutta samalla I/O-pinnit, joilla voisit ohjata näyttöä ja summeria. Tällöin voisit kirjoittaa JavaScriptillä koko paketin, koska myös Raspberryn I/O:n ohjaamiseen löytyy JS-kirjastoja.


Koodivinkkinä, kun ihmettelit kysymysmerkkiä nopeudessa. Jos kirjoitat JavaScriptillä speed || '?' niin nopeus nolla tulkitaan epätodeksi, jolloin kysymysmerkki tulee valituksi. Jos tuon on tarkoitus napata tilanteet, joissa tuo koko tietoalkio puuttuu, niin pitäisi verrata, onko se yhtäsuuri kuin undefined.

Niin ja UIC on siis tällainen: https://uic.org/ :-)

Jere Vainionpää

unread,
May 9, 2019, 2:05:17 AM5/9/19
to rata_digi...@googlegroups.com
Kiitos palautteestasi!

Tuo kävi mielessäni, että Raspberry-toteutus olisi myös mahdollinen. Yliopisto vaati nimenomaisesti Arduino Uno- tai LilyPad-alustaa, mutta onhan Raspberry huomattavasti korkeamman tason ohjelmointia suuremmalla abstraktointitasolla laitteistosta: siinä ei varmaan tarvitse välittää näytön muistiosoitteista tai siitä, mihin pinneihin mikäkin on liitetty, USB- ja näyttöajurit hoitanevat ne asiat. Toisaaalta minusta tuntuu, että hyödyllisin ja tehokkain (puhumattakaan taloudellisuudesta) käyttötarkoitus tälle APIlle on nettipalvelu. Raspberryllakin tehdysta laitteesta tulisi tehdä mahdollisimman pieni, siinä pitäisi olla akku, eikä sitä lopulta kukaan ostaisi, koska kännykällä voi tehdä saman ja enemmänkin.

Toki JavaScript tulkitsee numeerisen arvon 0 epätodeksi, mutta koodin kirjoitusvaiheessa kuvittelin tallentavani nopeudet tietokantaan String-muodossa, ja yritin hieman oikaista ja lyhentää koodia. Silloinhan esim. lausekkeessa speed '0' || '?' muuttuja saisi ensimmäisen arvon, koska se on ei-tyhjä merkkijono. Huomasin ongelmakohdan heti videon kuvaamisen jälkeen, ja korjasin kyseisen lausekkeen muotoon typeof nextEstimate[0].speed === 'number' ? `${nextEstimate[0].speed}` : '?', jotta kaikki muut kuin numeeriset muodot hylättäisiin (periaatteessa se voisi olla undefined tai null). Videolle korjauksesta tein vain lyhyen tekstimaininnan, Githubissa on korjattu versio.

Siihen en ole vielä korjausta tehnyt, että esim. Havukosken toteumat eivät jostain syystä kirjaudu Digitrafficiin ja tämän vuoksi Arduinon palvelin jää odottamaan sen toteumatietoa, mutta yksi tapa korjata se koodissani olisi käydä aikataulurivit läpi takaperin ja etsiä ensimmäinen toteumatieto, jolloin seuraava liikennepaikka olisi edellinen rivi. Tutkin hieman herätepisteitä, ja Havukosken saapumistoteuma kirjautuu suunnassa HVK -> KVY, jos juna varaa raideosuuden HVK 264 tai HVK 267 tai HVK 268 ja lähtötoteuma, jos juna vapauttaa raideosuuden HVK 264. Käytännössä lähes mikään R- tai Z-juna ei kulje näiden raideosuuksien kautta, tai raideosuuksien varautuminen ei ainakaan välity Digitrafficiin. Osa katsomistani junista meni raidetta HKH 262 -> KVY 282.

Se tuntuikin liian yksinkertaiselta, että UIC voisi olla Unique Identifier Code samoin kuin URI on Uniform Resource Identifier... Sitä en tiennyt, että UIC antaa myös asemille numerot, lähinnä se on tuttu vaunujen pidemmistä litteroista (ja UIC-numeroista, sitä en tiedä, kuka EVN-numerot myöntää, vaikka ei niissä taida mitään eroa olla) sekä näistä erilaisista datastandardeista, esim. vaunujen välillä kulkevassa UIC-kaapelissa.

Teemu Sirkiä

unread,
May 9, 2019, 2:42:19 AM5/9/19
to rata.digitraffic.fi


torstai 9. toukokuuta 2019 9.05.17 UTC+3 Jere Vainionpää kirjoitti:
Tuo kävi mielessäni, että Raspberry-toteutus olisi myös mahdollinen. Yliopisto vaati nimenomaisesti Arduino Uno- tai LilyPad-alustaa, mutta onhan Raspberry huomattavasti korkeamman tason ohjelmointia suuremmalla abstraktointitasolla laitteistosta: siinä ei varmaan tarvitse välittää näytön muistiosoitteista tai siitä, mihin pinneihin mikäkin on liitetty, USB- ja näyttöajurit hoitanevat ne asiat. Toisaaalta minusta tuntuu, että hyödyllisin ja tehokkain (puhumattakaan taloudellisuudesta) käyttötarkoitus tälle APIlle on nettipalvelu. Raspberryllakin tehdysta laitteesta tulisi tehdä mahdollisimman pieni, siinä pitäisi olla akku, eikä sitä lopulta kukaan ostaisi, koska kännykällä voi tehdä saman ja enemmänkin.

Jos käytät tuollaista samanlaista LCD-näyttöä, niin kyllä sitä voi ohjata halutessaan ihan samalla abstraktiotasolla kuin Arduinossa. Riippuu paljon, minkälaisella kirjastolla sitä käyttää ja kuinka paljon se tekee asioita valmiiksi.

Siihen en ole vielä korjausta tehnyt, että esim. Havukosken toteumat eivät jostain syystä kirjaudu Digitrafficiin ja tämän vuoksi Arduinon palvelin jää odottamaan sen toteumatietoa, mutta yksi tapa korjata se koodissani olisi käydä aikataulurivit läpi takaperin ja etsiä ensimmäinen toteumatieto, jolloin seuraava liikennepaikka olisi edellinen rivi. Tutkin hieman herätepisteitä, ja Havukosken saapumistoteuma kirjautuu suunnassa HVK -> KVY, jos juna varaa raideosuuden HVK 264 tai HVK 267 tai HVK 268 ja lähtötoteuma, jos juna vapauttaa raideosuuden HVK 264. Käytännössä lähes mikään R- tai Z-juna ei kulje näiden raideosuuksien kautta, tai raideosuuksien varautuminen ei ainakaan välity Digitrafficiin. Osa katsomistani junista meni raidetta HKH 262 -> KVY 282.

Havukoski on vähän hankala paikka ja täälläkin aiemmin keskusteltiin, että herätteitä puuttuu, mutta siihen oli jokin syy, miksi niitä herätteitä ei haluttu lisätä. Herätepisteiden säännöthän löydät täältä: https://rata.digitraffic.fi/api/v1/metadata/train-running-message-rules Lähtökohtaisesti kannattaa varautua siihen, että kaikille aikatauluriveille ei tule toteumia, koska niitä ei kaikilta paikoilta ole turvalaiteteknisesti saatavissa. Ei siis tiedetä, että juna on ohittanut esim. jonkin seisakkeen.
Reply all
Reply to author
Forward
0 new messages