Demonstrator av vinkelgivare Examensarbete 15hp Elektronik Eskilstuna Elektronik Partner AB, EEPAB Akademin för Innovation, design och teknik, IDT Mälardalens högskola Författare: Jonne Kivinen Handledare: Mikael Joki, VD (EEPAB) Handledare/ Examinator: Magnus Otterskog, MDH Datum: 2009-08-25 Sammanfattning Eskilstuna Elektronikpartner (EEPAB) är ett elektronikföretag som tillverkar vinkelgivare till bland annat kranar som är monterade på lastbilsflak. För att EEPAB på ett intressant sätt ska kunna demonstrera sin produkt på mässor har en demonstrator tagits fram. Denna demonstrator består av en fjärrstyrd grävmaskin och en elektronikenhet, som hanterar den analoga signalen från vinkelgivaren. Resultatet, som är vinkelgivarens lutning i grader, presenteras på två sjusegmentdisplayer som är placerade på grävmaskinens bägge sidor. Vinkeln skickas även trådlöst från elektronikenheten, via Bluetooth, till en PC. Grävmaskinens batteri (7,2V) strömförsörjer all hårdvara, vilket gör att demonstratorn är helt portabel. Denna rapport beskriver block för block de olika programfunktioner samt hårdvara, som behövs till en färdig och fungerande demonstrator. Abstract Eskilstuna Elektronikpartner (EEPAB) is an electronics company located in Eskilstuna that produces angle sensors to, for instance, cranes mounted on truck beds. For EEPAB to be able to demonstrate their product on fairs in an interesting way, a demonstrator has been made. The demonstrator consists of a remote controlled excavator and an electronic unit which handles the analog signal from the sensor. The result, which is the angle of the sensor in degrees, is presented on two sevensegment displays that are placed on both sides of the excavator. The angle is also sent wirelessly from the electronic unit via Bluetooth to a PC. The battery of the excavator powers all of the hardware, making the demonstrator fully portable. This thesis report describes the various programfunctions and hardware, part by part, necessary for a complete and functioning demonstrator. 2 Innehållsförteckning Sammanfattning ......................................................................................................................... 2 Abstract ...................................................................................................................................... 2 1 Inledning.................................................................................................................................. 5 1.1 Bakgrund .......................................................................................................................... 5 1.2 Syfte ................................................................................................................................. 5 1.3 Problemställning............................................................................................................... 5 1.4 Verktyg ............................................................................................................................. 5 2 Kundkravspecifikation ............................................................................................................ 5 3 Teori ........................................................................................................................................ 6 3.1 Vinkelgivare ..................................................................................................................... 6 4 Design...................................................................................................................................... 7 4.1 Hårdvara ........................................................................................................................... 7 4.1.1 Strömförsörjning ....................................................................................................... 7 4.1.1.1 12V Step up-regulator ........................................................................................ 7 4.1.1.2 5V Spänningsregulator ....................................................................................... 8 4.1.2 Vinkelgivare .............................................................................................................. 9 4.1.3 Mikrokontroller ......................................................................................................... 9 4.1.3.1 Interface mikrokontroller ................................................................................... 9 4.1.3.2 UART ............................................................................................................... 11 4.1.4 Blåtandsmodul ......................................................................................................... 11 4.1.5 Display .................................................................................................................... 12 4.2 Mjukvara ........................................................................................................................ 12 4.2.1 Initieringsfunktioner ................................................................................................ 13 4.2.2 Main-funktion.......................................................................................................... 13 4.2.3 Display-funktion...................................................................................................... 13 4.2.4 Omvandlings-funktion ............................................................................................ 13 4.2.5 Timer ....................................................................................................................... 14 4.2.6 Läsning av ADC ...................................................................................................... 15 4.2.7 Nollställning av vinkel ............................................................................................ 16 4.2.8 Power ON/OFF ....................................................................................................... 16 4.2.9 Fördröjning .............................................................................................................. 16 4.2.10 UART-funktioner .................................................................................................. 16 4.2.10.1 Print-funktion ................................................................................................. 17 4.2.10.2 RX-interrupt ................................................................................................... 17 4.2.10.3 TX-interrupt ................................................................................................... 17 5 Verifiering ............................................................................................................................. 17 5.1 Testning .......................................................................................................................... 17 5.2 Testning av elektronikenhet ........................................................................................... 17 6 Implementering ..................................................................................................................... 18 7 Resultat och diskussion ......................................................................................................... 19 8 Slutsats .................................................................................................................................. 20 9 Referenser.............................................................................................................................. 21 10 Bilaga A - Flödesscheman................................................................................................... 22 11 Bilaga B - Programkod ........................................................................................................ 25 12 Bilaga C - Kretsscheman ..................................................................................................... 30 13 Bilaga D – Datablad ............................................................................................................ 33 3 Förkortningar ADC Analog-to-Digital Converter CA CAD JTAG LED LSB MEMS MS MSB UART Common Anode Computer-Aided Design Joint Test Action Group Light Emitting Diode Least Significant Bit Micro-Electro-Mechanical Systems Microsoft Most Significant Bit Universal Asynchronous Receiver/Transmitter 4 1 Inledning 1.1 Bakgrund Detta projekt är ett förslag från två olika företag från Eskilstuna - Eskilstuna Elektronik Partner AB (EEPAB) och minST. Elektronik Partner är ett företag som erbjuder helhetslösningar från en idé till en färdig produkt och minST ett företag, som bland annat hjälper små och medelstora företag att, genom samarbete, utveckla sina egna produkter med ny teknik. EEPAB tillverkar bland annat vinkelgivare. Dessa givare är avsedda för att mäta lutning hos kranar som till exempel är monterade på lastbilar, för att lasta och lossa av gods från flaket. Eftersom inga riktiga kranar finns tillgängliga för projektet, samt att det är opraktiskt att behöva ha en kran som är stor och som tar mycket plats, så används en radiostyrd grävmaskin till att påverka givaren. En av de första uppgifterna i detta projekt var således att hitta en lämplig demonstrator för vinkelgivaren. Grävmaskinen som valdes är gjord i plast. Det faktum att den inte väger mycket gör att den lätt att transportera. Den är 74 cm lång, 49 cm hög och 22 cm bred – vilket gör att den är tillräckligt stor för att synas. Grävmaskinen kan köras framåt, bakåt, till höger och vänster. Skopan kan köras upp och ner. Detta gör att den fungerar utmärkt som en demonstrator för vinkelgivaren. 1.2 Syfte Syftet med projektet, demonstrator av vinkel, är att EEPAB på ett enkelt och intressant sätt ska kunna visa upp sin produkt (vinkelgivare), inför en publik på mässor eller liknande tillställningar, med dess unika funktioner. I detta projekt är det främst lutningen i grader, som ska demonstreras. 1.3 Problemställning Uppgiften i detta arbete är att kunna ta emot en analog signal från vinkelgivaren, som anger lutningen, och använda signalen i ett program för att sedan kunna presentera den på en sjusegmentdisplay. En ny elektronikenhet konstrueras för att uppnå detta. Resultaten, som skickas via Bluetooth, ska även kunna hanteras av en PC. 1.4 Verktyg Programmeringsmiljöerna som använts i detta projekt är Dev-C++, där de första testprogrammen skrivits, samt IAR Embedded Workbench, som använts för att skriva de slutliga programmen. AVR Studio 4 har använts för testning och debugging samt LTspice för simulering av elektronikkretsar. Även ett JTAG-interface användes i debugging. 2 Kundkravspecifikation Allmänt Aktuell vinkel ska presenteras på två parallellt inkopplade LED-displayer som ska bestå av gröna enkelradiga 4x7-segmentdisplayer med en teckenhöjd på minst 25mm. Vinkeln som visas ska vara mellan -185° och 185°. Elektronikenheten ska strömförsörjas från samma batteri som grävmaskinen. 5 En intern spänning på minst 10V måste genereras från batterispänningen för drivning av vinkelgivarna. Via en switch (digital ingång) ska det vara möjligt att nollställa aktuell vinkel. Vinkeln ska kunna läsas av via Bluetooth för att kunna hanteras av en PC. Kretslösning Ett kretskort ska tas fram som hanterar alla in- och utsignaler med hjälp av en mikrokontroller. Om det inte går att hitta en färdig LED-display (4x7-segment, höjd>25mm) ska ett separat kretskort tas fram för detta. EEPAB hjälper till med CAD av mönsterkort. 3 Teori 3.1 Vinkelgivare Vinkelgivaren som används är baserad på MEMS-teknik och innehåller två accelerometrar. Dessutom har den en mikrokontroller som bland annat är programmerad till för att filtrera bort periodiska lågfrekventa svängningar. Accelerometrar känner av acceleration med gravitationen som referens. Vinkelgivaren som används har en accelerometer i både x- och y-led. En accelerometer fungerar som en massa på en fjäder, se Figur 1. När en extern kraft, i detta fall gravitationskraften, påverkar accelerometern förflyttas massan tills det råder en balans mellan gravitationen och fjäderkraften. Därefter omvandlas förflyttningen till en acceleration. Nya accelerometrar är, för det mesta, mikro-elektro-mekaniska system (MEMS) som bland annat innehåller en konsolbalk och en (seismisk) massa, se Figur 2. När gravitationskraften påverkar accelerometern avviker massan ur sitt neutrala läge och denna avvikelse kan sedan mätas antingen på ett analogt eller digitalt sätt [1]. Figur 1. Accelerometerns funktionsprincip 6 Figur 2. En typisk MEMS-acceleometer 4 Design 4.1 Hårdvara Hårdvaran kan delas upp i fem olika block: strömförsörjning, vinkelgivare, mikrokontroller, display och blåtandsmodul, se Figur 3. Strömförsörjning Vinkelgivare Display Microcontroller Blåtand Figur 3. Blockdiagram för hårdvaran 4.1.1 Strömförsörjning På grund av att demonstratorn är en fjärrstyrd grävmaskin, strömförsörjs allting från grävmaskinens batteripack (7,2V). Detta är ett krav från kunden som vill kunna använda demonstratorn vid presentationstillfällena på ett så enkelt och smidigt sätt som möjligt. 4.1.1.1 12V Step up-regulator I detta projekt används en step up-regulator (LM2577) för att ge vinkelgivaren och displayen tillräcklig matningsspänning. Denna regulator ”boostar” batterispänningen upp till 12V, vilket är en bra nivå för vinkelgivaren då den fungerar med 10 - 30V matningsspänning. Med denna krets behövs endast få externa komponenter för att åstadkomma den önskade spänningsnivån. Exempel på hur man kopplar regulatorn med dess externa komponenter, i 7 olika applikationer, ges i databladet (se Bilaga D – 13.4). Kopplingen som används är tagen ur exemplen. Med 5V inspänning kan 12V utspänning levereras, se Figur 4, men i detta projekt matas regulatorn med 7,2V. Figur 4. Kopplingsschema för step up-regulatorn 4.1.1.2 5V Spänningsregulator Denna spänningsregulator (LM2734) används till att reglera 12V spänningen till 5V. Regulatorns min- och maxvärden för in- respektive utspänning, enligt databladet (se Bilaga D – 13.3), visas i Tabell 1 nedan. Tabell 1. Användningsområdet för LM2734 Både mikrokontrollern och blåtandsmodulen matas med 5V spänning. Matningen till mikrokontrollern får enligt databladet, se Bilaga D – 13.1 matas med högst 6V spänning, därför måste spänningsregulatorn användas, se Figur 5. Annars riskerar man att förstöra mikrokontrollern. Figur 5. Design för 5V-spänningsregulatorn 8 4.1.2 Vinkelgivare Signalen som givaren ger ut är en ström som varierar mellan 4mA och 20mA beroende på lutningen. Denna ström måste omvandlas till en spänning för att kunna A/D-omvandlas. Detta görs med en differetialförstärkarkoppling, se Figur 6. Signalen (strömmen) kommer från den mellersta kontakten (GIVARE1) och spänningen kommer ut efter operationsförstärkaren (LM2902), som är kopplad till mikrokontrollern. Figur 6. Differentialförstärkare för signalen från vinkelgivaren Vinkelgivaren kan matas med 10 - 30V men i detta projekt har det valts att mata den med 12V. Givaren innehåller även en regulator som ser till att strömmen alltid är 4 - 20mA, oberoende med vilken spänning den matas med, då matningsspänningen är 10 - 30V. 4.1.3 Mikrokontroller I detta projekt används Atmels Mega128. Detta var ett val från EEPAB:s sida. En mikrokontroller med mindre funktioner hade räckt, men Atmels Mega128 valdes för att EEPAB ville lägga till egna finesser för en slutprodukt med fler användningsmöjligheter. För programmering av ATMega128 kan programmeringsspråken Assembler och C användas. Eftersom C används på EEPAB så används den även i detta projekt. Microkontrollern används bland annat för att A/D-omvandla en signal samt skicka ut resultat till både displayer och en PC. 4.1.3.1 Interface mikrokontroller Inportar PORTD6 från SWITCH1 PORTD7 från SWITCH2 PORTF0 (ADC0) från GIVARE1 PORTF1 (ADC1) från GIVARE2 PORTF2 (ADC2) från GIVARE3 Utportar PORTA0 till segment ”DP” 9 PORTA1 till segment ”G” PORTA2 till segment ”F” PORTA3 till segment ”E” PORTA4 till segment ”D” PORTA5 till segment ”C” PORTA6 till segment ”B” PORTA7 till segment ”A” PORTC0 till CA pinnen i DISP1 PORTC1 till CA pinnen i DISP2 PORTC2 till CA pinnen i DISP3 PORTC3 till CA pinnen i DISP4 PORTE0 till RXD0 (Bluetooth) PORTE1 till TXD0 (Bluetooth) PORTE5 till Battery-Hold Figur 7. Illustration av I/O-portar för ATMega128 Analoga ingångar: In i dessa ingångar kommer en spänning på ca 0,86 - 4,26V som ska A/D-omvandlas. En 5V (uppmätt 4,92V) extern referensspänning används. Resultatet som fås efter A/Domvandlingen hanteras sedan i programmet. Digitala ingångar för switchar: Det finns två digitala ingångar tillgängliga för switchar. Med den ena switchen (switch 1) kan programmet stoppas och sedan startas. Med den andra (switch 2) kan den aktuella vinkeln nollställas. Digitala utgångar till segmenten: Denna port, PORTA, är kopplad till de åtta segmenten på 7-segmentdisplayen, som visar den aktuella lutningen. Punkten ”DP” är kopplad men används inte för mina ändamål. Digitala utgångar till CA på displayen: Dessa utgångar är kopplade till de gemensamma anoderna på 7-segmentdisplayen. Syftet med dessa signaler är att styra vilka av de åtta displayen som ska lysa. Digital utgång för Battery-Hold: För val av batteripack som spänningskälla måste en hög signal skickas från pinne 5 på PORTE. 10 Portar för UART: Med hjälp av dessa portar skickar man information från elektronikenheten till en dator, via Bluetooth. 4.1.3.2 UART UART är en hårdvara som sekventiellt skickar data bitvis till en annan hårdvara som också har UART. Mottagaren lägger sedan ihop datat till en hel byte igen. Med UART kan mikrokontrollern kommunicera med, i detta fall, en blåtandsmodul. Det sker genom att mikrokontrollern skickar data från sin Tx-port (transmitter) till blåtandsmodulens Rx-port (receiver). Därefter svarar blåtandsmodulen genom att skicka tillbaka data från dess Tx-port till mikrokontrollerns Rx-port. För att mikrokontrollern och blåtandsmodulen ska kunna kommunicera, måste samma inställningar sättas till bägge hårdvarorna för UART-interfacet. I detta projekt används följande inställningar: Baud rate: 9600 Data bits: 8 Paritet: none Stop bit: 1 UART-interfacet används i detta projekt till för att skicka den aktuella vinkeln från microcontrollen via Blåtandsmodulen till en PC. Syftet med denna funktion är att kunna se resultaten på en dataskärm, se Figur 8. UARTinterface Tx Rx Blåtandsmodul Mikrokontroller Rx Bluetooth Dongle PC Tx Figur 8. Blockschema för funktion av UART och blåtand. 4.1.4 Blåtandsmodul Blåtandsmodulen som används är en Ezurio BISM2 Bluetooth Version 2 Serial Module, se Bild 1. Denna modul har valts på grund av att EEPAB använder den i sina applikationer, därför används den även i detta arbete. Med hjälp av blåtandsmodulen kan data överföras till en extern enhet, i detta fall en PC. Datat överförs trådlöst från modulen till en så kallad Bluetooth dongle som sitter i PC:n, se Figur 8. Datat som skickas är grävskopans aktuella vinkel. 11 Bild 1. Ezurio BiSMII Bluetooth Version 2 Serial Module 4.1.5 Display För våra ändamål används gröna sjusegmentdisplayer (SA10-21GWA) med en teckenhöjd på 25,4 mm (vilket uppfyller kraven för höjd i kravspecifikationen). Dessa är av typen Common Anode (CA) vilket betyder att lysdioden i segmenten är kopplade så att de har en gemensam anod. Segmenten i denna display består av två lysdioder. För att kunna visa en vinkel mellan -185° och 185° behövs tre siffertecken, samt ett tecken för minus. I projektet behövdes 2x4 displayer som bildar två hela displayer – en på vardera sida av grävmaskinen. Då inga tillräckligt stora sjusegmentdisplayer med fyra tecken hittades, konstruerades ett display-mönsterkort. Därmed kopplades fyra separata sjusegmentdisplayer parallellt för att uppfylla kraven. För att visa en siffra på displayen tänder man de segment som bildar siffran, genom att skicka en logisk etta från de utgångar, som är kopplade till respektive segment. Dessutom måste man aktivera den displayen som man vill använda, genom att också skicka en logisk etta från utgången som är kopplad till CA-pinnen på den aktuella displayen. 4.2 Mjukvara Mjukvaran är modulärbaserad, detta innebär att programmet är uppdelat i flera olika separata delar (block), se Figur 9. Varje del är placerad i en egen källkodsfil. Detta för att det ska vara lättare att förstå programmet eftersom det är så pass stort. Initieringar Läsning av ADC UART ADC till grader Main Timer Display Kalibrering Figur 9. Blockdiagram för mjukvaran 12 4.2.1 Initieringsfunktioner För att göra main-funktionen så ”ren” och snygg som möjligt, användes egna funktioner för initiering av I/O-portar, ADC, Timer0 och UART. Dessa initieras således med bara några rader kod. I/O-portarna initieras så att de satisfierar interfacet för mikrokontrollern, Timer0 till att ge ett interrupt var nionde millisekund och i UART möjliggörs användning av mottagare och sändare samt receive interrupt. 4.2.2 Main-funktion Main-funktionen består inte av så mycket kod eftersom den vill göras lättåskådlig. Den innehåller initieringsfunktionerna samt en så kallad forever-loop. I forever-loopen anropas funktionen som omvandlar ADC-värdet till ett antal grader och därefter skickar resultatet ut till både displayen och PC:n. Detta forsätter tills programmet stängs av (se Bilaga A). 4.2.3 Display-funktion Med denna funktion styrs vilken display som ska vara aktiverad, det vill säga lysa, och här hanteras även utskrift av siffra. Display-funktionen är designad så att entalssiffran av vinkeln först skrivs ut på första displayen, sedan tiotalssiffran på andra displayen och slutligen hundratalssiffran på tredje displayen. Dessutom skrivs ett minustecken ut på fjärde displayen om vinkeln är negativ. I funktionen kommer vinkeln (talet) att gås igenom, i ordningen ental, tiotal, hundratal och eventuellt minus-tecken, med hjälp av en loop som scannar varje tecken en efter en. För att se en mer noggrann förklaring av funktionen, se Bilaga A (flödesschema) och Bilaga B (programkod). För utskrift av entalssiffran tas vinkeln modulus (%) 10. Till exempel om vinkeln är 123° tas 123%10 . 10 går 12 gånger i talet 123 och resten blir tre. Alltså skrivs det ut en trea. Därefter divideras talet med 10 vilket resulterar i 12,3. Men eftersom programmet endast hanterar heltal, blir siffran 12. Under nästa varv tas modulus 10 av talet igen och detta ger en tvåa. I näst sista varvet, när division med 10 utförts, är talet 1,2, vilket blir en etta. Slutligen kontrolleras om talet är negativt. I programkoden finns en variabel (Sevenseg[]) som är ett fält med 10 element. När respektive siffra skrivs ut används följande kodrad: PORTB=SevenSeg[x]; Istället för x erhålls en siffra av de operationer som beskrivits tidigare i kapitlet, till exempel 123%10 3 . Trean är i detta fall x:et. Det som finns i det tredje elementet i variabeln blir då utskrivet. I detta fall ”three”, som är definierad i koden. ”Three” motsvarar ett hexadecimalt tal (0xF2) som tänder de segment på displayen som slutligen bildar siffran tre (se Bilaga B för programkod). 4.2.4 Omvandlings-funktion För att det ska vara möjligt att hantera något som ger ut en analog signal i ett program måste den först analog-till-digital-omvandlas. Mikrokontrollern har en 10-bit ADC, som används för detta. Omvandlingsvärdet, ADC-värdet, som enligt databladet för ATMega128 (se Bilaga D – 13.1) fås ur följande ekvation: ADC VIN 1024 (1) VREF 13 där VIN är inspänningen och VREF är referensspänningen (uppmätt 4,92V). Utspänningen från differentialsteget, efter vinkelgivaren, varierar mellan ca 0,86V och 4,26V beroende av lutningen av givaren. Dessa värden motsvarar mininum (min) och maximum (max) ström från givaren före differentialsteget, det vill säga 4mA respektive 20mA. Enligt databladet för vinkelgivaren, se Bilaga D – 13.2, motsvarar 4mA en vinkel på -185° och 20mA vinkeln +185°. Dessutom motsvarar 12mA vinkeln 0°, se Tabell 2. Vinkelgivaren är därför linjär. VIN (V ) 0,857 2,558 4,259 I GIVARE (mA) 4 12 20 Vinkel () -185 0 185 ADC 178,4 532,4 886,4 Tabell 2. Konverteringsfaser från ström till vinkel När inspänningen sätts in i ekvation (1) erhålls motsvarande ADC-värde till spänningen, vilket också blir linjärt. Därmed kan en ekvation beräknas ur dess lutning. Detta har gjorts genom att rita upp en graf i MS Excel, med ADC-värdet på x-axeln och vinkeln på y-axeln, se Graf 1. Följande ekvation erhålls ur lutningen: y 0,5226 x 278,21 , där x är ADC (2) y = 0,5226x - 278,21 250 200 150 100 50 0 0 100 200 300 400 500 600 700 800 900 1000 -50 -100 -150 -200 -250 Graf 1. Förhållandet mellan ADC-värdet och vinkeln Eftersom en funktion för nollställning av vinkel används, behövs ekvation (2.) modifieras, se kapitel Nollställning av vinkel. Den ser då ut på följande sätt: y 0,5226 x , där x är ADC offset (3) I programkoden för själva omvandlingsfunktionen (ADC_To_Deg) används endast ekvation (3). Därefter sparas resultatet i en variabel och returneras till slut, se Bilaga C för programkod. 4.2.5 Timer Timern som används är Timer0. Den är en 8-bit Timer/Counter som räknar från 0 - 255. När den har nått sitt maxvärde genereras ett interrupt, om användning av interrupt möjliggjorts. 14 Vid ett interrupt avbryts programmet och fortsätter sedan i en så kallad timer-interruptfunktion. När timer-interrupt-funktionen är exekverad återgår programmet till den plats där interruptet skedde. Med hjälp av räknare, som är gjorda med if-satser, och information om processorns klockfrekvens kan fördröjningar av valfri storlek skapas. I detta projekt används en extern klocka, en kristall, på 7,3728 MHz. Med följande ekvation kan frekvensen av interrupten beräknas: f clk (4), där f clk är klockfrekvensen på kristallen, n är antalet bitar (8-bitar) på 2 N Timer/Counter0 och N är storleken på prescalern1. För att uppnå ett bra resultat är faktorn vald till 64 på prescalern. Med dessa parametrar instoppade i ekvation (4) fås frekvensen till 450 Hz, vilket betyder att interruptet sker ungefär varannan millisekund, som fås ur ekvation (6): f f n 1 1 1 0,00222s , där T är periodtiden och f är frekvensen. (5) T (6) T 450 Hz f För att sedan bestämma fördröjningens längd (sekunder) kan räknarens maxvärde beräknas med följande ekvation: T max värde delay (7) max värde delay (8). Maxvärdet sätts sedan som villkor i ifT satsen, se Bilaga C för programkod. När interruptet sker kontrolleras om ADC-räknaren samt nollställningssräknaren har nått sina maxvärden. Dessutom kontrolleras om displayräknaren nått sitt minimumvärde. Om inte, kommer bägge räknarna att adderas med ett och den sistnämnda kommer att subtraheras med ett. Därefter återgår man till main-funktionen. 4.2.6 Läsning av ADC Läsning av ADC sker i timer-interrupt-funktionen men inte vid varje interrupt. För att bestämma när läsningen sker används en egen räknare. Först när räknaren nått sitt maxvärde sker läsningen. När en A/D-omvandling är klar hittas resultaten i de två ADC data registren, ADCL (ADC Low) och ADCH (ADC High), där ADCL är de åtta LSBn och ADCH de två MSBn av 10bitars resultat, se Figur 10. I denna funktion läses ADC-registret av i sin helhet och sedan sparas resultatet i en variabel. Därefter startas en ny omvandling. Till slut nollställs räknaren för att senare hamna i denna funktion igen, se Bilaga A för flödesschema och Bilaga B för programkod. Figur 10. ADC data registren ADCL och ADCH Eftersom en analog-till-digital-omvandling bara tar 13 - 260 μs, enligt databladet för ATMega128, se Bilaga D – 13.1, kommer siffrorna på displayen att ändras för snabbt för att 1 Prescalern dividerar klockfrekvensen med någon av följande faktorer: 8, 32, 64, 128, 256 och 1024. 15 det ska vara lättbegripligt. Ett sätt att hantera detta problem är att minska på frekvensen för läsning av ADC-värdet. Tack vare att läsningen av ADC-värdet görs i timer-interruptfunktionen, är det möjligt att reglera frekvensen på avläsningen (i sekunder). 4.2.7 Nollställning av vinkel Med denna funktion kan den aktuella vinkeln, som visas på displayen, nollställas. Detta görs med ett knapptryck genom att hålla knappen nedtryck i två sekunder. Nollställningen sker även i timer-interrupt-funktionen. Detta betyder att tiden som knappen ska vara nedtryckt kan bestämmas, genom att välja ett lämpligt maxvärde för räknaren. Nollställningen görs genom att en variabel (offset, i ekvation 3) tilldelas det aktuella ADCvärdet, då knappen varit nedtryck i rätt tid. På detta sätt förflyttas nollstället till det aktuella ADC-värdet, vilket medför att y, som är vinkeln, i ekvation (3) blir noll. Slutligen nollställs nollställningsräknaren, se Bilaga A för flödesschema och Bilaga B för programkod. 4.2.8 Power ON/OFF För att kunna stänga av strömmen, och därmed spara batteri vid demonstrationstillfällena, finns en switch som man kan slå av batteriet med. Programmet startas då strömmen till demonstratorn slås på. När det är önskvärt att stänga demonstratorn kan detta göras genom att hålla switch1 intryckt i tre sekunder. För att starta programmet igen trycks switch1 in ytterligare en gång. 4.2.9 Fördröjning För att segmenten i displayen ska lysa kraftigt, så att siffrorna syns ordentligt, måste de hinna lysa en viss tid. Detta regleras genom att lägga en fördröjning efter att en display tänts. Fördröjningen skapas även med hjälp av en räknare i timer-interrupt-funktionen. Om räknaren inte har nått sitt minimumvärde kommer tändningen av display inte att ske, utan räknaren minskas för varje gång som timer-interruptet sker. 4.2.10 UART-funktioner UART-funktionerna Rx-interrupt och Tx-interrupt innehåller båda en cirkulär buffer, som är ett fält med 128 element, se Figur 11. Där lagras ny data som sedan skickas vidare. Ny indata kan därmed sparas samtidigt som utdata skickas iväg. Annars finns det en risk, att när data är på väg att skickas ut och just då kommer data in, att man förlorar det inkomna datat. Figur 11. Illustration av den cirkulära buffern Rx-interrupt och Tx-interrupt har både en head och en tail. Både head och tail pekar på ett element i respektive buffer. När nya tecken kommit in i Rx-buffern flyttas Rx-headen så långt framåt som tecken kommit in, genom att ett nytt index för Rx-headen beräknas. Sedan skickas ett tecken åt gången iväg och därefter beräknas ett nytt index för Tx-tailen. 16 4.2.10.1 Print-funktion Denna funktion används för att skicka den aktuella vinkeln till PC:n. I funktionen tas vinkeln som indata och skickas sedan till PC:n, genom att först konvertera den till en ASCII-sträng och sedan skicka datat som finns i Tx-buffern. Detta görs med 0,3 sekunders mellanrum så att resultaten på skärmen inte ändras för snabbt. Även denna funktion exekveras i timerinterrupt-funktionen. 4.2.10.2 RX-interrupt I denna funktion läses UART data registret och datat sparas i en variabel. Därefter beräknas ett nytt index för Rx-head och till slut sparas det mottagna datat i Rx-buffern. Om head och tail är lika, det vill säga att det inte finns några nya tecken, görs ingenting. 4.2.10.3 TX-interrupt Här kontrolleras först om all data skickats. Om det fortfarande finns data kvar i Tx-buffern, startas sändningen. Därefter beräknas ett nytt index för Tx-tail. Om all data är skickat, görs ingenting. 5 Verifiering 5.1 Testning Testandet påbörjades redan i en tidig fas. Detta skedde i form av simuleringar av olika elektronikkretsar i programvaran LTspice och i programmet Circuit Simulator Applet [2], som kan användas gratis på Internet. Det var främst för simuleringar av signalen från vinkelgivaren för att se att man får ut en rätt slags utspänning från differentialförstärkarkopplingen. Justeringar gjordes på resistorvärden på diff.kopplingen för att få de önskade spänningarna. Med 4mA och 20mA fick man 0,857V respektive 4,259V utspänning till A/D-ingångarna. Eftersom flera delar av elektronikkonstruktionen, såsom switchar och spänningsregulatorer, inte varit så avancerade har personalen på konstruktionsavdelningen på företaget kunnat granska dessa. Därför har de varken behövts simuleras eller testas rent fysiskt genom uppkoppling på en labb-platta. Med hjälp av Atmels utvecklingskort STK-500, och annan utrustning från EEPAB, samt ett labb-kort från MDH, har mycket av programkoden kunnat testas innan det slutliga mönsterkortet varit tillgänglig. Med ett spänningsaggregat kopplat till STK-kortet har man kunnat testa A/D-omvandlingen. Dessutom när labb-kortet, som innehåller en 7segmentdisplay med två tecken, kopplats till STK-kortet kunde man se hur spänningenförändringen påverkar resultatet på displayen. Även UART-interfacet har kunnat testas med samma STK-kort, genom att koppla kortet till datorns COM-port. Ett program, som heter Terminal, användes för att kunna se resultatet som man skickar från mikrokontrollern via UART-interfacet. 5.2 Testning av elektronikenhet Vad gäller testandet av elektronikenheten testades regulatorerna först för att se att man fick rätt spänning både in och ut. Step up-regulatorn skulle få in ca 7,2V från batteripacket och ge ut 12V. Vid testandet av elektronikenheten användes ett späningsaggregat istället för batteripacket från grävmaskinen, för verifiering av inspänning till step up-regulatorn. 17 Spänningsreglatorn skulle få in 12V och ge en utspänning på ca 5V. När allt detta var verifierat kunde testandet av mikrokontrollern påbörjas. På kortet finns två lysdioder som företaget lagt till för senare användning. För att testa mikrokontrollerns portar gjordes ett testprogram som tänder dessa lysdioder. När detta verifierats var det dags att koppla i displayen och testa dem. Slutligen kopplades vinkelgivaren på elektronikenheten för testning. Det sista som testades var kommunikationen mellan PC och elektronikenhet. Först måste spänningen till blåtandsmodulen kontrolleras, så att den får in 5V. Därefter kan verifieringen, av att mikrokontrollern kan skicka en vinkel via Bluetooth till ett terminalprogram i PC:n, göras. 6 Implementering När elektronikenheten hade testats och allt fungerade som det ska, monterades kortet in i grävmaskinen, se Bild 2 och Bild 4. Bild 2. Grävmaskinen Grävmaskinens batteripack kopplades till elektronikenheten så att den matas av grävmaskinen. Displayen, se Bild 3, sattes på plats på varsin sida av grävmaskinen. Vinkelgivaren fästes i skopan och en knapp för både nollställing av vinkel och för start och stop av programmet, monterades. Bild 3. Display som monteras på grävmaskinens bägge sidor Sedan drogs kablar från vinkelgivaren längs armen till elektronikenheten och från displayen till elektronikenheten. Det är i denna fas som demonstratorn blir till en färdig produkt, se Bild 5. 18 Bild 4. Elektronikenheten Bild 5. Den färdiga demonstratorn 7 Resultat och diskussion Det slutliga kortet, det vill säga elektronikenheten, som tillverkades fungerade i stort sett problemfritt redan från början. Endast värden på några resistorer fick ändras. Vad gäller programkod så fungerade allt nästan som det ska. Algoritmen för displayen hade några brister. Till exempel skrevs siffror på flera av displayerna samtidigt och på fel ställen, eftersom släckning av display inte utfördes rätt. Men med lite omkodning kunde problemet lösas. Nästa problem var att segmenten på displayen lyste alldeles för svagt. Detta berodde på att pnp-transistorn, som används i aktivering av display, inte öppnades ordentligt och därmed flöt inte tillräckligt mycket ström till displayen. Detta löstes med att byta plats på två resistorer. I kommunikation mellan elektronikenheten och PC:n finns några brister i programmet. Ett problem är att när buffern, dit tecknen som ska skickas lagras, blir full kommer några ”skräp”-tecken även att skrivas ut. För övrigt fungerar blåtandskommunikationen bra. Utöver det som var uppgiften i detta examensarbete gjordes det mycket annat till produkten. Företaget ville lägga till extra funktioner till demonstratorn så att den har bredare 19 användningsområde. Till exempel ville de att det ska vara möjligt att kunna koppla elektronikenheten till ett fordon. På grund av dessa extra funktioner påverkades uppgiften en aning, till exempel påverkades val av spänningsregulator samt att en Battery-Hold-signal, som aktiverar grävmaskinens batteripack som spänningskälla, fick läggas till. I det slutliga mönsterkortet som EEPAB tillverkat finns en switchad spänningsregulator, LM2734, istället för LM7805, som hade kunnat användas. Men eftersom EEPAB vill kunna koppla demonstratorn i ett fordon, och därmed matas den med fordonets batteri, vore inte LM7805 lämplig för detta. LM7805 är nämligen en linjär spänningsregulator som inte tål höga inspänningar. Däremot är LM2734 lämplig eftersom den kan matas med upp emot 20V, vilket räcker gott och väl då spänningen i ett fodonsbatteri är bara 12V. Dessutom fås mindre förluster, i form av värme, med LM2734. I kretsschemat ser man dock att en LM7805 används som 5V regulator även om det finns en LM2734 i det slutliga kretskortet. Detta på grund av att EEPAB ville ha denna extra funktion, som inte finns med i kravspecifikationen. 8 Slutsats Det har varit intressant att arbeta med detta projekt. Att få vara med i att designa och konstruera en produkt som kommer att användas av företaget känns roligt. Man har fått lära sig mycket nya saker under projektet och även se vad det är att jobba i ett företag. Eftersom arbetet utfördes individuellt var det bra att jobba på företaget då man kunde bolla idéer med kollegor. Tidsplanen höll inte eftersom det dröjde så pass länge innan kretskortet som konstruerats var tillgängligt. Detta på grund av att företaget själv ville rita in kretsscheman i sin programvara samt rita mönsterkortet. Eftersom företaget också hade annat att göra så var detta inte första prioritet. Dessutom beställdes kortet utomlands och därmed dröjde det ytterligare. Resultaten sett utifrån kravspecifikationen är bra. En fungerande demonstrator till företagets vinkelgivare har tagits fram. 20 9 Referenser [1] Accelerometer, http://en.wikipedia.org/wiki/Accelerometer, 2009-08-23 [2] Ciruit Simulator Applet, http://falstad.com/circuit 21 10 Bilaga A - Flödesscheman Main-funktion: START Main() INITIERING AV: I/O, TIMER0 ADC, UART AKTIVERA BATTERIPACK OÄNDLIG LOOP - GÖR DETTA SÅ LÄNGE SOM PROGRAMMET KÖRS. KONVERTERA ADC-RESULTAT TILL VINKEL SKRIV UT VINKEL PÅ DISPLAY 22 Display-funktion: START Display() DIGIT = 0 NEJ ÄR DISPLAYRÄKNARE 0? DISPLAYRÄKNARE-- JA DISPLAYRÄKNARE = 2 JA ÄR DIGIT 0? VINKELN LAGRAS I EN VARIABEL DIGIT = 8 NEJ SLÄCK ALLA SEGMENT I DISPLAY AKTIVERA DISPLAY(1,2,3,4) ÄR DIGIT 1? NEJ TA ABSOLUTBELOPPET AV VINKELN JA JA ÄR VINKELN NEGATIV? NEJ SLÄCK ALLA SEGMENT I DISPLAY SKRIV UT SIFFRA PÅ DISPLAY(1,2,3,4) DIVIDERA VINKEL MED 10 SKIFTA DIGIT EN BIT HÖGER 23 SKRIV UT MINUS-TECKEN PÅ DISPLAY 4 Timer-funktion: START A Timer() D ADCRÄKNARE++ HAR ADC-RÄKNARE NÅTT SITT MAX VÄRDE? NEJ STARTA TIMER0 JA NEJ LAGRA ADCRESULTAT I EN VARIABEL HAR TIMERN NÅTT MAX VÄRDE? STARTA NY OMVANDLING JA TIMER0 INTERRUPT SKER SKICKA VINKEL TILL PC A NOLLSTÄLL ADC-RÄKNARE B B NEJ C ÄR KALIB-SWITCH INTRYCKT? JA ÄR DISPLAYRÄKNARE 0? HAR KALIB-RÄKNARE NÅTT SITT MAX VÄRDE? NEJ KALIBRÄKNARE++ NEJ DISPLAYRÄKNARE-- JA NYTT OFFSETVÄRDE D NOLLSTÄLL KALIB-RÄKNARE C 24 JA 11 Bilaga B - Programkod Defines.h #define #define #define #define #define #define #define #define #define Bit0 0x01 Bit1 0x02 Bit2 0x04 Bit3 0x08 Bit4 0x10 Bit5 0x20 Bit6 0x40 Bit7 0x80 Bit15 0x8000 #define #define #define #define #define #define #define #define #define #define #define zero 0xFC one 0x60 two 0xDA three 0xF2 four 0x66 five 0xB6 six 0xBE seven 0xE0 eight 0xFE nine 0xF6 minus 0x02 #define #define #define #define SBit(Reg,Bit) (Reg |= Bit) // Sätter motsvarande bit i register Reg till 1. CBit(Reg,Bit) (Reg &= ~(Bit)) // Sätter motsvarande bit i register Reg till 0. Bit_True(Reg,Bit) ((Reg & Bit) == Bit) Bit_False(Reg,Bit) ((Reg & Bit) == 0) Main.c #include #include #include #include #include #include #include #include #include #include <ina90.h> <iom128.h> <stdio.h> <stdlib.h> <string.h> "basetype.h" "timer.h" "uart.h" "adc.h" "defines.h" int x; int tal1; int Angle; int Digit=0; int DispTemp; int value, value_abs; extern int counter_Disp; int SevenSeg[10]={zero,one,two,three,four,five,six,seven,eight,nine}; // Array med tio tecken som bildar siffrorna till displayen. void init_IO(void) // { DDRA=0xFF; // DDRB=0xFF; // DDRC=0xFF; // DDRD=0x00; // DDRE=0x22; // utport(Battery-Hold). DDRF=0x00; // } Initierar I/O-portarna. PORTA PORTB PORTC PORTD PORTE utport(Segments => Bildar siffrorna). utport utport(Common Anode => Styr displayen). bit 7:6 inport(Switch1 => Kalibrering av vinkel, start av program) bit 0 inport(UART Rx), bit 1 utport(UART Tx), bit 5 PORTF inport(ADC2:1 => Signal från givare) void Display(int value) // Display-funktion { if (counter_Disp != 0) // Om räknaren inte är 0... return; // ...gå ur funktionen. counter_Disp=2; // Räknaren tilldelas ett tal. if(Digit == 0) { Digit = 8; DispTemp = value; } // Om Digit är 0... // Tilldelas Digit 8, binärt 0000 1000. // Vinkeln lagras i variabeln DispTemp. 25 PORTA=0; // Släcker alla segment. PORTC=Digit; // Aktiverar D1/D2/D3/D4. if (Digit == 1) // Om Digit är 1... { if(value < 0) // Om vinkeln är negativ... { PORTA=minus; // Skriv ut minus-tecken på D4. } else // Annars... PORTA=0; // Släck segmenten. } else // Annars... PORTA=SevenSeg[abs(DispTemp%10)]; // Skriv ut siffra på display. DispTemp/=10; // Dividera DispTemp med 10. Digit >>=1; // Skifta Digit en bit till höger(minska med en bit). return; } void main(void) // Huvudprogram { /* Initieringar */ init_IO(); // Initierar in- och utportar. init_Timer0(); // Initierar timer0 för användning. init_ADC(); // Initierar A/D-omvandlaren. init_UART(); // Initierar UART-interfacet. __enable_interrupt(); // Möjliggör användning av interrupter. PORTB=0x30; PORTE=0x20; // Aktiverar batteripack. while(1) //forever loop { Angle=ADC_To_Deg(); // Sparar returvärdet från ADC_To_Deg() till varabeln Angle. Display(Angle); // Anropar funktionen Display() med Angle som inparameter. } } adc.c #include #include #include #include #include #include #include #include <ina90.h> <iom128.h> <stdio.h> <stdlib.h> <string.h> "basetype.h" "timer.h" "adc.h" float ADC_Angle; void init_ADC(void) { offset=524; ADCSR=0xC3; // Enable ADC(ADEN=1) och startar konversation. Prescaler faktor 8. ADMUX=0x40; // Extern ref.spänning(5V) och ADC0(PF0),som ingång,valt.Resultat Left Adjusted. } float ADC_To_Deg(void) { if (ADC_resultat > 150) // Om ADC-värdet är större än 150… ADC_Angle=(0.5226 * (float)(ADC_resultat-offset)); // Lutningen(vinkeln) fås ur ekvationen. else // Annars... ADC_Angle=0; // Skriv ut en nolla på display. return ADC_Angle; } timer.c #define timer_c #include <ina90.h> #include <iom128.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "basetype.h" #include "uart.h" 26 #include "timer.h" #include "adc.h" #include "defines.h" #define DELAY_ADC 135 #define DELAY_Kalib 900 #define DELAY_Stop 1350 int offset; int counter_ADC; int counter_Kalib; int counter_Stop; int counter_Disp; extern int Angle; /*---------------------------------------Timer Interrupt sker vid: DELAY_ADC ~300ms DELAY_Kalib ~2000ms DELAY_Stop ~3000ms -----------------------------------------*/ void init_Timer0(void) { TIMSK=0x01; // Timer/Counter Overflow Interrupt Enable. TCCR0=0x04; // Normal mode timer/counter. Prescaler faktor 64. } #pragma vector=TIMER0_OVF_vect __interrupt void TIMER_0_Interrupt (void) { if (counter_ADC++ >= DELAY_ADC) { ADC_resultat=ADC; // Läs av ADC-registret och spara till en variabel. ADCSR |= (1<<6); //Starta ny AD omvandling Print_int(Angle); // Skicka vinkeln till PC. counter_ADC=0; // Nollställer räknaren. } /* T1-Start/Stop */ if (Bit_True(PIND,Bit6)) // Om Switch1 intryckt… { if (counter_Stop++ >= DELAY_Stop) // Om tre sekunder gått… { PORTE=0x00; // Deaktiverar batteripack. PORTA=0x00; // Släcker segmenten. counter_Stop=0; // Nollställer räknaren. while (1); // Oändlig loop. } } else if (Bit_False(PIND,Bit6)) // Annars om Switch1 INTE är intryckt… { counter_Stop=0; // Nollställer räknaren. } /* T2-Nollställning */ if (Bit_True(PIND,Bit7)) // Om Switch2 intryckt… { if (counter_Kalib++ >= DELAY_Kalib) // Om två sekunder gått… { offset=ADC_resultat; // Ett nytt offset-värde tilldelas. counter_Kalib=0; // Nollställer räknaren. } } else if (Bit_False(PIND,Bit7)) // Annars om Switch2 INTE är intryckt… { counter_Kalib=0; // Nollställer räknaren. } if (counter_Disp != 0) { counter_Disp--; } // Om räknaren inte är 0… // Minska räknaren. } 27 uart.c #include #include #include #include #include #include #include #include #include #include <ina90.h> <iom128.h> <stdio.h> <stdlib.h> <string.h> "basetype.h" "timer.h" "adc.h" "defines.h" "uart.h" /* AT-Kommandon */ char HangUpp[] = "ATH\r"; char AskBTR[] = "AT+BTR?\r"; char HWReset[] = "ATZ\r"; char WriteNovRam[] = "AT&W\r"; char ClearNovRam[] = "AT&F*\r"; char Sreg504[] = "ATS504=1\r"; char Sreg507[] = "ATS507=0\r"; char Sreg512[] = "ATS512=1\r"; char Sreg520[] = "ATS520=9600\r"; char Sreg530[] = "ATS530=2000\r"; char PrintBuf[10]; /* UART Buffer Defines */ #define UART_RX_BUFFER_SIZE 128 #define UART_TX_BUFFER_SIZE 128 // 2,4,8,16,32,64,128 or 256 bytes #define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1 ) #if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK ) #error RX buffer size is not a power of 2 #endif #define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1 ) #if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK ) #error TX buffer size is not a power of 2 #endif char char char char char char UART_RxBuf[UART_RX_BUFFER_SIZE]; UART_RxHead; UART_RxTail; UART_TxBuf[UART_TX_BUFFER_SIZE]; UART_TxHead; UART_TxTail; /* Initiering av UART */ void init_UART(void) { unsigned char x; UBRR0L = 0x2F; // Sätter baud rate till 9600 /* Enable UART receiver och transmitter, och receive interrupt */ UCSR0B = ( (1<<RXCIE0) | (1<<RXEN0) | (1<<TXEN0) ); x = 0; UART_RxTail UART_RxHead UART_TxTail UART_TxHead = = = = x; x; x; x; } /* Interrupt hanterare */ #pragma vector=USART0_RXC_vect __interrupt void UART_RX_interrupt( void ) { unsigned char data; unsigned char tmphead; data = UDR0; // Läser mottagen data /* Beräkna buffer index */ tmphead = ( UART_RxHead + 1 ) & UART_RX_BUFFER_MASK; UART_RxHead = tmphead; // Lagra ny index 28 if ( tmphead == UART_RxTail ) { /* ERROR! Receive buffer overflow */ } UART_RxBuf[tmphead] = data; // Lagra mottagen data i buffer } #pragma vector=USART0_UDRE_vect __interrupt void UART_TX_interrupt( void ) { unsigned char tmptail; if ( UART_TxHead != UART_TxTail ) // Kontrollera om all data sänts { UDR0 = UART_TxBuf[UART_TxTail]; // Starta sändning /* Beräkna buffer index */ tmptail = ( UART_TxTail + 1 ) & UART_TX_BUFFER_MASK; UART_TxTail = tmptail; // Lagra ny index } else { UCSR0B &= ~(1<<UDRIE0); // Disable UDRE interrupt } } void TransmitArray(char *data, char size) { unsigned char tmphead; /* Beräkna buffer index */ tmphead = ( UART_TxHead + size ) & UART_TX_BUFFER_MASK; // Invänta ledig utrymme i buffern while ( tmphead == UART_TxTail ); if(UART_TxHead==0) { memcpy(&UART_TxBuf[UART_TxHead], data, size); } else if ( size < (char)(UART_TX_BUFFER_SIZE - tmphead)) { memcpy(&UART_TxBuf[tmphead], data, size); } UCSR0B |= (1<<UDRIE0); UART_TxHead = tmphead; /* Enable UDRE interrupt */ /* Lagra ny index */ } void Print_int(int data) { wordToAsciiString(PrintBuf, (WORD)data); TransmitArray(PrintBuf,strlen(PrintBuf)); } void wordToAsciiString(char * Buffer, WORD Value) { WORD InValue = Value; Buffer[0] = ' '; if (BITTRUE(InValue, BIT15)) { InValue = (~InValue)+1; Buffer[0] = '-'; } //Buffer[1] = (InValue/10000) + '0'; //InValue = InValue%10000; //Buffer[2] = (InValue/1000) + '0'; //InValue = InValue%1000; Buffer[1] = (InValue/100) + '0'; InValue = InValue%100; Buffer[2] = (InValue/10) + '0'; InValue = InValue%10; Buffer[3] = InValue + '0'; Buffer[4] = '\n'; //Buffer[7] = 0; } 29 12 Bilaga C - Kretsscheman Mikrokontroller + annat: 30 Transistorsteg: 31 Display: 32 13 Bilaga D – Datablad 13.1 ATMega128 33 34 35 13.2 Vinkelgivare 36 13.3 Spänningsregulator LM2734 37 13.4 Step up-regulator LM2577 38