Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum OPEN%SOURCE,%OPEN%DATA%& HOE%LAAT%KOMT%MIJN%TRAM? SvenBoor&ArjenKremers GymnasiumNovum 12maart2013 1
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum VOORWOORD Ditprojectbegoninhetvoorjaarvan2012,meneerVanLeeuwen,natuurkundedocentoponzeschoolentevensonzebegeleider,lietonseencomputertjeziendatmakkelijkzelfteprogrammerenwas,deArduino.Dezecomputerslootprimaaanbijonzewensomietstedoenmetprogrammerenenpraktischbezigtezijn.MeneerVanLeeuwengafonseenArduinomeeommeeteexperimenteren.VervolgenshebbenwijmetdeArduinoeenverbeterdeversievaneenvalproefgemaakt.HetprogrammahebbenwegeschreveninC.Vervolgenshebbenweeenhardwareversievandeheleoplossinglatenmakenwaardoordeproefmetbehulpvande Arduinoalsmicroprocessordirectinzetbaarisindeklas. Eenaantaldisplaysaantramlijn15inDenHaagtoontalenkelejarengeenreisinformatiemeer. Ditbleektewordenveroorzaaktdoorgeslotensystemen.Erwasgeendocumentatievandedisplaysenvandeinterfaces.Hierdoorwashetnoodzakelijkdespecificatiesviareverseengineeringboventafeltekrijgen.DoordeArduino,alsopensourcecomputer,zijnwegaanonderzoekenofhetmogelijkwasommetdeArduinoeengoedkopeoplossingterealiserenomweeractuelereisinformatietetonen.Inditwerkstukhebbenwedatonderzochteneenoplossinggevonden. DeArduinobleeknietgenoegmogelijkhedentegevenoméndedatateontvangenente verwerkenénomdezeomtezettennaarhetrs232signaaldathetledxdisplayverwachtte. DaaromhebbenwedehulpingeroepenvandeRaspberryPi,eenbudgetXmicrocomputerwaarinwemeteenLinuxvariantdetaalPythonkondendraaien.WemoestenopeenservereenprogrammamakendatdeopendatastroommetactueleXreisinformatieinformatievoorbewerktevoordeafzonderlijkehaltes,zodatdedatastroomnaardehalteplaatszeerbeperktkanblijven.WehebbenonsdetaalPythoneigengemaaktenwarenzoinstaatvoorca. 100aanconsumenteninkoopsprijsdehaltesreizigersinformatietelatenweergeven.Het StadgewestHaaglandenenHTMzijngeïnteresseerdinhetimplementerenvandeoplossing, voorhetaanpassenvan200anderedisplaysinderegioloopteenanderproject.hetbudgetvoorditprojectis 300.000 400.000.RealisatiemetbehulpvanonsopenconceptisvoorHaaglandenveelvoordeliger. Eendemonstratievanhetprobleemenonzeoplossingistebekijkenvia http://vimeo.com/60644074ofdooronderstaandeqrcodetescannen. GraagbedankenwijmeneerVanLeeuwenenmeneerVanSoestvoordeondersteuningenbegeleidingvanonswerkstuk.MeneerVanSoestinhetbijzondervooralhetsoldereneneenpermanenteopstellingmakenvandevalproef.DaarnaastwillenwehethostingbedrijfCJ2 bedankenvoorhetsponsorenvaneenserverenjcdecaux,deexploitantvandeabri s,voorde medewerkingbijhetterbeschikkingstellenvanhetdisplay. 2
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum INHOUD Voorwoord...2! Inhoud...3! Inleiding...4! Valproef...5! Algemeen...6! Hardware...7! Onderdelen...7! Schakelschema...11! Problemen...12! Software...13! Programma...13! Verbeteringen...17! Handleiding...18! Tramdisplay...20! Probleemstelling...21! Realisatie...25! Programmatuur...34! Conclusie...48! Bronvermelding...49! 3
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum INLEIDING OpensourceenopendatazijntweebegrippendiedeafgelopenjarenoveralindeITwereld opduiken.maarwathoudenbeidenbegrippeninenwatkanmenermee? Ditprofielwerkstukishetverslagvanonsonderzoeknaaropendataenopensource.Dit onderzoekisgedaandoorhethoudenvanpraktijkproevenmakenintweelosseprojecten. Heteersteprojectdiendevooralalsreservevooralshettweede,groteprojectnietvandegrondzoukomenwegensonvoorzieneproblemen.Hetprojecthieldeennatuurkundigeproefinwaarbijdegravitatieversnellingvandeaardebepaaldkanwordenmetbehulpvandetijddateenkogeltjeeroverdoetomovereenbepaaldeafstandtevallen.Hetdoelvanhetprojectwasomdezetijdnauwkeurigtemetenmetbehulpvaneenzelfgeprogrammeerdeopensourcemicrocontroller.DezeopstellingkandandoordenatuurkundesectieophetGymnasiumNovumwordengebruiktbijhetonderwijs. Hettweedeprojectishethoofdproject.HetdoelisomeenoudLEDXschermdatoptramhaltestegebruiktwerdomvertrektijdenvantramsweertegevenennietlangerfunctioneerdenieuwleveninteblazendoorgebruiktemakenvanopendataenopensource. OPENDATAENOPENSOURCESOFTWARE OpenDatazijngegevensdievrijvanrechtervoorhergebruikterbeschikkingwordtgesteld. Meestaldoordeoverheid,maarookandereorganisatieskunnenopendatabeschikbaarstellen. OpenDatakandebasisvormenvoornieuwedienstenmettoegevoegdewaarde.Alsburgersenbedrijvenvrijkunnenbeschikkenoverdezeopendata,kunnenzenuttigenieuwetoepassingenontwikkelen.EenvoorbeeldisBuienradar,datgebruikmaaktvangegevensvanhetKNMI. KortommethetvrijgevenvenOpenData,kunneneconomischeactiviteitenwordenontplooid. Opensourcesoftwarebetekentdatdebroncodewaarindesoftwareisgeschrevenvrijbeschikbaaris.Iedereenkandebroncodelezen,aanpassenenverspreiden.Bijandere geslotensource softwareisdegebruikerafhankelijkvandeoorspronkelijkeleverancierenheeftzelfgeentoegangtotdebroncode.netalsopenstandaardenisopensourcesoftwarebelangrijkommeeropenheidinictsystementerealiseren. DecombinatievanOpenDataenopensourcesoftwarekunneneninnovatieeneducatieeen enormeimpulsgeven. 4
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum VALPROEF VANANALOOGNAARDIGITAAL 5
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum ALGEMEEN Metdevalproefdiebeschrevenwordtkandevalversnellinguitgerekendworden.Devalversnellingwordtbepaalddoordeafstanddathetkogeltjevaltendetijddiehetkogeltjedaaroverdoetnauwkeurigtemeten.Debeschrijvingisopgedeeldineenstukoverhardware, softwareeneenhandleidingoverhoedeopstellinggebouwdkanworden. Devalproefwerdinhetverledenalgebruikt,alleenwaseraltijdeengrootprobleemmetdetijdwaarneming.Deexternetimerwaarmeewordtgewerktisnamelijkerggevoelig.Vroegerwerddetimeropeen analoge maniergeactiveerd.ertreedtdaneenbounceeffectopbijhetindrukkenvaneenschakelaar.ditiseenstuiteringofschommelingvandespanningbijhetafschakelenvandestroom.detimerwerktalleenopdigitalesignalen,duskanalleeneenlaageneenhoogsignaalwaarnemen.deschommelingvandespanningisvoordetimereenwisselendaanxenuitsignaal,ditisnietnauwkeuriggenoeg.doornueenstukjeelektronicatoetevoegenkunnenwesoftwarematigdatbounceeffectondervangenzodathetgeenstorendewerkingheeft.hierbijwordtvoorhetaansturenvandetimergebruikgemaaktvaneendigitaalsignaal. 6
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum 7 HARDWARE Dehardwarewordtindrieonderdelenbehandeld.Inheteersteonderdeelwordtuitgelegdwelkeonderdeleninhetcircuitzijnopgenomenenwelkefunctiezehebben.Inhettweededeelwordtuitgelegdhoedeverschillendeonderdelenmetelkaarsamenhangeneninhetlaatstedeelwordenproblemenmetdehardwarebehandeld. ONDERDELEN Hierondervolgteenlijstmetalleonderdelendieinhetcircuitopgenomenzijn. X Arduinomicrocontroller X 1rodeLED X 1geleLED X drukknop X spoel X luik X externespanningsbron X FET X diode X externetimer X weerstanden ARDUINO DeArduino 1 iseenprogrammeerbaremicrocontrollerdiesoftwarematigreageertopsignalenvansensorendieeropaantesluitenzijnenzelfsignalenafgeeftomanderehardwareaantesturen. LED S DeLED sinhetcircuitfungerenalscontrolelampjes.watdelampjespreciesaangeven,iste vindeninhetsoftwaregedeelteenindehandleiding. DRUKKNOP Dedrukknopisinhetcircuitopgenomenomdemetingtekunnenactiverenenteresetten. SPOEL Despoelisbedoeldomhetballetje vasttehouden tothetmomentwaaropdedrukknopwordtingedruktendestroomwordtonderbroken.despoelwerktmetbehulpvanhetprincipevanmagnetischeinductie.doorereenelektrischestroomdoorheentelatenstromenontstaateenmagnetischvelddathetstalenkogeltjevasthoudt.despoelheefteenkoperdraadmeteendoornedevan0,18mmeneenweerstandvan120,7ω. Vandespoelwarendevolgendegegevensbekend: X Diameterinwendig:12mm X Diameteruitwendig:30mm X Hoogte:15mm 1http://www.arduino.cc/ 2nl.wikipedia.org/wiki/Koperdraad
!"#$%&%'! =!!"#$%&'"(!!!"#$"%!&! =!30!!!!!12!!!! =!18!!!! Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum X Doorsnedekoperdraad:0,18mm X NietXmetallischekern X Geenredundantmagnetisme Detotalediameteristeberekenendoordeuitwendigediameterminusdeinwendigediameter tenemen. Hetoppervlaktevandedoorsnedevandespoelisalsvolgtteberekenen.!""#$%&'&!!"#$%! =!!"#$%&%'!!h!!!"#! =!18!!!!!15!!!! =!270!!!!! =!2,7!!"!! OpWikipedia 2 isopdepaginaoverkoperdraadhetaantalwindingentevindenbijeengegeven doorsnedevandekoperdraad.eenkoperdraadmeteendiametervan0,18mmgeeft2270 windingenpervierkantecentimeter.vermenigvuldigdatmethetaantalvierkantecentimeterdoorsnedediewijhaddenomhetaantalwindingentekrijgen.ditgetalmoetnoggedeeldwordendoortweeomdateenwindingzowelheenalsteruggaat,hijlooptimmersrondomdespoel.!! =!2,7!!2!!2270! =!3064,5!!"#$"#%&# Hieronderisinbeeldgebrachthoedezeberekeningtotstandisgekomen. 2nl.wikipedia.org/wiki/Koperdraad 8
(15!!!! +!6!!!)!!2! =!10,5!!!!!!"#$"#% =!!!!2!!!! =!!!!2!!10,5!!!! =!65,973!!!! =!0,065973!!!!!"##! =!!!"#$"#%!!!! =!0,065973!!!!3064,5! =!202,18!!! =!2,0218!h!!!! =!2,0218!h!!!69!!/h!! =!!139,5042!!! Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum Delengtevanéénwindingisongeveerdeomtrekvandespoel.Delengtevandehelekoperdraadmoetdanhetaantalwindingenmaaldelengtevanéénwindingzijn.Alsstraalwordthetgemiddeldegenomenvandebinnenstestraal,6mm,endebuitenstestraal,15mm. IndetabelopWikipediaisookaftelezenhoegrootdeweerstandisineenkoperdraadbijeen gegevendraaddikteperhectometer.bijeendraaddiktevan0,18mmisdit69ω/hm. VermenigvuldigditmetdeafstandinhectometeromdeweerstandinOhmtekrijgen. Afgerondopsignificantecijfersgeeftditeenweerstandvan140Ω. 9
Deschakelaarisinhetcircuitopgenomenomhetstalenkogeltjetedetecteren.Deschakelaar onderbreektdestroomalshijopenstaat,watwaargenomenkanwordendoordearduino. EXTERNESPANNINGSBRON Inhetcircuitiseenexternespanningsbronopgenomenomdespoelvaneenspanningvan30 volttekunnenvoorziendienodigisomdespoelgoedtelatenfunctioneren. FET DeArduinokandehogespanningdienodigisvoordespoelnietleveren,dusmoetereenexternespanningsbronwordenaangesloten.Dezemoetopeenapartcircuitwordenaangesloten,zodatdehogespanningooknietoverdeArduinokomttestaan,dusomdezespanningtelatenlopenofteonderbrekenmetdeArduinoiseenFETnodig. DIODE Naafschakelingvandestroomdoordespoelblijftereenstroomlopendoordespoeltotdathetmagnetischveldvandespoelwordtafgebroken.Ditkomtdoordatdemagneeteeninductiespanningopwekt.DezespanningkanoplopentotduizendenVolt.Deenergiekandanalleenwegdoormiddelvaneenvonkontlading,diewaarschijnlijkindeFETplaatsvinden.Dezekandaardoorkapotgaan.Ditistevoorkomendooreendiodetegengesteldparallelaandespoelintebouwen.Ophetmomentdatdestroomvanuitdespanningsbrondoordespoellooptgaatergeenstroomdoordediode,maarophetmomentdatdestroomwordtonderbrokenendespoeleenspanninggaatgenereren,kandezespanningteruggevoerdwordenviadediode. EXTERNETIMER Detimerisinhetcircuitopgenomenvoordetijdwaarneming.DeArduinobleekookprimainstaatomtijdwaarnemingtedoen.Vooralvankorteduur,zoalsinditgeval,wanttoengetestwerdovereentijdvantientallensecondenbleekereenredeljikgroteafwijkingtezijn.Voordemonstratiesindeklasisdegroteexternetimergeschikter,omdatdezedirectdewaargenomentijdlaatzienenergeencomputervoornodigisdiedeseriëleoutputvande Arduinoontvangt. Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum SCHAKELAAR 10
11 SCHAKELSCHEMA Onderstaandeafbeeldinggeefthetschakelcircuitweer. Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum 12 PROBLEMEN Tijdenshetontwikkelenzijnweooktegeneenaantalproblemenaangelopen.Bijvoorbeelddatwedeexternetimereerstoppin1haddenaangesloten,maardoordeseriëleinterfaceteinitialiseren,dieookzijnsignaalnaarpin1stuurt,isdezepoortnietmeertegebruiken.Hijgeeftdannamelijkelke1/9600 e vaneensecondeeenpulsbijeenbaudratevan9600.alsdeseriële interfacenietgeïnitialiseerdwordtispin1welgewoontegebruikenvooreenpuls aan en uit. Eenanderprobleemwaarwetegenaanliepenwarendedraadjesomdeverschillendeonderdelenvanonscircuitmetelkaarteverbinden.Dezedraadjeszijnergkwetsbaarendooreendefectdraadjeinhetcircuitwordtdeheleopstellingonbruikbaar.Eenprobleemalsditismoeilijktevinden,omdatjenietsnelbedenktdatdithetprobleemkanzijnenereengrotehoeveelheidaandraadjesisgebruikt.
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum #define LED 13 //De LED die aangeeft of de opstelling klaar is voor een meting. #define FET 5 //De FET. Door deze aan of uit te zetten kan de spoel wel of niet onder spanning worden gezet. #define SWITCH 4 //De schakelaar waar het kogeltje op valt. #define BUTTON 2 //De drukknop die gebruikt wordt voor het resetten en het starten van de meting. #define ALERT 12 //Deze LED is het waarschuwingslampje dat aan gaat als de schakelaar open is. #define TIMER 8 //De externe timer die gebruikt wordt om de valtijd op te meten. unsigned long starttime; //De tijd in millisecondes op het moment dat de meting begint en het kogeltje wordt losgelaten. unsigned long lastresettime; //De tijd in millisecondes dat de opstelling voor het laatst is gereset. boolean balldropped = false; //De vlag die aangeeft of het kogeltje aan het vallen is. boolean isset = false; //De vlag die aangeeft of de opstelling klaar is voor een meting.! Onzegehelesetup&functieisalsvolgtingericht: 13 SOFTWARE PROGRAMMA OmdeArduinonaareigeninzichttelatenreagerenopsignalenmoetdecontrollergeprogrammeerdworden.EenArduinoXprogrammabestaatuittweebasisonderdelen,tweefuncties.Eénwordtaangeroepenbijhetopstartenvanhetprogramma.Ditisdesetupfunctie. Deanderefunctieisdeloopfunctie.Dezefunctiewordtnadeinitialisatievanhetprogramma continuaangeroepen. Aanhetbeginvanhetprogrammawordendebenodigdeconstantenenvariabelengedeclareerddienodigzijninderestvanhetprogramma.Depoortendiegebruiktgaanwordenzijnallemaalgedeclareerdindepreprocessor.Ditzorgtervoordatvoordatdecodewordtgecompileerd, klaargemaaktomtewordengebruiktdoordearduino,alleovereenkomstenindecodewordenvervangendoordetoegewezenwaarde.opdezemanierwordtergeengeheugenverbruiktvoordezewaardesopdearduino,maarermoetgoedgeletwordenopmogelijkefoutendiegemaaktkunnenworden.dezewordennamelijknietopgevangendoordecompiler. Eerstwordthieraangegevendatdeseriëlepoortmoetwordengeactiveerd.MetdezepoortkunnengegevenswordenverstuurdviadeUSBXpoortopdeArduinonaardecomputer,omweergegeventewordenophetscherm.Bijdeinitialisatievandeseriëlepoortmoetookwordenaangegevenophoeveelbauddezedraait.Eenbaudisdeeenheidvoorhetaantalbitsdatpersecondewordtverstuurd.Hierisgekozenvooreenbaudratevan9600baud.Ditisnamelijkeenveelgebruiktesnelheid,engoedvooronsgebruik. Daarnawordendegebruiktepinsgeïnitialiseerd.Dedrukknopendeschakelaarwaarhetkogeltjeopvaltwordenalsingangenvoorgegevensgebruikt.Zokunnendewaardesafgelezenworden.Deoverigeattributen,detweeLED s,defetendeexternetijdmeter,hebbeneensignaalnodig.omteschrijvennaardezepinnenwordenzealsuitgangengeactiveerd.
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum void setup() { // Initialiseer de Serial met een snelheid van 9600 baud. Serial.begin(9600); Serial.flush(); // Initialiseer de output en input pins. pinmode(led, OUTPUT); pinmode(fet, OUTPUT); pinmode(timer, OUTPUT); pinmode(button, INPUT); pinmode(switch, INPUT); pinmode(alert, OUTPUT); digitalwrite(fet, LOW); //Stuur een laag signaal naar de FET zodat de spoel niet aan staat. }! 14 Deloopfunctieiseenstukcomplexerenzalindelenwordenuitgelegd.Voorheteigengemaken deeigenduidelijkheidisdecodezelfookalingedeeldinmeerderemethodes. Deeersteselectiedieindeloopmethodewordtuitgevoerdbepaaldhoelangdeopstellingalklaarisvoorgebruikt.Vanwegeveiligheidsredenenenhetgebruikvaneenmagnetischespoelwordtdeopstellingnatiensecondesweeruitgeschakeld,zodathijopnieuwgeresetmoetworden.Nadezecheckwordtgekekenoferopdedrukknopwordtgedrukt,enofdeschakelaarnaarbenedenis. void loop() { if (millis() lastresettime > 10000) { unset(); } // Als de bal al losgelaten is hoeft de knop niet meer gecheckt te worden, maar dan moet de schakelaar gecheckt worden. checkbutton(); checkswitch(); }
void checkbutton() { /* Als de bal aan het vallen is wordt de functie vroegtijdig afgebroken. Als de knop niet is ingedrukt gebeurt er eveneens niets. */ if (balldropped) { return; } } if (digitalread(button) == HIGH) { if (isset) { dropball(); } else { reset(); } }! Alsblijktdathetkogeltjealaanhetvallenis,wordtdefunctieafgebroken.Ergebeurtverderniets.Anderswordtdepindieaandeknopbevestigdisgelezen,metdemethodedigitalRead,enbepaaldofhetsignaalhoogisendeknopdusisingedrukt.Aangeziendeknopgebruiktmoetwordenvoortweedoeleinden,hetresettenenhetlatenvallenvandekogel,volgternogeenselectie.Alsdeopstellinggeresetis,endusklaarisomtemeten,wordthetballetjelosgelatenendemetinggestart.DitgebeurtindedropBallfunctie.Isdeopstellingnietklaarvoorgebruik,danbegintdeprocedureomhetsysteemklaartemakeninderesetfunctie. dropball&werktalsvolgt:allereerstwordtnaardeseriëleuitgangeenstringverzondendatdemetingisgestart.deballdroppedwaardewordtnaartruegezet,zodathetprogrammaweetdatdemetingloopt.destarttijdvandeinternetimerwordtnaardehuidigetijdgezet.naarde TIMERpoortwordteenhoogsignaalgeschrevenhetgeeninhoudtdatdeexternetimerstartmettellen.ErvolgteenaanroepnaardeunsetXfunctie,waardoordespanningopdemagneetspoelwordtweggenomenenhetkogeltjevalt. void dropball() { Serial.println("Meting gestart"); balldropped = true; starttime = millis(); //Start interne timer. digitalwrite(timer, HIGH); //Start externe timer. unset(); }! Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum DecheckButton&functiezieteralsvolgtuit: 15
void checkswitch() { if (digitalread(switch) == LOW) { if (balldropped) { digitalwrite(timer, LOW); // Stop de externe timer. unsigned int delta = millis() starttime; // Meet de interne verlopen tijd. balldropped = false; Serial.print("Millisecondes: "); // Zend de waarde van de interne timer naar de Serial. Serial.println(delta); float seconds = float(delta)/1000.0; //De millisecondes worden omgerekend naar hele secondes. Serial.print("Gravitatieversnelling: "); Serial.print(((2*0.335)/(seconds*seconds))); //Hier wordt de gravitatieversnelling uitgerekend met de formule. 0.335 is de afstand die het kogeltje heeft afgelegd. Serial.println(" m/s^2"); } digitalwrite(alert, HIGH); //De rode LED wordt aangezet. unset(); //De opstelling wordt gereset. } else { digitalwrite(alert, LOW); } }! Heteerstedatwordtgecontroleerdisofdeschakelaaropenisofgeslotendoorhetsignaalwaartenemen.Deschakelaarisgeopendalshetsignaallaagis,wantdanisdestroomkringonderbroken,enhijisgeslotenalshetsignaalhoogisendestroomkringgesloten.AlsdeschakelaargeslotenishoeftalleendewaarschuwingsXLEDuitgeschakeldteworden. Ishijgeopend,danishetdevraagofdemetingbezigis.Alsdemetingnamelijkgestartis,danbetekenthetdathetkogeltjedoordeschakelaarheenisgevallenendusdeafstandheeftafgelegd.Numoetdetijdgestoptworden.Datgebeurtallereerstdoordeexternetimertestoppenmeteenschrijfoperatienaarlaag.Daarnawordtdeverlopentijduitgerekenddoordestarttijdvandemetingvandehuidigetijdaftetrekken.Dezeberekendewaardewordtnaardeseriëleuitganggestuurd.Degravitatieversnellingwordtvervolgensookuitgerekendmetdeformuleg! = 2s!/!t! engeprintnaardeseriëlepoort. HiernawordtzowelinhetgevalvaneenmetingalswanneerergeenmetingheeftplaatsgevondendeopstellinggeresetenderodewaarschuwingsXLEDaangezet.DezeLEDgeeftaandatdeschakelaaropenstaat. Nuvolgtdedocumentatievandelaatstetweefuncties,reset()enunset(): Deopstellingkannooitgeresetwordenalsdeschakelaaropenstaat.Ditwordtdusallereerstgecontroleerdenerwordteenberichtverzondennaardeserialalsdithetgevalis.BijdewerkelijkeresetwordtdegeleLEDaangeschakeld,omaantegevendatdeopstellingklaarisvooreenmeting.DeFETwordtookaangezetzodatdeereenspanningdoordemagneetspoellooptomhetballetjevasttehouden.DelaatsteresettijdwordtnaardehuidigetijdgezetenheterwordtaangegevendatdeopstellinggeresetismetdeisSet&waarde.Ervolgteendelayvaneenseconde,watervoorzorgtdatdemetingnietonmiddelijkbegint.Dedrukknopisnamelijkwaarschijnlijknogsteedsingedrukt. Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum DecheckSwitchfunctieisalsvolgtingedeeld: 16
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum void reset() { if (digitalread(switch) == LOW) { Serial.println("Sluit de schakelaar"); } else { Serial.println("Reset"); digitalwrite(led, HIGH); digitalwrite(fet, HIGH); lastresettime = millis(); isset = true; } delay(1000); }! void unset() { digitalwrite(led, LOW); digitalwrite(fet, LOW); isset = false; } 17 InunsetwordtdeLEDdieaangeeftdatdeopstellingklaarisvooreenmetinguitgezet,samenmetdeFET.Hierdoorwordtdespanningvandespoelafgehaald.NaardeisSetwaardewordtfalsegeschreven. VERBETERINGEN Hetontwerpenvandeprogrammatuurverliepnietvolgensdebestemethode.Eenaanpassingvandeschakelinggingsteedsvoorafaaneenkleinetoevoegingaandecode.Opdezemanierwaszoweldeopstellingalshetprogrammaeenvoudigtetesten.Eennadeelvandezemethodeisdatmetnamehetprogrammanietoverzichtelijkwordtopgebouwd,waardoorenkeleslordighedenoverhethoofdzijngezien. Hierondervaltdemanierwaaropdedrukknopenschakelaarwordengecontroleerd.Eenbeterimplementatiewasgeweestalserzowelvoordeknopalsvoordeschakelaareenbooleanwasgedeclareerddiebijhieldofdeknopingedruktis,endatelkeiteratievanhetprogrammawordtgecontroleerdofdestaatvandeknopofschakelaarisveranderd.Alsdathetgevalis,wordtereenfunctieaangeroepen.Indezefunctiewordtdanvervolgenshetnodigegedaan.Dezemethodeisietsomslachtiger,maarveeloverzichtelijker,eneenbelangrijkprobleemwordtermeevermeden,namelijkdatsommigefunctieselkeiteratiewordenaangeroepenalsdatnietnodigis. Ditisookhetgevalbijdecontrolehoelangereenstroomdoordemagneetspoelloopt.Nadatdetiensecondendatdeopstellinggereedisverstrekenzijn,wordtcontinudeunsetfunctieaangeroepen,ookalisditslechtséénmaalnodig.
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum 18 HANDLEIDING 1. Zorgervoordatdeelektronicaendedradenalsvolgtzijnaangesloten: Degroundvandetimer,deArduinoendeexternespanningsbronmoetenmetelkaarverbondenzijn.Deexternespanningsbronmoetaangeslotenwordenopdecontactenwaar 25V= bovenstaateningesteldwordenop25voltgelijkspanning.hetmetalenklepje,hetluik,moetwordenaangeslotenbij luik endespoelbij spoel. DebundelkabeltjesuithetkastjegaatrichtingdeArduinoenmoetalsvolgtopde Arduinowordenaangesloten: WitXgeel: 5V Zwart: Pin12 Blauw: Pin13 Oranje: Pin2 Rood: Pin4 Wit: Pin5 Derodeaansluitingvandetimermoetviaeenapartkabeltjeoppoort8vandeArduinowordenaangesloten. 2. Controleerofschakelaar geslotenisenofdetimeropdit ( )symboolstaatendrukopdestartknopvandetimeromdezegereedtemakenvooreenmeting. 3. Drukeenmaalopdeknopomdespoelteactiveren.Hetgelelampjegaatbrandenalstekendatjedemetingkuntstarten. Let%op:%destroomdoorspoelwordtna10secondenautomatischonderbrokenenjemoethemopnieuwactiveren.Ditisterveiligheidzodatdespoelnietteheetwordt. Alshetluikopenstaatgaathetrodelampjebrandentertekendatdemetingnietgestart kanworden. 4. Plaatshetkogeltjeindeonderkantvandespoel.Verhoogdespanningalsdezenietblijft hangentotdathetkogeltjenetblijfthangen. 5. Druknogmaalsopdeknopomdeproefuittevoeren.Hetkogeltjevaltophetklepjeenopdetimerverschijntdevaltijd.
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum 19
20 TRAMDISPLAY HOELAATKOMTMIJNTRAM? Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum 21 PROBLEEMSTELLING NakennisgemaakttehebbenvanmetdeArduinodeopensourcecomputer,zijnweopzoekgegaannaarnieuwetoepassingsmogelijkhedenvanopensource.OpYouTube 3 kwamenweeen interessantfilmpjetegenoverhetgebruikvanopendatainhetopenbaarvervoer. InditfilmpjeuitBostonkomtnaarvorendatdoorhetvrijgevenvanopenbaarvervoersdata, ontwikkelaarsinkortetijdeengrootaantalnieuwetoepassingengaatmaken.ookinnederland wordtvanaf2012actuelereisinformatievanhetopenbaarvervoeropenvrijgegeven. EentermdiewordtgebruiktvoordatadievrijbeschikbaarwordtgemaaktisOpenData.HetideevanOpenDataisdathetvrijbeschikbaarisvooriedereontwikkelaar.Ontwikkelaarskunnenmetbehulpvandezedatazelfapplicatiesenoplossingenontwikkelen. Optramlijn15toondendetramdisplaysalenkelejarengeenactueleinformatieopeenaantalhaltesinYpenburgenRijswijk.OnsleekhetleukomteonderzoekenofhetmogelijkwasommetbehulpvandezevrijgegevenopenXdataeennieuweoplossingtebedenkenomdedisplaysaantesturen. 3http://www.youtube.com/watch?v=URmKRTUXhxQ
BijHTMhebbenwenagevraagdwaaromergeenactuelereisinformatieopdedisplaysvanlijn 15werdgetoond.HTMgafåaandatsinds2010gebruikwordtgemaaktvanandereboordcomputersindetrams.Dezeboordcomputerbepaaltopbasisvano.a.GPSwaarhetvoertuigisopderouteenhoeveeldetramtevroegoftelaatis. Dedisplayslangslijn15wareneenintegraalonderdeelvanhetoudevoertuigvolgsysteem.Dezekondennietmeerwordenaangestuurdmetdenieuweboordcomputers,erzijngeenopenstandaardenbeschikbaaromdedisplaysaantesturen. Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum WAAROMISERGEENREISINFORMATIE? 22
BijnaderonderzoekbleekdathetprobleemvanHTMinmeerregio svoorkomt.iederevervoerdermaaktgebruikvanhaareigenreizigersinformatiesystemen.daarwaarverschillendevervoerbedrijvensamenkomen,ishetnodigdegegevensuitmeerderesystementecombinerenopeendisplay.doorhetontbrekenvanstandaardsbetekendeditdatereengrootaantal(nxm)interfaceszoudenmoetenwordengerealiseerd. Sinds2002wordthetopenbaarvervoerindemeesteregio sinnederlandaanbesteed, waardoorerregelmatiganderevervoerdersineenregiokomenterijden.inhaaglandenredenvroegerallenbussenentramsvanhtmenconnexxion,tegenwoordigrijdenhtmbuzz,veoliaenarrivaindenhaag.dereizigerwilonafhankelijkvanhetvervoerbedrijf,goedereisinformatie. Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum KNELPUNTENBIJREISINFORMATIE 23
Deoplossingomhetaantalinterfacestebeperkenishetstandaardiserenvandeinformatiestromen.Doorvanuitallevervoerdersdegegevensaanteleverenaaneencentraalpunt,wordthetaantalinterfacesteruggebrachttot1xninterfaces(n=hetaantalvervoerdersdatdataaanlevert). Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum OPLOSSING 24
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum 25 REALISATIE DATA GOVI(GrenzelozeOpenbaarVervoerInformatie)iseenoverheidsinitiatiefmetalsdoeleenlandelijkedatabasetecreërenvooractuelereisinformatieafkomstigvanverschillendevervoerders.HetGOVIprojectisgestartin2007,enhadineersteinstantietotdoelgeïntegreerdereisinformatieteleverenvoordeweergaveopdisplaysbijhaltesenknooppunten. Omookophalteswaaronvoldoendereizigersinstappenomdeinvesteringindisplaysrendabeltemaken,isgezochtnaarmogelijkhedenomdereisinformatieookviamobielinternetteontsluiten.Vanaf2010isgeëxperimenteerdmeteeneersteBusXmobielprojectinNoord Brabant.Vanafmaart2012wordtereencontinuedatastroomactuelereisinformatiegeleverdvoorallehatesinhetGOVIgebiedaanOpenOV,eenstichtingdiezichtotdoelsteltomopenbaarvervoerdatabeschikbaartestellen. GOVIGEGEVENSSTROMEN VERVOERDER GOVI DeberichtenvandevervoerderrichtingGOVIbestaanuitgeplandevertrektijden(KV1),depositiesvanbussenentrams(KV6),vrijetekstenvooropdisplays(KV15)enuitvalofomleidingvanbepaalderitten(KV17).KVstaatvoor koppelvlak,eengegevensuitwisselingoververschillendeorganisaties. GOVI DRIS VanuitGOVIwordendegeplandevertrektijdenopeenbepaaldehalteindevormvanKV7 verstuurdnaarhetdrissysteem.eenkv8wordtelkekeeralsdeverwachtevertrektijd verandert,alseentramaankomtopeenhalteenalseentramvertrektvaneenhalteverstuurd. InKV8wordenookvrijetekstenenuitgevallenbussen&tramsdoorgegeven.
GOVIwasoorspronkelijkalleenbestemdvoorhetaansturenvanDRIS sen.metdeopkomstvan mobielinternetenappskwamerookvraagnaarinformatieopallehaltesinnederland.kv7/8 wasoorspronkelijkbedoeldomgebruikttewordenvoor5000haltesennietvoldoendeominformatieteverstrekkenoveralle50.000haltesinnederland.daaromisereenefficiëntereensnellereversievankv7/8ontwikkelt,namelijkkv78turbo.degroottevandeberichtenisopdezenieuwemanierveelkleineromdaterinplaatsvanxmlgebruikwordtgemaaktvanctx, eenbestandsformaatwaarindegegevensgescheidenzijndooreensluisteken( ). DeKV78TurboberichtenstroomwordtdoorgestuurdnaarOpenOV,eenorganisatiediezich inzetomalledatavanhetopenbaarvervoerinnederlandbeschikbaartestellenalsopendata. OpenOVdistribueertdezegegevensstroomvervolgensweernaaralleontwikkelaarsdieeenapplicatiemetdezedatawillenontwikkelen.VoorbeeldenvanapplicatiesdiemetbehulpvandezedatazijnontwikkeldzijnOVInfovoorAndroidenTranzzitenOpenbaarVervoervooriOS. Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum KV78TURBO 26
Watbetekentditvooronsproject?DebeschikbaarheidvandeKV78turbostroomincombinatiemetopensourcehardwareensoftwarevormdendebasisomteonderzoekenhoeweactuelereisinformatieopdedisplaysvantramlijn15kunnenkrijgen.Tijdensdeuitvoeringhebbenwedevolgendestappendoorlopen: 1. Hoekomenweaanhetdisplayt.b.v.naderonderzoek? 2. Hoekrijgenweeentekstophetdisplay? 3. Hoekrijgenwereisinformatieopdisplay? 4. Hoelatenweallessamenwerken? 5. Beheer 6. Uitrol Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum STAPPENPLAN 27
28 Deeersteuitdagingwasomdebeschikkingovereendisplaytekrijgenzodatweermeekondengaantesten.Wezochtenbeginaugustus2012contactmethetStadsgewestHaaglandendieverantwoordelijkisvoorallebusXentramhaltesinderegioHaaglanden.Haaglandengafaandatergeenreservedisplaywasommeetetesten.StadsgewestHaaglandenverweesonsdoornaar JCDecaux,deexploitantvandeabri s.jcdecauxverweesonsweerdoornaardehtm.ditkastjenaardemuurgestuur,leerdeonsdathetbeheervandedisplaysiniedergevalnieteenduidigwasgeregeld.naflinkheenenweermailenbleekjcdecauxbereidomonstehelpen. Eenmonteurheeftonsgeholpenmethetdemonterenvaneendisplayuitdeabriop26 september2012.ditprocesheeftuiteindelijkbijnatweemaandengeduurd. Opdezemanierzathetdisplaybevestigdindekast. Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum HOEKOMENWEAANHETDISPLAY?
Devolgendeonderzoeksvraagwashoewezelftekstenophetdisplaykondenweergeven.Heteerstedoelwasomdittebereikenviadecomputer.DegegevensvandeoudemicrocontrollerwerdenviaeenRSX232verbindingnaarhetdisplaygestuurd.ModernecomputershebbenalleeneenUSBuitgang,daaromzijnweopzoekgegaannaareenconvertervanUSBnaarRSX 232. OmhetLEDXdisplayaantesturenhaddenwijdedocumentatievandeLEDXcontrollerdiewekondengebruiken.Hierinstondbijvoorbeelddebaudrate,maarookdespecifiekecommando sdienaardeled swordenopgestuurdomteksttelatenverschijnen.dezedocumentatiebleekechternietdejuistetezijn,iniedergevalkregenwijhetdisplayernietmeeaandepraat.ookdeaangegevenbaudratebleekincorrect. OmdatwehaddenwaargenomendathetLEDXdisplaynaéénminuutuitgaatalsergeensignaalnaartoewordtverzondenendatdeweergegeventijdelkeminuutwerdververst,concludeerdenwijdatdeoudecontrollertenminste1xperminuuteensignaalmoetsturen.Doorhetcommandodatdecontrollerverstuurtoptevangenopdecomputer,kondenweditbevestigen. Weontvingeneenonleesbaarsignaal,maardoordebaudrateaantepassenluktehetonsuiteindelijkhetsignaalteonderscheppenendezetegebruikenomonzeeigentekstenophetdisplaytelatenverschijnen.Hierdoorkondenwijbepalenwelkeinstructiesnodigwarenomhetdisplaybepaaldeopdrachtentelatenuitvoeren.BovendienhaddenwezoookdebaudratewaarophetLEDXdisplaydesignalenverwerktuitgevonden.Dezemaniervanonderzoekenwordtookwelreverse&engineeringgenoemd. PYTHON Pythoniseenopensourceprogrammeeromgevingdiebedoeldisomprogrammereneenvoudigertemakenvoorzowelmensenmetervaringalsmensendienetbeginnenmetprogrammeren.Pythonwordtgeleverdmeteenzeergrotehoeveelheidaanzogenaamdelibraries,bibliothekenmetvoorgebouwdeprogramma sdietegebruikenzijnineigenprogramma s,zodatnietsteedshetwielopnieuwhoefttewordenuitgevonden.opdrachtendieinandereprogrammeertalenmeerdereregelsaancodenodighebben,zijninpythonmetéénfunctietebereiken.ditishetgevalbijbijvoorbeeldhetlezenvanbestanden,watingeavanceerderetalengeeneenvoudigetaakis,wordtinpythonzeereenvoudiggemaakt.omdatwijdecodeopdeserverendemicrocontrollereenvoudigwildenhoudenenbeidenbereidwareneennieuweprogrammeertaalteleren,leekhetonseengoedideeomvanpythongebruiktemaken. SERVER VooronssysteemgebruikenweookeenKV78turbogegevensstroom,dievanuitdeserversvan OpenOVnaaronzeeigenserverwordtgestuurd.Opditmomentgebruikenwealleennog KV8passtimes,degegevensstroommetdeactuelevertrektijdenvandetram.Opdeserverwordtdegegevensstroomgefilterdoptimingpointcode(eenunieknummerperhalte)endoorgestuurdnaardebijbehorendehaltecontroller.DehaltediedegegevensontvangtslaatzeopenverwerktzeindejuistevolgordetoteentekstvoorhetLEDXdisplay.Hetdisplaymaaktdetekstvervolgensleesbaar.Zieookonderstaandeschets. Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum LEDXDISPLAY 29
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum 30 VoordeverbindingtussenonzeserverendievanOpenOVgebruikenwijhetMQTTprotocol.DitiseenPublishXSubscribeprotocol(kortwegPubSub).Dathoudtindatdecliëntzichbijdeserverregistreert(subscribe)opéénofmeerdereonderwerpenendeserverperonderwerpberichtenpubliceert(publish)dieautomatischnaardegeregistreerdecliëntswordentoegezonden.Ditprotocolisuitstekendgeschiktvooronsproject.Hetbeperktdegegevensoverdracht,decliënthoeftimmersnietcontinuaandeservertevragenofernieuweberichtenzijn,enzorgtervoordatwanneerereennieuwberichtisdezevrijwelonmiddellijkdoordecliëntontvangenenverwerktwordtendezeduszoactueelmogelijkegegevensheeft.Softwarematigkondenwehet PubSubprotocoleenvoudigimplementerendoorgebruiktemakenvandeopenXsourcelibrary Mosquitto,dieookeenPythonXbindingheeft. KEUZEVOORMICROCONTROLLER Voordemicrocontrollerdiededatamoetaansturennaarhetsysteemhaddenwetweeeisen.Demicrocontrollermoettegenextremeweersomstandighedenkunnenenhijmoetverbindingmethetinternetkunnenmakenvia3G.Ietsandersdatmeewoogwasdeprijs.Wehebbenlangopinternetgezochtenzijnveeloplossingentegengekomen,zoalsvollediggeïntegreerdeoplossingenmaarookmodulairesystemen.AndereoptiesdieweoverwogenhebbeniseengoedkopeandroidtelefooneneenindustriëlecomputerdeiModX9400metingebouwdegprsondersteuning.Dezeoptiesvielenafvanwegedehogeprijsenhetgebrekaanflexibiliteit. UiteindelijkhebbenwegekozenvoordeRaspberryPi,eenmicrocomputerdievooreen minimaleprijs( 35)wordtgeproduceerd,maarwelzeergeavanceerdespecificatiesheeft. HierdoorishetmogelijkomeenstandaardlinuxXdistrotegebruiken.Ditheeftalsvoordeeldatheelveelhardwarezonderhetinstallerenvandriversfunctioneert.DeRaspberryPizelfheeftgeen3GmodemenRSX232aansluiting,maarheeftweltweeUSBaansluitingen.OpéénvandieaansluitingeniseenHUAWEI160G3gstickaangeslotenvoordeverbindingmetinternet.OpdeandereiseenUSBnaarRSX232Xconverteraangeslotenzodatdecontrollergegevenskan
PIALSMICROCONTROLLER DenieuwetaakwasnuomdeRaspberryPidetaakvandeoudemicrocontrollerovertelaten nemen.hiertoediendedezegeprogrammeerdteworden. Desoftwareopdemicrocontrollerbestaatuittweelosfunctionerendeonderdelen,dieviaeenlokaledatabasemetelkaarcommuniceren.Hetenegedeelteregistreertzichbijdeserveromdeberichtenmetvertrektijdenteontvangenenslaatdezeopindedatabase.Hetanderegedeelteleestdezedatabaseenverwerktdegegevensvervolgenstoteentekstophetdisplaymetdetramsindejuistevolgordeopvertrektijd.OokopdeRaspberryPikondenwijgebruikmakenvanPythonalsprogrammeertaal,watwijuiteraardhebbengedaan,zodatdeserverendecontrollersoftwarematighetzelfdewerkenenwijdezelfdelibrariesenstukjescodekondengebruiken. DeverbindingtussendeserverendehaltecontrollerverlooptopdezelfdemanieralstussenonzeserverendievanOpenOV.Decliëntregistreertzichopeenbepaaldonderwerpbijdeserver,wanneerdeservereenberichtontvangtvanOpenOVpubliceerthijdezeophetonderwerpmetalsnaamdetimingpointcodevandehalte.Dehaltemetdietimingpointcode,diedusopdatonderwerpisgeregistreerd,ontvangtdanditbericht. Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum verzendennaarhetledxdisplay.uiteindelijkkostdezeoplossingquahardwareongeveer100 euro. 31
Omhetdisplaygebruiksvriendelijkenduidelijktemakenvoorreizigers,hebbenwegebruikgemaaktvandeMijksenaar 4 Xstandaardvoordisplaysvooropenbaarvervoer.Dezestandaardisontwikkelddoorhet(informationdesign)consultancybureauMijksenaar.Ditbedrijfrichtzichophetontwerpenvangebruiksvriendelijkeenefficiëntebewegwijzeringeninformatieenisoverdehelewereldbekend,vooralvandebewegwijzeringssystemenopLuchthavens.HetleekonsverstandigonsaandevoorschriftentehoudendiezijnontwikkelddoorMijksenaarwatbetreftdisplaysvoorhetopenbaarvervoer. Regelswaarwijdanophebbenmoetenlettenzijnbijvoorbeelddevolgordeenbreedtevandekolommenwaarindegegevens,lijnnummer,eindhalteenaantalminutentotvertrek,zijningedeeldendathetaantalminutentotvertrekwordtgevolgddoor min.aaneenaantalvoorschriften,zoalshetlatenalternerenvanspecialeberichtenendevariabeleletterbreedte, hebbenwijonsnietgehoudenomdathetdisplaynietbeschikteoverdebenodigdefuncties hiervoor. BEHEER Omhetmogelijktemakendatonsontwerpvandehaltedisplayinproductiekanwordengenomen,isereenmaniernodigomervoortezorgendatdedisplaysfunctioneelblijvenwerkeneneventueelsoftwarematigverbeterdkunnenworden.Omhetprojectaftesluitenbogenwijonsnogoverditprobleem. Aangezienhetsysteemgebruikmaaktvaneendraadlozeverbindingeninhetopenbaarwordtgebruikt,iseenveiligeverbindingnodig.Hetenigedatnodigisomdehaltecontrollertebesturen,istoegangtotdeconsole.DezetoegangisteverkrijgenviaeenSSHverbinding,diestandaardbeschikbaarisoponzemicrocontroller,deRaspberryPi.DitiseenzeerveiligeverbindingdiegebruikmaaktvanRSAencryptie. Dezeverbindingkannietpermanentbestaanenmoetdaaromopaanvraagtotstandkomen. Extraveiligheidisnodig,zodatpersonenvanbuitenafgeenverbindingkunnenaanvragenmetdecontroller.DaaromisHetIPXadresvanonzeserveringeprogrammeerdindehaltecontrollerzodatdehaltecontrolleralleenmetonzeserververbindingkanmaken.AangezieneraleenpublishXsubscribeverbindingtussendecontrollerenserveraanwezigis,leekhetonshandigdeaanvraagvooreenSSHXverbindingookviadezewegteversturen.DeserververzendteenapartberichtwaaropdecontrollermethetingeprogrammeerdeIPXadresvandeserververbindingmaakt.Opdezemanierzullenpersonenvanbuitenafnooitverbindingkunnenmakenmetdecontroller,omdatdezemetmaaréénserverdeverbindingaangaat. Vooreenzogoedmogelijkbeheervandehaltecontrollersmoethetbekendzijnwanneereenbepaaldecontrollerdefectisencontrolevereist,zodatditkanwordenverholpen.Eenvoordehandliggende,maarwelzeerbruikbaremethodeisomdecontrolleromhethalfuureenkleinberichtnaardeservertelatensturen.Deserverhoudtdanvanelkecontrollerbijhoelanggeledendezeeenberichtheeftgestuurd.Alsdatlangerisdaneenhalfuuriserwaarschijnlijk 4http://nl.wikipedia.org/wiki/Paul_Mijksenaar Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum MIJKSENAARXSTANDAARD 32
Onderdeel KOSTEN Ditprojectisbegonnenmethetaandepraatkrijgenvan1vande7displaysdienietwerkten, ééndisplayhebbenwenuaandepraat.dezeoplossingvalttekopiërennaardeanderehaltes. Voorelkdisplaymoetdeonderstaandehardwareaangeschaftworden,hetoudeLEDXdisplay kanhergebruiktworden: Geschatte%prijs RaspberryPi 40 3GDongle 30 USBXrs232converter 15 5VUSBvoeding 10 SDcard 5 Totaal:% 100 Voorhetombouwenvanalle7displaysisdatinongeveer 700.Voorgotereaantallengeldenuiteraardlagerestuksprijzen.Naastdeeenmaligekostenvanhetombouwenvanhetdisplayzijnerooknogmaandelijksekosten.Dezekostenbestaanuitdeserverwaarophetprogrammadraaitomdeberichtentedistribuerenenkostenvoordemobieledata.Dekostenvoordeserverbedragenongeveer 25permaand(onafhankelijkvanhoeveeldisplayseropwordenaangesloten).Dekostenvoorhetgebruikvanmobieledatabedragenperdisplayongeveer 10 permaand.debeheerkostenpermaandzijndusongeveer 100.Watbijditplaatjenognietis meegerekendzijndearbeidskosten(alleurendiewijeralingestopthebben). Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum ietsmismetdecontrollerenmoeteractiewordenondernomen.deserverzoudaneenberichtnaardebeheerderkunnensturen.dezemethodekanwordengeïmplementeerdalstoekomstigeoplossingvoordathetsysteeminproductiewordtgenomen. 33
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum 34 PROGRAMMATUUR Ditgedeeltehebbenweopgenomenvoordetechnischgeïnteresseerdelezeromeniginzichtte krijgenhoedeprogramma swerken. SERVER Indezeparagraafwordendetweeprogramma sbeschrevendieoponzedistributieserver draaien. KV8.PY OnderstaandeprogrammaishetprogrammadatdedatadieontvangenwordtviaZMQ(600 berichtenpersecondeophetdrukstemoment)filtertendoorstuurtviahetmqttprotocolnaar dejuistehalte. import sys # Toegang tot systeem functies import os import zmq # De ZeroMQ library om gegevens van de OpenOVserver te ontvangen. import datetime # De time functie uit de time library om de huidige tijd in secondes op te vragen. from gzip import GzipFile # Nodig om bestanden met Gzip compressie te lezen. from cstringio import StringIO # Hulpmiddel voor Strings tpcs = ['32005935', '32005937', '32005939', '32005215', '32005216', '32005108', '32005107'] # De TimePointCodes van de haltes waar wij van willen ontvangen in een lijst (array). context = zmq.context() # Een ZeroMQ "context" wordt aangevraagd. kv8 = context.socket(zmq.sub) # Maakt een socket aan voor de verbinding met OpenOV. # Een verbinding met de OpenOVserver wordt tot stand gebracht. kv8.connect("tcp://83.98.158.170:7817") kv8.setsockopt(zmq.subscribe, "/GOVI/KV8") poller = zmq.poller() poller.register(kv8, zmq.pollin) print("collect data from server") counter = 0
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum # Deze functie verwerkt het ontvangen bestand, dat de vorm heeft van een String. def processpackage(content): global tpcs # De verwijzing naar variabele tpcs is een globale verwijzing. for line in content.split('\r\n')[:1]: if line[0] == '\\': if line[1] == 'G': label, name, subscription, path, endian, enc, res1, timestamp, _ = line[2:].split(' ') if label!= 'KV8turbo_passtimes': print content elif line[1] == 'T': types = line[2:].split(' ')[1] elif line[1] == 'L': keys = line[2:].split(' ') else: # De gegevens worden ingedeeld in een map, in de volgorde die de \Llijn heeft aangegeven. row = {} values = line.split(' ') for k,v in map(none, keys, values): if v == '\\0': row[k] = None else: row[k] = v if row['timingpointcode'] in tpcs: # Alleen als de TimingPointCode van de halte in de tpcs array zit, zijn de gegevens voor ons interessant en worden ze verwerkt in de database. now = datetime.datetime.now() print str(now) try: f = open("tmp.gz", "w+") gz = GzipFile(fileobj=f, mode="w") gz.write(line) gz.close() f.close() #os.system("mosquitto_pub m '" + sio.getvalue() + "' t '" + row['timingpointcode'] + "/KV8passtimes'") os.system("mosquitto_pub f 'tmp.gz' t '" + row['timingpointcode'] + "/KV8passtimes'") print "Send!" except Exception as e: print e raise # Zolang het programma draait wordt opgevraagd of er een bericht is ontvangen. Is dit het geval, dan wordt het bericht geunzipt en wordt de 'processpackage' functie aangeroepen. while True: socks = dict(poller.poll()) if socks.get(kv8) == zmq.pollin: multipart = kv8.recv_multipart() content = GzipFile('','r',0,StringIO(''.join(multipart[1:]))).read() processpackage(content) subscriber.close() context.term() 35 CONNECTSSH.PY
import os import time #timinpointcode van te beheren halte tpc = raw_input("enter Tpc: ") #poort haltecontroller>server port = raw_input("enter port: ") #stuur bericht om verbinding te maken met server os.system('mosquitto_pub t "' + tpc + '/con" m "' + port + '"') #wacht totdat connectie tot stand komt print('wait on SSH') time.sleep(10) #verbind met halte controller os.system('ssh pi@localhost p ' + port) Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum Ditprogrammazorgtervoordatdehaltecontroller(deRaspberryPi)opafstandmeteenveiligeverbindingbeheerdkanworden.HetisslechtseenkleinscriptdatomuserinputvraagtendatomzetinLinuxXcommandodatdeSSHXverbindingtotstandbrengt. 36
Indezeparagraafbeschrijvenwegedetailleerddesoftwaredieopdehaltecontrollerdraait. Indebovenstaandesysteemschetsvandehaltecontroller,deRaspberryPi,ishetprogrammawatervoorzorgtdatdeKV8passtimes,&de&verwachtevertrektijden,indedatabasekomengetkv8.py.Hetprogrammadisp_cmd.pyververstelkesecondededataophetdisplayenmaaktdaarvoorgebruikvandisplay.py.Beideprogramma smakengebruikvandisp_config.pyomde TimePointCodevandehaltewaardesoftwareopdraaittewetenenenigeandereconfiguratie. Koppelvlak7isnognietgeïmplementeerdinonzesoftware,netzoalsKV8generalmessage,de algemeneberichten. Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum HALTECONTROLLER(RASPBERRYPI) 37
Ditprogrammazorgtvooreeninternetverbindingenverwerktgepushteberichtenvanafserver ineenlokaledatabase. #importeer softwarebibliotheken import mosquitto import sqlite3 import os from gzip import GzipFile from cstringio import StringIO import disp_config as confg #laad configuratie bestand print "Loading configuration file" confg.read() tpc = str(confg.tpc) #configureer database en mqtt pconnected = False connection = sqlite3.connect("/home/pi/data.db", timeout=3) client = mosquitto.mosquitto(tpc) #toon Connected indien verbinding met server succesvol is def on_connect(rc): print "Connected" #wordt uitgevoerd als er een nieuw bericht binnen komt def on_message(msg): global tpc print "\nget" print "Topic: " + msg.topic print "Raw: " + msg.payload try: #maak string van bericht sio = StringIO(msg.payload) #ungzip bericht gz = GzipFile(fileobj=sio, mode="r") payload = gz.read() print "Uncompressed: " + payload except Exception as e: print "Not gzipped" payload = msg.payload #als server bericht stuurt om te beheren if msg.topic == tpc + "/con": os.system('ssh nnt R ' + str(payload) + ':localhost:22 sven4all@94.124.88.194 &') print "ok" #anders (dus in het geval kv8passtimes bericht) else: kv8 = payload keys = kv8.split(' ') Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum GETKV8.PY 38
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum cursor = connection.cursor() #cursor.execute("select * FROM departure WHERE journeynumber=(%s) and timingpointcode=(%s)", (row["journeynumber"], row["timingpointcode"],)) cursor.execute('select * from realization WHERE(journeynumber=(?))', (keys[3],)) valueindb = cursor.fetchone() #als ritnummer nog niet in database zit if valueindb == None: #voeg rit toe aan DB cursor.execute('insert INTO realization VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', (keys[0], keys[1], keys[2], keys[3], keys[4], keys[5], keys[6], keys[7], keys[8], keys[9], keys[10], keys[11], keys[12], keys[13], keys[14], keys[15], keys[16], keys[17], keys[18], keys[19], keys[20], keys[21], keys[22], keys[23], keys[24], keys[25], keys[26], keys[27], keys[28], keys[29], keys[30], keys[31], keys[32],)) #anders (als rit er dus al wel in zit) else: #update bestaande rit in DB cursor.execute("update realization SET expectedarrivaltime=(?), expecteddeparturetime=(?), lastupdatetimestamp=(?), tripstopstatus=(?) WHERE journeynumber=(?);", (keys[13], keys[14], keys[10], keys[15], keys[3],)) #als status van een bus in het systeem "PASSED" of "CANCELED is gooi bus van display cursor.execute("delete FROM realization WHERE tripstopstatus=(?) or tripstopstatus=(?);", ("PASSED", "CANCELED",)) expectedarray = cursor.fetchone() connection.commit() #voer uit zolang programma draait while True: #als er geen verbinding (meer) met server is if client.loop()!= 0: #als er niet eerder een verbinding is geweest if not pconnected: #initialiseer 3G modem os.system("sudo /./sakis3g start SIM_PIN='0000' APN='internet'") pconnected = True print "Connected to internet" #anders else: #herinitialiseer 3G modem os.system("sudo /./sakis3g reconnect SIM_PIN='0000' APN='internet'") print "Reconnected to internet" #maak verbinding met server client.connect("94.124.88.194") #abonneer op topic van tpc van desbetreffende halte client.subscribe(tpc + "/+", 0) client.on_message = on_message client.on_connect = on_connect 39
import sys import serial global ser DISPLAY_WIDTH = 32 def create(device): global ser ser = serial.serial(device, 9600) def destroy(): global ser if ser: ser.close() NuvolgtdezelfgeschrevenPythonXklassealshulpmiddelvoorhetaansturenvanhetLEDX display.debreedtevanhetscherm,hetaantalkaraktersdatkanwordenweergegeven,isineen constanteopgeslagen.decreatexfunctiemaakteenseriëleverbindingmeteenbaudratevan 9600aanmethetLEDXdisplayopdeaangegevenpoort,device.DedestroyXfunctieverbreekt dezeverbindingweer. clearmaakthetschermleeg,detxt_*xfunctieslateneenaangegeventekstopdeaangegeven regelzienopdemanierdiehoortbijdefunctie.datkanzijnhorizontaalenverticaalscrollend, ofgewoonstilstaand.detekst,hetlijnnnummereneventueelwelkeffectmoetwordengebruiktwordenverwerktineencommandodatnaarhetviadeseriëleverbindingnaardeled swordtgestuurd.inelkefunctiewordtgecontroleerdofdeseriëleverbindingserbestaat,alsdatnietzoisgebeurterniets. def clear(): txt_show("",0) txt_show("",1) txt_show("",2) def txt_show(text, line): global ser if ser == None: return cmd = "#0A>FF#00#00#0%s#%s#00#cc<" % (str(line), text) ser.write(cmd) def txt_scroll_hor(text, line): global ser if ser == None: return cmd = "#0A>FF#00#01#0%s#%s#00#cc<" % (str(line), text) ser.write(cmd) def txt_scroll_vert(text, line): global ser if ser == None: return cmd = "#0A>FF#00#02#0%s#%s#00#cc<" % (str(line), text) ser.write(cmd) Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum DISPLAY.PY 40
tpc = 0 namemap = {} def read(): global tpc global namemap try: f = open("/home/pi/disp.confg", "r") line = f.readline().strip() tpc = int(line) print("line: " + line) line = f.readline() while line!= None and len(line) > 0: s = line.split(" ", 2) i = int(s[0].strip()) j = int(s[1].strip()) name = s[2].strip() namemap[mapkey(i,j)] = name line = f.readline() except IOError: print("cannot read config file") raise except: print("invalid config file") raise def getname(num, dir): global namemap key = MapKey(num, dir) try: return namemap[key] except KeyError: pass return "" DevolgendePythonklassehebbenweookgeschrevenalshulpmiddel,dezedientvoorhetlezenvandehalteXconfiguratie.InditbestandstaatdeTimePointCodevandehalteeneentabelwaarindecodesvaneindhaltestegenoverdenamenvandezeeindhaltesstaan.DitconfiguratiebestandmoetdoorbeidePythonprogramma sopdecontrollergelezenwordenendaaromiseenaparteklassenodig,zodatnietinbeideprogramma sdezelfdecodeopgenomenhoeftteworden. IndezehulpklassezitookeenfunctiegetNameopgenomendiedoordeandereprogramma saangeroepenkanwordenomviahetlijnnummerendelijnrichtingdenaamvandeeindhalteteverkrijgen. DeaparteklasseMapKeydientalssleutelvoordetabeldieaandehandvandehetlijnnummerendelijnrichtingdestringmetdenaamvandeeindhalteopzoekt.Dezesleutelbevathetlijnnummerendelijnrichtingencreëertinde hash Xfunctiedezogenaamdehashcodedieindetabelgebruiktwordtvoorhetopzoekenvandebijbehorendenaamvandeeindhalte. Hiervoorisookde eq Xfunctienodig,dienagaatoftweeinstantiesvanMapKeyaanelkaar gelijkzijn. Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum DISP_CONFIG.PY 41
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum class MapKey: def init (self, num, dir): self.linenum = num self.linedir = dir def eq (self, obj): return self.linenum == obj.linenum and self.linedir == obj.linedir def hash (self): return self.linedir + self.linenum * 4 import sys import display import disp_config as confg import sqlite3 import time from cstringio import StringIO NAME_WIDTH_LIMIT = display.display_width 11 EMPTY_NAME = " " journeys = {} message = None msgalternationtimer = 0 msgindex = 0 journeypassedtimer = 0 42 DISP_CMD.PY HetlaatsteprogrammaishetprogrammadatdegegevensvandevertrektijdenuitdedatabaseleestenzeindejuistevolgordelaatzienophetLEDXscherm.DeNAME_WIDTH_LIMIT&constantebewaartdemaximalelengtevandenaamvandeeindhaltediekanwordenweergegeven.Dezeisgelijkaanhetmaximaleaantalkaraktersdathorizontaalophetschermpastverminderdmet 11.Deze11bestaatuitdriekaraktersvoorhetlijnnummer,spatiesvoorenachterdenaamvan deeindhalteen6karaktersvoorhetaangevenvanhetaantalminutentotvertrek. DeEMPTY_NAMEconstantebevateentekenreeksvanspaties,meteenlengtezogrootals NAME_WIDTH_LIMIT.Dezetekenreekswordtgebruiktomdetekenreeksvandenaamvande eindhalteoptevullenmetspaties,zodatdetijdentotvertrekmooiuitgelijndworden. Eerstwordenhetconfiguratiebestandgelezen,zoalsbeschrevenonderdisp_config.py,en vervolgenswordtdeverbindingmethetdisplaytotstandgebracht,zieookdisplay.py.beide USBXuitgangenwordenuitgeprobeerd.Daarnawordtdeverbindingmetdedatabasegemaakt metbehulpvandesqlite3library.
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum #Load config print "Loading configuration file" confg.read() #Init display print "Starting up display" try: display.create("/dev/ttyusb0") except: display.create("/dev/ttyusb1") #Init database print "Establishing connection with database" con = None cur = None try: con = sqlite3.connect("/home/pi/data.db", timeout=3) cur = con.cursor() print "Connected with database" except sqlite3.error, e: print e sys.exit(1) #Done init def displaynormalmessage(ptline, stopname, min, line): strio = StringIO() if ptline < 10: strio.write(" ") elif ptline < 100: strio.write(" ") strio.write(str(ptline)) strio.write(" ") if len(stopname) > NAME_WIDTH_LIMIT: stopname = stopname[0:name_width_limit] strio.write(stopname) strio.write(empty_name[0:name_width_limit len(stopname)]) strio.write(" ") min = int(min) if min < 10: strio.write(" ") strio.write(str(min)) strio.write(" min") display.txt_show(strio.getvalue(), line) del strio 43 Devolgendefunctie,displayNormalMessage,bouwtvanhetlijnnummer,denaamvandeeindhalteenhetaantalminuteneentekenreeks,dienaardisplay.pywordtgestuurdomvervolgensophetLEDXdisplaytewordenlatenzien.ErwordtgebruikgemaaktvaneenStringIOobject.Eenvirtueelbestandwaarnaartoegeschrevenkanwordenenvervolgensineennormaletekenreeksomgezetkanworden.Ditiseenveelefficiëntereoplossingdanconcatenatievantekenreeksen. DeJourneyXklasseisdeklassedieallenodigegegevensdiebijeenbepaaldreisnummerhoren bewaart.eriseencalcdeltatimexfunctieopgenomenommetdehuidigetijdhetaantalminuten
class Journey: def init (self, jour, line, dir, deptime, depdate): self.delta = 99 self.deltafloat = 99 self.journeynum = jour self.linenum = line self.linedir = dir self.deptime = deptime self.depdate = depdate def calcdeltatime(self, currenttime): if int(self.deptime[:2]) >= 24: self.deptime = "0" + str(int(self.deptime[:2]) 24) + self.deptime[2:] timeobj = time.strptime(self.depdate + " " + self.deptime, "%Y%m%d %H:%M:%S") dep = time.mktime(timeobj) + 86400 else: timeobj = time.strptime(self.depdate + " " + self.deptime, "%Y%m%d %H:%M:%S") dep = time.mktime(timeobj) prevdelta = self.deltafloat self.deltafloat = dep currenttime if self.deltafloat < 60: cur.execute("delete FROM realization WHERE JourneyNumber=(?);", (self.journeynum,)) con.commit() del journeys[self.journeynum] else: self.deltafloat /= 60 if self.deltafloat > prevdelta and self.deltafloat < prevdelta + 1.0: self.deltafloat = prevdelta self.delta = max(int(round(self.deltafloat, 0)), 0) def display(self, index): displaynormalmessage(self.linenum, confg.getname(self.linenum, self.linedir), self.delta, index) DereadDatabaseXfunctieleestdegegevensuitdedatabase.MetSQLwordendebenodigdegegevensopgevraagd.Datzijndedatum,deverwachtevertrektijd,hetlijnnummer,delijnrichtingenhetreisnummer.Dezegegevenswordeninvolgordevandeverwachtevertrektijdineenlijstgezet.Erwordteenmapbijgehoudenwaarindereisnummersverwijzennaarde JourneyXobjecten.Dereisnummerszijnelkedaguniekpertramdielangsrijdt.Alsdemapeenbepaaldreisnummernognietbevat,wordteennieuwJourneyXobjectgemaakt,degegevensuitdedatabasewordeninhetobjectgeschrevenenhetobjectwordttoegevoegd.AlshetJourneyX objectalwelbestaat,wordtdeverwachtevertrektijdbijgewerkt.alsdetramvandat reisnummervoorbijiswordthetobjectweerverwijderduitdemap. Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum totvertrekteberekenen.dedisplayxfunctieroeptdeglobaledisplaynormalmessagexfunctieaan metzijngegevensalsargumenten. 44
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum def readdatabase(): global journeys global journeypassedtimer #NEW activejourneys = [] cur.execute("select OperationDate, ExpectedDepartureTime, LinePlanningNumber, LineDirection, JourneyNumber from realization order by ExpectedDepartureTime") row = cur.fetchone() while row!= None: jn = int(row[4]) activejourneys.append(jn) if jn in journeys: j = journeys[jn] j.deptime = row[1] else: linenum = int(row[2]) amount = 0 j = Journey(jn, int(row[2]), int(row[3]), row[1], row[0]) journeys[jn] = j row = cur.fetchone() for jn, j in journeys.items(): if not j.journeynum in activejourneys: if j == journeys.values()[0]: journeypassedtimer = 3 del journeys[j.journeynum] display.txt_show("", 0) time.sleep(3) print "deleterow" else: j.calcdeltatime(time.time()) del activejourneys 45 OmdegelezengegevenstelatenzienophetdisplayisdedisplayJourneysXfunctie.Ditiseenapartefunctie,omdatdecodeduidelijkerwordtalshetlezenvandedatabaseenhetschrijvennaarhetdisplaygescheidenworden.Dereizen,Journeys,wordenopaantalminutentotvertrekgesorteerdenvervolgenswordtvandeeerstedrieinstantiesdedisplayXfunctieaangeroepen, datervoorzorgtdatdereisinformatieophetdisplaykomttestaan. DesetMessageXfunctieendemsgAlternationTimerXvariabelezijnbedoeldomvrijetekstenophetdisplaytelatenzien,maarditisnognietgeïmplementeerdinkoppelvlak8enwordendaaromnognietgebruikt.
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum def displayjourneys(): global journeys global message global journeypassedtimer counter = {} index = 0 if journeypassedtimer!= 0: display.txt_show("", 0) index += 1 max = 3 if message!= None: max = 1 for j in sorted(journeys.values(), key=lambda jo : jo.deltafloat): amount = 0 if j.linenum in counter: amount = counter[j.linenum] if amount < 2: counter[j.linenum] = amount + 1 j.display(index) index += 1 if index == max: break while index < 3: if index!= 2 or message == None: display.txt_show("", index) index += 1 del counter def setmessage(msg): global message if msg == None: message = None return message = [] while len(msg) > 0: message.append(msg[0:display.display_width]) msg = msg[display.display_width:] 46 DemainPloopvanhetprogrammawordtgestartzodraalleverbindingentotstandzijngebrachtendeinitialisatieisvoltooid.Deloopwordtgesynchroniseerdzodatprecieselkesecondededatabasewordtgelezenenhetschermwordtbijgewerkt.DitgebeurtmetdesleepXfunctiediehetprogrammaeenbepaaldetijdpauzeert.Alsereenfoutontstaatofhetprogrammawordtonderbrokenstoptdeloopenwordendeverbindingengesloten.
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum try: while True: starttime = time.time() if journeypassedtimer > 0: journeypassedtimer = 1 if msgalternationtimer > 0: msgalternationtimer = 1 elif message!= None: msgalternationtimer = 3 msgindex = (msgindex + 1) % len(message) if message!= None: display.txt_show(message[msgindex], 2) readdatabase() displayjourneys() except: print "\nstopping" finally: del journeys display.clear() display.destroy() if con: con.close() #timestr = time.asctime(time.localtime(starttime)) #display.txt_show(timestr, 2) starttime += 1 time.sleep(max(starttime time.time(), 0)) 47
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum 48 CONCLUSIE Hetwasvooronseenbijzondereervaringomkennistenemenvandepraktijkvanopensourceenopendata.Desamenwerkingmeteencommunity,waarinmensenbelangeloosmetelkaarmeedenkenenmeehelpen,maarwaarookdeproblemenenoplossingenvananderentevindenzijn,iseenergbijzonderfenomeen.Doordeherbruikbaarheidvansoftware,ismensnelinstaatomcomplexevraagstukkenoptelossen. Indepraktijkhebbenwijkunnenervarendatopensourceenopendatainnovatieensamenwerkingtussenverschillendepartijenstimuleren.Doordatergeendrempelsmeerzijnindevormintellectueleeigendomsrechtenwordenoplossingengoedkoperenkomenzesnellertotstand. Eenvolgendevraagdiewijonsstellenisofhetmogelijkisomgeldteverdienenmetonze oplossing?hoeverkoopjeeenproductopbasisvanopensourceenopendata? Hieroverhebbenwediverseideeën,zoals Haaglanden/HTMhebbenbelangbijactuelereisinformatie.Hetbeeldvanhetopenbaarvervoerwordtbetermetactuelereisinformatie.Deinvesteringenbeheerkostenzijngering.Bij5extrareizigersperdagontstaataleenbreakevensituatie(compensatievanextrakostenmetextrareizigersopbrengsten). VoorJCDecaux,exploitantvandeabri s,kanhetheelinteressantzijndigitaledisplaystegebruikenvoorreclame,afgewisseldmetreisinformatie,waardoordeattentievandereizigersbijhetdisplayblijft. Samenwerkenmetleveranciersvandisplays.ZijkunnengoedkoperdisplayslevereninclusiefbeheerenonderhouddoorgebruiktemakenvanopensourceXenopendataoplossingen. Debusinesscaseswillenwenaderverkennennaonsexamen.HetBelgischevervoersbedrijfDe Lijnheeftalcontactmetonsopgenomennaaraanleidingvanhetfilmpjedatwehebbengemaakt.Hetbedrijftoondeinteresseinonsprojectomdatzijtemakenhebbenmetvergelijkbareproblematiekalswijinditwerkstukonderzochthebben.
Profielwerkstuk Opensource,opendata&Hoelaatkomtmijntram? SvenBoor&ArjenKremers GymnasiumNovum 49 BRONVERMELDING RasberryPI: http://www.raspberrypi.org/ http://www.savagehomeautomation.com/projects/raspberryxpixinstallingxaxrs232xserialx port.html /180910053409?pt=US_Internal_Network_Cards&hash=item2a1f145821 http://www.savagehomeautomation.com/projects/raspberryxpixrs232xserialxinterfacex optionsxrevisit.html http://www.raspberrypi.org/phpbb3/viewtopic.php?p=90223 Arduino:http://www.arduino.cc/ Modem:http://www.ebay.com/itm/7X2MbpsXHUAWEIXE220XHSDPAXUMTSX3GXUSBXDongleX WirelessXModemXforXAndroidXXPXWin7X pl2303x:http://www.noah.org/wiki/rsx232#5xwire_rsx232 SSHTunneling:http://www.linuxhorizon.ro/sshXtunnel.html GOVI:http://govi.nu/ PaulMijksenaar:http://nl.wikipedia.org/wiki/Paul_Mijksenaar Koppelvlakinformatie:http://nl.wikipedia.org/wiki/Koppelvlak Opendatainformatie:http://nl.wikipedia.org/wiki/Open_data Opensourceinformatie:http://nl.wikipedia.org/wiki/Open_source Gegevensvaneenkoperdraad:http://nl.wikipedia.org/wiki/Koperdraad Python:http://www.python.org/ Informatieoverinductiestoringinmagneetspoel:http://www.idd.nl/key/inductiestoring.html FilmpjetoepassingopendatainOVinBoston:http://www.youtube.com/watch?v=URmKRTUX hxq Filmpjeoverhetwerkstuk:http://vimeo.com/60644074 Apps: https://play.google.com/store/apps/details?id=nl.skywave.ovinfo&hl=nl https://itunes.apple.com/nl/app/tranzzit/id591675055?mt=8&ignxmpt=uo%3d4 http://openbaarvervoerapp.nl/ Syntaxcolouring:http://pygments.org