Dessa komponenter plus några motstånd, klockkrets, kondensatorer och annat smått och gott har åstadkommit ett fungerande POV-hjul.



Relevanta dokument
Microprocessor / Microcontroller. Industrial Electrical Engineering and Automation

Tentamen på kursen DA7351, Programmering , kl Malmö högskola Teknik och samhälle. DA7351, Programmering

Microprocessor / Microcontroller

Föreläsning 1 & 2 INTRODUKTION

Tentamen OOP

OOP Objekt-orienterad programmering

Programmering med Java. Grunderna. Programspråket Java. Programmering med Java. Källkodsexempel. Java API-exempel In- och utmatning.

Kungliga Tekniska Högskolan Ämneskod 2D4134 Nada Tentamensdag maj - 19 Tentamen i Objektorientering och Java Skrivtid 5 h

"if"-satsen. Inledande programmering med C# (1DV402)

Vem är vem på kursen. Objektorienterad programvaruutveckling GU (DIT011) Kursbok Cay Horstmann: Big Java 3rd edition.

Tänk på följande: Det finns en referensbok (Java) hos tentavakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Tentamen i Objektorienterad programmering

Övningar Dag 2 En första klass

SMD 134 Objektorienterad programmering

Tentamen för kursen Objektorienterad programvaruutveckling GU (DIT010)

Programmering A C# VT Ett kompendie över Programmering A (50p) i c# Stefan Fredriksson

Att använda pekare i. C-kod

Examination i. PROGRAMMERINGSTEKNIK F1/TM1 TIN212 (Dugga) Dag: Onsdag Datum: Tid: (OBS 3 tim) Rum: V

Realtidsprogrammering. En introduktion Implementering (med exempel från PIC)

#include <pic.h> #include <sys.h> char LEFT,RIGHT,MOTORHASTIGHET;

Tentamen, EDAA20/EDA501 Programmering

Tentamen DE12, IMIT12, SYST12, ITEK11 (även öppen för övriga)

Lösningsförslag, tentamen FYTA11 Javaprogrammering

DUGGA: Objektorienterade applikationer. Läs detta! Uppgifterna är inte avsiktligt ordnade efter svårighetsgrad.

Dagens program. Programmeringsteknik och Matlab. Vad är arv? Vi ärver från GregorianCalendar. Kan vi bygga vidare på existerande klasser?

Effektpedal för elgitarr

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering

F4. programmeringsteknik och Matlab

trafiksimulering Intro OU5 trafiksimulering

Lite om reella tal. Programmering. I java. Om operatorers associativitet och prioritet

Kungliga Tekniska Högskolan Ämneskod 2D4134 Nada Tentamensdag aug - 23 Tentamen i Objektorientering och Java Skrivtid 5 h

Växtviskaren EITF11 Digitala projekt VT15, I12

Omdirigering. Omdirigering

Föreläsning 3-4 Innehåll

Algoritmanalys. Genomsnittligen behövs n/2 jämförelser vilket är proportionellt mot n, vi säger att vi har en O(n) algoritm.

Dagens föreläsning. Repetition. Repetition - Programmering i C. Repetition - Vad C består av. Repetition Ett första C-program

Grundläggande programmering med C# 7,5 högskolepoäng

Objektorienterad programmering i Java

Översikt. Installation av EasyPHP 1. Ladda ner från Jag använder Release Installera EasyPHP.

String [] argv. Dagens Agenda. Mer om arrayer. Mer om arrayer forts. String [] argv. argv är variabelnamnet. Arrayer och Strängar fortsättning

PROGRAMMERING A VC# 2008 EXPRESS UTVECKLINGSVERKTYGET VISUAL C#

Påminnelse: en datatyp för bilder. Programmering. En datatyp för bilder. Spegelbild. hh.se/db2004

Hej Då, Karel! Programmering. Vårt första Javaprogram. hh.se/db2004. Java. Grundtyper, variabler och arrayer

//Använd main som ett "handtag" för att hålla ihop programmet. //Själva programmet finns i övriga klasser.

Thunder s Truck projektrapport

ITK:P1 Föreläsning 1. Programmering. Programmeringsspråket Java. Stark typning Explicit typning Strukturerat Hög säkerhet

Föreläsning 6: Introduktion av listor

Föreläsning 3-4 Innehåll. Diskutera. Metod. Programexempel med metod

Editering, Kompilering och Exekvering av Javaprogram

Programmering A. Johan Eliasson

Digitala Projekt (EITF11)

Grundkurs i programmering, 6 hp (725G61) Dugga 2 tillfälle 2

Objektorienterad programmering D2

F2 Datatyper och variabler. ID1004 Objektorienterad programmering Fredrik Kilander

Det finns en referensbok (Java) hos tentavakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Patrik Calén

NXT LEGO-robot laboration Programmering och felsökning av en LEGOrobot

DELPROV 1 I DATAVETENSKAP

Översikt 732G11 PROGRAMMERING 1. Personal. Kursens mål. Litteratur. Kursens innehåll

PIC-programmeringsuppgift (PROA)

Klassdeklaration. Metoddeklaration. Parameteröverföring

Mer källkod. Styrstrukturer Val Slingor Operatorer Källkodsexempel med minne. Erik Forslin. Rum 1445, plan 4 på Nada

INGENJÖRSHÖGSKOLAN INGENJÖRSHÖGSKOLAN

Larmcentral. Digitala Projekt. Cecilia Olsson & Erika Björck Handledare: Bertil Lindvall LUNDS TEKNISKA HÖGSKOLA

Att skriva till och läsa från terminalfönstret

Introduktion till PHP

Tentamen. Lösningsförslag

Lite om felhantering och Exceptions Mer om variabler och parametrar Fält (eng array) och klassen ArrayList.

Institutionen för TENTAMEN CTH HT-15 Datavetenskap TDA540. Tentamen för TDA540 Objektorienterad programmering

4 13 / %.; 8 </" '': " / //&' " " ' * TelefonKostnad +,-%&. #!" $% " &' . > / ' 5 /' * 13/ &' static Math 1+" &'/ % 12 "" static "' * 1 /") %& &

Redovisning av inlämningsuppgifter

TENTAMEN PROGRAMMERINGSMETODIK MOMENT 2 - JAVA, 4P

Introduktion till Datalogi DD1339. Föreläsning 3 29 sept 2014

public och private Obs: private inte skyddar mot access från andra objekt i samma klass.

Programmering av stegmotorer ett miniprojekt i samarbete med Svensk Maskinprovning

Tentamen, EDA501 Programmering M L TM W K V

Tentamen , Introduktion till Java, dtaa98, dtea53

Input. Programmering. Andra källor

Härliga hörselskydden Hilma

Föreläsning 3: Booleans, if, switch

OOP Omtenta

Grunderna i stegkodsprogrammering

Manual för WMR- 252 inbyggnadsmottagare med universaldimmer

Dagens föreläsning. Repetition. Repetition - Programmering i C. Repetition - Vad C består av. Repetition Ett första C-program

Felsökning av mjukvara

Tentamen. Grundläggande programmering i Java A 5p, DTAA

Programmeringsteknik med C och Matlab

Laboration 10 - NetBeans

Provmoment: Ladokkod: Tentamen ges för: Tentamen TE111B El3. Namn: Personnummer: Tentamensdatum: Tid: 14:00-18:00.

Tentamen i. för D1 m fl, även distanskursen. fredag 13 januari 2012

LEGO Robot programmering och felsökning Hur svårt ska det vara att följa den svarta linjen?

Föreläsning 2, vecka 8: Repetition

Skizz till en enkel databas

Tentamen. 2D4135 vt 2005 Objektorienterad programmering, design och analys med Java Lördagen den 28 maj 2005 kl

Lektion 1 - Programmeringsteknik F1, ht 2003

Lite mer om Javas stöd för fält. Programmering. Exempel: vad är det största talet? hh.se/db2004. Fält samt Input/Output

Chapter 3: Using Classes and Objects

Systemkonstruktion SERIEKOMMUNIKATION

Övning 7. Timer, serieport

2. Komma igång Skapa grupper och elever Skriv också ut sidan 13 så att eleverna har en snabbguide till programmet.

Transkript:

Om POV, persistence of vision. POV eller persistence of vision är ett fenomen som uppstår på näthinnan i ögat där en efterbild ser ut att finnas kvar i ungefär en tjugofemtedels sekund efter att den flyttat sig eller försvunnit. Detta fenomen kan man utnyttja genom att låta en rad med radiellt monterade lysdioder rotera på ett hjul och om hjulet roterar tillräckligt fort kan man skapa en bild eller text genom att tända och släcka dioderna vid vissa vinklar. Vi ville undersöka möjligheterna för att montera en sådan anordning på ett cykelhjul och således få ut en bild eller text på sidan av hjulet. För detta proof of concept -arbetet valde vi en uppsättning med 8 ljusdioder monterade på ett cykelhjul som med styrning av en PIC-processor och en halleffektswitch för att mäta omloppstiden på hjulet. Vår inledande tes var att föregående varvtid skulle vara en tillräckligt god approximation för nästa varv i tillämpningen. Hårdvaran Kretskortets huvudkomponenter är: PIC-processor 8 st ljusdioder halleffektswitch magnet (på gaffeln till cykeln) Dessa komponenter plus några motstånd, klockkrets, kondensatorer och annat smått och gott har åstadkommit ett fungerande POV-hjul. Kretsen monteras med hjälp av eltejp eller annan fästanordning efter behag på cykelhjulet så att halleffektswitchen kommer i närheten av magneten en gång per varv. För att driva kretsen används ett batteripack monterat nära navet i hjulet för att undvika allt för stor mekanisk obalans. Kretsen har även stöd för ICSP vilket gör det smidigt att ändra programvaran och på så sätt uppdatera bilden som visas. I bilaga 3 kan man se hur kretsen är monterad på cykelhjulet. Kopplingsschema för kretsen finns i bilaga 6 och ritning över vårt PCB finns i bilaga 7.

Tillverkning Tillverkningen av kretskortet börjades med att rita upp kopplingschema för att därefter anta den större utmaningen att CADa upp hur kretskortet skulle se ut. Efter CAD och godkänd ritning av handledare, skickades ritningen och kopplingschemat för tillverkning. Etsningen av kretskortet gjordes av handledare eftersom detta krävde erfarenhet av utrustningen som användes. Därefter borrades det hål för komponenter för att slutligen löda fast samtliga komponenter. För att ha något att testa kretsen på användes en framgaffel från en cykel med tillhörande hjul, där framgaffeln svetsades fast på en tung metallklump för att den skulle stå stilla. (se bild bilaga 3) Programmeringen Snabbfakta om programmet: Programmerat i C. Nuvarande varvs hastighet antas vara samma som föregående. Timers används för att veta var på varvet man antas vara. Allting nollställs(=nytt varv) när halleffektswitchen passerar den fast installerade magneten. Ger förskjutning kraftig acceleration/retardation. Ett varv är indelat i 128 delar, d.v.s. man kan kontrollera om en diod ska vara tänd eller släckt i intervall om ca 3. Bilden ligger i programminnet som en switch-case sats, då RAM-minnet (data space) inte räcker till för att lagra så stora variabler. Källkoden återfinns i bilaga 2. Själva main-funktioner ser ut som följande. void main() { IoportInit(); while (1) { Där det enda den gör är att initierar portar och startar en oändlig loop för att hålla programmet levandes. Resten av programmet styrs med hjälp av interrupts. Med följande kod. void interrupt interruptfunc(void) { if (INTF) // Extern interrupt (från halleffecktsswitchen) { //INTF=0; // Reset the external interrupt flag prevcnt=cnt; cnt=0; //move=move+10; //Används för att ha en rullande bild if (move >= 128){

move = 0; INTF=0; //Reset external interrupt. else if (T0IF) { //Timer interrupt. if (prevcnt > 128) { //Måste vara så, annars delar vi med 0 senare i koden. int sektorlength = (int)(prevcnt/128); int sektor = cnt/sektorlength + move; // sektor = 128*cnt/prevCnt; if (sektor>127){ sektor = sektor - 128; diodsoutput(imagefunc(sektor)); cnt++; //count, räknar timerinterrupts. T0IF=0; //Reset timerinterrupt. Där första delen hanterar den externa (från halleffektswitchen) interrupten (INTF). Den delen av funktionen sparar undan föregående varvets hastighet (i timerinterrupts-cyckler) och nollställer det nya varvets räknare. Den andra delen av funktionen hanterar timer interrupts (T0IF). Dessa används för att hålla koll var på varvet vi är och tända rätt dioder vid rätt tillfälle. Första vi gör är att kolla så prevcnt > 128. Detta görs för annars kommer det divideras med noll senare i koden. Och om prevcnt < 128, så har hjulet rört sig med väldigt låg hastighet. Om prevcnt > 128 så räknar vi ut hur många timer-cykler det gick på föregående varv och på så sätt får fram hur långt på varvet vi har kommit på det nuvarande varvet, och tänder eller släcker därefter rätt dioder.

Webbgränssnittet Webbgränssnittet hittas på http://dev.brange.nu/mek_proj/, fram till en bra stund efter inlämnandet av denna rapport. Webbgränssnittet var det första gränssnittet vi utvecklade för att skapa data till vårt POV-hjul. Det är ett väldigt enkelt gränssnitt som bygger på 8*128st kryssboxar, som man antingen kan kryssa i eller inte. Dessa motsvarar om en diod ska vara tänd eller släckt på ett specifikt ställe på hjulet. I webbgränssnittet ritar man upp en bild eller ett ord som man vill överföra till hjulet. Man ritar genom att antingen klicka i kryssboxarna manuellt eller genom att hålla inne SHIFT-tangenten samtidigt som man för musen över en eller flera kryssboxar. Därefter klickar man på generera och sedan genereras en switch-case sats som man sedan kan kopiera in i programmet. Källkoden till webbgränssnittet finns i Bilaga 1. Javaprogram för konvertering av digital bild För att undersöka om det skulle kunna gå att få en större bild att se bra ut på hjulet skrevs ett javaprogram som konverterade informationen i en digital bild med xy-koordinater till radiella koordinater i upplösningen som kortet har. Försöken med detta föll inte så väl ut eftersom upplösningen helt enkelt blev för dålig på hjulet samt att användarvänligheten blev låg på grund av dålig grafisk återkoppling för användaren. Trots det dåliga resultatet tror vi att detta system kan fungera väl med högre upplösning på hjulet. Källkoden till detta finns i bilaga 5.

Framtidsplaner Nedan finns tankar och idéer om saker som man kan göra eller förbättra för att POV-hjulet ska bli bättre. Fler lysdioder radiellt längs med hjulet. Fler rader med lysdioder jämt fördelade över hjulet för att öka uppdateringsfrekvensen Reglering av mätvärdena - för att minska vridnings effekt vid acceleration om upplösningen blir högre, framförallt vinkelupplösningen. Kanske med hjälp av en PID regulator. Seriell till parallell-kretsar för att få plats med fler lysdioder (slippa behöva använda onödigt stor PIC-processor) Använda RGB-dioder för att kunna få flera färger. Hantering av externa minnen för enklare programmering. Rörliga bilder - film Trådlös överföring av bild/film från antingen laptop eller mobiltelefon. Bättre fästanordning av kretsen på cykelhjulet

Bilaga 1 - webbgränssnittets källkod <?php // index.php $width = 1200; //Skärmstorlek (på min laptop) $height = 760; $x = $width/2.0; $y = $height/2.0+150; //Antal dioder på hjulet (= max- min) $diod_min = 8; //Hur långt ut de början, ungefär $diod_max = 16; //Hur långt ut de går, ungefär. $vink = 128; //Antal cirkelsektioner. //Formulär med massa checkboxar som ritas ut i en cirkel. Dom motsvarar diodernas position. echo "<form name=\"matris\" method=\"post\" action=\"index.php\">"; for ($r=$diod_min;$r<$diod_max;$r++) { for ($v=0;$v<$vink;$v++) { $left = $x+20.0*$r*cos($v*2*m_pi/$vink+m_pi/2); $top = $y+20.0*$r*sin($v*2*m_pi/$vink+m_pi/2); echo "<input style=\"position:absolute; left: ".$left."px; top: ".$top."px;\" type='checkbox' name='check_".$r."_".$v."' onmouseover=' if (!this.checked) { if (event.shiftkey) this.checked = true; else { if (event.ctrlkey) this.checked = false; '"; if ($_POST["check_".$r."_".$v]) echo "checked"; echo " >"; echo "<input type='submit' name='gen' value='generera' style=\"position:absolute; left: ".($x- 20)."px; top:".$y.";\">"; echo "</form>"; if (isset($_post['gen'])) { //Om Generera- knappen är tryckt. //Skriv ut värdena från checkboxarna i lämpligt format. echo "<div style=\"position:absolute; top:".(2.3*$y)."px;\">"; echo "char imagefunc(int nbr) {<br>"; echo "switch(nbr) {"; for ($v=0;$v<$vink;$v++) { echo "case ".$v.":<br>"; echo "return 0b"; for ($r=$diod_min;$r < $diod_max;$r++) { if ($_POST["check_".$r."_".$v]) echo "0";

else echo "1"; if ($v < $vink- 1) echo ";<br>"; echo ";"; echo "<br>default:<br> "; echo "<br><br></div>";?> </body> </html>

Bilaga 2 - källkod #define XTAL_FREQ 16MHZ #include "pic.h" #include "delay.h" /* DIOD PLATS_PÅ_PICen interrupt RB0 1 RB3 2 RB2 3 RB1 4 RB4 5 RB5 6 RB6 7 RB7 8 RA0 */ void IoportInit(){ TRISA = 0xfe; TRISB = 0x01; PORTB = 0xfe; PORTA = 0xff; //External interrupt(hall- switch) GIE=1; // Global interrupt enable INTF=0; // Reset the external interrupt flag INTE=1; // Enable external interrupts from RB0 //timer0 interrupt T0IE=1; // Enable timer0 interrupt. (internal) T0IF=0; // Reset timer0 interrupt flag. T0CS=0; // Clock source select = 0 => internal. (ENTE RA4/T0CLK pinnen) PSA=0; //Prescaler Assignment, 0 => till timer0 PS0=0; // Bit0: Prescale 128 PS1=0; // Bit1 - "- PS2=0; // Bit2 - "- int cnt=0; int prevcnt=0; int move=0; char imagefunc(int nbr) { switch(nbr) { case 0:

return 0b10111111; case 1: return 0b10111111; case 2: return 0b00111111; case 3: return 0b01111111; case 4: case 5: case 6: case 7: case 8: return 0b10001111; case 9: return 0b00001111; case 10: return 0b11011110; case 11: return 0b10111111; case 12: return 0b00111111; case 13: return 0b01111111; case 14: return 0b01111110; case 15: return 0b11111110; case 16: return 0b11111110; case 17: return 0b11111110; case 18: case 19: case 20: case 21: return 0b11111110; case 22: case 23: case 24: case 25: case 26: return 0b00011111;

case 27: return 0b00111111; case 28: return 0b00111111; case 29: return 0b00111111; case 30: return 0b00011111; case 31: return 0b00011111; case 32: return 0b01111111; case 33: case 34: case 35: case 36: case 37: case 38: case 39: return 0b10001111; case 40: return 0b01111111; case 41: return 0b01111111; case 42: return 0b11100010; case 43: return 0b01011011; case 44: return 0b00111011; case 45: return 0b00110011; case 46: return 0b10001110; case 47: return 0b11111110; case 48: return 0b11111110; case 49: return 0b01111110; case 50: case 51: case 52: case 53:

return 0b11111110; case 54: return 0b01111111; case 55: return 0b00111111; case 56: case 57: case 58: case 59: case 60: case 61: case 62: case 63: case 64: case 65: case 66: case 67: case 68: case 69: case 70: case 71: case 72: case 73: case 74: return 0b11111110; case 75: case 76: case 77: case 78: return 0b11110110; case 79: return 0b11111010;

case 80: return 0b11111000; case 81: return 0b01111010; case 82: return 0b00000011; case 83: case 84: case 85: return 0b11111110; case 86: case 87: return 0b00011111; case 88: return 0b10011111; case 89: case 90: case 91: case 92: case 93: case 94: case 95: return 0b01111111; case 96: return 0b00011111; case 97: return 0b00011111; case 98: return 0b00111111; case 99: return 0b00111111; case 100: return 0b00111111; case 101: return 0b00011111; case 102: case 103: case 104: case 105: case 106:

return 0b11111110; case 107: case 108: case 109: case 110: return 0b11111110; case 111: return 0b11111110; case 112: return 0b01111110; case 113: return 0b00111110; case 114: return 0b00011111; case 115: return 0b01001111; case 116: return 0b01100111; case 117: return 0b11111110; case 118: case 119: case 120: case 121: case 122: case 123: return 0b01111111; case 124: return 0b01111111; case 125: return 0b00111111; case 126: return 0b10111111; case 127: return 0b10111111; default: void diodsoutput(int bitar) { RB3 = bitar%2; bitar=bitar >> 1;

RB2 = bitar%2; bitar=bitar>> 1; RB1=bitar%2; bitar=bitar>> 1; RB4=bitar%2; bitar=bitar>> 1; RB5=bitar%2; bitar=bitar>> 1; RB6=bitar%2; bitar=bitar>> 1; RB7=bitar%2; bitar=bitar>> 1; RA0=bitar%2; void interrupt interruptfunc(void) { if (INTF) { //INTF=0; // Reset the external interrupt flag prevcnt=cnt; cnt=0; move=move+0; if (move >= 128){ move = 0; INTF=0; else if (T0IF) { // T0IF=0; // Reset timer0 interrupt flag if (prevcnt > 128) { int sektorlength = (int)(prevcnt/128); int sektor = cnt/sektorlength + move; // sektor = 128*cnt/prevCnt; if (sektor>127){ sektor = sektor - 128; diodsoutput(imagefunc(sektor)); cnt++; //count, räknar timerinterrupts. T0IF=0; void main(){ IoportInit(); while (1) {

Bilaga 3

Bilaga 4

Bilaga 5 - Bildkonverteringens källkod import java.io.file; public class bildhanterare { public static void main(string[] args){ Reality reality = new Reality(170, 10, 5, 270); Wheel wheel = new Wheel(8,128); RadialImage radialimage = new RadialImage(wheel, reality); File f = new File(args[0]); Bitmap bitmap = new Bitmap(f); radialimage.drawradialimagefrombitmap(bitmap); System.out.println("char imagefunc(int nbr) { \nswitch(nbr) {"); for(int phi = 0 ; phi < wheel.getnumsectors(); phi++){ System.out.print("case " + phi + ":\nreturn 0b"); for(int r = 0 ; r < wheel.getnumleds(); r++){ if(radialimage.getradialpixel(r, phi)) System.out.print(0); else System.out.print(1); System.out.print(";\n"); System.out.print("default: \nreturn 0b"); for(int i=0; i < wheel.getnumleds(); i++){ System.out.print(1); System.out.print(";\n\n"); public class Reality{ private double mmtowheelhub; //distance from the hub to the middle of the innermost LED private double mmbetweenleds; //distance between the center of the LEDs private double mmledwidth; //the width of an LED private double sensorangle; //in degrees, parallel to x- axis and counter clock wise positive public Reality(){ public Reality(double mmtowheelhub, double mmbetweenleds, double mmledwidth, double sensorangle){ this.mmtowheelhub = mmtowheelhub; this.mmbetweenleds = mmbetweenleds; this.mmledwidth = mmledwidth; this.sensorangle = sensorangle;

public double getmmtowheelhub(){ return mmtowheelhub; public double getmmbetweenleds(){ return mmbetweenleds; public double getmmledwidth(){ return mmledwidth; public double getsensorangle(){ return sensorangle; public void setmmtowheelhub(double mmtowheelhub){ this.mmtowheelhub = mmtowheelhub; public void setmmbetweenleds(double mmbetweenleds){ this.mmbetweenleds = mmbetweenleds; public void setmmledwidth(double mmledwidth){ this.mmledwidth = mmledwidth; public void setsensorangle(double sensorangle){ this.sensorangle = sensorangle; public class Wheel{ private int numleds; private int numsectors; public Wheel(){ public Wheel(int numleds, int numsectors){ this.numleds = numleds; this.numsectors = numsectors; public int getnumleds() { return numleds; public int getnumsectors() { return numsectors;

public void setnumleds(int numleds){ this.numleds=numleds; public void setnumsectors(int numsectors){ this.numsectors=numsectors; import java.awt.point; import java.awt.image.bufferedimage; public class RadialImage{ boolean[][] radialimage; Reality reality; Wheel wheel; public RadialImage(Wheel wheel, Reality reality){ radialimage = new boolean[wheel.getnumleds()][wheel.getnumsectors()]; this.reality = reality; this.wheel = wheel; public void setradialpixel(int r, int phi){ radialimage[r][phi]=true; public void clearradialpixel(int r, int phi){ radialimage[r][phi]=false; public boolean getradialpixel(int r, int phi){ return radialimage[r][phi]; public boolean[][] getradialimage(){ return radialimage; public Point translateradialcoordtocartesian(int r, int phi, int imagewidth, int imageheight){ double ddiameter = (Math.min(imageWidth, imageheight)) / (double)((wheel.getnumleds()- 1)*reality.getMmBetweenLEDs()+reality.getMmToWheelHub()); int radius = (int)((r*reality.getmmbetweenleds()+reality.getmmtowheelhub()) * ddiameter / 2); double startangle = (double)phi/wheel.getnumsectors()*360 + reality.getsensorangle(); double dangle = 1.0/(double)wheel.getNumSectors() * 360.0; double angle = startangle + (dangle/2); angle *= Math.PI/180;

return (new Point((int)(Math.cos(angle)*radius+(imageWidth/2)),(int)((imageHeight/2)- Math.sin(angle)*radius))); public void drawradialimagefrombitmap(bitmap bitmap){ Point p; for (int r=0; r<wheel.getnumleds(); r++) { for (int phi=0; phi<wheel.getnumsectors(); phi++) { p = translateradialcoordtocartesian(r, phi, bitmap.getthebufferedimage().getwidth(), bitmap.getthebufferedimage().getheight()); if ( bitmap.getthebufferedimage().getrgb((int)p.getx(), (int)p.gety()) == - 1) { clearradialpixel(r,phi); else { setradialpixel(r,phi); public BufferedImage getimagerepresentation(int width, int height){ BufferedImage image = new BufferedImage(width, height, 1); Point p; for (int r=0; r<wheel.getnumleds(); r++) { for (int phi=0; phi<wheel.getnumsectors(); phi++) { p = translateradialcoordtocartesian(r,phi,width,height); if (getradialpixel(r,phi)){ image.setrgb((int)p.getx(), (int)p.gety(), 0x00ff00ff); return image; import java.awt.image.bufferedimage; import java.io.file; import java.io.ioexception; import javax.imageio.imageio; public class Bitmap{ BufferedImage thebufferedimage; public Bitmap(){ public Bitmap(File f){ try { thebufferedimage = ImageIO.read(f); catch (IOException e) { // TODO Auto- generated catch block

e.printstacktrace(); public BufferedImage getthebufferedimage(){ return thebufferedimage;

Bilaga 6 Kopplingsschema I kopplingsschemat saknas halleffektswitchen samt ett pull-up motstånd till den.

Bilaga 7 PCB