swn.nuswn.nu/cg/projekter/cykel/doc/eood2a_rapport.doc  · web viewindholdsfortegnelse. indledning...

175
Superbike December 2004 Side 1 af 175

Upload: others

Post on 06-Jul-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Side 1 af 134

Page 2: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Indholdsfortegnelse

Indledning............................................................................5Problemformulering.....................................................................................5

Begrænsninger.............................................................................................6

Pc-program...........................................................................7Kravspecification for pc-program................................................................7

Anvendt design process...............................................................................9

Use-cases...................................................................................................10PC-program................................................................................................................10

Cykelcomputer...........................................................................................................12

Use Case Model.........................................................................................................14

Domain model............................................................................................15

Design Model.............................................................................................16Klasse diagram...........................................................................................................16

Kort beskrivelse af klassediagrammet:......................................................................17

Detaljeret beskrivelse af klasserne:...........................................................................17

Komplekse metoder:..................................................................................................20

Samhørighed og kobling............................................................................................21

Beskrivelse af test metode.........................................................................22

Cykelcomputer...................................................................24Kravspecifikation til cykelcomputer..........................................................24

Usecases på cykelcomputer.......................................................................25

Specifikation af træningsprogram..............................................................26

Specifikation af statistik.............................................................................27

Specifikation af kommunikationen............................................................29

Design af hardware....................................................................................31Displayet....................................................................................................................32

Side 2 af 134

Page 3: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

CPLD som decoder....................................................................................................32

Tastatur......................................................................................................................33

Cyklen........................................................................................................................34

CPLD som UART......................................................................................................34

Sammensætning.........................................................................................................35

Forbindelsesdiagram..................................................................................................36

Layout diagram over komponenter............................................................................38

Layout diagram over printets baner...........................................................................38

Design af software.....................................................................................39Klassediagram............................................................................................................40

Beskrivelse af klasser................................................................................................42

Beskrivelse af assemblerkode....................................................................................46

Konklusion.........................................................................47

Bilag...................................................................................48Brugervejledning for pc-program..............................................................48

Oprette og gemme et program...................................................................................48

Vise programliste.......................................................................................................49

Overføre et program til cyklen..................................................................................51

Slette program fra programliste.................................................................................52

Vise statestik over cykling.........................................................................................53

Brugermanual for cykelcomputeren..........................................................54Gennemgang af displayet og tastaturet......................................................................54

Kom nemt i gang.......................................................................................................54

Source kode til JAVA................................................................................56StatistikArkiv.............................................................................................................56

Traeningssession........................................................................................................58

ProgramArkiv............................................................................................................66

Program......................................................................................................................69

Maaling......................................................................................................................71

Side 3 af 134

Page 4: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

DataTransport............................................................................................................73

CykelComputer..........................................................................................................77

Arkiv..........................................................................................................................82

Frame1.......................................................................................................................84

UserInterface..............................................................................................................90

Source kode til Assembler.........................................................................91ASKELET..................................................................................................................91

INITSEG....................................................................................................................94

Source kode til C++...................................................................................99Computer...................................................................................................................99

Display.....................................................................................................................108

Keyboard..................................................................................................................112

Bike..........................................................................................................................115

ComPort...................................................................................................................118

Seriel........................................................................................................................124

QUE.........................................................................................................................126

Measurment.............................................................................................................127

Session.....................................................................................................................129

Side 4 af 134

Page 5: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

IndledningVi har nok alle prøvet at sætte os på en motionscykel og bare cyklet derudad uden at

tænke over hvordan vores puls lige pludselig kan stå på et display, eller hvordan vi ved

hjælp af nogle taster på cyklen kan bestemme hvor meget modstand der skal være i

pedalerne.

Som bruger af en motionscykel er vi alle interesserede i at få oplyst al den information, vi

kan få, om vores træningsforløb. Det kan også virke motiverende, hvis man f. eks. hele

tiden kan følge med i hvor mange kalorier man har forbrændt eller hvor mange kilometre

man har lagt bag sig, og kan sætte dette i forhold til hvor hårdt man træder i pedalerne

eller hvor højt et gear man cykler i.

Benytter man en motionscykel jævnligt, er det også af stor interesse og motivation at få

en statistik over hele træningforløbet, så man på den måde kan se sine eventuelle

forbedringer eller forværinger.

Efter som at dette projekt omhandler to fag, har vi også valgt at dele rapporten op i to

dele. En pc-del og en hardware-del.

ProblemformuleringVores ene formål med denne rapport, er at udvikle og beskrive en cykelcomputer til brug

i en motionscykel. Brugeren af motionscyklen skal have et display og et tastatur til

rådighed til henholdsvis at få oplyst sin puls, forbrændte kalorier og andet og til at kunne

informere cykelcomputeren om vægt, ønsket træningstid og andet.

Vores andet formål er at udvikle og beskrive et program, hvor brugeren efter endt træning

kan gå ind og læse sin statistik og hvor man eventuelt kan oprette nye programmer til

motionscyklen. Vi vil prøve at benytte den teori, vi har lært i dette semester, til at opnå

det ønskede resultat.

Side 5 af 134

Page 6: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Begrænsninger

Vi har på grund af tidspres måtte indskrænke opgaven. De elementer der er fjernet er:

- PC-del

o Ingen programpopup når musen kører over program listen ved visning af

program

o Ingen statestikpopup når musen kører over statestik listen ved visning af

statestik

o Ingen detaljeret visning når muse cursoren kører over statestikvinduet

Side 6 af 134

Page 7: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Pc-program

Kravspecification for pc-programFor at komme i gang med dette projekt, er det meget vigtigt, at der først bliver lavet en

god analyse af kravene. Dette bliver gjort mens projektet befinder sig i inception fasen af

den iterative udvikling. Dette projekt har nogle krav som skolen sætter og resten er nogle

af vores egne krav. Nogle af de krav, som skolen satte frem, var:

- Pc-programmet skulle kunne afspegle information fra cykelcomputeren.

- Skulle kunne give brugeren en muligthed for at vælge mellem nogle

predefinerede programmer.

- Tillade brugeren at få mulighed for at designe sine egne programmer.

- Tillade brugeren at gemme og åbne data fra en træningssession.

Dette var de krav som skolen stillede til projektet. Der var dog nogle andre krav til

funktionaliteten, som vi gerne ville lægge til.

- Det skal være muligt at slette programmer fra programlisten

- Der skal kunne vises statestik over en træningssessin, dvs. graf over hastighed,

kalorieforbrænding, puls, distance og gear.

- Der skal være en hjælpefunktion, hvor brugeren kan navigere rundt og få hjælp

om alle funktioner i programmet.

- Der skule være mulighed for at ændre i de programmer fra programlisten og enten

overskrive de gamle eller gemme under nyt navn.

- Mulighed for at trykke på annuller, hvis det var nødvendigt.

Når nu de funktionelle krav var kommet på plads, var brugergrænsfladen tilbage. Her

skulle også en delting komme på plads. Her er så kravene, som vi kom frem til:

- Brugergrænsefladen skulle have nogle knapper der hele tiden var synlige, og så et

vindue, som kunne ændres alt efter hvad der blev valgt.

- Knapperne skule være: Opret program, Vis statestik, Vis program, Overfør

program, Hjælp, Gem, Annuller, Slet, Afslut.

Side 7 af 134

Page 8: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

- Der skule være en meddellelserbar nederst på siden, som kunne informere

brugeren om hvad han lavede, og om hvor han var henne i programmet.

- Knapperne skulle være fordelt på venstre side og nederst langs siden.

- Vinduet, som skule være det dynamiske på brugrænsefladen, skule være placeret i

resten af pladsen på i selve grænsefladen.

Efter at have sat disse krav for os selv, syntes vi at det ville være godt med et mere

overordnet blik, derfor lavede vi et simple design af vores brugergrænseflade.

Side 8 af 134

Opret program

Vis program

Overfør program

Vis statistik

Hjælp

AfslutAnnullerUdskriv/Gem

Hovedindhold

Slet

Page 9: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Anvendt design processDa vi startede på dette semester blev vi introduceret til Unified Process, der lægger vægt

på den iterative udvikling. Dette er en udviling, som gennem en riskdrivin arbejdsgang,

sikrer fremskridt i projektet, og springer derfor aldrig over hvor gærdet er lavest. Dette er

selvfølgelig en god arbejdsfilosofi, og en der er værd at implementere. Den arbejder med

milestones, som definerer slutningen af hver iteration, og disse milestones sætter også

krav til, hvilke artifacts der skal være færdige på det satte tidspunkt.

Vi gjorde brug af disse artifacts, og prøvede at følge iterationerne så godt som muligt.

Det var dog en hjælp for os, at læreren havde predefineret milestonene for os.

Når man går i gang med et sådant projekt, handler det meget om overvejelser, og om

hvad man vælger at tage med eller sortere fra. I inception bliver de første overvejelser

lavet i kraft af kravspecificationen, men også senere er der nogle design overvejelser, der

skal træffes. Design overvejelserne omhandler både GUI og funktionelle overvejelser.

Det er derfor meget vigtigt at have nogle gode værktøjer at benytte. Til de funktionelle

overvejelser bruger man mange af de artifacts som UP anvender, og specielt patterns er

gode til dette formål. Et pattern er, når man har en hændelse, der sker igen og igen, og

man gerne vil få beskrevet løsiningen til problemet. Vi vil påpege nogle patterns senere i

rapporten, når vi skal til at beskrive klasserne. Klasse diagram og use-case’es er også

gode til at få tingene op at vende til overvejning. Vi overvejede meget, om vi skule bruge

inheritance, fordi det er smart at være fri for at gentage sig angående metoder og

attributter. Men dette har vi også tænkt os at påpege senere, når vi beskriver klasserne.

Side 9 af 134

Page 10: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Use-cases Her er de use-cases, som vi lagde til grunde for vores design

PC-program

Send træningsprogramAktører TrænermandStartantagelse Cykelcomputer er tændt og tilsluttet RS232 forbindelse.Forløb 1. Træner vælger ”Overfør program”

2. PC system viser form med oversigt over træningsprogrammer3. Træner vælger program i oversigten4. Usecase ” Send programslotsoversigt” udføres5. PC system viser oversigt over programslots i cykelcomputeren6. Træner vælger hvilket slot programmet skal sendes til7. Usecase ”Modtag træningsprogram” udføres8. PC system underretter træner om overførslens succes

Målsætning Overførsel af program så cykelkvinde kan begynde at træne.Slutantagelse Træningsprogram sent til cykelcomputerens programslot.

Opret træningsprogramAktører TrænermandStartantagelse PC er tændt.Forløb 1. Træner vælger ”Opret program”

2. PC system viser blank træningsprogram i hovedindholdsrammen

3. Træner justerer træningssektionerne til ønskede niveau og vælger navn til træningsprogram

4. Træner vælger gem5. PC system gemmer træningsprogram i arkiv6. PC system underretter træner om at træningsprogram er gemt

Målsætning At træneren har oprettet træneren har et overblik over træningssessionerne.

Slutantagelse Statistik analyseret/udskrevet.

Rediger træningsprogramAktører TrænermandStartantagelse PC er tændt. Træningsprogram findes.Forløb 1. Træner vælger ”Vis program”

2. PC system viser form med oversigt over træningsprogrammer3. Træner vælger træningsprogram4. PC system henter træningsprogram ind i

hovedindholdsrammen5. Træner justerer træningssektionerne til ønskede niveau og

Side 10 af 134

Page 11: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

redigerer evt. navn til træningsprogram6. Træner vælger gem7. PC system gemmer træningsprogram i arkiv8. PC system underretter træner om at træningsprogram er gemt

Målsætning At træneren har oprettet træningsprogram og har et overblik over træningssessionerne.

Slutantagelse Statistik analyseret/udskrevet.

Slet træningsprogramAktører TrænermandStartantagelse Træningsprogram findes i systemet.Forløb 1. Træner vælger ”Vis program”

2. PC system viser form med oversigt over træningsprogrammer3. Træner vælger program fra oversigten4. PC system sletter træningsprogram5. PC system underretter træner om sletningens succes

Målsætning Sletning af program. Rydning i systemet.Slutantagelse Træningsprogram slettet fra systemet.

Modtag statistikAktører CykelcomputerStartantagelse Cykelcomputer og PC tændt. Cykelcomputer tilsluttet RS232

forbindelseForløb 1. Cykelcomputer anmoder PC system om lov at sende statistik

2. PC bekræfter anmodning og gør klar til modtagelse3. Cykelcomputer sender statistik4. PC system bekræfter modtagelse af statistik5. PC system gemmer statistik i arkiv med tidsmærke og

programnavn6. PC system underretter bruger om modtagelse af statistik

Målsætning Overførsel af statistik.Slutantagelse Statistik sendt til PC og gemt i statistikarkiv, cykelcomputer klar til

brug

Vis statistikAktører TrænermandStartantagelse PC er tændt og statistik findes.Forløb 1. Træner vælger ”Vis statistik”.

2. PC system viser form med oversigt over gemte statistikker3. Træner vælger statistik4. PC system viser statistikken i hovedindholdsrammen5. Træner vælger evt. ”udskriv”6. PC system udskriver statistikken som vist på skærmen7. PC system underretter træner om udskrivningens succes

Målsætning At træneren har et overblik over træningssessionerne.

Side 11 af 134

Page 12: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Slutantagelse Statistik analyseret/udskrevet.

Slet statistikAktører TrænermandStartantagelse Træningsprogram findes i systemetForløb 1. Træner vælger ”Vis statistik”

2. PC system viser oversigt over statistikker, der er gemt i systemet

3. Træner vælger statistik fra oversigten4. PC system sletter statistik5. PC system underretter træner om sletningens succes

Målsætning Sletning af statistik. Rydning i systemet.Slutantagelse Statistik er slettet fra systemet.

CykelcomputerVi har taget nogle use-cases med fra hardwaredelen, fordi de giver en bedre

helhedsforståelse af systemet

CykleAktører Cykelkvinde.Startantagelse Cyklen er tændt og ved startmenuenForløb 1. Cykelcomputer viser programvalg

2. Cykelkvinde vælger programnummer- hvis program 0 så spring til punkt 5

3. Cykelcomputer viser niveauvalg4. Cykelkvinde vælger niveau5. Cykelcomputer viser vægtvalg6. Cykelkvinde indtaster vægt

- hvis program 0 så spring til punkt 97. Cykelcomputer tidsvalg8. Cykelkvinde vælger træningstid9. Cykelcomputer starter træningsprogram ved at begynde

tidstælleren, samt sætte rette gear på cyklen i forhold til valgte træningsprogram

10. Cykelkvinde begynder at cykleMålsætning Cykelkvinden har forbedret sin kondi.Slutantagelse Cykling gennemført.

Send statistikAktører Cykelkvinde, PC systemStartantagelse Cykelcomputer og PC tændt. Cykling gennemført el. afsluttet, pc

tilsluttet RS232 forbindelseForløb 1. Cykelcomputer spørger om statistik skal sendes til PC

Side 12 af 134

Page 13: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

2. Cykelkvinde vælger ”Send statistik”3. Usecase ”Modtag statistik” udføres4. Cykelcomputer viser startmenu

Målsætning Overførsel af statistik.Slutantagelse Statistik sendt til PC og gemt i statistikarkiv, cykelcomputer klar til

brug

Send programslotsoversigtAktører PC systemStartantagelse PC system er tilsluttet RS232 forbindelse.Forløb 1. PC system anmoder cykelcomputer om programslotsoversigt

2. Cykelcomputer sender programslotsoversigt til PC system3. PC system bekræfter modtagelse af programslotsoversigt

Målsætning Giver PC system mulighed for at se ledige programslots på cykelcomputeren

Slutantagelse Programslotsoversigt overført til PC.

Modtag træningsprogramAktører PC systemStartantagelse Cykelcomputer og PC er tændt. Pc’en er tilsluttet RS232 forbindelse.Forløb 1. PC system sender træningsprogram til cykelcomputeren

2. Cykelcomputer bekræfter modtagelse af program og gemmer i ønskede programslot

Målsætning Overførsel af program så cykelkvinde kan begynde at træne.Slutantagelse Træningsprogram gemt i cykelcomputerens programslot.

Side 13 af 134

Page 14: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Use Case ModelSammenhænget mellem tilhørsforholdet af de forskellige usecases samt aktører, er vist i

nedenstående figur.

Side 14 af 134

Træner Cykelkvinde

Cykle

Send træningsprogram

Modtag træningsprogram

Send program-slotsoversigt

Send statistik

Opret træningsprogram

Rediger træningsprogram

Slet træningsprogram

Modtag statistik

Vis statistik

Slet statistik

PC system

Cykelcomputer

RS232for-

bindelse

Page 15: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Domain modelDomain modellen er et resultat af inception fasen, hvor man prøver at få et billede over,

hvordan man kunne tænke sig at opbygge programmet. Domainmodellen er sammen med

use-case’ene en stor del af begyndelsen til designet i iteration 1.. Domain modellen er et

simplificeret billede af hvordan arbejdsprocessens omhandlende problemområde skal

foregå.

1

1

har

1 1vælger

1

1

har

11har

1

1..*

opretter

1..*1analyserer

1 1..9har

Program Cyklist

TræningsSessionStatestikTræner

CykelComputer

Side 15 af 134

Page 16: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Design Model

Klasse diagramKlasse diagrammet er et billede af hvordan vores system hænger sammen. Diagrammet er

blevet revideret mange gange under udviklingen af projektet. Det viste klassediagram er

lavet ud fra kildekoden, og er stort set identisk med de tidligere klassediagrammer.

Systemet er delt op i pakker for at markere sammenhængen mellem klasserne.

Side 16 af 134

ProgramArkiv

+ProgramArkiv+nytProgram:void-loadProgram:Program+vis:JPopupMenu+vaelgProgramTilOverforsel:JPopupMenu+saveSession:void-genFilNavn:String+sletProgram:void

-AabenAction-OverforeselsAction

program:Program

StatistikArkiv

+StatistikArkiv-loadSession:Traeningssession+vis:JPopupMenu+saveSession:void

-AabenAction

traeningsSession:Traeningssession

Arkiv

#Arkiv#getArkivSti:String#load:Object#getFileList:String[]#setArkivSti:void

HyperlinkListenerDataTransport

+DataTransport+visStatistikArkiv:void+udskrivGem:void+gemStatistik:void+attachStatusField:void+attachMainPane:void+visStatistik:void-showPopup:void+sendProgram:void+opretProgram:void+visProgram:void+visProgramArkiv:void+slet:void+clearAll:void+showHelp:void+hyperlinkUpdate:void+actionPerformed:void+visSlotList:void

SerializableTraeningssession

+Traeningssession+nextMaaling:boolean+MaalingerRewind:void+vis:Graphics-calcMaxima:double[]+currentMaaling:Maaling+gem:void+setStatistik:void

antalMaalinger:int id:String vaegt:int niveau:int maaling:Maaling

SerializableMaaling

+Maaling

rpm:int pulse:int dist:double speed:double energy:double power:double kal:double gear:int

FrameEventListenerCykelComputer

+CykelComputer-genererTraeningsProgramPakke:String+requestSlotList:void-initSlotList:void-analyseSlotList:void+analyseData:void-convertStatistik:void+visSlotList:JPopupMenu+frameReady:void+doListen:void+dontListen:void

-TransferAction

status:String

SerializableProgram

+Program+opdater:void+vis:JPanel+gem:void

niveau:int[] name:String

Pakke: BikeProject

java.util.EventListenerinterface

FrameEventListener

+frameReady:void

EventObjectFrameEvent

-dataString:String

+FrameEvent

data:String

SerialPortEventListenerSerialFrame

-frameEventListener:FrameEventListener-portList:Enumeration-portId:CommPortIdentifier-serialPort:SerialPort-inputStream:InputStream-outputStream:OutputStream-frame:String-STOP_CHAR:char-BAUDRATE:int

+SerialFrame+closePort:void+addFrameEventListener:void+serialEvent:void+sendFrame:void+sendFrameRaw:void

Pakke: SerialPak

JFrameFrame1

UserInterface

Pakke: App

Page 17: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Kort beskrivelse af klassediagrammet:Vores model er mht. bruger interface opbygget med et observer pattern i tanke. Al

interaktion med brugeren sker gennem klasserne Userinterface og Frame1, disse stiller

en tegneflade til rådighed for den egentlige datamodel (BikeProject pakken) og brugerens

handling bliver kommunikeret til modellen som behandler brugerens forespørgsler.

Datamodellen er lavet med tanke både på strategy pattern og observer pattern, alle

klasserne i datamodellen indeholder metoder til at vise sig selv på en hensigtsmæssig

måde.

Pakken SerialPak, har vi ændret lidt på, stop byte er sat til char(255) i stedet for ’#’.

Dette er gjort da en måling godt kan have den samme ASCII værdi som en havelåge i den

protokol vi har specificeret for kommunikation.

Detaljeret beskrivelse af klasserne:bemærk: Alle klasserne har desuden en detaljeret beskrivelse lavet med Javadoc.

Klasse: ArkivBeskrivelse: Indeholder de nødvendige funktioner for at strømline arbejdet med Java objekter og

harddisken.Ansvar: At indlæse og liste objekter fra en sti defineret som et arkivMetoder: Arkiv() – tom konstruktør

String getArkivSti() – metode til at hente arkivsti Object load(String fil) – indlæser et objekt med filnavn som parameter. String[] getFileList() - henter en liste over filerne i arkivstien setArkivSti(String s) - metode til at sætte arkivstien = s

Klasse: CykelComputerBeskrivelse: Klasse der indeholder alle metoder der skal bruges for at kommunikkere med hardware

cykelcomputer, (herefter kaldet 'HWCC'.)Ansvar: At sende og modtage data fra 'HWCC' samt vise en oversigt over hvad der ligge på HWCC

af programmer.Metoder: CykelComputer() – sætter stadie til INIT

String genererTraeningsProgramPakke(Program p, int slotnummer) - Sammensætter en pakke til seriel transmission fra et træningsprogram til det format som HWCC bruger metoden skal udover en pointer til træningsprogrammet også have et nummer som er destinationssnummeret på HWCC.

requestSlotList() - Spørger cykelcomputeren om den kan få en slot liste initSlotList()- Initialiserer slotListen spledes at man kan se der ikke er modtaget

data endnu. analyseSlotList(String[] segments) - Hvis der er modtaget en slotListe fra

'HWCC' kaldes denne metode

Side 17 af 134

Page 18: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

analyseData(String data) - Analyser en modtaget pakke sammenholdt med hvilket stadie cykelcomputeren står i.

convertStatistik(String data) - konverterer en streng til et statisk objekt. hvis strengen bliver godkendt som et stykke statistik, bliver den gemt på hd ved hjælp af statistikArkiv.

JPopupMenu visSlotList(Program prg) - opretter en popupmenu over cykelprogrammer på computerenmetoden returnerer en liste uansetr om cykelcomputeren er tilgængelig eller ej. listen har tilknyttede handlinger (Action) af typen transfer Action når man trykker på en handling, overføres programmet til det valgte slot.

frameReady(FrameEvent be) - eventen forekommer når der er ligger en pakke data på den serielle kanal. dataen bliver send direkte videre til analyseData

doListen()- åbner den serielle kanal dontListen()-lukker den serielle kanal.

Klasse: DataTransportBeskrivelse: Styre klasse, klassen kalder metoder i de andre klasser baseret på hhv. hvad brugeren

indirekte beder om eller når metoderne svarer igen!Ansvar: Har ansvaret for den interne kommunikation i programmet, samt opdatering af skærmen.Metoder: DataTransport() – konstruktør – initialiserer datastruktur

visStatistikArkiv() - viser statistikarkiv gem()-gemmer nuværende objekt attachStatusField(JTextField t) - bruges til at vedhæfte statusfeltet som bruges af

dataModellen, dette bliver brugt til at vise evt. statusmeddelser i attachMainPane(JPanel p) - bruges til at vedhæfte et JPanel til cykelmodellen,

dette vil blive brugt til at vise hovedindholdet af datamodellen i visStatistik() - viser en statistik showPopup(JPopupMenu pop) - wrapper til ensartet visning af jpopupmenuer sendProgram() - starter send program sekvensen opretProgram() - opretter et tomt program og viser det. visProgram() - viser det aktuelle program visProgramArkiv() - viser en liste over programmerne som popupmenu slet() - slet nuværemde element clearAll() - renser skærmen. showHelp() - viser html hjælpe menuen i hovedvinduet hyperlinkUpdate(HyperlinkEvent event) - åbner en side når der trykkes på et

link, hvis siden ikke findes skrives en pæn fejlmeddelelse i statusfeltet. visSlotList(Program program)- viser en popupliste med programmer fra cyklen,

skal have et program som parameter, dette program vil blive overført ved klik på et slot fra listen.

Klasse: MaalingBeskrivelse: Maaling klassen indeholder en måling samt metoder til at hente data fra målingen.

en måling representerer altid 1 sek!Ansvar: at give metoder der giver adgang til måling dataMetoder: Maaling(byte maalingData) - konstruktør der gemmer en måling

int getRpm() - henter antal omdrejning i minuttet som denne måling har haft. int getPulse() - henter hvor mange hjerteslag der har været til denne måling. int getGear() - metode til at se hvad gear cyklen stod i til en måling double getDist() - udregner længden der er kort i dette øjeblik. double getSpeed() - udregner hastigheden der blev kørt med i denne måling.

double double getEnergy() - udregner hvormeget energi der er produceret i denne

måling.

Side 18 af 134

Page 19: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

double getPower() - udregner hvor mange watt der er blevet forbrændt i dette sekund.

double getKal() - udregner kalorierne der er forbrændt i denne måling.

Klasse: ProgramBeskrivelse: Program klasse indeholder navn og indstillinger for et programAnsvar: Har ansvaret for hvad der kan foregå med et træningsprogram.Metoder: Program(String _name, int[] _niveau) - konstruktør,et program skal oprettes med

et navn som string og nogle niveauer. antallet af niveau skal være == LENGTH

int[] getNiveau() - metode til at hente et array af niveauer. opdater() - opdaterer et program til værdierne fra JSliderne. JPanel vis() - metode der bruges til at vise et program. metoden returner et JPanel

som indeholder træningsprogrammet. der returnerede JPanel har layoutmanager=NULL

gem(String sti) - gemmer et program på harddisken.Sti fortæller hvor på hd der skal gemmes... udskriver en fejlmeddelelse hvis der opstår fejl ved skrivning til hd.

String getName() - metode til at hente navnet fra træningsprogrammet.

Klasse: ProgramArkivBeskrivelse: arkiv til behandling af programmerAnsvar: har ansvaret for at vise en liste med programmer, samt bestemme hvor de skal ligge.Metoder: ProgramArkiv() - konstruktør initaliser, opretter et programArkiv

nytProgram() - opretter et nyt program, med et standard niveau på 3 og nanvet 'navn'

Program loadProgram(String fil) - indlæser et program fra fil. Skal have et filnavn til programmet som parameter.

JPopupMenu vis(DataTransport controller) - viser en popupmenu med en liste af programmer, ved klik på et program indlæses og vises programmet skal have DataTransport som parameter.

JPopupMenu vaelgProgramTilOverforsel(DataTransport c) - viser en popupmenu indeholdne en liste af programmer, ved klik på et program åbnes cykelcopmputeren slot liste dette forgår dog gennem datatransport. skal have DataTransport som parameter.

saveSession() - gemmer det nuværende program på harddisken Program getProgram() - returnerer nuværende program String genFilNavn() - returnerer et filnavn der passer til arkivsti samt program

sletProgram() - sletter det indlæste program fra harddisken hvis program har samme navn som fil.

Side 19 af 134

Page 20: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Klasse: StatistikArkivBeskrivelse: arkiv til behandling af træningssessionerAnsvar: har ansvaret for at vise en liste over træningssessioner, samt bestemme hvor de skal ligge.Metoder: StatistikArkiv()- konstruktør initaliser, opretter et Traeningsarkiv

Traeningssession loadSession(String fil) - indlæser en traeningssession fra hd JPopupMenu vis(DataTransport t) - viser elementerne i traeningsarkivet, ved klik

vises statistik for træningssessionen saveSession() - metode til at gemme en træningssession

benytter traeningssessions gem(filNavn) Traeningssession getTraeningsSession() - returnerer nuværende trænigssession

Klasse: TraeningssessionBeskrivelse: indeholder nøgle data om en træningssession

alle målinger er gemt her og der er lavet metoder til at navigere målingerene efter behov. samt metoder til at gemme på hd

Ansvar: har ansvaret for en træningssession.Metoder: Traeningssession() - konstruktør oprettet en tomt træningssession.

boolean nextMaaling() - vælger den næste måling som current MaalingerRewind() - 'spoler' måling listen tilbage til start int getAntalMaalinger() - hent antal måling i træningssession vis(JPanel pane) - tegner grafer der viser dat over en måling... Maaling currentMaaling() - hent den nuværende måling String getId() - hent nuværende id, id er programmets navn der blev afviklet under

træningssessionen int getVaegt() - hent vægt int getNiveau() - hent niveau Maaling getMaaling() - hent måling gem(String sti) - gem program, parameter er en sti hvor der skal gemmes. setStatistik(String _programId, int _vaegt, int _niveau, ArrayList _maalinger) -

opretter et statestiksæt ud fra statistikdata

Efter beskrivelsen af klasserne og de tilhørende metoder, er der dog nogle punkter af

funktionaliteten, som kunne være beskrevet en smule mere detaljeret. F.eks. har vi valgt

at bruge nedarving til arkivdelen af programmet. Vi har et ProgramArkiv og et

StatestikArkiv. Her er der nogle ting, som er ens. Derfor kom superklassen Arkiv, som de

to andre klasser arver fra.

Komplekse metoder:Både Program – og StatistikArkiv har private klasser der bruges til at behandle klik i

menuen. Som eksempel vises beskrivelsen nedenfor.

Side 20 af 134

Page 21: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Privat klasse AabenAction ( fra StatistikArkiv)Beskrivelse: Klasse der indeholder knap funktionalitetAnsvar: Skal omdirigere et knaptryk til kontrolleren.Metoder: AabenAction (String _ts, DataTransport _controller, StatistikArkiv parent) -

konstruktør knytter en abbenHandling til popmenuen. actionPerformed() – beder pænt kontrolleren om at vise statistikken

Samhørighed og kobling.Samhørighed er en indikator af hvor ’knyttet’ attributter og metoder er i en klasse. Man

bør bestræbe en høj samhørighed. Kobling er en beskrivelse af hvor meget klasserne er

knyttet til hinanden. Man bør bestræbe en lav kobling. hvis disse overholdes, er det

lettere at vedligeholde og opdatere / ændre programmet.

Generelt er der i projektet opnået en forholdsvis lav kobling, der er dog nogle

undtagelser. Der er en høj kobling mellem DataTransport og Frame1 klasserne, dette

skyldes at alle metoderne som Frame1 kalder, er defineret i DataTransport klassen.

Frame1’s ansvar er at tegne brugerfladen og videredirigere brugerens forespørgsler til

DataTransport. Dette betyder at hvis man vil have et nyt brugerinterface skal man

’forbinde’ knapperne i brugerinterfacet med metoderne i DataTransport, hvilket næppe

vil kunne undgås.

I den modsatte ende findes Traeningssession som holder data om en træningssession,

denne klasse har en meget lav kobling. Klassen er koblet op mod Maaling klassen som

den består af.

StatistikArkiv er koblet op mod forholdsvis mange klasser. Når en bruger f.eks. trykker

på knappen ’vis statistik’ i Frame1 kaldes visStatiskArkiv() i DataTransport.

DataTransport kalder vis() i StatistikArkiv som returnerer en JPopupmenu. Denne menu

har eventhandlere der også kender til DataTransport klassen. Således udløser et klik i

popupmenuen et kald til DataTransport visStatistik(). visStatistik() beder StatistikArkiv

om nuværende Traeningssession og viser denne.

Side 21 af 134

Page 22: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Der er 3 popupmenuer i programmet, de har alle høj kobling, på den anden side, kun ’1’

koblingspunkt pr menu, derfor vil det stadigt være overskueligt at opdatere.

Samhørighed er generelt høj i vores system. Dog skal siges, at DataTransport klassen må

siges at have en lav samhørighed. Den har mange metoder og derfor et stort ansvar

overfor de andre. Den kan være svær at overskue og er derfor ikke optimal hvad

samhørighed angår. Men på grund af at DataTransport har taget så meget ansvar over på

sig selv, kan de andre klasser ånde mere let, og har derfor en relativ høj samhørighed. En

klasse som har høj samhørighed, må være Program. Den har kun nogle enkelte metoder,

og står ikke og ændrer sig hele tiden. De andre klasser har en rimelig høj samhørighed,

men det bliver dog altid til et smagspørgsmål.

Beskrivelse af test metode.Gennem projektudviklingen har vi bestræbt os på hele tiden at teste vores kode. Til dette

er der bl.a. benyttet JUnit. Der er dog ikke alle steder at det ville være hensigtsmæssigt at

benytte JUnit, da det i nogle af klasserne ville kræve en stor mængde tid samt ekstra og

unødvendigt arbejde. Disse metoder er dog alle testet i praksis, ved at vi har gennemgået

vores usecases, og afprøvet dem på systemet. Nedenfor har vi nogle testcases, som høre

nøje sammen med use-case’ene:

Test cases for PC i forhold til kravspecifikation TC Scenario Start tilstand Funktion Display Forventet resultat101 Modtag statistik N/A V Statistik modtaget og

gemt i arkiv for aktuelle program og bruger informeret

102 Modtag crap statistik

N/A V Bruger informeret, og statistik kasseret

103 Udskriv statistik på skærm

Statistik eksisterer i systemet

udskriv statistik(’skærm’)

V Medievalg bliver præsenteret for brugeren. Brugeren vælger skærm Statistik bliver udskrevet på skærmen.

104 Udskriv statistik på printer

Statistik eksisterer i systemet

udskriv statistik(’printer’)

V Medievalg bliver præsenteret for brugeren. Brugeren vælger printer Statistik bliver udskrevet på printer.

Side 22 af 134

Page 23: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

105 Overfør træningsprogram

Et træningsprogram er oprettet

Send() V Træningsprogram bliver overført til cyklen. Brugeren bliver informeret

106 Slet træningsprogram

Et træningsprogram er oprettet

Slet program()

V Træningsprogram bliver slettet

107 Slet statistik En statistik findes i systemet

Slet statistik()

V Statistikken bliver slettet. Brugeren bliver informeret

108 Vis graf At statestik findesi systemet

visGraf() V Grafen viser de rigtige data,og at de bliver representeretpå den rigtige måde

Som sagt har vi, ved at gennemgå vores use-cases i systemet, fået lave test på alle de

scenarier, og fundet ud af, om det virker eller ej. Testmetoder i JUnit ligger i bilag.

Side 23 af 134

Page 24: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

CykelcomputerCykelcomputeren er den del af projektet, der omhandler hardwaren, samt det software,

der skal køre på det hardware. Det er den del, der bliver tilsluttet den fysiske

træningscykle. Her bliver den specificeret.

Kravspecifikation til cykelcomputer

Cykelcomputeren skal bruges til at styre cyklens gear, overvåge sensorer, videregive

information, samt fungere som interface mellem bruger og cykel. Udover dette skal

cykelcomputeren også fungere som interface til Pc’en.

For konkret at specificere de krav, der sættes cykelcomputeren er det derfor først

nødvendigt at få et overblik over hardwaren, som skal udgøre cykelcomputeren.

Denne prototype af cykelcomputeren er bygget omkring et 8088 minimum system.

Systemet består af lidt RAM, lidt ROM, en timer, en UART og diverse porte. Udover

dette skal der bruges nogle lysdioder, et display, samt et tastatur for input.

Der sættes følgende krav til cykelcomputeren:

- Serielt interface til Pc

o Overførsel af program og træningsdata mellem Pc og cykel.

- Tastatur funktioner

o Valg af program

o Valg af gear

o Valg af niveau

o Valg af puls

o Valg af tid

o Godkend

o Fortryd

Side 24 af 134

Page 25: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

o Tilbage

- Overvågningsfunktioner (puls, hastighed, distance, kalorier, tid, gear)

- Afvikle programmer (Programstyret, manuelt styret)

- Logge data (aflæse puls fra sensor, aflæse rpm fra sensor)

Der er vedtaget, at cykelcomputeren skal have 6 taster for dette vurderes at give bedste

brugervenlighed. Disse taster er følgende: Op, ned, ok, fortryd, gear op samt gear ned.

Displayet, der skal bruges til denne prototype er består af 8x7-segments displays. På

displayet skal teksten være venstre justeret og tallene er højrejusteret. Displayet skal vise

følgende ting under en træningssession:

- Gear

- Kalorieforbrug

- Puls

- Resterende tid eller afviklet tid

- Hastighed

- Distance

Ud fra disse oplysninger der lavet usecasene til cykelcomputeren. Disse skal give et

overblik over hvordan systemet skal fungere overfor brugerne.

Usecases på cykelcomputerCykleAktører Cykelkvinde.Startantagelse Cyklen er tændt og ved startmenuenForløb 1. Cykelcomputer viser programvalg

2. Cykelkvinde vælger programnummer- hvis program 0 så spring til punkt 5

3. Cykelcomputer viser niveauvalg4. Cykelkvinde vælger niveau5. Cykelcomputer viser vægtvalg6. Cykelkvinde indtaster vægt

- hvis program 0 så spring til punkt 9

Side 25 af 134

Page 26: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

7. Cykelcomputer tidsvalg8. Cykelkvinde vælger træningstid9. Cykelcomputer starter træningsprogram ved at begynde

tidstælleren, samt sætte rette gear på cyklen i forhold til valgte træningsprogram

10. Cykelkvinde begynder at cykleMålsætning Cykelkvinden har forbedret sin kondi.Slutantagelse Cykling gennemført.

Send statistikAktører Cykelkvinde, PC systemStartantagelse Cykelcomputer og PC tændt. Cykling gennemført el. afsluttet, pc

tilsluttet RS232 forbindelseForløb 1. Cykelcomputer spørger om statistik skal sendes til PC

2. Cykelkvinde vælger ”Send statistik”3. Usecase ”Modtag statistik” udføres4. Cykelcomputer viser startmenu

Målsætning Overførsel af statistik.Slutantagelse Statistik sendt til PC og gemt i statistikarkiv, cykelcomputer klar til

brug

Send programslotsoversigtAktører PC systemStartantagelse PC system er tilsluttet RS232 forbindelse.Forløb 1. PC system anmoder cykelcomputer om programslotsoversigt

2. Cykelcomputer sender programslotsoversigt til PC system3. PC system bekræfter modtagelse af programslotsoversigt

Målsætning Giver PC system mulighed for at se ledige programslots på cykelcomputeren

Slutantagelse Programslotsoversigt overført til PC.

Modtag træningsprogramAktører PC systemStartantagelse Cykelcomputer og PC er tændt. Pc’en er tilsluttet RS232 forbindelse.Forløb 1. PC system sender træningsprogram til cykelcomputeren

2. Cykelcomputer bekræfter modtagelse af program og gemmer i ønskede programslot

Målsætning Overførsel af program så cykelkvinde kan begynde at træne.Slutantagelse Træningsprogram gemt i cykelcomputerens programslot.

Specifikation af træningsprogram

Et træningsprogram består af 20 træningssektioner. Disse sektioner består kun af hvilket

gear, cyklen skal være i, når der cykles i vedkommende sektion. Træningstiden samt

Side 26 af 134

Page 27: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

niveau bliver bestemt af cyklisten før træningssessionen begynder. Diagrammet nedenfor

viser en visuel repræsentation af et træningsprogram. Trænings-sektionernes varighed

bestemmes således af den samlede træningstid divideret med 20.

Træningscyklen har 8 gear, og det er derfor nødvendigt at kunne gemme disse. De 8 gear

kan holdes med 3 bit, og ved at fylde de øvrige 5 bit ud, kommer hvert træningssektion at

fylde en byte. Dette bliver gjort således, at der bliver lagt 48 til gearet, som vist på

figuren nedenfor.

Grunden til disse 48 bliver lagt til gearet er, at når et træningsprogram bliver sendt fra

pc’en, kan man med fordel kikke på dette i en terminal, og hurtigt se om det er de rigtige

værdier, der bliver sendt. Dette er altså en fordel under selve udviklingen.

Træningsprogrammet har ud over gear også et navn.

Specifikation af statistikDet kræves af EBC (extreemly bankrupt company) at cykelcomputeren kan vise

vedrørende oplysninger gennem en træningssession. Her tænkes på puls, distance,

træningstid, m.m.

Side 27 af 134

gear

træningssektioner

gear

0 0 1 1 0 x x x

Page 28: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Det skal være muligt at analysere disse tal på en PC efter træningssessionen. Derfor er det

nødvendigt at gemme disse oplysninger gemmen hver træningssession, for siden at

overføre disse til PC systemet efter træningen.

For at danne disse oplysninger skal 4 ting overvåges. Tiden, pulsen, omdrejningerne samt

gearet på cyklen. Der er vedtaget at tage målingerne skal have fast mellemrum, og derved

er det unødvendigt at gemme tiden for hver måling, idet den kan beregnes til enhver tid

ud fra et antal målinger. Disse målinger har en hyppighed på 1Hz, dvs. en måling pr.

sekund. Det kan endvidere konstateres, om træningssessionen er efter et foruddefineret

træningsprogram, så kan gearet også udregnes for en given måling. Dette er dog ikke

tilfældet for manuel cykling, og derfor er det nødvendigt at gemme oplysninger om

hvilket gear, cyklen er i, til en hver måling.

For at spare plads på statistikken er der endvidere vedtaget at gemme delta-puls slag og

delta-omdrejninger for hver måling. Dette gør det muligt at udregne en jævn puls ved at

beregne pulsen over f.eks. de sidste 10 målinger.

Vi har antaget følgende:

- Maksimale antal omdrejninger er 180 omdrejninger pr. min.

- Maksimal puls er 240 slag pr minut.

Der eksisterer følgende begrænsning på cyklen:

- Cyklen har 8 gear

Og vedtaget følgende:

- Det bliver lavet en måling pr. sek.

- Der bruges en byte til hver måling

o 160omdr/min / 60sek = 3omdr/sek = 2bit

o 240slag/min / 60sek = 4slag/sek = 3bit

o 8 gear = 3bit

Side 28 af 134

Page 29: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Desuden startet vores målinger med en header som indeholder programnavn, niveau samt

cyklistens vægt.

Herved kan der ses, at man på 1 time skal bruge:

- 1byte * 60sek * 60min = 3600 bytes pr. time til datalogning.

Specifikation af kommunikationenDa der skal kommunikeres mellem PC og cykelcomputer, er det nødvendigt at specificere

kommunikationens protokol. Protokollen defineres bedst ved et tilstandsdiagram.

Diagrammet viser, hvordan cykelcomputerens kommunikations system fungerer ret

funktionelt. Det ses, at cykelcomputeren kan sende statistik og programslotsoversigt.

Kommunikationen mellem pc’en og cykelcomputeren foregår således, at begge parter

hele tiden venter på information fra hinanden. Dvs. når cyklisten ønsker at sende en

træningssession efter en træning kan han gøre dette uden at forberede pc programmet til

Side 29 af 134

idle

sendSlot-List

sendStat()

receive-Program

sendACK

send-Statistik waitACK

resend

TxT = 255

Timeout = 1

RxT = ACKsetIdle()

resend()

TxT = 255

RxT = ’!’RxT>=’1’RxT<=’9’

TxT = ACK

Timeout = 1

RxT = 255

Page 30: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

modtagelse. Ligeledes kan pc programmet sende et træningsprogram til cyklen uden

nogen forberedelse på cyklen.

Programslotsoversigten bruges til at informere pc’en om hvilke programmer findes på

cykelcomputeren til enhver tid. Dette bruges af pc’en til at informere brugeren, når han

ønsker at sende et træningsprogram.

Ud fra ovenstående konstateres, at statistikken sendes til pc’en, som vist nedenfor.

først sendes programnavnet efterfulgt af en character 13, så pc’en kan tilknytte denne

statistik til det rigtige program. Dernæst sendes cyklistens vægt som characters efterfulgt

af character 13, siden niveau som characters, og til sidst kommer målingerne for hele

træningssessionen. Transmissionen bliver afsluttet med character 255.

Programslotsoversigten, som sendes til pc’en ses på figuren nedenfor. Der er ikke meget

at kommentere her. For alle slots, hvor der findes et program, sendes først slotsnummeret

siden programnavnet og siden character 13. Også denne transmission bliver afsluttet med

character 255.

Træningsprogrammerne, der kommer fra pc’en består af et slotsnummer, der hvor

programmet ønskes gemt, siden programnavnet efterfulgt af character 13, 20

træningssektioner, og til sidst character 255.

Side 30 af 134

ProgramIDvilkårlig længde

13idid id

Vægt for cyklistvilkårlig længde

13 nv

Valgt niveauvilkårlig længde

13 255v m m m

Målingervilkårlig længde

Slut karakterfor transmission

m

Slotnr

13idsid id

ProgramIDvilkårlig længde

id2 13 5 255id

Slut karakterfor transmission

id 13id 13

Slotnr ProgramIDvilkårlig længde

Page 31: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Design af hardwareFor at kunne designe hardwaren til cykelcomputeren bliver der først lavet et blokdiagram,

der giver overblik over hele hardwaren. Blokdiagrammet kan ses nedenfor. Det viser

hvilke komponenter bruges i systemet, og hvor de bliver tilsluttet. Det viser også hvilke

dele af minimumsystemet bliver brugt på hardware interfacet.

DisplayetDisplayet bliver tilsluttet med et 16-pins interface. Displayet består af en 8x7-segment

displays, som kan skrive tal fra 0 til 9, samt med lidt improvisering diverse bogstaver.

Figuren nedenfor viser et 7-segment display. Ved at tænde forskellige segmenter, kan

Side 31 af 134

13idsid id

20 x Gear / tidsenhed

gg g g 255g

Slut karakterfor transmission

g gg g

ProgramIDvilkårlig længde

Slotnr

MinSys

Tastatur

DisplayHardwareinterface

Cykel

PC

Cykelcomputer

4

Gear

LEDs

16

3

Puls/Rpm

2

86

RS232

INTR

8

INTApo

rtA

portB

portC

DAT

A

8

clk

TIM

ITI

MO

NM

I

Page 32: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

disse tal og bogstaver skrives. Displayet består af 8 af disse displays. Hver af disse kan

vælges ved hjælp af et 8-bit signal.

Ved at skrive en character ad gangen, kan skrivningen synkroniseres med timeren, der

bruges til klokken. Dette giver hver karakter 1ms, og der går dermed 7ms inden man

kommer tilbage til hver character. Dette er nok til at brugeren ser det som om alle

characters er tændt samtidig.

CPLD som decoderDa det kun er behov for 32 diverse symboler (tegnoversigten er vedlagt som bilag) at vise

på displayet, kan disse gemmes i 5 bits i hukommelsen. Og at vælge hvilken af de 8

characters, der skal skrives til kræves 3 bits (værdi fra 0 til 7). Det vil sige, at alt displayet

kan styres med en output port på minimumsystemet med en decoder tilsluttet porten.

Decoderen bliver lavet således, at de første 3 bits (MSB) på port A fra minimumsystemet

bliver decodet til at vælge én, og kun en, character på displayet. Den valgte character

bliver outputtet på en af de 8 ledninger, der bruges til at vælge character. De øvrige 5 bits

(LSB) bruges så til at angive hvilket tegn der skal vises, og decoderens opgave er at sørge

for at de rigtige segmenter bliver tænd. Det vil sige, at decoderen bliver tilsluttet de 8 bits

fra port A på minimumsystemet og til de 8 bits der vælger character på displayet samt de

Side 32 af 134

A

B

C

D

E

F

G

H

Page 33: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

8 bits der vælger segments. Figuren nedenfor viser dette grafiskt. Tegnoversigten i

bilagene viser hvad der skal skrives for at få de ønskede tegn.

TastaturTil input fra brugeren bruges det tastatur, der er sat til rådighed til dette projekt. Det er

helt enkelt en matrix hvor hver knap kortslutter to ben. Det ene ben repræsenterer

rækkerne, og det andet repræsenterer søjlerne. Når der kun bruges 6 taster, er det nok kun

at bruge én række. Nedenfor ses en tegning over tastaturet. Disse 6 knapper bliver

tilsluttet input port B på minimumsystemet.

CyklenPå cyklen sidder der to sensorer. En hjertesensor og en pedalsensor. Disse bruges til at

aflæse cyklistens data under træningssessionen. For at få et mere konkret signal fra disse

Side 33 af 134

Decoderpå CPLD

8

8

8

Digit

Segment

Input

Page 34: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

sensorer er der sat Schmitt invertere på begge disse signaler, inden de bliver tilsluttet til

de to resterende bit på port B på minimumsystemet.

Udover disse sensorer har cyklen også en serielport, hvor gear-skift kommandoer kan

sendes. Disse sendes som character 3 og 4 for hendholdsvis gear op og gear ned.

Hastigheden på denne serielport er 300 baud, ingen paritetsbit og 1 stopbit.

CPLD som UARTDa der kun skal sendes to forskellige tegn (gear op/gear ned) er der valgt at implementere

denne på en CPLD. Signalet, der skal sendes til cyklen ses på figuren nedenfor.

Signalet skal sendes med 300 baud. Det vil sige 1/300 sekund pr. bit og 10/300 sekund

for hvert gearskift svarende til omkring 33ms. For at kunne sende ønskede kurv er det

nødvendigt at bruge en timer og tilslutte den til clock-generatoren på minimumsystemet.

Kurven kan så genereres ved at implementere en tilstandsmaskine på CPLD’en jævnfør

nedenstående diagram.

Side 34 af 134

idle

1

0

Gear up

idle

1

0

Gear down start LSB MSB stop

stopMSBLSBstart idle

idle

Page 35: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Til denne tilstandsmaskine er der, udover clocken, brug for to input ben. Et til at indikere

gear op og et til at indikere gear ned. Disse tilsluttes output port C på minimumsystemet.

Outputtet på denne UART tilsluttes så RxT-benet på cyklens serielport. Det ses på

tilstandsdiagrammet, at denne UART ikke kommer tilbage til idle igen før begge input

linjer er sat lave igen.

SammensætningUdover tastatur, display og cykel skal der også tilsluttes 3 lysdioder. Disse tilsluttes 3 bit

på minimumsystemets port C. Det er også vedtaget, at lave en NMI (Non-maskable-

interrupt) hvert millisekund, for nemt at lave en klokke, som vises på displayet. Denne

Side 35 af 134

timer=1 up=0 down=0

timer=0

timer=1timer=1 stopRxT=0

waitRxT=1

timer=1

timer=1

timer=0

timer=0

down8

down5RxT=1

down6

down7RxT=0

timer=1

timer=0

down3RxT=1

down4RxT=0

down=1timer=0

timer=1

timer=0

timer=1

timer=0

timer=1

up=1timer=0up_start

RxT=0

up2

down1

idle down_startRxT=0

up1RxT=1

timer=0

timer=1

timer=0

timer=1

up4

up6

up8

up3RxT=0

up5RxT=1

up7RxT=0

timer=0

down2

Page 36: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

interrupt giver også mulighed for at synkronisere nogle af elementerne i softwaren til

denne klokke. Til dette bruges timeren på minimumsystemet.

Men en interrupt på en millisekund er ikke nok, når det gælder data fra pc’en, fordi

kommunikationen mellem pc’en og cykelcomputern skal være med 19200 baud, og det er

vedtaget, ifølge usecasene, at pc’en skal kunne sende data, selv om der er en

træningssession i gang. Dette medfører, at modtagelsesprocessen på cykelcomputeren

ikke kan være blokerende for resten af softwaren på minimum-systemet. Den skal kun

modtage og behandle en character, når der er kommet en, og så fortsætte men at overvåge

og udføre træningssessionen.

Bedste måde at løse dette problem på er at

interrupte CPU’en når der kommer en

character fra pc’en. Dette gøres ved at

tilslutte RxTRDY fra UART’en til INTR på

CPU’en. Diagrammet til venstre viser,

hvordan dette laves med en 8 bit tri-state

buffer. Når der kun skal bruges én maskable

interrupt, kan den tilssluttes som vist på

diagrammet. Der skrives ”3” på databussen for hver interrupt acknowledge fra CPU’en.

Det bliver så softwarens opgave at læse characteren fra pc’en, så UART’en ikke

interrupter igen når interrupt-routinen er færdig.

ForbindelsesdiagramUd fra den ønskede sammensætning er der tegnet følgende forbindelsesdiagram.

Diagrammet viser hvilke komponenter der skal bruges til implementeringen af hardwaren

samt dets forbindelser.

Side 36 af 134

Page 37: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

V C C

s e g m e n t 6

s e g m e n t 5

po r t B 2

V C C

TD I

p o r t A 2

d ig it 6

c y k e l_ R x T

le f ts e g m e n t 3

p o r t A 0 d 3

D 3

LE D

po rt B 4

d ig it 1

p o r t A 1

po rt C 2

gear Up

p o r t C 1d 6

p o r t A 3

r ig h t

p o r t A 4

TC K

d 7c lk

po r t A 7

d 2

po r t B 7

d ig it 0

TM S

V C C

Tri-state buffer for interrupt

s e g m e n t 1

D 1

LE D

CPLD

po r t B 5

d 5

U 3 B

74 H C 2 4 4

357911

131517

19Y 3Y 2Y 1Y 0A 0

A 1A 2A 3

O E

Afkobling

R 1R E S I S TO R S I P 4

12 3 4

U 3 A

74 H C 2 4 4

1 21 41 61 82

468

1Y 3Y 2Y 1Y 0A 0

A 1A 2A 3

O E

s e g m e n t 7

d ig it 4

V C C

in t a

d ig it 5

XC 9 5 7 2 / L C C 4 4

U 1

32

123489

1112

13141819

17

20222425

37384344

30

15

16

2627282933343536

567394240

V C C I O

I / OI / OI / OI / OI / OI / OI / OI / O

I / OI / OI / OI / O

TC K

I / OI / OI / OI / O

I / OI / OI / OI / O

TD O

TD I

TM S

I / OI / OI / OI / OI / OI / OI / OI / O

I / O / G C K 1I / O / G C K 2I / O / G C K 3

I / O / G S RI / O / G TS 1I / O / G TS 2

s e g m e n t 4

C 1

TD O

C 2

po r t C 4

V C C

po rt B 6

d 0

R 5

R E S I S TO R S I P 9

1 23456789

Pullup resistors for inputs

s e g m e n t 0

d ig it 2

s e g m e n t 2p o r t A 6

d 1d ig it 3

p o r t C 3

po r t B 3

C 3

d ig it 7

d 4

in t a

D 2

L E D

LEDs

po r t C 0

gear Down

p o r t A 5

Udover disse komponenter er der også lavet et forbindelsesdiagram over de stik, der skal

bruges for tilslutning af de forskellige hardware enheder. Disse ses på diagrammet

nedenfor. Her ses også de Schmitt invertere, der er tilsluttet hjerte og pedal sensorerne på

cyklen.

heart

JTAG interface

p o rt B 2

s e g m e n t1

p o rt C 3

J 9

C O N 2 6

1234567891 01 11 21 31 41 51 61 71 81 92 02 12 22 32 42 52 6

Keyboard interface

d ig it 2 V C C

J 1 3

13579

1 11 31 51 71 92 12 32 52 72 93 13 33 53 73 94 14 34 54 74 95 15 35 55 75 96 1

24681 01 21 41 61 82 02 22 42 62 83 03 23 43 63 84 04 24 44 64 85 05 25 45 65 86 06 2

6 3 6 4

d ig it 3p o rt A 1

le f t

J 1 1

C O N 1 0

1234567891 0

p o rt B 6

p o rt B 6

p o rt C 2

s e g m e n t2

d ig it 0

p o rt C 1

p o rt B 3

V C C

U 2 B7 4 H C 1 4

3 4

s e g m e n t7

d 3

p o rt A 4

s e g m e n t6

p o rtB 0

p o rt A 0

c y k e l_ R x T

TD I

p o rt A 5

minSys interface

p o rt A 6

s e g m e n t3

p o rt A 3

d 6

p o rt C 4

d 0

p o rt B 7p o rt B 5

p o rtB 1

p o rt B 2

in t a

cykel interface

c lk

p o rt A 2d ig it 5

TC K

TM S

p o rt C 0

J 1 4

C O N 7

1234567

d 4

d ig it 6 TimerOut -> NMI

p o rt B 5

rig h t

s e g m e n t5

d 7

p o rt B 3

s e g m e n t0

d 5

p o rt A 7

RxRDY -> INTR

V C C

d ig it 1

p o rt B 7

s e g m e n t4

TD O

c lk

d 1

J 1 0

C O N 2 6

123456789

1 01 11 21 31 41 51 61 71 81 92 02 12 22 32 42 52 6

d ig it 4

pedal

p o rt B 4

d 2

p o rt B 1

d ig it 7

Display interface

p o rt B 4

p o rt B 0

U 2 A7 4 H C 1 4

1 2

Side 37 af 134

Page 38: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Layout diagram over komponenterNår det logiske diagram er lavet, og komponenterne er definerede, laves et printudlæg

over hvor komponenterne kan placeres i forhold til hinanden. Under placeringsprocessen

er der taget hensyn til forbindelserne mellem de forskellige komponenter, for at undgå

luse på printet. Der er også taget hensyn til pladsen disse komponenter tager, således at

printet kan fremstilles på et 5x10 cm ensidet print, med kun 3 luse. Med i overvejelserne

er også stikkenes tilslutning til CPLD, lysdioder, tastatur og til hinanden, og resultatet af

denne proces kan ses på layout-diagrammet herunder.

Layout diagram over printets banerEfter at placeringen af komponenter og stik skal baner trækkes således, at der kommer

mindst mulige lus på. Dette ses på billedet nedenfor. Det ses, at der ikke er meget plads,

der bliver spildt i dette print.

Side 38 af 134

Page 39: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Design af softwareMenusystemet udgør den mest betydende del af softwaren for forbrugeren, i den forstand,

at det svarer til hele brugergrænsefladen på systemet. Under dette menusystem ligger der

flere komponenter, der kører i baggrunden, og holder cyklen fungerende. Disse elementer

består af et kommunikationssystem, cykel- og sessionsstyring og tastaturinput.

Menusystemet er bygget som en tilstandsmaskine, hvor det primært er input fra tastaturet,

der medfører ændringer på cykelcomputerens tilstand. Tilstandsdiagrammet kan ses

nedenfor.

Side 39 af 134

Page 40: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Tilstandsdiagrammet viser, hvordan brugeren kan navigere rundt på cykelcomputeren, og

herved hvordan dette interface skal implementeres.

KlassediagramUdover disse oplysninger, samt usecases og kravspecifikationen er der udarbejdet det

klassediagram, som vises nedenfor.

Det, der ikke er implementeret som klasser er selve programmerne fra pc’en.

Programmerne bliver gemt direkte til memory, og der er derfor reserveret plads i

Side 40 af 134

session cleared

RxT=255prog=0key=cancel

prog=0 key=ok

key=up/down

key=cancel

prog=0 key=ok

key=ok

time=0

key=cancel

key=cancel

key=ok

key=up/down

prog<>0key=cancel

key=cancel

prog<>0key=ok

key=up/down

key=ok

key=cancel

prog<>0key=ok

key=up/downkey=up/down

reqProgram

reqTime transferreqWeight

cycleProgram

clearSessionreqLevel

reqTransfercycleManual

key=up/down

Page 41: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

assembler programmet til 9 programslots, der hver fylder 40 characters. 20 til

programnavnet, og 20 til træningssektionerne.

Målingerne (Measurement klassen) er heller ikke implementeret, fordi rent praktisk var

der ikke plads på minimumsystemet til disse. Måling-klassen er implementeret som en

linket liste, og det indebær, at der skal bruges en pointer til næste måling i hver måling.

Disse pointere medførte, at en måling fyldte unødvendigt meget; 4 bytes til hver pointer,

som jo er 4 gange så meget som en måling.

Diagrammet danner grundlag for programmeringen, og det viser sammenhængen mellem

de forskellige klasser.

Side 41 af 134

Computer

-getPos()-encode()-multiplex()+setText()+addText()+update()

DisplayKeyboard

+getKeyPress()+update()

Session

+prevProgram()+nextProgram()+getProgramSlot()+set / get:

Weight()Level()Duration()

+start()+stop()+reset()+isStarted()+addMeasurement()+getFirst()+getPuls()+getSpeed()+getDistance()+getCalories()

ComPort

+sendSession()+isSending()+reqResend()+setIdle()+resend()+charReceived()+update()

Serial

+getData()+isDataReceived()+readyToSend()+send()

Measurement

+getNext()+setNext()+getMeasurement()+setRpm()+setPuls()+setGear()

Bike

+gearUp()+gearDown()+getGear()+getPuls()+getRpm()+reset()

Que

+getSum()+push()+reset()

Page 42: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Beskrivelse af klasserComputerBeskrivelse Det er her, c++ programmet starter. Minimumsystemet er, ved hjælp af

assemblerkode, sat op, og så køre main metoden her. Dette er ikke rigtigt implementeret som en klasse.

Ansvar Overordnet styring af cykelcomputeren. Særdeles styring af brugergrænsefladen (menusystemet).

Metoder (ingen)

DisplayBeskrivelse Klassen bruges til at styre displayet således at det altid viser den rigtige

tekst til brugeren.Ansvar At holde displayet tændt og opdateret.Metoder char getPos(char) returnerer positionsværdien for en encoded

character char encode(char) encoder en character. Se tegnoversigten i

bilag char multiplex(char,char) returnerer en character, hvor

positionsværdien på displayet er multiplexet sammen med en encoded character. Inputs er encodede character og positionsværdien

void setText(?) sætter teksten på displayet. Denne metode er overrided med flere forskellige typer

void addText(?, int) tilføjer tekst til displayet startet fra den position, cursoren er kommet til. Denne metode er også overridet til at kunne skrive strings og integers

void update(void) er metoden, der skal kaldes hvert millisekund, for at holde displayet tændt. Den sender teksten, en character for hvert millisekund til port A (CPLD decoderen) og starter så forfra.

KeyboardBeskrivelse Læser fra den globale variable ”port b” for at konstatere om nogen tast

er trykket. Den holder også styr på om samme tast bliver holdt nede i længere periode, hvorved den gentager tastetrykket hurtigere og hurtigere. Den definerer også en enumerated type key

Ansvar Holder styr på tastaturinput fra brugeren.Metoder key getKeyPress(void) returnerer hvilken tast, brugeren har

trykket. Den nulstiller også sig selv efter hvert kald. Dette giver mulighed for at gentage tastetryk efter et styk tid

void update(void) synkroniserer tastaturet til et millisekund. Dette gør det muligt at bruge timing til delayet mellem hvert tastetryk

Side 42 af 134

Page 43: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

BikeBeskrivelse Styrer data fra og til cyklen og kan præsentere det på venlig for overfor

øvrige objecter.Ansvar Holde styr på data fra cyklen.Metoder void gearUp(void) sender signal på port C til CPLD’en om at

skifte gear på cyklen void gearDown(void) magen til gearUp() for at skifte gear ned int getPuls(void) returnerer antal pulsslag siden sidste kald int getRpm(void) returnerer antal omdrejninger på pedalen siden

sidste kald int getGear(void) returnerer cyklens nuværende gear void reset(void) nulstiller alle værdierne for objectet, puls og

rpm tælling, samt sørger for at få cyklen sat tilbage til gear 3 void update(void) bruges til timing, samt at den kikker på

inputtene fra cyklens sensorer, for at registrere flangerne, og herved kunne tælle puls og rpm. Den viser også pulsen på den røde lysdiode på cykelcomputeren. Denne metode skal kaldes hvert millisekund

ComPortBeskrivelse Holder styr på kommunikationen mellem pc’en og cykelcomputeren.

Helt konkret, så implementerer den kommunikationens tilstandsdiagram, som vist i specifikationen. Ved hjælp af Serial klassen kan den sende og modtage fra UART’en på minimumsystemet.

Ansvar Holder styr på kommunikationssystemet.Metoder void sendSession(Session *) sender en session. Denne session

skal være stopped inden den sendes. Denne metode blokerer ikke resten af systemet. Den læser værdierne fra sessionen in i objektets buffer, og skifter så tilstanden på ComPort’en så denne buffer bliver sendt

bool isSending(void) returnerer true hvis objektet er ved at sende statistik til pc’en

bool reqResend(void) returnerer true hvis det mislykkedes at sende en statistik. Sammen med setIdle() giver det mulighed for at gensende en statistik, om det mislykkedes

void setIdle() skifter tilstanden til idle på objektet, hvis det er i resend tilstand

void resend() gensender statistik, hvis det mislykkedes første gang. Systemet skal være i resend tilstand

void charReceived(void) interrupt funktion til at læse character fra UART’en og behandle den. Den skal kaldes når CPU’en får en interrupt 3

void update(void) synkronisering af kommunikationssystemet. Denne metode skal kaldes hvert millisekund. Den står for at sende, om der skal sendes noget, samt timing

Side 43 af 134

Page 44: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

SerialBeskrivelse Sender characters på UART’en på minimumsystemet. Den fungerer som

en wrapper over hardwaren, som kan bruges af kommunikationssystemet.

Ansvar Styring af UART’en på minimumsystemetMetoder char getData(void) returnerer den character, der står på

UART’en bool isDataReceived() returnerer true, om der er data på

UART’en void send(char) sender en character på UART’en. Den

kontrollerer ikke, om UART’en er opdaget med at sende void writePc(?) metode til at sende diverse datatyper til pc’en.

Bruges til debugging. Metoden er overrided med forskellige typer input

QueBeskrivelse Skal kun holde en liste af tal, og give en sum had disse. Den fungerer

som en buffer, som fyldes med tal op til den er fuld, og så bare dropper de ældste tal når der ikke er plads til flere

Ansvar Skal give sum af en liste talMetoder int getSum(void) returnerer sum af alle elementer i listen

void push(char) putter et tal på listen. Grunden til typen char er at den bruges ikke til større tal end 255

void reset(void) sletter alle tal fra listen

Measurement (obselete)Beskrivelse Skal holde målingerne for sessionsklassenAnsvar Linket liste til at gemme målingerne for SessionsklassenMetoder Measurement *getNext(void) returnerer næste måling i listen

void setNext(Measurement *) sætter denne at pege på næste måling

char getMeasurement(void) returnerer målingen som char. Denne char er defineret i specifikationen

int getRpm(void) returnerer omdrejningerne for denne måling void setRpm(int) sætter omdrejningerne for denne måling int getPuls(void) henter puls void setPuls(int) sætter puls int getGear(void) henter gear void setGear(int) sætter gear

Side 44 af 134

Page 45: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

SessionBeskrivelse Styring af træningssessionen. Den holder styr på mange af de ting, der

skal vises på displayet under træningen, samt logging af træningen.Ansvar Styr på træningssessionens data.Metoder void prevProgram(void) skifter til forrige program i

programbanken void nextProgram(void) skifter til næste program i

programbanken (om der findes et) int getProgramSlot(void) returnerer slotsnummeret for det

program, der er valgt for sessionen int getWeight(void) hent cyklistens vægt void setWeight(int) sæt cyklistens vægt int getLevel(void) hent sessionens niveau void setLevel(int) sæt sessionens niveau int getDuration(void) hent sessionens længde i minutter void setDuration(int) sæt sessionens længde i minutter void reset(void) nulstil alle variabler til default værdier, og

nulstil også de globale variabler der bruges til at holde tiden void start(void) start sessionen void stop(void) stop sessionen bool isStarted(void) returnerer true om sessionen er startet void addMeasurement(int,int,int) tilføjer en måling. Inputtene

er rpm, puls og gear. Når en måling bliver tilføjet, bliver alle værdier opdateret. Eks. samlede distance, kalorieforbrug m.m. Metoden skal kaldes hvert millisekund

char *getFirst(void) returnerer adressen til første måling int getLength(void) returnerer antal målinger unsigned int getDistance(void) returnerer den samlede distance,

cyklisten har cyklet siden starten af sessionen unsigned int getCalories(void) returnerer samlede forbrændte

kalorier unsigned int getPuls(void) returnerer en middelværdi af pulsen

over de sidste 10 sekunder. Denne bruges kun til visning i displayet

unsigned int getSpeed(void) returnerer en middelværdi af hastigheden i km/t over de sidste 3 sekunder. Denne bruges kun til visning i displayet

Implementeringen af alle klasserne findes som bilag.

Side 45 af 134

Page 46: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Beskrivelse af assemblerkodeAssemblerkoden sætter hele minimumsystemet op og klar til brug af c++ programmet.

Nedenfor står pseudokode for dette assemblerprogram. Pseudokoden beskriver klart,

hvad der skal laves af assemblerkoden ved opstart. Selve assemblerkoden findes som

bilag.

Definer konstanterDefiner faste programmerReserver plads til øvrige programslotsReserver plads til målingerne

Sæt op stack'en samt øvrige registreStop timeren (hvis den kører)Programmér timer kredsen (ic 8155)

Initialiser minsys til C++Sæt interrupt vektorer for NMI og INTR 3

Initialiser port A,B og C som in- eller output porte (ic 8155)Start timeren

Do foreverkør main metoden på computer.cpp i c++

loop

Side 46 af 134

Page 47: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

KonklusionNår vi nu er kommet til vejs ende med dette projekt, er det tid til at kigge bag om

skulderen, og se hvad der er kommet ud af forløbet.

Vi var introduceret for et projekt, som havde to elementer i sig. Dette omhandlede fagene

OOP og DIG. Disse to fag er meget langt fra hinanden, hvad arbejdsmetode angår. Der

var lagt op til, og blev benyttet, en meget struktureret OOP udviklingsmetode, og en mere

afslappet DIG arbejdsprocess. De to dele blev dog blandet sammen, i det at der var opsat

nogle milestones, som definerede hvad der skulle være lavet til bestemte tidspunkter.

Med en afslappet arbejdsprocess menes, at der var ikke lige mange artifacts, som skulle

være lavet, og at det var lidt mere lagt i hænderne på eleverne at tilrettelægge en

arbejdsplan.

Foruden den viden vi fik, af at arbejde med et så stort projekt, har vi lært en hel del om os

selv, og hvordan vi arbejder, når der er pres på. ActionItemListen, som blev lavet for at

holde styr på de ting, som skulle laves, var guldværd, men problemet var bare, at vi vidste

ikke lige hvor lang tid de kristiske punkter ville tage, og det er som regel dem, man

kommer til at sidde tilbage med, når slutningen er ved at nærme sig.

Nu når rapporten er lavet, og projektet er slut, må vi konkludere, at det har været en

meget lærerig process. Vi har fået en bedre kundsskab til hardware, og hvor kompliceret

det kan være, at få det til at samspille på den rigtige måde. Også har vi fået en lidt bedre

forståelse af Java, og lært hvordan man bruger et stort udviklingsværktøj som JBuilder.

Til sidst er vært at tilføje, at vi kan tage mange af de ting, som vi har lært i dette forløb,

med os til en anden gang, og specielt prøve at undgå de fejl i arbejdsprocess, som vi har

lavet.

Side 47 af 134

Page 48: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Bilag

Brugervejledning for pc-programDa vi skulle i gang med at lave brugermanualen, bestemte vi os for, at lave den i HTML.

Det var fordi, at så kunne vi bruge den som hjælpefil i pc-programmet. Der er nemlig en

knap, der hedder ”Hjælp”, og så kan man surfe rundt i manualen efter behov. Vi syntes,

at det altid var godt, med at have hjælp lige veg hånden.

Brugermanualen er her indsat som HTML-dokumenter:

Dette er en vejledning til brugeren af dette program, og om hvordan der skal navigeres

rundt, så der kan kommes i gang med at cycle

Vejledningen er delt op i disse punkter:Oprette og gemme et program       Vise programliste      

Overføre et program       Slette et program      

Vise statestik      

Oprette og gemme et programNår du vil i gang med at cykle, men selv vil designe dit program, kan du trykke på "Opret

program" i venstre side af brugergrænsefladen.

Side 48 af 134

Page 49: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Når du har trykket på denne knap vil der komme 20 "sliders" frem.

Disse sliders repræsenterer sværhedsgraden af programmet. Det er muligt at lave noget

der ligner et bakketerræn eller en mere lige tur ud af landevejen. Sliderne kan justeres

med musen eller ved brug af tabulator og pile på tastaturet. Programmet skal også have

et navn, og så er det klart til at blive gemt ved at trykke på "Gem" nederst på siden.

Nu er programmet gemt i progamlisten, og er klart til at blive overført til cyklen

Vise programlisteNår man vil i gang med at cykle, og ikke gider at lave sit eget program, eller allerede har

lavet et forinden, kan man trykke på "Vis program" på brugergrænsfladen.

Når du har trykket på denne knap vil der komme en liste med programmer frem.

Side 49 af 134

Page 50: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Hvis vi f.eks. vælger det øverste program i listen, kommer dette frem

Her ser vi hvordan det valgte program ser ud, og nu kan vi enten, lave om på

programmet, overføre det, eller slette det. Vælger man lave om i programmet, kan man

bare trække sliderne op og ned efter valg, og så gemme programmet ved at trykke på

"Gem" nederst på siden. Vælger man at gemme programmet under samme navn, bliver

det gamle overskrevet, men vælger man et nyt navn, gemmes programmet under det nye

navn og lader det gamle være.

Overføre et program til cyklenNår der skal overføres et program til cykelcomputer, trykker man på "Overfør program"

på brugergrænsfladen

Side 50 af 134

Page 51: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Når man har gjort det, kommer denne popupmenu frem:

I denne menu kan man vælge det program, som skal overføres. Efter at have valgt det

ønskede program, skal man vælge et "slot" på cykelcomputeren, at overføre programmet

til. Det bliver valgt i denne menu:

Efter at dette er blevet gjort, er programmet blevet overført til cyklen.

Side 51 af 134

Page 52: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Slette program fra programlisteNår man vil slette et program fra programlisten, må man først trykke på "Vis program" på

brugergrænsefladen

Når du har trykket på denne knap vil der komme en liste med programmer frem.

Hvis vi f.eks. vælger det øverste program i listen, kommer dette frem

Når nu det valgte program er kommet fren, kan man trykke på "slet" nederst på

brugergrænsfladen, og så er programmet væk fra listen.

Side 52 af 134

Page 53: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Vise statestik over cyklingNår man vil se statestik over hvordan det er gået med en cykling, kan man trykke på "Vis

statestik" på brugergrænsfladen

Efter at have trykket på denne knap, kommer denne menu frem:

Her er det muligt at vælge den statestik der er ønskelig at se. Statestikken er gemt under

træningsprogramnavn og et tidsmærke. Nu vises der en graf over de nøgletal som er

nødvendige.

Side 53 af 134

Page 54: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Brugermanual for cykelcomputeren

Cyklen har to sensorer, der overvåger din puls og din cykling. Med disse censorer er det

muligt at konstatere diverse informationer om din træning så som kalorieforbrug, distance

m.m. Cyklen er endvidere udstyret med en meget avanceret cykelcomputer, der består af

fire knapper, tre lysdioder, samt et display, der informerer dig gennem hele træningen.

Gennemgang af displayet og tastaturet

Vores display består af otte 7-segmenter. Vi har valgt at bruge dem alle sammen således

at vi bruger fire de første til bogstaver og fire de sidste til tal. Tastaturet består af 32

knapper, hvoraf vi kun bruger 6, som der ses ovenover. De to pile til venstre bliver brugt

til at vælge tilstand i menuen. Derefter er det muligt at bruge de to næste knapper til enten

at konfirmere(OK) eller annulere(C). De to sidste, bliver kun brugt til at skifte gear med.

Side 54 af 134

↑ ↓ OK C G↑ G↓

. .... ...

Page 55: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Kom nemt i gang

Når du har sat din træningscykel op og tilsluttet strøm, starter cykelcomputeren også op.

Hurtigste måde at komme i gang er at bruge manuel cykling. Dvs. at du selv kan

bestemme gear gennem hele træningen. Sådan starter du en manuel træning:

1. Vælg manuel træning med at trykke gentagende på (↑) eller (↓) til displayet viser

”prog 0” og tryk derefter (OK)

2. Indtast din vægt ved at bruge (↑) eller (↓) til vægten står i displayet. Tryk derefter

på (OK)

Cyklingen begynder nu, og du kan gennem hele cyklingen skifte gear ved at trykke på

(G↑) eller (G↓). For at standse cyklingssessionen kan du trykke på (C) og derefter på

(OK). Du bliver nu spurgt om du vil overføre statistikken for din træningssession til en

PC. Om en PC er tilsluttet cykelcomputeren og pc-softwaren startet kan du med fordel

vælge (OK) for at få pulsmålinger m.m. overført til Pc’en for at se det som en graf. Om

du ikke ønsker statistikken overført til Pc’en vælger du (C). Cyklen vender nu tilbage til

start positionen, hvor du igen kan påbegynde en ny træningssession.

For at træne efter et program på cyklen er fremgangsmåden denne:

1. Vælg træningsprogram med at trykke gentagende på (↑) eller (↓) til displayet

viser det ønskede program og tryk derefter (OK)

2. Indtast Niveau ved at bruge (↑) eller (↓) til det ønskede niveau står i displayet

(dette er et procenttal). Tryk derefter på (OK)

3. Indtast din vægt ved at bruge (↑) eller (↓) til den ønskede vægt i kg står i

displayet. Tryk derefter på (OK)

4. indtast hvor længe du ønsker at træne i minutter ved at bruge (↑) eller (↓). Tryk

derefter (OK)

Side 55 af 134

Page 56: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Cyklingen begynder nu, og du har nu ingen mulighed for at skifte gear. For at standse

cyklingssessionen kan du trykke på (C) og derefter på (OK). Du bliver nu spurgt om du

vil overføre statistikken for din træningssession til en PC.

Side 56 af 134

Page 57: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Source kode til JAVA

StatistikArkivpackage bikeProject;import java.util.*;import java.awt.event.*;import javax.swing.*;

/** * * <p>Title: Bike Project</p> * <p>Description: arkiv til behandling af træningssessioner * <h3>Ansvar</h3>: har ansvaret for at vise en liste over træningssessioner, samt bestemme hvor de skal ligge. * </p> * @author CPOGG + KP * @version 0.1 */

public class StatistikArkiv extends Arkiv { private Traeningssession traeningssession; private final String arkivSti = super.getArkivSti() + "/STAT/";

/** * konstruktør * initaliser, opretter et Traeningsarkiv */ public StatistikArkiv() { super.setArkivSti(arkivSti); traeningssession = new Traeningssession(); }

/** * indlæser en traeningssession fra hd * @param String sti * @return Traeningssession */ private Traeningssession loadSession(String fil) { Object obj = new Object(); try { obj = (Traeningssession)super.load(fil); } catch (ClassCastException e) { System.err.print("Forkert klasse\n"); } Traeningssession np; System.out.print(obj.getClass()); if (obj.getClass() == traeningssession.getClass()) { np = (Traeningssession) obj; } else { np = traeningssession; System.err.print("Fejl ved indlæsning af program, filnanv: " + fil); } return np; }

/** * viser elementerne i traeningsarkivet, ved klik vises statistik for træningssessionen */ public JPopupMenu vis(DataTransport t) { JPopupMenu p = new JPopupMenu(); String[] liste = (getFileList()); JMenuItem i; for (int x = 0; x < liste.length; x++) { Action a = new AabenAction(arkivSti + liste[x], t, this); i = new JMenuItem();

Side 57 af 134

Page 58: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

i.setText(liste[x]); i.addActionListener(a); p.add(i); } return p; }

/** * metode til at gemme en træningssession * <br>benytter traeningssessions gem(filNavn) */ public void saveSession() { Date t2 = new Date(); String filNavn = t2.getDate() + t2.getDay() + "-" + t2.getTime() + getTraeningsSession().getId() + ".tDat"; System.out.print("\n" + filNavn); traeningssession.gem(arkivSti + filNavn); }

/** * returnerer nuværende trænigssession * @return true hvis der er flere, ellers returneres false. */ public Traeningssession getTraeningsSession() { return traeningssession; }

/** * <p>Title: Bike Project</p> * <p>Description: Klasse der indeholder knap funktionalitet</p> * @author CPOGG * @version 0.1 */ private class AabenAction extends AbstractAction { String ts; DataTransport controller; StatistikArkiv statistikArkiv; /** * knytter en abbenHandling til popmenuen * @param _ts Traeningssession: traeningssessionen som der skal åbnes. * @param _controller DataTransport: controlleren der skal åbne traeningssessionen * @param parent StatistikArkiv: statistikArkivet der ved vide hvad der skal åbnes. */ AabenAction(String _ts, DataTransport _controller, StatistikArkiv parent) { statistikArkiv = parent; ts = _ts; controller = _controller; } /** * bed pænt controlleren om at vise statistikken * @param e ActionEvent */ public void actionPerformed(ActionEvent e) { statistikArkiv.traeningssession = loadSession(ts); ; controller.visStatistik(); } }

}

Side 58 af 134

Page 59: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Traeningssessionpackage bikeProject;

import java.io.*;import java.util.*;import javax.swing.*;import java.awt.*;

/*** <p>Title: Statestik</p>* <p>indeholder nøgle data om en træningssession<br>* alle målinger er gemt her og der er lavet metoder til at navigere målingerene efter behov.* <br>samt metoder til at gemme på hd</p>* <h3>Ansvar<h3/>har ansvaret for en træningssession.* @author Sólja í Dali* @version 0.1*/public class Traeningssession implements Serializable { private String programId; private int vaegt; private int niveau; private ArrayList maalinger; private ListIterator it; private Maaling currentMaaling; /** * konstruktør * oprettet en tomt træningssession. */ public Traeningssession() { currentMaaling = new Maaling( (byte) 0); it = null; }

/** * vælger den næste måling som current * @return true hvis der er flere, ellers returneres false. */ public boolean nextMaaling() { if (it.hasNext()) { currentMaaling = (Maaling) it.next(); return true; } else { return false; } }

/** * 'spoler' måling listen tilbage til start */ public void MaalingerRewind() { it = maalinger.listIterator(); currentMaaling = (Maaling) maalinger.get(0); }

/** * hent antal måling i træningssession * @return int */ public int getAntalMaalinger() { return maalinger.size(); }

/** * tegner grafer der viser dat over en måling... */ public void vis(JPanel pane) {

Side 59 af 134

Page 60: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

JLabel l = new JLabel("Statistik"); this.MaalingerRewind(); Maaling m; Color c; Graphics gl;// = new Graphics(); gl = pane.getGraphics();

//find maximaer double[] maximaer = calcMaxima(); double maxKal = maximaer[0]; double maxPuls = maximaer[1]; double maxDist = maximaer[2]; double maxGear2 = maximaer[3]; double maxSpeed = maximaer[4]; final double maxGear=10;

//offset, grafheight og grafwidth bliver defineret final int leftOffset = 32; final int rightOffset = 58; final int widthOffset = leftOffset + rightOffset; final int topOffset = 10; final int bottomOffset = 26; final int heightOffset = topOffset + bottomOffset; final int rammeWidth = pane.getWidth() - widthOffset; final int rammeHeight = (int)Math.floor((double)(pane.getHeight() - heightOffset)); final int grafWidth = pane.getWidth() - (widthOffset+2); final int grafHeight = (int)Math.floor((double)(pane.getHeight() - (heightOffset+2)));

//find punktafstanden og antal af målinger for hvert punkt int summer; int punktAfstand; int restGrafWidth = grafWidth; int antalMaalinger = this.getAntalMaalinger(); if (this.getAntalMaalinger()>grafWidth) { punktAfstand = 1; summer = (int)Math.ceil((double)antalMaalinger/(double)grafWidth); } else { punktAfstand = grafWidth/antalMaalinger; summer = 1; }

//tegn ramme hvori grafen bliver tegnet og y skala'en if (gl!=null) { gl.drawRect(leftOffset, topOffset, rammeWidth, rammeHeight); gl.drawString(" 0", 0, grafHeight+topOffset+5); gl.drawString(" 10%", 0, (grafHeight*9)/10+topOffset+5); gl.drawLine(leftOffset-1, (grafHeight*9)/10+topOffset+1, leftOffset+1, (grafHeight*9)/10+topOffset+1); gl.drawString(" 20%", 0, (grafHeight*8)/10+topOffset+5); gl.drawLine(leftOffset-1, (grafHeight*8)/10+topOffset+1, leftOffset+1, (grafHeight*8)/10+topOffset+1); gl.drawString(" 30%", 0, (grafHeight*7)/10+topOffset+5); gl.drawLine(leftOffset-1, (grafHeight*7)/10+topOffset+1, leftOffset+1, (grafHeight*7)/10+topOffset+1); gl.drawString(" 40%", 0, (grafHeight*6)/10+topOffset+5); gl.drawLine(leftOffset-1, (grafHeight*6)/10+topOffset+1, leftOffset+1, (grafHeight*6)/10+topOffset+1); gl.drawString(" 50%", 0, (grafHeight*5)/10+topOffset+5); gl.drawLine(leftOffset-1, (grafHeight*5)/10+topOffset+1, leftOffset+1, (grafHeight*5)/10+topOffset+1); gl.drawString(" 60%", 0, (grafHeight*4)/10+topOffset+5); gl.drawLine(leftOffset-1, (grafHeight*4)/10+topOffset+1, leftOffset+1, (grafHeight*4)/10+topOffset+1); gl.drawString(" 70%", 0, (grafHeight*3)/10+topOffset+5); gl.drawLine(leftOffset-1, (grafHeight*3)/10+topOffset+1, leftOffset+1, (grafHeight*3)/10+topOffset+1); gl.drawString(" 80%", 0, (grafHeight*2)/10+topOffset+5); gl.drawLine(leftOffset-1, (grafHeight*2)/10+topOffset+1, leftOffset+1, (grafHeight*2)/10+topOffset+1); gl.drawString(" 90%", 0, (grafHeight)/10+topOffset+5);

Side 60 af 134

Page 61: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

gl.drawLine(leftOffset-1, (grafHeight)/10+topOffset+1, leftOffset+1, (grafHeight)/10+topOffset+1); gl.drawString(" 100%", 0, topOffset+5);

//beregn og tegn x skala'en int xSkala; xSkala = getAntalMaalinger()/10; gl.drawString("0", leftOffset-2, grafHeight+topOffset+2+15); for(int i=grafWidth/50; i>0; i--){ if (getAntalMaalinger() > 180) { gl.drawString("" + ( (double) ( (int) ((xSkala * i * 10) / 60)) / 10), leftOffset - 2 + ( (i * xSkala * grafWidth) / getAntalMaalinger()), grafHeight + topOffset + 2 + 15); } else { gl.drawString("" + xSkala*i, leftOffset - 2 + ( (i * xSkala * grafWidth) / getAntalMaalinger()), grafHeight + topOffset + 2 + 15); } gl.drawLine(leftOffset + 1 + ((i*xSkala * grafWidth)/getAntalMaalinger()), topOffset+rammeHeight-1, leftOffset + 1 + ((i*xSkala * grafWidth)/getAntalMaalinger()), topOffset+rammeHeight+1); }

if (getAntalMaalinger()>180){ gl.drawString("tid / min", leftOffset+rammeWidth+15, grafHeight+topOffset); } else { gl.drawString("tid / sek", leftOffset+rammeWidth+15, grafHeight+topOffset); }

//tegn højre kolonne c = Color.ORANGE; gl.setColor(c); gl.drawLine(leftOffset+rammeWidth+10, topOffset, leftOffset+rammeWidth+(rightOffset-10), topOffset); c = Color.BLACK; gl.setColor(c); gl.drawString("Kcal", leftOffset+rammeWidth+10, topOffset+12); gl.drawString(""+((double)((int)(maxKal*10))/10), leftOffset+rammeWidth+10, topOffset+24);

c = Color.RED; gl.setColor(c); gl.drawLine(leftOffset+rammeWidth+10, topOffset+40, leftOffset+rammeWidth+(rightOffset-10), topOffset+40); c = Color.BLACK; gl.setColor(c); gl.drawString("Km", leftOffset+rammeWidth+10, topOffset+52); gl.drawString(""+((double)((int)(maxDist/100))/10), leftOffset+rammeWidth+10, topOffset+64);

c = Color.GREEN; gl.setColor(c); gl.drawLine(leftOffset+rammeWidth+10, topOffset+80, leftOffset+rammeWidth+(rightOffset-10), topOffset+80); c = Color.BLACK; gl.setColor(c); gl.drawString("Gear", leftOffset+rammeWidth+10, topOffset+92); gl.drawString(""+(int)maxGear2, leftOffset+rammeWidth+10, topOffset+104);

c = Color.BLUE; gl.setColor(c); gl.drawLine(leftOffset+rammeWidth+10, topOffset+120, leftOffset+rammeWidth+(rightOffset-10), topOffset+120); c = Color.BLACK; gl.setColor(c); gl.drawString("Puls", leftOffset+rammeWidth+10, topOffset+132); gl.drawString(""+((double)((int)(maxPuls*600))/10), leftOffset+rammeWidth+10, topOffset+144);

Side 61 af 134

Page 62: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

c = Color.MAGENTA; gl.setColor(c); gl.drawLine(leftOffset+rammeWidth+10, topOffset+160, leftOffset+rammeWidth+(rightOffset-10), topOffset+160); c = Color.BLACK; gl.setColor(c); gl.drawString("Km/t", leftOffset+rammeWidth+10, topOffset+172); gl.drawString(""+((double)((int)(maxSpeed*36))/10), leftOffset+rammeWidth+10, topOffset+184);

//find start punkt for nuværende graf

//find x int curX=leftOffset+1;

//find y double calcKalY =0.0; double calcPulsY =0.0; double calcDistY = 0.0; double calcGearY = 0.0; double calcSpeedY = 0.0; int counter=0; this.MaalingerRewind(); m= this.currentMaaling(); calcGearY = m.getGear(); //skal kun hentes for gearene, for de skal ikke starte fra 0 //System.out.print("\nY:"+calcKalY+ "< gh:"+ grafHeight + "< s:"+summer + "< mc:"+maxKal+ " < pa:"+punktAfstand+ "< gw:"+grafWidth+"< am:"+this.getAntalMaalinger());

//find første kordinater Point pKal1 = new Point(curX,(int)((calcKalY/maxKal)*grafHeight)); Point pPuls1 = new Point(curX,(int)((calcPulsY/maxPuls)*grafHeight)); Point pDist1 = new Point(curX,(int)((calcDistY/maxDist)*grafHeight)); Point pGear1 = new Point(curX,(int)((calcGearY/maxGear)*grafHeight)); Point pSpeed1 = new Point(curX,(int)((calcSpeedY/maxSpeed)*grafHeight)); //System.out.print("\nseg: " + pKal1.x +"," + pKal1.y); Point pKal2 = new Point(); Point pPuls2 = new Point(); Point pDist2 = new Point(); Point pGear2 = new Point(); Point pSpeed2 = new Point();

//to array's bliver defineret til at beregne et gennemsnit for de seneste x antal målinger (kun for puls og km/t), så grafen bliver "blødere" (som u9 siger) int arrSize = 10; double[] pulsArray = new double[arrSize]; double[] speedArray = new double[arrSize]; int pointerPuls = 0; int pointerSpeed = 0;

for(int i=0; i<(arrSize); i++){ pulsArray[i] = 0.0; speedArray[i] = 0.0; } pulsArray[pointerPuls] = m.getPulse(); pointerPuls = (pointerPuls+1)%arrSize; speedArray[pointerSpeed] = m.getSpeed(); pointerSpeed = (pointerSpeed+1)%arrSize;

double pulsGennemsnit=0.0; double speedGennemsnit=0.0;

//find de efterfølgende punkter for (int am=getAntalMaalinger()-summer;am>=0;am-=summer) {//tegn grafen sålænge der er målinger curX=curX+punktAfstand; //find næste punkt //nulstil y calcPulsY = 0; calcGearY = 0; calcSpeedY = 0;

Side 62 af 134

Page 63: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

//calcKalY = 0; skal ikke nulstilles da man gerne vil se ALLE forbrændte kalorier hidtil //calcDistY = 0; samme her counter=0;

//beregn gennemsnit for næste y do { pulsGennemsnit=0.0; speedGennemsnit=0.0; for(int i=0; i<arrSize; i++){ pulsGennemsnit += pulsArray[i]; speedGennemsnit += speedArray[i]; } pulsGennemsnit = pulsGennemsnit/(double)arrSize; speedGennemsnit = speedGennemsnit/(double)arrSize;

calcKalY = m.getKal()+calcKalY; calcDistY = m.getDist()+calcDistY; calcGearY = m.getGear()+calcGearY; calcPulsY = pulsGennemsnit+calcPulsY; calcSpeedY = speedGennemsnit+calcSpeedY;

counter++; this.nextMaaling(); m = this.currentMaaling(); pulsArray[pointerPuls] = m.getPulse(); pointerPuls = (pointerPuls+1)%arrSize; speedArray[pointerSpeed] = m.getSpeed(); pointerSpeed = (pointerSpeed+1)%arrSize; } while (counter<summer);

calcPulsY=calcPulsY/summer; calcGearY=calcGearY/summer; calcSpeedY=calcSpeedY/summer; calcKalY=calcKalY; //skal ikke divideres med summer, da dette skal være summen istedet for et gennemsnit calcDistY=calcDistY;

//find punkt 2 pKal2 = new Point(curX,(int)((calcKalY/maxKal)*grafHeight)); pPuls2 = new Point(curX,(int)((calcPulsY/maxPuls)*grafHeight)); pDist2 = new Point(curX,(int)((calcDistY/maxDist)*grafHeight)); pGear2 = new Point(curX,(int)((calcGearY/maxGear)*grafHeight)); pSpeed2 = new Point(curX,(int)((calcSpeedY/maxSpeed)*grafHeight));

//tegn graf c = Color.ORANGE; gl.setColor(c); gl.drawLine(pKal1.x, grafHeight-pKal1.y+topOffset, pKal2.x, grafHeight-pKal2.y+topOffset);

c = Color.BLUE; gl.setColor(c); gl.drawLine(pPuls1.x, grafHeight-pPuls1.y+(topOffset), pPuls2.x, grafHeight-pPuls2.y+(topOffset));

c = Color.RED; gl.setColor(c); gl.drawLine(pDist1.x, grafHeight-pDist1.y+(topOffset), pDist2.x, grafHeight-pDist2.y+(topOffset));

c = Color.MAGENTA; gl.setColor(c); gl.drawLine(pSpeed1.x, grafHeight-pSpeed1.y+(topOffset), pSpeed2.x, grafHeight-pSpeed2.y+(topOffset));

c = Color.GREEN; gl.setColor(c); gl.drawLine(pGear1.x, grafHeight-pGear1.y+topOffset, pGear1.x, grafHeight-pGear2.y+topOffset);

Side 63 af 134

Page 64: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

gl.drawLine(pGear1.x, grafHeight-pGear2.y+topOffset, pGear2.x, grafHeight-pGear2.y+topOffset);

//beregn ny summer, ny punktafstand og antal målinger tilbage if (summer < antalMaalinger){ antalMaalinger = antalMaalinger - summer; restGrafWidth = restGrafWidth - punktAfstand; if (this.getAntalMaalinger()>grafWidth) { summer = (int)Math.ceil((double)antalMaalinger/(double)restGrafWidth); } else { if ((int)antalMaalinger > 0) { punktAfstand = restGrafWidth / antalMaalinger; } } } pKal1 = pKal2; pPuls1 = pPuls2; pDist1 = pDist2; pSpeed1 = pSpeed2; pGear1 = pGear2; } } else { System.err.print("\nGraphics er null, kan ikke tegne på overfladen"); } }

//beregning af maximaer private double[] calcMaxima() { double[] arr = new double[5]; this.MaalingerRewind(); double maxPuls=0; double maxDist=0.0; double maxKal=0.0; double maxSpeed=0.0; int maxGear2=0;

int arrSize = 10; double[] pulsArray = new double[arrSize]; double[] speedArray = new double[arrSize]; int pointerPuls = 0; int pointerSpeed = 0;

for(int i=0; i<(arrSize); i++){ pulsArray[i] = 0.0; speedArray[i] = 0.0; }

double pulsGennemsnit=0.0; double speedGennemsnit=0.0;

while (this.nextMaaling()) { maxKal = maxKal+this.currentMaaling.getKal();

pulsArray[pointerPuls] = this.currentMaaling.getPulse(); pointerPuls = (pointerPuls+1)%arrSize; pulsGennemsnit=0.0; for(int i=0; i<arrSize; i++){ pulsGennemsnit += pulsArray[i]; } pulsGennemsnit = pulsGennemsnit/(double)arrSize; if (pulsGennemsnit>maxPuls) { maxPuls = pulsGennemsnit; }

speedArray[pointerSpeed] = this.currentMaaling.getSpeed(); pointerSpeed = (pointerSpeed+1)%arrSize; speedGennemsnit=0.0; for(int i=0; i<arrSize; i++){ speedGennemsnit += speedArray[i]; }

Side 64 af 134

Page 65: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

speedGennemsnit = speedGennemsnit/(double)arrSize; if (speedGennemsnit>maxSpeed) { maxSpeed = speedGennemsnit; }

if (this.currentMaaling.getGear()>maxGear2) { maxGear2 = this.currentMaaling.getGear(); }

maxDist = maxDist+this.currentMaaling.getDist(); } arr[0]=maxKal; arr[1]=maxPuls; arr[2]=maxDist; arr[3]=maxGear2; arr[4]=maxSpeed; return arr; }

/** * hent den nuværende måling * @return Maaling */ public Maaling currentMaaling() { return currentMaaling; } /** * hent nuværende id, id er programmets navn der blev afviklet under træningssessionen * @return String */ public String getId() { return programId; } /** * hent vægt * @return int */ public int getVaegt() { return vaegt; } /** * hent niveau * @return int */ public int getNiveau() { return niveau; } /** * hent måling * @return Maaling */ public Maaling getMaaling() { return (Maaling) maalinger.get(0); } /** * gem program, parameter er en sti hvor der skal gemmes. * @param sti String */ public void gem(String sti) { try { FileOutputStream file = new FileOutputStream(sti); ObjectOutputStream out = new ObjectOutputStream(file); out.writeObject(this); out.flush(); out.close(); } catch (IOException ex) { System.err.println("Der opstod en fejl under skrivning til disk"); } } /**

Side 65 af 134

Page 66: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

* opretter et statestiksæt ud fra statistikdata * @param _programId int * @param _vaegt int * @param _niveau int * @param _maalinger ArrayList */ public void setStatistik( String _programId, int _vaegt, int _niveau, ArrayList _maalinger) { programId = _programId; vaegt = _vaegt; niveau = _niveau; maalinger = _maalinger; maalinger.listIterator(); }}

Side 66 af 134

Page 67: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

ProgramArkivpackage bikeProject;

import java.io.*;

import java.awt.event.*;import javax.swing.*;

/** * <p>Title: Bike Project</p> * <p>Description: arkiv til behandling af programmer * <h3>Ansvar</h3>: har ansvaret for at vise en liste med programmer, samt bestemme hvor de skal ligge. * </p> * @author CPOGG + KP * @version 0.1 */public class ProgramArkiv extends Arkiv { private Program program; //nuvæærende program. private final String arkivSti = super.getArkivSti() + "/PROG/";

/** * konstruktør * initaliser, opretter et programArkiv */ public ProgramArkiv() { super.setArkivSti(arkivSti); int[] i = new int[20]; for (int x = 0; i.length > x; x++) { i[x] = 0; } program = new Program("TEMP", i); }

/** * opretter et nyt program, med et standard niveau på 3 og nanvet 'navn' */ public void nytProgram() { final int DEFAULT_TRIN = 3; int[] i = new int[20]; for (int x = 0; i.length > x; x++) { i[x] = DEFAULT_TRIN; } program = new Program("Navn", i); }

/** * indlæser et program fra fil. Skal have et filnavn til programmet som parameter. * @param String fil * @return Program */ private Program loadProgram(String fil) { Object obj = new Object(); try { obj = (Program)super.load(fil); } catch (ClassCastException e) { System.err.print("Forkert klasse\n"); } Program np; if (obj.getClass() == program.getClass()) { np = (Program) obj; } else { np = program; System.err.print("Fejl ved indlæsning af program, filnanv: " + fil); } return np;

Side 67 af 134

Page 68: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

}

/** * viser en popupmenu med en liste af programmer, ved klik på et program indlæses og vises programmet skal have DataTransport som parameter. * @param controller DataTransport * @return JPopupMenu */ public JPopupMenu vis(DataTransport controller) { JPopupMenu p = new JPopupMenu(); String[] liste = (getFileList()); JMenuItem i; for (int x = 0; x < liste.length; x++) { Action a = new AabenAction(arkivSti + liste[x], controller, this); i = new JMenuItem(); i.setText(liste[x]); i.addActionListener(a); p.add(i); } return p; }

/** * viser en popupmenu indeholdne en liste af programmer, ved klik på et program åbnes cykelcopmputeren slot liste * <br>dette forgår dog gennem datatransport. * <br>skal have DataTransport som parameter. * @param controller DataTransport * @return JPopupMenu */ public JPopupMenu vaelgProgramTilOverforsel(DataTransport c) { JPopupMenu p = new JPopupMenu(); String[] liste = (getFileList()); JMenuItem i; for (int x = 0; x < liste.length; x++) { Action a = new OverforeselsAction(arkivSti + liste[x], c); i = new JMenuItem(); i.setText(liste[x]); i.addActionListener(a); p.add(i); } return p; }

/** * gemmer det nuværende program på hd. */ public void saveSession() { program.gem(genFilNavn()); }

/** * returnerer nuværende program * @return nuværende trænigssession */ public Program getProgram() { return program; }

/** * generer et filnavn der passer til arkiv sti samt program navn * @return String */ private String genFilNavn() { return arkivSti + getProgram().getName() + ".pDat"; }

/** * sletter det indlæste program fra hd hvis program har samme navn som fil. */ public void sletProgram() {

Side 68 af 134

Page 69: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

File f = new File(genFilNavn()); f.delete(); }

/** * <p>Title: Bike Project</p> * <p>Description: indeholder en handling der der åbner et program</p> * @author CPOGG * @version 0.1 */ private class AabenAction extends AbstractAction { String programFil; DataTransport controller; ProgramArkiv programArkiv; /** * knytter en aabenaction til menuen * @param _p String programsti * @param _controller DataTrasport * @param parent ProgramArkiv */ AabenAction(String _p, DataTransport _controller, ProgramArkiv parent) { programArkiv = parent; programFil = _p; controller = _controller; }

/** * actionPerformed * @param e ActionEvent */ public void actionPerformed(ActionEvent e) { Program prg; programArkiv.program = programArkiv.loadProgram(programFil); controller.visProgram(); } }

/** * * <p>Title: Bike Project</p> * <p>Description:klasse der inholder en overførselshandling. </p> * @author CPOGG * @version 0.1 */ private class OverforeselsAction extends AbstractAction { String programSti; DataTransport controller;

/** * knytter en overførselsaction til et program * @param _p Program * @param _c DataTransport */ OverforeselsAction(String _p, DataTransport _c) { controller = _c; programSti = _p; }

/** * be datatransport om at vise slotoversigten ved klik. * @param e ActionEvent */ public void actionPerformed(ActionEvent e) { ProgramArkiv pa = new ProgramArkiv(); Program program = pa.loadProgram(programSti); controller.visSlotList(program); } }}

Side 69 af 134

Page 70: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Programpackage bikeProject;

import java.io.*;

import java.awt.*;import javax.swing.*;

/** * <p>Title: Bike Project</p> * <p>Description: Program klasse * indeholder navn og indstillinger for et program * <h3>ansvar</h3>har ansvaret for hvad der kan foregå med et træningsprogram. * </p> * @author Kristjan Petursson * @version 0.1 */public class Program implements Serializable { private final int LENGTH = 20; //antal niveau indstillinger programmet skal have private String name; private int[] niveau; private JTextField ti; // text felt der indeholder navnet midlertidligt private JSlider[] jArr; //array der indeholder pointerer til de slidere der buges når der skal gemmes et progam.

/** * konstruktør,et program skal oprettes med et navn som string og nogle niveauer. * <br>antallet af niveau skal være == LENGTH * @param _name String * @param _niveau int[] */ public Program(String _name, int[] _niveau) { jArr = new JSlider[20]; name = _name; if (_niveau.length == LENGTH) { //der Skal være 20 niveauer ! niveau = _niveau; } else { System.err.println("Ugyldig længde " + _niveau.length); } }

/** * metode til at hente et array af niveauer. * @return int[] */ public int[] getNiveau() { return niveau; }

/** * opdaterer et program til værdierne fra JSliderne. */ public void opdater() { for (int x = 0; x < LENGTH; x++) { niveau[x] = jArr[x].getValue(); } name = ti.getText(); }

/** * metode der bruges til at vise et program. * metoden returner et JPanel som indeholder træningsprogrammet. * <br>der returnrede JPanel har layoutmanager=NULL * @return JPanel */ public JPanel vis() { JPanel p = new JPanel();

Side 70 af 134

Page 71: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

p.setLayout(null); final int SPACING = 25; final int WIDTH = 15; final int HEIGHT = 200; final int YPOS = 50; for (int x = 0; x < LENGTH; x++) { jArr[x] = new JSlider(0, 7); jArr[x].setBounds(new Rectangle( ( (SPACING * x) + SPACING), YPOS, WIDTH, HEIGHT)); jArr[x].setOrientation(JSlider.VERTICAL); jArr[x].setBackground(p.getBackground()); jArr[x].setValue(niveau[x]); jArr[x].setSnapToTicks(true); p.add(jArr[x], null); } JLabel l = new JLabel("Navn: "); l.setBounds(260, 5, 40, 20); p.add(l); ti = new JTextField(name); ti.setBounds(300, 5, 100, 20); p.add(ti); p.updateUI(); return p; }

/** * gemmer et program på hd. * <br>Sti fortæller hvor på hd der skal gemmes... * udskriver en fejlmeddelse hvis der opstår fejl ved skrivning til hd. * @param sti String */ public void gem(String sti) { try { FileOutputStream file = new FileOutputStream(sti); ObjectOutputStream out = new ObjectOutputStream(file); out.writeObject(this); out.flush(); out.close(); } catch (IOException ex) { System.err.println("Der opstod en fejl under skrivning til disk"); } }

/** * metode til at hente navnet fra træningsprogrammet. * @return String */ public String getName() { return name; }}

Side 71 af 134

Page 72: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Maalingpackage bikeProject;

import java.io.*;

/** * <p>Title: Maaling</p> * <p>Description: Maaling klassen indeholder en måling samt metoder til at hente data fra målingen. * <br>en måling representerer altid 1 sek! * <br><h3>Ansvar</h3> * at give metoder der giver adgang til måling data * </p> * @author U9 * @version 0.1 */public class Maaling implements Serializable { byte maaling;

/** * konstruktør der gemmer en måling * @param maalingData byte */ public Maaling(byte maalingData) { maaling = maalingData; }

/** * henter antal omdrejning i minuttet som denne måling har haft. * @return int: */ public int getRpm() { int rpm; int mask = 3; rpm = maaling >>> 6; //Zero-fill right shift Shifts right, but always fills in with 0's rpm &= mask; return rpm; }

/** * henter hvor mange hjerteslag der har været til denne måling * @return int */ public int getPulse() { int pulse; int mask = 7; //"7=111 bin" pulse = maaling >>> 3; //Zero-fill right shift Shifts right, but always fills in with 0's pulse &= mask; return pulse; }

/** * metode til at se hvad gear cyklen stod i til en måling. * @return int */ public int getGear() { int gear; gear = maaling; int mask = 7; //"7=111 bin" gear &= mask; return (gear+1); }

/** * udregner længden der er kort i dette øjeblik * L=R*(2+G) [m]

Side 72 af 134

Page 73: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

* @return double */ public double getDist() { //da gear er mellem 0 7 i vores model skal vi +3 isted for 2 return (double) getRpm() * (3.0 + (double) getGear()); }

/** * udregner hastigheden der blev kørt med i denne måling * V=dl/dt[m/s] * @return double */ public double getSpeed() { //da det ealtid drejer sig om et sekund er dt = 1 // dL gælder også kun denne måling, derfor // getSpeed er lavet for syns skyld... se formel... return getDist(); }

/** * udregner hvormeget energi der er produceret i denne måling * E=(k1+k2*V)*L[J] (k1=3N og k2 2kg/s se 'Notes for dig 2 A' næst sidste side. * @return double energy produceret. */ public double getEnergy() { double k1 = 3; //'re dig2 note' double k2 = 2; //'re dig2 note' return (k1 + k2 * getSpeed()) * getDist(); }

/** * udregner hvor mange watt der er blevet forbrændt i dette sekund * P=dE/dT [W] * @return double */ public double getPower() { return getEnergy(); }

/** * udregner kalorierne der er forbrændt i denne måling. * @return float */ public double getKal() { return getEnergy() / (4.2 * 1000); }

}

Side 73 af 134

Page 74: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

DataTransportpackage bikeProject;

import java.io.*;import java.awt.*;import javax.swing.*;import javax.swing.event.*;

/** * virker som komunikationskontroller... * <p>Title: Bike Project</p> * <p>Description: Styre klasse, klassen kalder metoder i de andre klasser baseret på hhv. hvad brugeren indirekte beder om eller når metoderne svarer igen! * <h3>Ansvar</h3>Har ansvaret for den interne kommunikation i programmet, samt opdatering af skærmen. * </p> * @author CPOGG + Kristjan Petursson * @version 0.1 */public class DataTransport implements HyperlinkListener { private final String HELPLOCATION = "file:C:/bikedata/help/bv.html"; private JPanel mainPane; private ProgramArkiv programArkiv; private StatistikArkiv statistikArkiv; private JTextField status; private Object currentO; private CykelComputer cykelComputer; private JEditorPane htmlPane; private JPopupMenu popUpMenu; private Emulator emulator = new Emulator();

/** * konstruktør */ public DataTransport() { statistikArkiv = new StatistikArkiv(); programArkiv = new ProgramArkiv(); cykelComputer = new CykelComputer(); emulator.frameEmulate(statistikArkiv); }

/** * viser statistikarkiv */ public void visStatistikArkiv() { currentO = statistikArkiv; showPopup(statistikArkiv.vis(this));

}

/** * gemmer nuværende objekt */ public void gem() { if (currentO != null) { if (currentO.getClass() == programArkiv.getProgram().getClass()) { programArkiv.getProgram().opdater(); programArkiv.saveSession(); status.setText("Program " + programArkiv.getProgram().getName() + " er nu gemt"); } } }

/** * bruges til at vedhæfte statusfeltet som bruges af dataModellen, dette bil blive brugt til at vise evt. statusmeddelser i * @param t JTextField

Side 74 af 134

Page 75: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

*/ public void attachStatusField(JTextField t) { status = t; }

/** * bruges til at vedhæfte et JPanel til cykelmodellen, dette bliver brugt til at vise hovedindholdet af datamodellen i * @param p JPanel */ public void attachMainPane(JPanel p) { mainPane = p; }

/** * viser en statistik */ public void visStatistik() { currentO = statistikArkiv.getTraeningsSession(); clearAll(); statistikArkiv.getTraeningsSession().vis(mainPane); }

/** * wrapper til ensartet visning af jpopupmenuer * @param pop JPopupMenu */ private void showPopup(JPopupMenu pop) { popUpMenu = pop; pop.show(mainPane, 30, 50); }

/** * starter send program sekvensen */ public void sendProgram() { currentO = programArkiv.getProgram(); clearAll(); cykelComputer.requestSlotList(); showPopup(programArkiv.vaelgProgramTilOverforsel(this)); status.setText("Vælg program fra listen der skal overføres"); }

/** * opretProgram. * opretter et tomt program og viser det. */ public void opretProgram() { currentO = programArkiv.getProgram(); this.clearAll(); programArkiv.nytProgram(); visProgram(); status.setText("Jeg er klar til at oprette et træningsprogram, instil skyderne til de ønskede niviauer,indtast navn og tryk gem."); }

/** * viser det aktuelle program */ public void visProgram() { currentO = programArkiv.getProgram(); JPanel p; p = programArkiv.getProgram().vis(); p.setBounds(0, 0, mainPane.getWidth(), mainPane.getHeight()); mainPane.add(p); status.setText( "Viser program. hvis der foretages ændringer gemmes programmet under 'navn'"); }

/** * viser en liste over programmerne som popupmenu

Side 75 af 134

Page 76: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

*/ public void visProgramArkiv() { currentO = programArkiv; this.clearAll(); showPopup(programArkiv.vis(this)); status.setText("Programmer indlæst."); }

/** * slet nuværemde element */ public void slet() { if (currentO != null) { if (currentO.getClass() == programArkiv.getProgram().getClass()) { programArkiv.sletProgram(); status.setText("Program slettet."); this.clearAll(); } if (currentO.getClass() == statistikArkiv.getTraeningsSession().getClass()) { //programArkiv.sletProgram(); status.setText("Statistik slettet slettet."); //clearAll(); statistikArkiv.getTraeningsSession().vis(mainPane); } } else { status.setText("?? hvad skal jeg slette."); } }

/** * clearAll, renser skærmen... */ public void clearAll() { mainPane.removeAll(); mainPane.repaint(); }

/** * viser html hjælpe menuen i hovedvinduet */ public void showHelp() { clearAll(); int offset = 10; status.setText( "Jeg vil gerne hjælpe dig at navigere rundt i programmet, vælg et emne."); String url = HELPLOCATION; try { htmlPane = new JEditorPane(url); htmlPane.setEditable(false); htmlPane.addHyperlinkListener(this); JScrollPane scp = new JScrollPane(htmlPane); scp.setBounds(new Rectangle(offset, offset, mainPane.getWidth() - 2 * offset, mainPane.getHeight() - 2 * offset)); mainPane.add(scp); } catch (IOException ioe) { System.err.println("\nError displaying " + url); } }

/** * åbner en side når der trykkes på et link, hvis siden ikke findes skrives en pæn fejlmeddelelse i statusfeltet. * @param event HyperlinkEvent */ public void hyperlinkUpdate(HyperlinkEvent event) { if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { try { htmlPane.setPage(event.getURL());

Side 76 af 134

Page 77: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

status.setText(event.getURL().toString()); } catch (IOException ioe) { System.err.print("\nError displaying " + event.getURL().toString()); status.setText("Fejl, mangler: " + event.getURL().toString()); } } }

/** * viser en popupliste med programmer fra cyklen, skal have et program * som parameter, dette program vil blive overført ved klik på et slot fra listen. * @param program Program */ public void visSlotList(Program program) { showPopup(cykelComputer.visSlotList(program)); }}

Side 77 af 134

Page 78: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

CykelComputerpackage bikeProject;

import java.util.*;

import java.awt.event.*;import javax.swing.*;

import serialPak.*;

/** * * <p>Title: Bike Project</p> * <p>Description: * Klasse der indeholder alle metoder der skal bruges for at kommunikkere med * hardware cykelcomputer, (herefter kaldet 'HWCC'.) * <br><h3>Ansvar</h3> * At sende og modtage data fra 'HWCC' samt vise * en oversigt over hvad der ligge på HWCC af programmer.. * </p> * @@author CPOGG * @version 0.1 */public class CykelComputer implements FrameEventListener { private final String PORT = "COM5"; private final int NUMBOFSLOTS = 9; //max antal programmer der kan være på HWCC private final int MAXNAMELENGTH = 20; //max længe et programnavn må have på HWCC private SerialFrame sf1; private boolean isListening; private JPopupMenu p;

private String[] slotliste; //liste over programSlot private int STATE; //bruges til at se hvad der skal gøres med data der kommer fra cyklen

//stadie erklæring start***************************** private final int INIT = 0; private final int WAITINGFORSLOTLIST = 1; private final int READYTOSEND = 2;

/** * konstruktør, opretter et cykelcomputer objekt * <br>status sættes til 'oprettet', stadi sættes til INIT */ public CykelComputer() { initSlotList(); STATE = INIT; isListening = false; doListen(); }

/** * sammensætter en pakke til seriel transmission * fra et træningsprogram til det format som HWCC bruger * metoden skal udover en pointer til træningsprogrammet også have et * nummer som er destinationssnummeret på HWCC * @param p Program * @param slotnummer int * @return String */ private String genererTraeningsProgramPakke(Program p, int slotnummer) { String name = p.getName(); if (name.length() > MAXNAMELENGTH) { name = name.substring(0, MAXNAMELENGTH); } String programPakke = ""; programPakke += slotnummer; programPakke += p.getName(); programPakke += (char) 13;

Side 78 af 134

Page 79: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

int[] n = p.getNiveau(); for (int x = 0; x < n.length; x++) { programPakke += n[x]; } return programPakke; }

/** * Spørger cykelcomputeren om den kan få en slot liste... * <br>Det interne stadie sættes til WAITINGFORSLOTLIST */ public void requestSlotList() { String givemeData = "!"; if (!isListening) { doListen(); } sf1.sendFrameRaw(givemeData); STATE = WAITINGFORSLOTLIST; }

/** * Initialiserer slotListen spledes at man kan se der ikke er modtaget data endnu */ private void initSlotList() { slotliste = new String[NUMBOFSLOTS]; int index = 0; do { //pad slot array... slotliste[index] = "ingen data modtaget"; index++; } while (index < NUMBOFSLOTS); }

/** * Hvis der er modtaget en slotListe fra 'HWCC' kaldes denne metode * <br>den input er et array af strenge der hvert indeholder et slotnummer og et navn. * Indgangstrengen skal være af formatet<br> * [SLOTNUMMER][PROGRAMNAVN], hvis det første tegn ikke er et gyldigt nummer * udksrives en fejlmeddelse.<br> * cykelcomputeren sender intet data om tomme SLOTS, derfor antages det med sindsro at de slots der ikke er modtagedet data om, er tomme * <br>det interne stadi sættes til READYTOSEND * @param segments String[] */ private void analyseSlotList(String[] segments) { String[] tempSlotList = new String[NUMBOFSLOTS]; int index; String name; index = 0; //System.err.print(segments[0]); do { //pad slot array ,ed tomme felter... tempSlotList[index] = "Intet Program"; index++; } while (index < NUMBOFSLOTS); for (int i = 0; i < segments.length; i++) { index = segments[i].charAt(0); index = index - 48; //trækker 48 fra for at konverere fra ascii til integer if (index >= 0 && index < NUMBOFSLOTS) { //se om nummeret er i et tilladt område name = segments[i].substring(1, segments[i].length()); tempSlotList[index] = name; } else { System.err.print("\nUgyldigt index: " + index); } } slotliste = tempSlotList; STATE = READYTOSEND; }

/**

Side 79 af 134

Page 80: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

* Analyser en modtaget pakke sammenholdt med hvilket stadie cykelcomputeren står i. * <br>Hvis Stadiet er WAITINGFORSLOTLIST bliver den opdelte data sendt videre til analyseslotlist. * <br>hvis cykelcomputeren står i et andet stadie, antages det at der er statistik der er modtaget. * og data sendes direkte videre til converStatistik * @param data String * @param arkiv StatistikArkiv */ public void analyseData(String data) { //vi bruger en cr (char 13 ) til at dele vores data i mindre segmenter... String delimiter = "" + (char) 13; String[] segments; segments = data.split(delimiter); switch (STATE) { case WAITINGFORSLOTLIST: //REGNER MED DET EN SLOTLIST analyseSlotList(segments); break; default: System.out.print( "Jeg venter ikke på noget data, data behandles som statistik..."); convertStatistik(data); } }

/** * konverterer en streng til et statisk objekt. * hvis strengen bliver godkendt som et stykke statistik, bliver den gemt på hd ved hjælp af statistikArkiv. * <br>udskriver en fejlmeddelse hvis stattistikken ikke bliver godkendt * @param data String */ private void convertStatistik(String data) { String tempId = ""; String tempVg = ""; String tempN = ""; int programId = 0; int vaegt = 0; int niveau = 0;

ArrayList maalinger = new ArrayList(); String tempStatestik = data; //parsing tempStatestik int parsedLength = 0; int chunks = 0; while (tempStatestik.length() > parsedLength) { //de første stykke stykke af strengen skal være programId char cc = tempStatestik.charAt(parsedLength++); switch (cc) { case 13: chunks++; // skift et element frem break; default: switch (chunks) { case 0: //vi får noget program id... tempId += cc; try { programId = Integer.parseInt(tempId.trim()); } catch (NumberFormatException e) { System.err.print(e.getStackTrace()); } break; case 1: //vi får noget vaegt... tempVg += cc; try { vaegt = Integer.parseInt(tempVg.trim()); } catch (NumberFormatException e) { System.err.print(e.getStackTrace()); }

Side 80 af 134

Page 81: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

break; case 2: //vi får et niveau...; try { tempN += cc; niveau = Integer.parseInt(tempN.trim()); } catch (NumberFormatException e) { System.err.print(e.getStackTrace()); } break; default: //resten skulle gerne være målinger... Maaling m = new Maaling( (byte) cc); maalinger.add(m); break; } } } // System.out.print("\nsetStatistik\n"+ maalinger.toString() +"\n"); if (chunks >= 3) { StatistikArkiv arkiv = new StatistikArkiv(); arkiv.getTraeningsSession().setStatistik(tempId, vaegt, niveau, maalinger); arkiv.saveSession(); // arkiv.getTraeningsSession().gem(arkiv.getArkivSti()); String confirmChar = "" + (char) 6; sf1.sendFrame(confirmChar); } else { System.err.print("ukendt format: chunks!=3 -> chunks=:" + chunks); } }

/** * opretter en popupmenu over cykelprogrammer på computeren<br> * metoden returnerer en liste uansetr om cykelcomputeren er tilgængelig eller ej. * listen har tilknyttede handlinger (Action) af typen transfer Action * når man trykker på en handling, overføres programmet til det valgte slot. * <br>metoden tager 1 parameter, nemlig programmet der skal overføres. * @param prg Program * @return JPopupMenu */ public JPopupMenu visSlotList(Program prg) { p = new JPopupMenu(); p.setLabel("CykelComputer slotListe"); JMenuItem i; for (int x = 0; x < slotliste.length; x++) { Action a = new TransferAction(prg, x); i = new JMenuItem(); i.setText(slotliste[x]); i.addActionListener(a); p.add(i); } return p; }

/** * eventen forekommer når der er ligger en pakke af dat apå den serielle kanal. * dataen bliver send videre til analyseData * @param be FrameEvent */ public void frameReady(FrameEvent be) { analyseData(be.getData()); }

/** * åbner den serielle kanal. Hvis kanalen allerede er åben foretages intet. */ public void doListen() { if (!isListening) { isListening = true; try {

Side 81 af 134

Page 82: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

sf1 = new SerialFrame(PORT); sf1.addFrameEventListener(this); } catch (TooManyListenersException ex) { System.err.print(ex.getStackTrace()); } } else { } }

/** * lukker den serielle kanal, hvis kanalen allerede er lukket, foretages intet. */ public void dontListen() { if (isListening) { sf1.closePort(); sf1 = null; isListening = false; } }

/** * <p>Title: Transfer action</p> * <p>Description: action der overfører beder cykelcomputeren om at overføøre et program til 'HWCC' til et bestemt slot</p> * <p>Copyright: Copyright (c) 2004</p> * <p>Company: </p> * @author CPOGG * @version 0.1 */ private class TransferAction extends AbstractAction { Program program; int slot;

/** * Konstruktør: * knytter en TransferAction til popUpmenuen * @param _p Program der skal overføreres * @param _s int slot nummer der skal overføres til */ TransferAction(Program _p, int _s) { program = _p; slot = _s; }

/** * actionPerformed * @param e ActionEvent */ public void actionPerformed(ActionEvent e) { //System.out.print("\nPRogram: " + genererTraeningsProgramPakke(program, slot)); sf1.sendFrame(genererTraeningsProgramPakke(program, slot)); } }}

Side 82 af 134

Page 83: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Arkivpackage bikeProject;

import java.io.*;

/** * <p>Title: Bike Project</p> * <p>Description: klasse der indeholder de nødvendige funktioner for at * <br>strømline arbejdet med java objecter og hd. * <br>så som arkiv sti osv</p> * @author Sólji í Dali * @version 0.1 */

public class Arkiv { private String arkivSti = "c:/bikedata";

/** * Konstruktør, tom */ protected Arkiv() { }

/** * metode til at hente arkivstien * @return String */ protected String getArkivSti() { return arkivSti; }

/** * metode til at indlæse et objekt * @param fil String * @return Object */ protected Object load(String fil) { Object objekt = new Object(); FileInputStream file = null; try { file = new FileInputStream(fil); } catch (FileNotFoundException ex) { System.err.print("\nFil ikke fundet "); } ObjectInputStream input = null; try { input = new ObjectInputStream(file); } catch (IOException ex1) { System.err.print("\nfejl ved indlaesning "); } try { objekt = input.readObject(); } catch (ClassNotFoundException ex2) { System.err.print("\nKlasse ikke fundet:-"); } catch (IOException ex2) { System.err.print("\nUkendt klasse ved udpakning - dette kan skyldes en opdateret version af programmet "); } try { input.close(); } catch (IOException ex3) { System.out.print("\nfejl ved lukning af filstrøm "); } return objekt;

Side 83 af 134

Page 84: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

}

/** * henter en liste over filerne i arkivstien * @return String[] */ protected String[] getFileList() { File f; f = new File(getArkivSti()); return f.list(); }

/** * metode til at sætte arkivstien * @param s String */ protected void setArkivSti(String s) { arkivSti = s;

}

}

Side 84 af 134

Page 85: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Frame1package app;import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.border.*;

import bikeProject.*;import com.borland.jbcl.layout.*;

/**

* <p>Description: Brugergrænsflade til cykelcomputeren </p> * <p>Copyright: Copyright (c) 2004</p> * <p>Company: </p> * @author Kristjan Petursson * @version 0.1 */

public class Frame1 extends JFrame { JPanel contentPane; JButton jButton1 = new JButton(); TitledBorder titledBorder1; TitledBorder titledBorder2; JButton jButton2 = new JButton(); JButton jButton3 = new JButton(); JButton jButton4 = new JButton(); JButton jButton5 = new JButton(); JButton jButton6 = new JButton(); TitledBorder titledBorder3; JButton jButton7 = new JButton(); JButton jButton8 = new JButton(); JButton jButton9 = new JButton(); JPanel jPanel1 = new JPanel(); JPanel jPanel2 = new JPanel(); VerticalFlowLayout verticalFlowLayout1 = new VerticalFlowLayout(); JPanel jPanel3 = new JPanel(); VerticalFlowLayout verticalFlowLayout2 = new VerticalFlowLayout(); VerticalFlowLayout verticalFlowLayout3 = new VerticalFlowLayout(); JPanel jPanel4 = new JPanel(); VerticalFlowLayout verticalFlowLayout4 = new VerticalFlowLayout(); JPanel jPanel5 = new JPanel(); FlowLayout flowLayout1 = new FlowLayout(); JPanel jPanel6 = new JPanel(); JTextField jTextField1 = new JTextField(); DataTransport dataModel = new DataTransport();

//Construct the frame public Frame1() { enableEvents(AWTEvent.WINDOW_EVENT_MASK); try { jbInit(); } catch(Exception e) { e.printStackTrace(); } }

//Component initialization private void jbInit() throws Exception { dataModel.attachMainPane(jPanel6); dataModel.attachStatusField(jTextField1);

contentPane = (JPanel) this.getContentPane(); titledBorder1 = new TitledBorder(""); titledBorder2 = new TitledBorder(""); titledBorder3 = new TitledBorder(""); this.getContentPane().setBackground(Color.white);

Side 85 af 134

Page 86: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

this.setResizable(false); this.setSize(new Dimension(800, 500)); this.setTitle("Cykel Program"); contentPane.setLayout(null);

//Knap 1 bliver lavet jButton1.setBackground(Color.white); jButton1.setAlignmentX((float) 0.0); jButton1.setBorder(null); jButton1.setPreferredSize(new Dimension(93, 23)); jButton1.setBorderPainted(true); jButton1.setHorizontalAlignment(SwingConstants.CENTER); jButton1.setHorizontalTextPosition(SwingConstants.CENTER); jButton1.setText("Vis Statestik"); jButton1.setVerticalAlignment(javax.swing.SwingConstants.CENTER); jButton1.setVerticalTextPosition(javax.swing.SwingConstants.CENTER); jButton1.addActionListener(new Frame1_jButton1_actionAdapter(this));

//Knap 2 bliver lavet jButton2.setVerticalTextPosition(javax.swing.SwingConstants.CENTER); jButton2.addActionListener(new Frame1_jButton2_actionAdapter(this)); jButton2.setVerticalAlignment(javax.swing.SwingConstants.CENTER); jButton2.setText("Vis Program"); jButton2.setHorizontalTextPosition(SwingConstants.LEADING); jButton2.setPreferredSize(new Dimension(93, 23)); jButton2.setActionCommand("Vis Program"); jButton2.setHorizontalAlignment(SwingConstants.CENTER); jButton2.setBorder(null); jButton2.setAlignmentX((float) 0.0);

//Knap 3 bliver lavet jButton3.setVerticalTextPosition(javax.swing.SwingConstants.CENTER); jButton3.addActionListener(new Frame1_jButton3_actionAdapter(this)); jButton3.setVerticalAlignment(javax.swing.SwingConstants.CENTER); jButton3.setText("Opret Program"); jButton3.setHorizontalTextPosition(SwingConstants.LEADING); jButton3.setPreferredSize(new Dimension(93, 23)); jButton3.setHorizontalAlignment(SwingConstants.CENTER); jButton3.setBorder(null); jButton3.setAlignmentX((float) 0.0);

//Knap 4 bliver lavet jButton4.setVerticalTextPosition(javax.swing.SwingConstants.CENTER); jButton4.addActionListener(new Frame1_jButton4_actionAdapter(this)); jButton4.setVerticalAlignment(javax.swing.SwingConstants.CENTER); jButton4.setText("Overfør Program"); jButton4.setHorizontalTextPosition(SwingConstants.LEADING); jButton4.setPreferredSize(new Dimension(93, 23)); jButton4.setHorizontalAlignment(SwingConstants.CENTER); jButton4.setBorder(null); jButton4.setAlignmentX((float) 0.0);

//Knap 5 bliver lavet jButton5.setAlignmentX((float) 0.0); jButton5.setBorder(null); jButton5.setPreferredSize(new Dimension(93, 23)); jButton5.setHorizontalAlignment(SwingConstants.CENTER); jButton5.setHorizontalTextPosition(SwingConstants.LEADING); jButton5.setText("Hjælp"); jButton5.setVerticalAlignment(javax.swing.SwingConstants.CENTER); jButton5.setVerticalTextPosition(javax.swing.SwingConstants.CENTER); jButton5.addActionListener(new Frame1_jButton5_actionAdapter(this));

//Knap 6 bliver lavet jButton6.setAlignmentX((float) 0.0); jButton6.setBorder(null); jButton6.setPreferredSize(new Dimension(93, 23)); jButton6.setHorizontalAlignment(SwingConstants.CENTER); jButton6.setHorizontalTextPosition(SwingConstants.LEADING); jButton6.setText("Afslut"); jButton6.setVerticalAlignment(javax.swing.SwingConstants.CENTER);

Side 86 af 134

Page 87: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

jButton6.setVerticalTextPosition(javax.swing.SwingConstants.CENTER); jButton6.addActionListener(new Frame1_jButton6_actionAdapter(this));

//Knap 7 bliver lavet jButton7.setVerticalTextPosition(javax.swing.SwingConstants.CENTER); jButton7.addActionListener(new Frame1_jButton7_actionAdapter(this)); jButton7.setVerticalAlignment(javax.swing.SwingConstants.CENTER); jButton7.setText("Annuller"); jButton7.setHorizontalTextPosition(SwingConstants.LEADING); jButton7.setHorizontalAlignment(SwingConstants.CENTER); jButton7.setPreferredSize(new Dimension(93, 23)); jButton7.setBorder(null); jButton7.setAlignmentX((float) 0.0);

//Knap 8 bliver lavet jButton8.setVerticalTextPosition(javax.swing.SwingConstants.CENTER); jButton8.addActionListener(new Frame1_jButton8_actionAdapter(this)); jButton8.setVerticalAlignment(javax.swing.SwingConstants.CENTER); jButton8.setText("Gem"); jButton8.setHorizontalTextPosition(SwingConstants.LEADING); jButton8.setHorizontalAlignment(SwingConstants.CENTER); jButton8.setPreferredSize(new Dimension(140, 23)); jButton8.setActionCommand("Gem"); jButton8.setBorder(null); jButton8.setAlignmentX((float) 0.0);

//Knap 9 bliver lavet jButton9.setVerticalTextPosition(javax.swing.SwingConstants.CENTER); jButton9.addActionListener(new Frame1_jButton9_actionAdapter(this)); jButton9.setVerticalAlignment(javax.swing.SwingConstants.CENTER); jButton9.setText("Slet"); jButton9.setHorizontalTextPosition(SwingConstants.LEADING); jButton9.setHorizontalAlignment(SwingConstants.CENTER); jButton9.setPreferredSize(new Dimension(93, 23)); jButton9.setBorder(null); jButton9.setAlignmentX((float) 0.0);

jPanel1.setBackground(Color.lightGray); jPanel1.setBorder(BorderFactory.createEtchedBorder()); jPanel1.setDebugGraphicsOptions(0); jPanel1.setBounds(new Rectangle(11, 82, 132, 37)); jPanel1.setLayout(verticalFlowLayout3);

jPanel2.setBackground(Color.lightGray); jPanel2.setBorder(BorderFactory.createEtchedBorder()); jPanel2.setBounds(new Rectangle(11, 139, 132, 68)); jPanel2.setLayout(verticalFlowLayout1);

jPanel3.setBackground(Color.lightGray); jPanel3.setForeground(Color.black); jPanel3.setBorder(BorderFactory.createEtchedBorder()); jPanel3.setBounds(new Rectangle(11, 26, 132, 37)); jPanel3.setLayout(verticalFlowLayout2);

jPanel4.setBackground(Color.lightGray); jPanel4.setBorder(BorderFactory.createEtchedBorder()); jPanel4.setDebugGraphicsOptions(0); jPanel4.setVerifyInputWhenFocusTarget(true); jPanel4.setBounds(new Rectangle(11, 227, 131, 65)); jPanel4.setLayout(verticalFlowLayout4);

jPanel5.setBackground(Color.lightGray); jPanel5.setBorder(BorderFactory.createEtchedBorder()); jPanel5.setBounds(new Rectangle(163, 310, 593, 38)); jPanel5.setLayout(flowLayout1);

jPanel6.setBackground(Color.lightGray); jPanel6.setBorder(BorderFactory.createEtchedBorder()); jPanel6.setOpaque(true);

Side 87 af 134

Page 88: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

jPanel6.setBounds(new Rectangle(163, 26, 592, 266)); jPanel6.setLayout(null); jTextField1.setBackground(Color.white); jTextField1.setDoubleBuffered(false); jTextField1.setEditable(false); jTextField1.setText("Meddelelser"); jTextField1.setBounds(new Rectangle(163, 368, 592, 27));

contentPane.setBorder(null); contentPane.setDebugGraphicsOptions(0); contentPane.setMinimumSize(new Dimension(1, 1)); contentPane.setOpaque(true); contentPane.setRequestFocusEnabled(true); jPanel2.add(jButton2, null); jPanel2.add(jButton3, null);

contentPane.add(jPanel4, null); contentPane.add(jPanel3, null); jPanel3.add(jButton4, null); contentPane.add(jPanel1, null); jPanel1.add(jButton1, null); contentPane.add(jPanel2, null); jPanel4.add(jButton5, null); jPanel4.add(jButton6, null); contentPane.add(jPanel5, null); jPanel5.add(jButton7, null); jPanel5.add(jButton8, null); jPanel5.add(jButton9, null); contentPane.add(jPanel6, null); contentPane.add(jTextField1, null); }

//Overridden so we can exit when window is closed protected void processWindowEvent(WindowEvent e) { super.processWindowEvent(e); if (e.getID() == WindowEvent.WINDOW_CLOSING) { System.exit(0); } }

void jButton2_actionPerformed(ActionEvent e) { dataModel.visProgramArkiv(); }

void jButton1_actionPerformed(ActionEvent e) { dataModel.visStatistikArkiv(); }

void jButton6_actionPerformed(ActionEvent e) { System.exit(0); }

void jButton3_actionPerformed(ActionEvent e) { dataModel.opretProgram(); }

void jButton8_actionPerformed(ActionEvent e) { dataModel.gem(); }

void jButton4_actionPerformed(ActionEvent e) { dataModel.sendProgram(); }

void jButton5_actionPerformed(ActionEvent e) { dataModel.showHelp(); }

void jButton9_actionPerformed(ActionEvent e) { dataModel.slet();

Side 88 af 134

Page 89: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

}

void jButton7_actionPerformed(ActionEvent e) { dataModel.clearAll(); }

class Frame1_jButton8_actionAdapter implements ActionListener { Frame1 adaptee;

Frame1_jButton8_actionAdapter(Frame1 adaptee) { this.adaptee = adaptee; } public void actionPerformed(ActionEvent e) { adaptee.jButton8_actionPerformed(e); } }

class Frame1_jButton4_actionAdapter implements ActionListener { Frame1 adaptee;

Frame1_jButton4_actionAdapter(Frame1 adaptee) { this.adaptee = adaptee; } public void actionPerformed(ActionEvent e) { adaptee.jButton4_actionPerformed(e); } }

class Frame1_jButton1_actionAdapter implements ActionListener { Frame1 adaptee;

Frame1_jButton1_actionAdapter(Frame1 adaptee) { this.adaptee = adaptee; } public void actionPerformed(ActionEvent e) { adaptee.jButton1_actionPerformed(e); } }

class Frame1_jButton7_actionAdapter implements ActionListener { Frame1 adaptee;

Frame1_jButton7_actionAdapter(Frame1 adaptee) { this.adaptee = adaptee; } public void actionPerformed(ActionEvent e) { adaptee.jButton7_actionPerformed(e); } }

class Frame1_jButton2_actionAdapter implements ActionListener { Frame1 adaptee;

Frame1_jButton2_actionAdapter(Frame1 adaptee) { this.adaptee = adaptee; } public void actionPerformed(ActionEvent e) { adaptee.jButton2_actionPerformed(e); } }

class Frame1_jButton6_actionAdapter implements ActionListener { Frame1 adaptee;

Frame1_jButton6_actionAdapter(Frame1 adaptee) { this.adaptee = adaptee;

Side 89 af 134

Page 90: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

} public void actionPerformed(ActionEvent e) { adaptee.jButton6_actionPerformed(e); } }

class Frame1_jButton5_actionAdapter implements ActionListener { Frame1 adaptee;

Frame1_jButton5_actionAdapter(Frame1 adaptee) { this.adaptee = adaptee; } public void actionPerformed(ActionEvent e) { adaptee.jButton5_actionPerformed(e); } }

class Frame1_jButton9_actionAdapter implements ActionListener { Frame1 adaptee;

Frame1_jButton9_actionAdapter(Frame1 adaptee) { this.adaptee = adaptee; } public void actionPerformed(ActionEvent e) { adaptee.jButton9_actionPerformed(e); } }

class Frame1_jButton3_actionAdapter implements ActionListener { Frame1 adaptee;

Frame1_jButton3_actionAdapter(Frame1 adaptee) { this.adaptee = adaptee; } public void actionPerformed(ActionEvent e) { adaptee.jButton3_actionPerformed(e); } }}

Side 90 af 134

Page 91: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

UserInterfacepackage app;import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.border.*;

import bikeProject.*;import com.borland.jbcl.layout.*;

/** * <p>Title: </p> * <p>Description: </p> * <p>Copyright: Copyright (c) 2004</p> * <p>Company: </p> * @author Kristjan Petursson * @version 1.0 */public class UserInterface { boolean packFrame = false;

//Construct the application public UserInterface() { Frame1 frame = new Frame1(); //Validate frames that have preset sizes //Pack frames that have useful preferred size info, e.g. from their layout if (packFrame) { frame.pack(); } else { frame.validate(); } //Center the window Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension frameSize = frame.getSize(); if (frameSize.height > screenSize.height) { frameSize.height = screenSize.height; } if (frameSize.width > screenSize.width) { frameSize.width = screenSize.width; } frame.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2); frame.setVisible(true); }

//Main method public static void main(String[] args) { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch(Exception e) { e.printStackTrace(); } new UserInterface(); }}

Side 91 af 134

Page 92: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Source kode til AssemblerHer findes kildekoden til assembler delen af softwaren på cykelcomputeren.

ASKELET; ASKELET.ASM 2004-12-10 u9

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Skeleton for 8088 minimum system;;;; Use this skeleton when linking assembly and C++ modules together.;;;; Segment definitions and initialization procedures needed by the C++ modules;; are in the included file INITSEG.ASM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; the include file INITSEG.ASM contains segment definitions and initialization; procedures. This is needed when linking assembly and C++ togetherINCLUDE INITSEG.ASM ; include file

; define constants

; Port addressesPORTA = 8001H ; Port APORTB = 8002H ; Port BPORTC = 8003H ; Port CSYSLED = 0A000H ; LED's on 8088 min. system

; port configurationPORT_A_MODE = 1; ; 0 = input, 1 = outputPORT_B_MODE = 0; ; 0 = input, 1 = outputPORT_C_MODE = 1; ; 0 = input, 1 = outputPORT_MODE_PATTERN = PORT_A_MODE + PORT_B_MODE*10B + PORT_C_MODE * 1100B ; combine bits

; timer configurationFREQUENCY_DIVISOR = 4915; ; set count for frequency divider on 8155 chip

; size of stackbytes = 0F00HSTACKSIZE = 2 * bytes ; size of stack in bytes

; segment for interrupt vectors_INTERRUPT_VECTORS segment para public 'INTVECT'

; Interrupt vectors start at address 0INT0OFF dw ? ; offset of interrupt vector 0INT0SEG dw ? ; segment of interrupt vector 0INT1OFF dw ? ; offset of interrupt vector 1INT1SEG dw ? ; segment of interrupt vector 1INT2OFF dw ? ; offset of interrupt vector 2INT2SEG dw ? ; segment of interrupt vector 2INT3OFF dw ? ; offset of interrupt vector 3INT3SEG dw ? ; segment of interrupt vector 3

_INTERRUPT_VECTORS ends

; define data segment

Side 92 af 134

Page 93: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

_DATA segment word public 'DATA'

; Program bank - large area of data to store programs - first to programs defined here

_BANK DB 's','t','a','n','d','a','r','d',' ','p','r','o','g','r','a','m',' ','1', 0 , 0 ,'2','2','3','4','5','6','6','6','7','7','6','5','4','4','3','3','2','2','1','1','H','a','r','d','c','o','r','e',' ','t','r','a','i','n','i','n','g', 0 , 0 , 0 ,'2','2','3','4','5','6','6','6','7','7','6','5','4','4','3','3','2','2','1','1',280 dup (0)

; Space for measurements_LOG DB 600 dup (0)

; Make available to c++public _BANK, _LOG

_DATA ends

; define stack segment_STACK segment stack 'STACK'

STACKTOP dw STACKSIZE/2 dup (?) ; reserve space for stackSTACKBOTTOM label word ; mark end of stack

_STACK ends

; combine data segments into a group so that they can be addressed with ; the same segment registerDGROUP group _INTERRUPT_VECTORS, _DATA, _STACK

; define code segment; (Must be defined exactly the same way as the C++ compiler does:)_TEXT segment byte public 'CODE' ; code segment starts here

assume cs:_TEXT,ds:DGROUP,ss:DGROUP ; tell which segment registers to use

extrn _main:near, _interrupt2:far, _interrupt3:far ; external links to functions in C++ module

STARTADR: ; program starts here

; Initialize segment registers and stackmov ax, DGROUP ; address of data segments groupmov ds, ax ; data segment registermov ss, ax ; stack segment registerlea sp, DGROUP:STACKBOTTOM ; stack pointercall StopTimer

; Initialize data segments and C++ modulescall InitializeCPP ; initializations required by C++ modules

; initialize interrupt vector 2mov INT2OFF, offset _interrupt2 ; make interrupt vector point to

interrupt routinemov INT2SEG, seg _interrupt2

; initialize interrupt vector 3mov INT3OFF, offset _interrupt3 ; make interrupt vector point to

interrupt routinemov INT3SEG, seg _interrupt3

; now, we can allow interruptssti ; set interrupt flag

; initialize 8155 chipmov al, PORT_MODE_PATTERN ; tell which ports to use for input/outputcall ConfigurePortABC

Side 93 af 134

Page 94: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

; start timer on 8155 chipmov ax, FREQUENCY_DIVISOR ; decide timer frequencycall StartTimer ; start timer on 8155 chip

; now, we are ready to call mainMAINAGAIN:

call _main ; call main programjmp MAINAGAIN ; call again if main returns

_TEXT ends ; code segment ends here

; define reset segment_RESET segment para public 'RESET' ; the CPU goes here when reset assume cs:_RESET jmp far ptr STARTADR ; far jump to program start_RESET ends

end STARTADR ; place start address after END

Side 94 af 134

Page 95: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

INITSEG; INITSEG.ASM 2003-05-19 AgF

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Segment definitions and initialization procedures for 8088 minimum system.;; This makes it possible to run C++ programs on the minimum system.;;;; This file must be included in the start of your asm module before any;; segment declarations.;;;; IMPORTANT: Do not change the names or order of the segments.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Define names, order and alignment of all segments:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; segment for interrupt vectors:_INTERRUPT_VECTORS segment para public 'INTVECT'_INTERRUPT_VECTORS ends

; empty segment for alignment:; (Data that needs copying to ROM must be paragraph aligned because the; locator can relocate only segments, not offsets)ALIGN1 segment para public 'DATA' ; align _DATA by 16, overriding the compiler's word alignmentALIGN1 ends

; segment for initialized data:_DATA segment word public 'DATA'datastart label byte ; start of data segment_DATA ends

; empty segment for alignment (same reason as for ALIGN1):ALIGN2 segment para public 'INITDATA' ; align _INIT_ by 16, overriding the compiler's word alignmentALIGN2 ends

; segment for initialization requests:_INIT_ segment word public 'INITDATA'InitStart label byte_INIT_ ends

; end of initialization list:_INITEND_ segment byte public 'INITDATA'InitEnd label byte_INITEND_ ends

; segment for at-exit requests:_EXIT_ segment word public 'EXITDATA'_EXIT_ ends

; segment for uninitialized data:_BSS segment word public 'BSS'BSS_begin label byte_BSS ends

; end of uninitialized data:_BSSEND segment byte public 'BSS'BSS_end label byteend_of_data label byte_BSSEND ends

; stack segment:

Side 95 af 134

Page 96: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

_STACK segment stack 'STACK'_STACK ends

; combine data segments into a group, so that they can all be addressed with the same segment register:DGROUP group _INTERRUPT_VECTORS,ALIGN1,_DATA,_INIT_,_INITEND_,_BSS,_BSSEND,_STACK

; empty segment for alignment (to make debugging easier):ALIGN3 segment para public 'CODE' ; align code by 16, overriding the compiler's byte alignmentALIGN3 ends

; Define code segment:_TEXT segment byte public 'CODE'assume cs:_TEXT,ds:DGROUP,ss:DGROUP_TEXT ends

; define copy of _DATA segment in ROM:_ROMDATA1 segment para public 'ROMDATA1'romdatabegin label byte_ROMDATA1 ends

; define copy of _INIT_ segment in ROM:_ROMDATA2 segment para public 'ROMDATA2'_ROMDATA2 ends

; end of ROM data segments:_ROMDATAEND segment byte public 'ROMDATA3'_ROMDATAEND ends

; group ROM data segments togetherRGROUP GROUP _ROMDATA1,_ROMDATA2,_ROMDATAEND

; reset segment_RESET segment para public 'RESET'; the CPU goes here when reset_RESET ends

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Initialization procedures;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

_TEXT segmentassume cs:_TEXT,ds:DGROUP,ss:DGROUP

; define bit patterns for configuring 8155 port/timer chip:CONTROL_PORT = 8000H ; control portCOUNTLLO_PORT= 8004H ; Count length low byteCOUNTLHI_PORT= 8005H ; Count length high byteSTOP_TIMER_PATTERN = 01000000B ; command to stop timerSTART_TIMER_PATTERN = 11000000B ; command to start timer TIMER_WAVEFORM_PATTERN = 01000000B ; request square wave

StopTimer proc near ; stop timer in 8155 chip mov al, _control_8155 and al, 00001111B ; lower 4 bits contain port configuration or al, STOP_TIMER_PATTERN ; upper 2 bits contain start/stop command mov _control_8155, al ; sawe control word mov dx, CONTROL_PORT out dx, AL ; command to 8155 port controller retStopTimer endp

StartTimer proc near ; start timer in 8155 chip ; AX = frequency divisor mov dx, COUNTLLO_PORT out dx, al ; low byte of frequency divisor

Side 96 af 134

Page 97: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

mov dx, COUNTLHI_PORT mov al, ah ; high byte of frequency divisor and al, 00111111B or al, TIMER_WAVEFORM_PATTERN ; request square wave out dx, al ; output 6 bits of frequency divisor + 2 bits of waveform mov al, _control_8155 and al, 00001111B ; lower 4 bits contain port configuration or al, START_TIMER_PATTERN; upper 2 bits contain start/stop command mov _control_8155, al ; sawe control word mov dx, control_port out dx, al ; command to 8155 port controller retStartTimer endp

ConfigurePortABC proc near ; configure ports on 8155 chip ; AL = port configuration mov ah, _control_8155 and ah, 11000000B ; upper 2 bits contain start/stop command and al, 00001111B ; lower 4 bits contain port configuration or al, ah ; combine bits mov _control_8155, al ; sawe control word mov dx, control_port out dx, al ; command to 8155 port controller retConfigurePortABC endp

ResetInterruptVectors proc near; Makes all interrupt vectors point to _abort or debugger push di mov dx, _DATA mov cl, 4 shl dx, cl ; start of _DATA = end of _INTERRUPT_VECTORS sub bx, bx ; 0 mov di, [bx+5*4] ; read interrupt vector 5 = debug trap for unsupported interrupts mov cx, [bx+5*4+2] cmp cx, 0FC00H ; debugger code segment je DEBUGGER_ACTIVE lea di, cs:_abort ; no debugger active.. mov cx, cs ; point to _abort function insteadDEBUGGER_ACTIVE: mov ax, csIVECLOOP:cmp bx, dx ; loop through all interrupt vectors jnb IVECEND cmp [bx+2], ax je SKIPI ; this one allready initialized cmp word ptr [bx+2], 0FC00H je SKIPI ; this one allready initialized mov [bx], di ; make interrupt vector point to debugger or _abort function mov [bx+2], cxSKIPI: add bx, 4 ; next interrupt vector jmp IVECLOOPIVECEND:pop di ; end of loop retResetInterruptVectors endp

InitializeDataSegments PROC near; copy segments _DATA and _INIT_ from ROM to RAM push ds push si push di cld mov ax, ds mov es, ax mov ax, cs

Side 97 af 134

Page 98: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

cmp ax, 8000h ; are we running from ROM? jb NO_ROM_DATA mov ax, RGROUP mov ds, ax lea si, RGROUP:romdatabegin ; address of ROM copy lea di, DGROUP:datastart ; destination for copy lea cx, DGROUP:InitEnd ; end of destination sub cx, di ; size of data to copy jz NO_ROM_DATA rep movsb ; copy cx bytes from ds:si to es:diNO_ROM_DATA:; initialize BSS segment to 0 lea di, DGROUP:BSS_begin ; beginning of uninitialized data lea cx, DGROUP:BSS_end sub cx, di ; size of uninitialized data jle BSSINITEND sub ax, ax ; = 0 rep stosb ; write cx bytes of al to es:diBSSINITEND: pop di pop si pop ds retInitializeDataSegments endp

InitializeCPP proc near push si push di lea si, DGROUP:InitStart lea di, DGROUP:InitEnd cmp si,di jnb INITCPPDONE mov word ptr ds:[4*21h],offset cs:DOSService mov word ptr ds:[4*21h+2],cs

; the following code is adapted from c0.asm, the startup code used by the TC compiler. ; The _INIT_ segment contains structures CALLREQUEST pointing to initialization ; procedures to call before main:

CALLREQUEST STRUC ; define structurecalltype db ? ; 0=near,1=far,FF=finishedpriority db ? ; calling order. 0 = first, FF = lastpproc dd ? ; far pointer to initialization procedureCALLREQUEST ENDS

INITCPPSTART: mov ax, 100H ;start with lowest priority mov dx, di ;set sentinel to end of table mov bx, si ;bx = start of table

INITCPPTOP: cmp bx, di ;and the end of the table? je INITCPPENDTB ;yes, exit the loop cmp [bx].calltype,0FFH ;check if allready handled je INITCPPNEXT mov cl, [bx].priority ;move priority to CX sub ch, ch cmp cx, ax ;check the priority jae INITCPPNEXT ;too high? skip mov ax, cx ;keep priority mov dx, bx ;keep index in dxINITCPPNEXT: add bx, SIZE CALLREQUEST ;bx = next item in table jmp INITCPPTOP

INITCPPENDTB: cmp dx, di ;did we exhaust the table? je INITCPPDONE ;yes, quit mov bx, dx ;bx = highest priority item cmp [bx].calltype, 0 ;is it near or far? mov [bx].calltype, 0FFH ;wipe the call type je INITCPPNEARCALL call DWORD PTR [bx].pproc ; near call to function pointer jmp INITCPPSTART

Side 98 af 134

Page 99: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

INITCPPNEARCALL:call WORD PTR [bx].pproc ; far call to function pointer jmp INITCPPSTART

INITCPPDONE: pop di pop si retInitializeCPP endp

DOSService PROC FAR ; emulate DOS system calls (int 21h) used by floating point emulator cmp ah,25h jne DOSSERVEND cmp al,5 jbe DOSSERVEND push bx ; DOS service 25h = set interrupt vector push cx push di push es mov di,_DATA mov cl,4 shl di,cl ; end of _INTERRUPT_VECTORS sub bx,bx mov es,bx mov bl,al shl bx,1 shl bx,1 ; address of desired interrupt vector cmp bx,di jnb _abort ; outside allocated interrupt vector space cli mov es:[bx], dx ; set interrupt vector mov es:[bx+2], ds sti pop es pop di pop cx pop bxDOSSERVEND:iretDOSService endp

; error exit: flash system LEDs_abort proc near__terminate label near ; synonyms for _abort procedure__exit label near_exit label nearPUBLIC _abort,__terminate,__exit,_exit mov al, 0FH mov dx, SYSLEDFLASHLOOP: out dx, al not al dec cx loop $ ; loop to same instruction jmp FLASHLOOP_abort endp

_TEXT ends

_DATA segment word public 'DATA'; define data needed by C++__MMODEL dw 1 ; memory model. 1 = near__psp label word_errno dw 0___brklvl dw DGROUP:end_of_data ; initialize to bottom of heap__version dw 3__RealCvtVector dw 0public __MMODEL,__psp,_errno,___brklvl,__version,__RealCvtVector

; data needed by StopTimer, StartTimer, ConfigurePortABC:_control_8155 db 0 ; control word for 8155 chip on min. system

_DATA ends

Side 99 af 134

Page 100: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Source kode til C++Her findes kildekoden til c++ delen af softwaren på cykelcomputeren.

Computer// define constants -----------------------------------------------------------const int PORTA = 0x8001;const int PORTB = 0x8002;const int PORTC = 0x8003;const int SYSLED = 0xA000;

// Constants patterns for port cconst char LED_RED = 0x4;const char LED_YELLOW = 0x8;const char LED_GREEN = 0x10;

// Definition of boolean valuesconst enum bool {false, true};

// Global variables -----------------------------------------------------------// Timingchar minutes = 0; // minutes since start of trainingchar seconds = 0; // Counts seconds since start of trainingint milliseconds = 0; // Holds millisecondsbool secondFlag = false;

// Values on input and output portschar portc = 0; // What is currently on port Cchar portb = 0; // Input from port B (keyboard & bike pulses)

// Program bank - Space reserved in data segment in assemblerextern char BANK; // The size is (20+20) * 9 == (progName+ProgGears) * numOfProgs

// Space for measurements ( 1 hour )extern char LOG;

// header files --------------------------------------------------------------#include <dos.h>#include <stdlib.h>#include <string.h>

#include "display.h" // display driver - Connected to port A#include "keyboard.h" // keyboard driver - Connected to 6 bits on port B#include "bike.h" // state of bike, incl. micro-UART and pulses from bike#include "session.h" // Training session - Holds info about session#include "comPort.h" // serial communications sub-system to pc

// Global objects -------------------------------------------------------------Display myDisplay( "" );Keyboard myKeyboard;Bike myBike;Session mySession;ComPort myPCcomm;

// What is being displayed during sessionconst enum disp { duration, puls, speed, distance, calories, gear };disp showing = duration;void showDisplay( void );

Side 100 af 134

Page 101: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

// main program ---------------------------------------------------------------extern "C" void main (void){

// State of bikecomputerconst enum state {reqProgram, reqLevel, reqWeight, reqTime,

cycleProgram, cycleManual, reqTransfer, transfer, clearSession };

// Initialize Computerstate bikeState = reqProgram;bool displayUpdate = true; // Entire display needs updatingbool numUpdate = true; // Numbers in display need updatingbool request = false; // Displaying requester?key keypress = nokey;

// Main loopwhile(1) {

// Read the keyboardkeypress = myKeyboard.getKeyPress();

// Entire menusystem is implementet here as a statemachineswitch (bikeState) {

case reqProgram ://

----------------------------------------------------------------// Update displayif (numUpdate || displayUpdate) {

// Just arrived in this state, then update text alsoif (displayUpdate) {

myDisplay.setText( "prog" );displayUpdate = false;

}

myDisplay.setText( mySession.getProgramSlot(), 7 );numUpdate = false;

}

// React on possible keypresses that are valid in this stateif (keypress == up) {

mySession.nextProgram();numUpdate = true;

}else if (keypress == down) {

mySession.prevProgram();numUpdate = true;

}else if (keypress == ok) {

// If program 0 (manual cycling) skip level and time request

if (mySession.getProgramSlot() == 0)bikeState = reqWeight;

elsebikeState = reqLevel;

displayUpdate = true;}break;

case reqLevel ://

----------------------------------------------------------------// Update displayif (numUpdate || displayUpdate) {

// Just arrived in this state, then update text also

Side 101 af 134

Page 102: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

if (displayUpdate) {myDisplay.setText( "gear" );displayUpdate = false;

}

// Position the number right allignedif (mySession.getLevel() > 99)

myDisplay.setText( mySession.getLevel(), 5 );else

myDisplay.setText( mySession.getLevel(), 6 );

numUpdate = false;numUpdate= false;

}

// React on possible keypresses that are valid in this stateif (keypress == up) {

mySession.setLevel( mySession.getLevel()+10 );numUpdate= true;

}else if (keypress == down) {

// If value becomes shorter entire display needs updating

if (mySession.getLevel() == 100)displayUpdate = true;

mySession.setLevel( mySession.getLevel()-10 );numUpdate= true;

}else if (keypress == ok) {

bikeState = reqWeight;displayUpdate = true;

}else if (keypress == cancel) {

bikeState = reqProgram;displayUpdate = true;

}break;

case reqWeight ://

----------------------------------------------------------------// Update displayif (numUpdate || displayUpdate) {

// Just arrived in this state, then update text alsoif (displayUpdate) {

myDisplay.setText( "uaegt" );displayUpdate = false;

}

// Position the number right allignedif (mySession.getWeight() > 99)

myDisplay.setText( mySession.getWeight(), 5 );

elsemyDisplay.setText( mySession.getWeight(),

6 );numUpdate = false;

}

// React on possible keypresses that are valid in this stateif (keypress == up) {

mySession.setWeight( mySession.getWeight()+1 );numUpdate = true; // this will cause the display to

update}else if (keypress == down) {

Side 102 af 134

Page 103: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

// If value becomes shorter entire display needs updating

if (mySession.getWeight() == 100)displayUpdate = true;

mySession.setWeight( mySession.getWeight()-1 );numUpdate = true; // this will cause the display to

update}else if (keypress == ok) {

if (mySession.getProgramSlot() == 0) {mySession.start();bikeState = cycleManual;

}else

bikeState = reqTime;

displayUpdate = true;}else if (keypress == cancel) {

if (mySession.getProgramSlot() == 0)bikeState = reqProgram;

elsebikeState = reqLevel;

displayUpdate = true;}break;

case reqTime ://

----------------------------------------------------------------// Update displayif (numUpdate || displayUpdate) {

// Just arrived in this state, then update text alsoif (displayUpdate) {

myDisplay.setText( "tid" );displayUpdate = false;

}

// Minutes as 1 or 2 digits?if (mySession.getDuration() > 99)

myDisplay.setText( mySession.getDuration(), 3 );

else if (mySession.getDuration() > 9)myDisplay.setText( mySession.getDuration(), 4

);else

myDisplay.setText( mySession.getDuration(), 5 );

// Add seconds for at better representation of a clock

myDisplay.addText( "00" );numUpdate = false;

}

// React on possible keypresses that are valid in this stateif (keypress == up) {

mySession.setDuration( mySession.getDuration()+1 );numUpdate = true; // this will cause the display to

update}else if (keypress == down) {

// If value becomes shorter entire display needs updating

if (mySession.getDuration() == 100 || mySession.getDuration() == 10)

displayUpdate = true;

Side 103 af 134

Page 104: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

mySession.setDuration( mySession.getDuration()-1 );numUpdate = true; // this will cause the display to

update}else if (keypress == ok) {

mySession.start();bikeState = cycleProgram;displayUpdate = true;

}else if (keypress == cancel) {

bikeState = reqWeight;displayUpdate = true;

}break;

case cycleProgram :// ******MANGLER ENDNU AT FÆRDIGGØRE******//

----------------------------------------------------------------// Update displayif (numUpdate || displayUpdate) {

showDisplay();displayUpdate = false;numUpdate = false;

}

// Add measurement and update display every secondif (secondFlag) {

mySession.addMeasurement( myBike.getRpm(), myBike.getPuls(), myBike.getGear()-1 );

// Update display only if no requester presentif (!request)

numUpdate = true;

secondFlag = false;}

// We are cycling so we need to update display every second. But only if no requester present

if (secondFlag) {numUpdate = true;secondFlag = false;

}

// React on possible keypresses that are valid in this stateif (keypress == up) {

showing = ++showing % 6;displayUpdate = true;

}else if (keypress == down) {

showing = --showing % 6;displayUpdate = true;

}else if (keypress == ok) {

// If asking user about reset then reset, else do nothing

if (request) {mySession.stop();bikeState = reqTransfer;

}}else if (keypress == cancel ) {

if (request) {request = false; // Canceled the request for

terminatondisplayUpdate = true; // Update the display

}else {

// Request termination

Side 104 af 134

Page 105: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

request = true;myDisplay.setText( "stop?" );

}}break;

case cycleManual ://

----------------------------------------------------------------// Update displayif (numUpdate || displayUpdate) {

showDisplay();displayUpdate = false;numUpdate = false;

}

// Add measurement and update display every secondif (secondFlag) {

mySession.addMeasurement( myBike.getRpm(), myBike.getPuls(), myBike.getGear()-1 );

// Update display only if no requester presentif (!request)

numUpdate = true;

secondFlag = false;}

// React on possible keypresses that are valid in this stateif (keypress == up) {

showing = ++showing % 6;displayUpdate = true;

}else if (keypress == down) {

if (showing == 0)showing = 5;

elseshowing--;

displayUpdate = true;}

// If asking user about reset then reset, else do nothingelse if (keypress == ok && request) {

mySession.stop();request = false;displayUpdate = true;bikeState = reqTransfer;

}else if (keypress == cancel ) {

if (request) {request = false; // Canceled the request for

terminatondisplayUpdate = true; // Update the display

}else {

// Request terminationrequest = true;myDisplay.setText( "stop?" );

}}else if (keypress == left) {

myBike.gearUp();numUpdate = true;

}else if (keypress == right) {

myBike.gearDown();}break;

case reqTransfer :

Side 105 af 134

Page 106: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

// ----------------------------------------------------------------

// Just arrived in this state, so update displayif (displayUpdate) {

myDisplay.setText( "send pc?" );displayUpdate = false;

}

// React on possible keypresses that are valid in this stateif (keypress == ok) {

bikeState = transfer;displayUpdate = true;

}else if (keypress == cancel) {

bikeState = clearSession;displayUpdate = true;

}break;

case transfer ://

----------------------------------------------------------------// Just arrived in this state, so update displayif (displayUpdate) {

myDisplay.setText( "sending" );displayUpdate = false;

}

// If request then just wait for answerif (myPCcomm.reqResend() && !request) {

myDisplay.setText( "resend?" );request = true;

}else if (!myPCcomm.isSending() && !request) {

myPCcomm.sendSession( &mySession );request = false;

}// Done sending?else if (!myPCcomm.isSending() && !myPCcomm.reqResend()) {

bikeState = clearSession;displayUpdate = true;request = false;

}

// React on possible keypresses that are valid in this state// Only if something has been requestedif (keypress == ok && request) {

myPCcomm.sendSession( &mySession );request = false;displayUpdate = true;

}if (keypress == cancel && request) {

bikeState = clearSession;request = false;displayUpdate = true;

}break;

case clearSession ://

----------------------------------------------------------------// Just arrived in this state, so update displayif (displayUpdate) {

myDisplay.setText( "reseting" );displayUpdate = false;

}

// Reset session at return to menumySession.reset();bikeState = reqProgram;displayUpdate = true;

Side 106 af 134

Page 107: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

// No keys are valid in this statebreak;

} // End of switch statement} // End main while loop

} // End of main function

// interrupt routine. This will be called every millisecondextern "C" void interrupt interrupt2 (void){

// Read port Bportb = ~inportb( PORTB ); // Invertet because switches are active low

// Skip avoidable code if session not startedif ( mySession.isStarted() ){

// Timingmilliseconds++;if (milliseconds == 1000) {

seconds++;secondFlag = true; // Flag indicating new secondmilliseconds = 0;

if (seconds == 60) {minutes++;seconds = 0;

}}

}

// The update methods are a kind of "task sharing". This allows objects to have a kind

// of multithreaded behavior. These threads are syncronized to 1ms interupt routine

myDisplay.update();myKeyboard.update();myBike.update();myPCcomm.update();

}

// interrupt routine for serial data from PC (RXRDY on UART)extern "C" void interrupt interrupt3 (void) {

myPCcomm.charReceived();}

/** Show display* This method displays the requested text on the display*/void showDisplay( void ) {

switch (showing){case duration :

myDisplay.setText( "tid " );if (minutes < 10)

myDisplay.addText( "0" );myDisplay.addText( (int) minutes );if (seconds < 10)

myDisplay.addText( "0" );myDisplay.addText( (int) seconds );break;

case puls :myDisplay.setText( "puls" );

Side 107 af 134

Page 108: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

int p = mySession.getPuls();if (p > 99)

myDisplay.addText( " " );else if (p > 9)

myDisplay.addText( " " );else

myDisplay.addText( " " );

myDisplay.addText( p );break;

case speed :myDisplay.setText( "spd" );int s = mySession.getSpeed();if (s > 99)

myDisplay.addText( " " );else if (s > 9)

myDisplay.addText( " " );else

myDisplay.addText( " " );

myDisplay.addText( s );break;

case distance :myDisplay.setText( "dist" );int d = mySession.getDistance()/100;if (d > 999)

;//myDisplay.addText( "" );else if (d > 99)

myDisplay.addText( " " );else if (d > 9)

myDisplay.addText( " " );else

myDisplay.addText( " " );

myDisplay.addText( d );break;

case calories :myDisplay.setText( "cal" );int c = mySession.getCalories();if (c > 99)

myDisplay.addText( " " );else if (c > 9)

myDisplay.addText( " " );else

myDisplay.addText( " " );

myDisplay.addText( c );break;

case gear :myDisplay.setText( "gear" );myDisplay.addText( " " );myDisplay.addText( myBike.getGear() );break;

}}

Side 108 af 134

Page 109: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Display/** class display* @author CG* @released 2004.11.18*/

#ifndef DISPLAY_H#define DISPLAY_H

#include <stdlib.h>#include <dos.h>

/** class Display* Class to handle the display for the bikecomputer. It just* displays what it's told to (if displayable), and keeps the* display lit with the interupt rutine, which calls the the* "listener" (update) method every ms.*/class Display {

protected:char text[10]; // Space for 8 digits and 2 dotschar curCharacter; // Current character to draw (interrupt

rutine)char strLength; // Length of the string to display

// Private methodschar getPos( char ); // Return position of coded characterchar inline encode( char ); // Encode according to specificationschar inline multiplex( char , char ); // Multiplex position to encoded

character

public:Display( char * );void update( void ); // to be called in interupt rutine

void setText( char * ); // Set new text in displayvoid setText( int );void setText( char *, int ); // Set text starting from a given posvoid setText( int, int );void addText( char * ); // Appends the current text on displayvoid addText( int );

}

/** Constructor of class Display* Initialize display* @param initial is a string with the initial value of the display*/Display::Display( char * initial ) { // constructor for display class

curCharacter = 0;strLength = 0;

// Clear entire stringfor (int i=0; i<10; i++ )

text[i] = multiplex( encode( ' ' ), i);

// set new textsetText( initial, 0 );

}

/** Returns position value of at multiplexed character*/char Display::getPos( char c ) {

c = c >> 5;

Side 109 af 134

Page 110: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

return (c & 7);}

/** Method encode( char tegn )* Returns the coded character, as it should be sent to* port A. If the display does not support the character,* a special "error" character is sent.* param tegn er pointer til tegnet, der skal kodes* @return coded character to be multiplexed with position*/char Display::encode( char tegn ) {

switch (tegn){case '0': return 0x00; // These characters are also coded in the CPLDcase '1': return 0x01; // Se tegnoversisgt for more infocase '2': return 0x02;case '3': return 0x03;case '4': return 0x04;case '5': return 0x05;case '6': return 0x06;case '7': return 0x07;case '8': return 0x08;case '9': return 0x09;case 'a': return 0x0A;case 'c': return 0x0B;case 'd': return 0x0C;case 'e': return 0x0D;case 'f': return 0x0E;case 'g': return 0x0F;case 'h': return 0x10;case 'i': return 0x11;case 'j': return 0x12;case 'l': return 0x13;case 'n': return 0x14;case 'o': return 0x15;case 'p': return 0x16;case 'r': return 0x17;case 's': return 0x18;case 't': return 0x19;case 'u': return 0x1A;case ' ': return 0x1B;case '.': return 0x1C;case '-': return 0x1D;case '?': return 0x1E;}return 0x1F; // Om tegnet ikke kan skrives

}

/** Method multiplex( char tegn, char pos )* Multiplexes a coded character with a position value.* @param tegn Coded character to be multiplexed* @param pos Position of the character on the display. Range 0 - 7* @return Character and position multiplexed according to documented specifications*/char Display::multiplex( char tegn, char pos ) {

pos &= 0x7; // max pos er jo 7, så set alle bits til 0 undtaget 3 LSBpos = pos << 5; // Shift bits til deres rigtige plads i det multiplexede tegnreturn (pos | tegn ); // Multiplex position og tegn sammen. Første 3 bit i tegn er

0'er om det er coded}

/** Method setDisplay( char * newText, int startAt )* Sets the text, that is to be displayed on the display starting at a given position* @param newText string, that should be displayed.

Side 110 af 134

Page 111: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

* @param startAt is the position of the first character. Previous chars will be untouched*/void Display::setText( char * newText, int startAt ) {

int displayOffset = 0; // Used if dots are in the text (dots are part of previous character on display)

int stringPos = 0; // Current pos in the internal string. add offset to get the char pos on display

// move forward in current text to the requested characterwhile (stringPos < strLength && startAt > getPos( text[stringPos] ) ) {

// handle dot-offsets if any are found in current text up to startAtif ( (text[stringPos] & 0x1F) == encode( '.' ) ) // remove pos value and

compare with dotdisplayOffset--;

stringPos++;}

// Not enough characters in current string so fill spaces out to startAtwhile (stringPos+displayOffset < startAt) {

text[stringPos] = multiplex( encode( ' ' ), stringPos+displayOffset );stringPos++;

}

// Loop through the new text adding characters to the display starting at requested position

while ( stringPos <= 10 && newText[stringPos+displayOffset-startAt] != NULL) {

// if dot then make positioning offsetif ( newText[stringPos+displayOffset-startAt] == '.' )

displayOffset--;

// Encode the character, multiplex with it's position value, and store it in text[]

text[stringPos] = multiplex( encode( newText[stringPos+displayOffset-startAt] ), (char) stringPos+displayOffset );

// Next characterstringPos++;strLength = stringPos;

}

// Finally register the length with new text addedstrLength = stringPos;

}

/** Overridede metoder til setText*/void Display::setText( int i ) { setText( i, 0 );}

void Display::setText( int i, int pos ) { char text[10];

ltoa( i, text, 10) ; setText( text, pos );}

void Display::setText( char * s ) {setText( s, 0 );

}

/** Append text to current text on the display*/void Display::addText( char * s ) {

setText( s, getPos( text[strLength-1] )+1 );}

Side 111 af 134

Page 112: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

/** Overrided to handle integers*/void Display::addText( int i ){

setText( i, getPos( text[strLength-1] )+1 );}

/** Method update( void )* Update the display with the current text. To be called every millisecond*/void Display::update( void ) {

// Output current character to displayif (curCharacter < strLength ){

outportb( PORTA, text[curCharacter++] );

} else if (curCharacter < 10) {

// Output empty character so that the display always maintains a constant brightness

outportb( PORTA, encode( ' ' ) );curCharacter++;

} else// At the end of the string, so reset current charactercurCharacter = 0;

}#endif

Side 112 af 134

Page 113: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Keyboard/** class Keyboard* @author u9* @released 2004.11.18*/

#ifndef KEYBOARD_H#define KEYBOARD_H

// define type keyenum key {nokey, up, down, ok, cancel, left, right};

// define constantsconst char KEY_UP = 0x80;const char KEY_DOWN = 0x40;const char KEY_OK = 0x20;const char KEY_CANCEL = 0x10;const char KEY_LEFT = 0x8;const char KEY_RIGHT = 0x4;

/** class keyboard* Hold the state of the keyboard. How long the user has held a key, which key and so on* The last pressed key will be the only one that will give a true on the getKeyPress()* method. Also, if user holds the key, the internal timer will allow for a short delay* before repeating the keypress.** @author u9* @released 2004.11.18*/class Keyboard {

protected:// Holder fysiske tilstand på tastaturet. Kun sidst trykkede tast// Bits fordeles således: xxHVFJNO -> (ubenyttet)(ubenyttet)(højre)

(venstre)(fortryd)(ja)(ned)(op)char keystate;

unsigned int delay; // Holds the time to wait before repeating the keypress event

unsigned int holdTime; // Time, current key has been pressed

public:Keyboard( void );

// Er der registreret et tryk på nogen tast? HUSK: Reset'et efter hvert kald

key getKeyPress( void );

// Interupt rutine. Skal kaldes hvert millisekundvoid update( void );

};

/** Constructor */Keyboard::Keyboard() {

keystate = 0; // no key presseddelay = 0;holdTime = 0;

}

/** Method getKeyPress()

Side 113 af 134

Page 114: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

* @return the key that is pressed if any. Important: ***Remember that it is reset after each read! ****/key Keyboard::getKeyPress() {

// Om delay er udløbet, så reset det, ellers returner nokeyif (delay || !keystate)

return nokey;else {

// Reset delaydelay = 300 / (holdTime/1000+1) + 50;

// Delay var nået til 0, så returner den registrerede tastswitch (keystate) {

case KEY_UP :return up;

case KEY_DOWN :return down;

case KEY_OK :return ok;

case KEY_CANCEL :return cancel;

case KEY_LEFT :return left;

case KEY_RIGHT :return right;

}

return nokey;}

}

/** Method update()* Update state of the keyboard. If new key pressed, or current key still holding, etc.* Also used for time synchronization. Should be called every millisecond*/void Keyboard::update() {

// Læs taster på port Bchar keyboard;keyboard = portb; // portb is the global variable read every millisecond in the

interupt rutine

// Check om samme tast er trykket ved af afmaske alt uden gamle værdiif ( keystate & keyboard ){

// Decrement delay om det ikke er nået til 0if (delay)

delay--;

// Increment holdTime, om den ikke er nået maximumif (holdTime < 10000)

holdTime++;

} else { // Muligvis ny tast

keystate = (keyboard & 0xFC); // afmask 2 sidste bits

// Kun én tast skal være registreret i keystate, så fjern resten om der er flere

if (keystate & KEY_UP)keystate = KEY_UP;

Side 114 af 134

Page 115: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

else if (keystate & KEY_DOWN)keystate = KEY_DOWN;

else if (keystate & KEY_OK)keystate = KEY_OK;

else if (keystate & KEY_CANCEL)keystate = KEY_CANCEL;

else if (keystate & KEY_LEFT)keystate = KEY_LEFT;

else if (keystate & KEY_RIGHT)keystate = KEY_RIGHT;

// Reset delay og delayFactordelay = 0;holdTime = 0;

}}#endif

Side 115 af 134

Page 116: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Bike/** class Bike* @author u9* @released 2004.12.01*/

#ifndef BIKE_H#define BIKE_H

// Constants patterns for port bconst char PULS_HEART = 0x1;const char PULS_PEDAL = 0x2;const char GEAR_UP = 0x1;const char GEAR_DOWN = 0x2;

/** class Bike* Class to handle and maintain bike. It's inputs and outputs*/class Bike {

private:

// Data (to bike)int gearDelay; // Delay in millisecondsbool lineFlag; // Is a gear line high?char curGear; // Gear on the bike is mirrored on minSys

// Data (from bike)char heartBeats; // Hartbeats since last measurementbool heartLineHigh;char pedalBeats; // Pedal rotations since last measurementbool pedalLineHigh;

public:Bike( void );void gearUp( void ); // Tell bike to gear up 1 gearvoid gearDown( void ); // Tell bike to gear down 1 gearvoid update( void ); // Method to be called every millisecond for

synchronization

int getPuls( void ); // Reset after each call - should be called in interrupt rutine

int getRpm( void ); // Reset after each call - should be called in interrupt rutine

int getGear( void );

void reset( void ); // Reset entire bike - also restores physicle bike to gear 3}

/** Constructor*/Bike::Bike( void ) {

gearDelay = 0;lineFlag = false;curGear = 3;outportb( PORTC, portc = 0 );

reset();}

/** Tell bike to gear up

Side 116 af 134

Page 117: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

*/void Bike::gearUp( void ) {

// Check if enough time has passed since last gear changeif ( !gearDelay && curGear < 8 ) {

outportb( PORTC, portc |= GEAR_UP );gearDelay = 10; // 10ms delay before line can go lowlineFlag = true; // Represent line statecurGear++; // Represents bikes current gear

}}

/** Tell bike to gear down*/void Bike::gearDown( void ) {

if ( !gearDelay && curGear > 1) {outportb( PORTC, portc |= GEAR_DOWN );gearDelay = 10;lineFlag = true;curGear--;

}}

/** Returns number of pulses since last call and resets itself*/int Bike::getPuls( void ) {

char tmp = heartBeats;heartBeats = 0;return ((int) tmp & 0xFF); // Bitwise AND for at undgå negering af resultat

}

/** Returns number of pedal rotations since last call and resets itself*/int Bike::getRpm( void ) {

char tmp = pedalBeats;pedalBeats = 0;return ((int) tmp & 0xFF); // Bitwise AND for at undgå negering af resultat

}

/** Returns current gear on the bike*/int Bike::getGear( void ) {

return (int) curGear;}

/** Synchronization to 1ms* Allows object to keep track of time, such as time passed since last gearchange* NOTE: the variable portb is set in the 1ms interrupt to the value of port B*/void Bike::update( void ) {

// Regarding gears on bike -----------------------------if (gearDelay)

gearDelay--; // Decrement delay, if any

// if no delay but a line high, then clear the line and set delay to 500ms to allow bike to react

else if (lineFlag) {outportb( PORTC, portc &= ~GEAR_DOWN & ~GEAR_UP ); // clear gear-change

bits on port ClineFlag = false;

Side 117 af 134

Page 118: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

gearDelay = 500; // CPLD only needs 40ms to send command}

// Regarding pulses from bike --------------------------if (portb & PULS_HEART) {

heartLineHigh = true;outportb( PORTC, portc |= LED_RED ); // Show puls on red led

}

else if (heartLineHigh) {heartLineHigh = false; // Register falling flank of signalheartBeats++;

}

if (portb & PULS_PEDAL)pedalLineHigh = true;

else if (pedalLineHigh) {pedalLineHigh = false; // Register falling flank of signalpedalBeats++;outportb( PORTC, portc &= ~LED_RED ); // Show puls on red led

}}

/** Reset bike variables, and restore bike to 3rd gear*/void Bike::reset( void ) {

heartBeats = 0;heartLineHigh = false;pedalBeats = 0;pedalLineHigh = false;

// Reset gear on bikeif (curGear > 3){

// Gear down until in thirdwhile (curGear != 3) {

curGear--;gearDown();

// Small delay for bike to reactint i = 0;while (++i < 0xFFF) {};

}} else {

// Gear up until in thirdwhile (curGear != 3){

curGear++;gearUp();

// Small delay for bike to reactint i = 0;while (++i < 0xFFF) {};

}}

}

#endif

Side 118 af 134

Page 119: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

ComPort/** class ComPort* @author u9* @released 2004.12.01*/

#ifndef COMPORT_H#define COMPORT_H

// header files --------------------------------------------------------------#include "serial.h" // serialport class for basic communication to pc#include <stdlib.h>#include <string.h>

const char BUFFERSIZE = 42;

/** class ComPort* Class to handle and maintain communicationssubsystem.*/class ComPort {

protected:// State of the communications subsystemenum state { idle, sendStatistik, waitACK, resend, sendSlotList,

receiveProgram, sendACK };enum transmissionState { done, slotID, progName, statHead, measurements };

// membersint timer; // internal timer variable to implement

timeoutsstate serialState; // Serial internal state. See documentation for

state diagramSerial *serialPort; // Serial object

char buffer[BUFFERSIZE]; // For data (programSize = name + chr(13) + gears + char(255))

int bufferPointer; // Point to next character in buffer

char * sendPointer; // Pointer to memorylocationchar sendProgNum; // Used under transmission of programslotlist

to indicate current slottransmissionState sendState; // State for transmissionchar * startMeasurement; // Pointer to next measurement to sendint measurementLength; // Number of measurements to send

public:ComPort( void );

// Methodsvoid sendSession( Session * ); // Send statistik

// Check and alter state of subsystembool isSending( void );bool reqResend( void );void setIdle( void );void resend( void;

// Interrupt methodsvoid update( void ); // Method for timer interruptvoid charReceived( void ); // CPU interrupted by a character on the UART

};

Side 119 af 134

Page 120: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

/** Constructor*/ComPort::ComPort( void ) {

// Serial objectserialPort = new Serial();

// set memberstimer = 0;serialState = idle;

bufferPointer = 0;

sendPointer = 0;sendProgNum = 0;sendState = done;startMeasurement = NULL;

}

/** Set subsystem up to send a set of statistics. Stores name, weight and program* level in the buffer, and sets state of system to start sending*/void ComPort::sendSession( Session * s ) {

// Wait for subsystem to be available and set values. System might currently be receiving

while( serialState != idle ) {};serialState = sendStatistik;bufferPointer = 0;startMeasurement = s->getFirst();measurementLength = s->getLength();

// if manual cycling, then just write that to the buffer else get program name from bank

if (s->getProgramSlot() == 0) {char tmpName[] = "manuel";strcpy( buffer, tmpName );bufferPointer = strlen( tmpName );

}else {

sendPointer = (&BANK) + (( s->getProgramSlot() - 1) * 40); // Address of program

// Store program name in bufferwhile ( *sendPointer != NULL)

buffer[bufferPointer++] = *sendPointer++;

}buffer[bufferPointer++] = (char) 13; // Store end of name according to

specifications

// Get weight and add to buffer char w[10];

ltoa( s->getWeight(), w, 10 );for (int i=0; i<strlen(w); i++ )

buffer[bufferPointer++] = w[i];buffer[bufferPointer++] = (char) 13; // Store end of weight according to

specifications

// Add level to bufferchar n[10];ltoa( s->getLevel(), n, 10 );for (i=0; i<strlen(n); i++ )

buffer[bufferPointer++] = n[i];buffer[bufferPointer++] = (char) 13; // Store end of level according to

specifications

// Terminate the string

Side 120 af 134

Page 121: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

buffer[bufferPointer++] = NULL;

// Start sending string followed by measurements. This will be handeled by the interrupt

bufferPointer = 0;timer = 5000; // 5 seconds before timeout. 1 hour training session takes about 3

secs to transmit leaving 1 secs for ACKsendState = statHead;

}

/** Returns true if system is sending statistik*/bool ComPort::isSending( void ) {

return serialState == sendStatistik;}

/** Returns true if system is currently waiting for a resend command*/bool ComPort::reqResend( void ) {

return serialState == resend;}

/** Cancel transmission of failed statistik and return to idle state*/void ComPort::setIdle( void ) {

// MANGLER...}

/** Resend failed statistik*/void ComPort::resend( void ) {

// MANGLER...}

/** interrupt routine. Should be called every millisecond. Controlles the transmission* of data and synchronization of timer*/void ComPort::update( void ) {

// Count down the delay if setif (timer)

timer--;

// Switch according to state of serial subsystem and send a character if needed// Cases for timeout rutine are also included here so that subsystem can timeout

if need beswitch (serialState){case sendStatistik :

// Noting happens here unless UART is ready to sendif (serialPort->readyToSend()) {

switch (sendState){// Send head of statisticscase statHead :

if ( buffer[bufferPointer] != NULL )serialPort->send( buffer[bufferPointer++] );

Side 121 af 134

Page 122: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

// else done sending statistics head - start sending measurements

else {bufferPointer = 0;sendState = measurements;

}break;

case measurements :if (bufferPointer < measurementLength)

serialPort->send( *(startMeasurement+bufferPointer++) );

// else no measurement left to send so sent transmission termination and wait for ACK

else {serialPort->send( (char) 255 );sendState = done;serialState = waitACK;

}break;

}}break;

case waitACK :if (timer == 0) {

serialState = resend;sendState = done;

}break;

case resend :break;

case sendSlotList :

// Noting happens here unless UART is ready to sendif (serialPort->readyToSend()) {

switch (sendState){case done :

// If no more programslots to send info on, reset values and send termination character

if (sendProgNum == 9) {sendProgNum = 0;serialPort->send( (char) 255 );serialState = idle;

} else {sendProgNum++;

// ((sendProgNum-1) * 40) holds offset to current program name

sendPointer = (&BANK) + ((sendProgNum-1) * 40);}

// Start sending if name found at current programslotif ( *sendPointer != NULL )

sendState = slotID;break;

case slotID :serialPort->send( sendProgNum + 48 ); // Send current slot

ID as ascii charactersendState = progName;break;

case progName :// Send program name until NULL, then send char(13) and

return to done (next program slot)

Side 122 af 134

Page 123: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

if (*sendPointer != NULL)serialPort->send( *sendPointer++ ); // send

character and increment pointerelse {

serialPort->send( 13 );sendState = done;

}

}

} // End for UART readyToSend testbreak;

case receiveProgram :if (timer == 0) {

serialState = idle;sendState = done;

}break;

case sendACK :serialPort->send( 6 );serialState = idle;break;

}}

/** Interrupt routine for the INTR3 vector. Handles the received character* according to the definition of the state diagram for the communications system*/void ComPort::charReceived( void ) {

char received;received = serialPort->getData();outportb( PORTC, portc ^= LED_YELLOW );

// Switch according to state of serial subsystem.// Here, states are only valid that await characters on UART - other states in

update() methodswitch (serialState){case idle :

// In idle, so reset bufferbufferPointer = 0;

// ProgramSlotList requested then switch to that stateif (received == '!')

serialState = sendSlotList;

else if (received >= 0x31 && received <= 0x39) {// If program name being sent then register in buffer // char 255 we use for terminationbuffer[bufferPointer++] = received;serialState = receiveProgram;timer = 1500;

}

// else not a valid character sent, so ignore itbreak;

case waitACK :

// ACK character received so return to idleif (received == 6)

serialState = idle;

break;

case receiveProgram :

Side 123 af 134

Page 124: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

// Store character from PCbuffer[bufferPointer++] = received;

// 255 is termination character of transmissionif (received == (char) 0xFF) {

outportb( PORTC, portc ^= LED_GREEN );

// Error control - the shortest named program is 24 characters including termination

if (bufferPointer < 24)serialState = idle;

// End of program received, so store programelse {

bufferPointer = 0;

// slot holds the address of the requested slot. The *40 is because each slot is 40 bytes in size

char * slot = (&BANK) + ((buffer[bufferPointer] -49) * 40);

// Store name in bankwhile (buffer[++bufferPointer] != (char) 13)

*(slot + bufferPointer - 1) = buffer[bufferPointer];

// Terminate program name with a NULL*(slot + bufferPointer - 1) = NULL;

// Get address of gears for requested slot (has offset of 20 from start of slot)

// The current bufferPointer is also deducted to synchronize buffer and slot

slot += (20 - bufferPointer);

// Store gearsfor (int i=0; i<20; i++ ) {

bufferPointer++;*(slot + bufferPointer - 1) =

buffer[bufferPointer];}

// Done so send ACKserialState = sendACK;

} // endif of error control

} // endif termination character

// Too much garbage on UART - ignore by returning to idle without sending ACK

if (bufferPointer == BUFFERSIZE-1)serialState = idle;

break;

}}

#endif

Side 124 af 134

Page 125: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Seriel// Serial communication for 8088 minimum system

/** class Serial* Define methodes and attributes of the classes, and maintain status of RS232 UART* @released 2004.11.19 / u9*/

#ifndef SERIAL_H#define SERIAL_H

#include <dos.h>#include <stdlib.h>#include <string.h>

// Constants patterns for UARTconst int DATAPORT = 0x9000;const int STATUSPORT = 0x9001;const int TRANS_READY_FLAG = 1;const int REC_READY_FLAG = 2;

/** class Serial* RS232 class to handle serial input and output*/class Serial {

public:Serial( void );

// Input methodschar getData( void ); // read one character, return valuebool isDataReceived( void ); // show if data is received on the port

// Output methodsbool readyToSend( void ); // show if port is ready for sendingvoid send( char ); // Send one charactervoid writePc( char ); // Send one charactervoid writePc( char * ); // Send stringvoid writePc( int ); // Send integer

};

/** Constructor of class Serial* Initialize serial interface to 19200 baud, 8N1* Initialize all variables*/Serial::Serial( void ) {

// Setup of the UART on MinSysstatic char initstring[6] = {0,0,0,0x40,0x4E,0x37}; // initialization commandsfor (int i=0; i<6; i++) {

outportb(STATUSPORT, initstring[i]); // output commandfor (int j=0; j<3; j++) {}; // short pause

}inportb (DATAPORT); // clear input

}

/** Method isDataReceived()* Return the status of the port* @return true if character is received on the port*/bool Serial::isDataReceived( void ) { return (inportb(STATUSPORT) & REC_READY_FLAG) != 0;}

Side 125 af 134

Page 126: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

/** Method getData()* Get character from the inputport* @return The character received*/char Serial::getData( void ) {// for (int j=0; j < 4; j++) {} // short pause

return (char) inportb(DATAPORT); // get data}

/** Method readyToSend()* Return the status of the port* @return true if the output port is ready, else false*/bool Serial::readyToSend() {

return (inportb(STATUSPORT) & TRANS_READY_FLAG) != 0;}

/** Method send(char c)* Sends one character to the output port when ready.* @param c The character to send*/void Serial::send(char c) { outportb(DATAPORT,c);}

/** output text string to Pc* If a newline character (\n) is found without a preceeding* return character (\r), a \r is inserted before the \n* Example: char txt[ ] = "Hey\n";* obj.writePc(txt); // write the line to Pc,* // translate \n to \r\n* @param s the pointer to the text string to output*/void Serial::writePc(char * s) {

int len = strlen(s); // get the length of the string

for (int i=0; i<len; i++) {if (s[i] == '\n' && (i==0 || s[i-1] != '\r')) send('\r'); // translate \n

to \r\n

while(!readyToSend()) {}; // wait until port readysend(s[i]); // write one character at the time until empty

}}

/** output integer to Pc* The integer is converted to ascii and saved in* a text string before output to the Pc* @param i the i integer*/void Serial::writePc( int i ) { char text[32]; ltoa( i, text, 10) ; writePc( text );}

void Serial::writePc( char c ) {while( !readyToSend() ) {};send( c );

}

#endif

Side 126 af 134

Page 127: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

QUE#ifndef QUE_H#define QUE_H

/** class que* @author KP* @released 2004.11.20*/class Que {

protected:char que[20]; // Space reserved for a max of 20 elementsint nextElement; // Pointer to next element in queint queSize; // Size of que

public:Que( int );int getSum( void ); // Sum of all values in the quevoid push( char ); // Add element to que, and loose the oldest if que

fullvoid reset( void ); // Clear all elements in que

};

/** Constructor of class Que* Initialize que and reset all variables*/Que::Que( int size ) {

queSize = size;reset();

}

/** Method getAverage()* Returns the average of all elements... or just 0 if no elements in que* @return sum of elements in que*/int Que::getSum( void ) {

int sum = 0;

// Count value of all elementsfor ( int i=1; i <= queSize; i++ ){

if ( que[(i+nextElement) % queSize] != (char) 0xFF ) {sum += (unsigned int) que[(i+nextElement) % queSize];

}}return sum;

}

/** Method push( char element )* @param element The element to be added to the que. Note oldest element will be lost :)*/void Que::push( char element ) {

que[nextElement] = element;nextElement++;nextElement %= queSize;

}

/** Method reset( void )* Clear all elements in the que*/void Que::reset( void ) {

int i = -1;while (++i < queSize)

que[i] = (char) 0xFF; // Clear all elements in que

nextElement = 0;}

#endif

Side 127 af 134

Page 128: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Measurment/** class measurement* @author Sólja í Dali* @release 2004.11.01*/

// header files#include <dos.h>#include <stdlib.h>

#ifndef MEASUREM_H#define MEASUREM_H

// ----------------------------------------------------class Measurement{

private:char measurement; // Målingernes opbygning kan læses i specifikationen for

statistikkenMeasurement *next; // Pointer til forige måling

public:// ConstructorMeasurement( char, Measurement * );

// Destructor~Measurement( void );

// MetoderMeasurement *getNext( void );void setNext( Measurement * );char getMeasurement( void ); // Returnerer målingsværdier som character

int getRpm( void );int getPuls( void );int getGear( void );void setRpm( int );void setPuls( int );void setGear( int );

}

/* c = målingen som character *n = pointer til forrige måling */Measurement::Measurement( char c, Measurement *previous ) {

measurement = c;next = NULL;

if (previous != NULL)previous->setNext( this );

}

Measurement::~Measurement( void ) {

// Delete next measurement in listif (next != 0)

delete next;}

Measurement * Measurement::getNext( void ) {return next;

}

void Measurement::setNext( Measurement * n ) {next = n;

}

Side 128 af 134

Page 129: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

char Measurement::getMeasurement( void ) {return measurement;

}

int Measurement::getRpm( void ) {return (int) ((measurement >> 6) & 0x03); // flyt 6 til højre og afmask med

00000111}

int Measurement::getPuls( void ) {return (int) ((measurement >> 3) & 0x07); // flyt 3 til højre og afmask med

00000111}

int Measurement::getGear( void ) {return (int) (0x07 & measurement); // 00000111 afmaskning

}

void Measurement::setRpm(int rpm) {measurement &= 0x3F; // Fjern "gamle" bits

rpm = rpm << 6; // flyt bits til rigtige positionrpm &= 0xC0; // Afmask uønskede bitsmeasurement |= rpm; // Tilføj "nye" bits

}

void Measurement::setPuls(int puls) {measurement &=0xC7; // Fjern gamel værdi ved at ANDe dem ud

puls = puls << 3; // Flyt LSBs på ønskede positionpuls &= 0x38; // Afmask uønskede bitsmeasurement |= puls; // tilføj værdier

}

void Measurement::setGear(int gear) {measurement &=0xF8; // Fjern gamle værdi

gear &= 0x3; // Afmask uønskede bitsmeasurement |= gear; // tilføj værdier

}

#endif

Side 129 af 134

Page 130: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

Session/** class Session* @author u9* @released 2004.12.12*/

#ifndef SESSION_H#define SESSION_H#include "que.h"

/** class Session* Class to handle and maintain the trainingsession. It also handles* logging of statistics received every second*/class Session{

private:char program; // Program to execute when session startschar weight; // Weight of userchar level; // Level of trainingsessionchar duration; // Duration of trainingsession in minutesbool started;unsigned int totalCal; // Total calories burned this sessionunsigned int totalDist; // Total distance traveled this sessionint numMeasurements; // How many measurements logged this sessionQue *heartBeat; // Average of current heartrate (for displaying to

user)Que *speed; // Average speed (for displaying to user)

public:Session( void );

// Session parameter. Set and getvoid prevProgram( void );void nextProgram( void );int getProgramSlot( void );void setWeight( int );int getWeight( void );void setLevel( int );int getLevel( void );void setDuration( int );int getDuration( void );

// Clear all parameters and return to default valuesvoid reset( void );

// Session activityvoid start( void );void stop( void );bool isStarted( void );void addMeasurement( int, int, int ); // Add a measurement ( rpm, puls,

gear )char * getFirst( void ); // Returns pointer to latest measurementint getLength( void ); // Returns number of measurements

unsigned int getDistance( void ); // Get total distance traveledunsigned int getCalories( void ); // Get total calories burnedunsigned int getPuls( void ); // Get puls (for displaying on display)unsigned int getSpeed( void ); // Get speed (for displaying on display)

};

/** Constructor*/Session::Session() {

Side 130 af 134

Page 131: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

// Create ques for puls and speed. They will be used to// give an average speed over a larger period of time then// the second, that measurements are takenheartBeat = new Que(10);speed = new Que(3);

reset(); // Initialize session}

/** Clear all values and set to default*/void Session::reset( void ) {

program = 0;weight = 75;level = 100;totalCal = 0;totalDist = 0;duration = 10;started = false;numMeasurements = 0;

// Reset global timingvariablesminutes = 0;seconds = 0;milliseconds = 0;secondFlag = false;

// Initialize queheartBeat->reset();speed->reset();

}

/** Set to previous program in bank. Program 0 is manual cycling*/void Session::prevProgram( void ) {

if (program == 0)return;

char * pointer;

// Find previous program in program BANKdo {

pointer = (&BANK) + (--program-1) * 40;

// Program name found so just return as member already setif ( *pointer != NULL )

return;

} while ( program > 0 );

return; // No program found - 0 used (manual)}

/* Set to next program in bank (if any found)*/void Session::nextProgram( void ) {

char * pointer;

// Find next programfor (int i=program; i<8 ;i++ ) {

pointer = (&BANK) + i * 40;

Side 131 af 134

Page 132: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

// Found one so set member and returnif ( *pointer != NULL ) {

program = i+1;return;

}}

return; // Done looping and we didn't find a program, so just return with no change to member}

/** return number of current program*/int Session::getProgramSlot( void ) {

return ((int) program) & 0xFF;}

void Session::setWeight( int w ) {if (w < 40)

w = 40;

if (w > 250)w = 250;

weight = (char) w;}

int Session::getWeight( void ) {return ((int) weight) & 0xFF;

}

void Session::setLevel( int L ) {L = (L + 5) / 10 * 10; // round to nearest 10

if (L < 10)L = 10;

if (L > 200)L = 200;

level = (char) L;}

int Session::getLevel( void ) {return ((int) level) & 0xFF;

}

void Session::setDuration( int d ) {if (d < 5)

d = 5;

if (d > 99)d = 99;

duration = (char) d;}

int Session::getDuration( void ) {return ((int) duration) & 0xFF;

}

void Session::start( void ) {started = true;

}

void Session::stop( void ) {

Side 132 af 134

Page 133: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

started = false;}

bool Session::isStarted( void ) {return started;

}

/** Add measurement to session. Measurements should be added every second.* Accumulated values are also updated, along with the puls and speed*/void Session::addMeasurement( int rpm, int puls, int gear ) {

// Calculate new calories and distanceint deltaDist = rpm * (3+gear);totalDist += deltaDist;int energy = (3+(2 * deltaDist)) * deltaDist;totalCal += energy / 4200;

// Keep average puls and speedheartBeat->push( puls );speed->push( deltaDist );

// Store measurement in memorychar m = 0;char * pointer = &LOG;

rpm = rpm << 6; // flyt bits til rigtige positionrpm &= 0xC0; // Afmask uønskede bitsm |= rpm; // Tilføj bits

puls = puls << 3; // Flyt LSBs på ønskede positionpuls &= 0x38; // Afmask uønskede bitsm |= puls; // tilføj værdier

gear &= 0x7; // Afmask uønskede bitsm |= gear; // tilføj værdier

// Store value*(pointer+numMeasurements++) = m;

}

/** Returns number of measurements currently logged*/int Session::getLength( void ) {

return numMeasurements;}

/** Returns a pointer to the first measurement*/char * Session::getFirst( void ) {

return &LOG;}

/** Returns accumulated distance traveled for this session*/unsigned int Session::getDistance( void ) {

return totalCal;}

/** Returns accumulated calories burned for this session*/unsigned int Session::getCalories( void ) {

Side 133 af 134

Page 134: swn.nuswn.nu/cg/projekter/cykel/doc/EOOD2A_rapport.doc  · Web viewIndholdsfortegnelse. Indledning 5. Problemformulering 5. Begrænsninger 6. Pc-program 7. Kravspecification for

Superbike December 2004

return totalDist;}

/** Returns a more stable average puls (measured over a period of 10 seconds)*/unsigned int Session::getPuls( void ) {

return heartBeat->getSum() * 6;}

/** Returns a more stable speed measurement (averaged over 3 seconds)*/unsigned int Session::getSpeed( void ) {

return speed->getSum() * 3600 / 3;}

#endif

Side 134 af 134