Autonom robotväckarklocka med trådlös basstation - KTH
Autonom robotväckarklocka med trådlös basstation - KTH
Autonom robotväckarklocka med trådlös basstation - KTH
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
<strong>Autonom</strong> <strong>robotväckarklocka</strong> <strong>med</strong> <strong>trådlös</strong><br />
<strong>basstation</strong><br />
ANDRÉ BERGLUND<br />
JOANNA FREDRIKSSON LARSSON<br />
ANNIE GUSTAFSSON<br />
MAZDA IMANI<br />
OLA JOHANNESSON<br />
Kandidatarbete<br />
Stockholm, Sverige 2011
<strong>Autonom</strong> <strong>robotväckarklocka</strong> <strong>med</strong> <strong>trådlös</strong> <strong>basstation</strong><br />
av<br />
André Berglund<br />
Joanna Fredriksson Larsson<br />
Annie Gustafsson<br />
Mazda Imani<br />
Ola Johannesson<br />
Kandidatarbete MMKB 2011:53 MDAB 022<br />
<strong>KTH</strong> Industriell teknik och management<br />
Maskinkonstruktion<br />
SE-100 44 STOCKHOLM
Godkänt<br />
2011-005-18<br />
Sammaanfattningg<br />
Exa aminator<br />
Ma artin Edin GGrimheden<br />
n<br />
Han ndledare<br />
Sta affan Qvarrnström<br />
KKandidata<br />
arbete MMKB<br />
2011:553<br />
MDAB 022<br />
A<strong>Autonom</strong><br />
robotväck karklocka <strong>med</strong> <strong>trådlös</strong><br />
bass station<br />
AAndré<br />
Berg glund, Joan nna Fredrikksson<br />
Lars sson<br />
Anni ie Gustafss son, Mazda<br />
Imani<br />
Ola Joh hannessonn<br />
Handledare<br />
H<br />
Martin M Edinn<br />
Grimhede en<br />
Handledare<br />
H<br />
Ulf U Andorff<br />
Denna rrapport<br />
är reesultatet<br />
av ett projektaarbete<br />
i en grundkurs g i mekatronikk.<br />
Målet var att<br />
integrerra<br />
moduler ffrån<br />
gruppm <strong>med</strong>lemmarnnas<br />
expertom mråden till en funktionnsduglig<br />
pro ototyp.<br />
Temat fför<br />
projektett<br />
var att gör ra en tråkig vardagssyssla<br />
roligare.<br />
Temat tolkkades<br />
till at tt det aldrig<br />
är kul attt<br />
försova siig,<br />
vilket resulterade<br />
attt<br />
en ny typ av väckarklocka<br />
konsttruerades.<br />
Det D<br />
speciella<br />
<strong>med</strong> dennna<br />
är att stop ppknappen fför<br />
alarmet flyttar på si ig under nattten,<br />
vilket innebär att<br />
den somm<br />
ska väckaas<br />
både måst te kliva uppp<br />
ur sängen och leta red da på avstänngningsknap<br />
ppen.<br />
Avstänggningsknapppen<br />
monterades<br />
på en ssjälvgående<br />
e robot, som m förflyttar ooch<br />
naviger rar i<br />
rummett<br />
<strong>med</strong> hjälp av stegmoto orer och ulttraljud.<br />
På roboten r finn ns det en LEED-matris<br />
so om visar<br />
den aktuuella<br />
tiden ooch<br />
text<strong>med</strong> ddelanden. IInställning<br />
av tid och alarm a sker vvia<br />
en stationär<br />
basstatioon<br />
<strong>med</strong> en ppekskärm.<br />
Kommunika K ationen mel llan enheterna<br />
sker via blåtand. Slu utligen<br />
tillverkaades<br />
en funggerande<br />
pro ototyp som ” ”proof of co oncept” <strong>med</strong> d en basstattion<br />
i plexig glas och<br />
robot i bbockat<br />
alumminium.
Approved<br />
2011-005-18<br />
Abstraact<br />
Exa aminer<br />
Ma artin Edin GGrimheden<br />
n<br />
Sup pervisor<br />
Sta affan Qvarrnström<br />
BBachelor<br />
Thesis T MM MKB 2011: 53 MDAB 022<br />
Autoonomous<br />
robotic al larm clockk<br />
with a wireless w<br />
cont trol unit<br />
AAndré<br />
Berg glund, Joan nna Fredrikksson<br />
Lars sson<br />
Anni ie Gustafss son, Mazda<br />
Imani<br />
Ola Joh hannessonn<br />
Supervisor<br />
Martin Edin<br />
Grimhed den<br />
Supervisor<br />
Ulf Andorfff<br />
This repport<br />
is the reesult<br />
of a pr roject in an introductor ry course in mechatroniics.<br />
The obj jective was<br />
to integrrate<br />
modulees<br />
from each h group memmbers'<br />
area as of experti ise into a fun unctioning prototype. p<br />
The themme<br />
for the pproject<br />
was to make a ddire<br />
daily ac ctivity more e fun. The thheme<br />
was in nterpreted<br />
that it iss<br />
never fun to oversleep p, which arrrived<br />
at a ne ew type of alarm a clockk<br />
being cons structed.<br />
What iss<br />
special aboout<br />
is that th he off buttonn<br />
for the ala arm moves during the nnight,<br />
which h means<br />
that the person whoo<br />
needs to wake w up hass<br />
to get out of o bed and find f it. The off button was w rigged<br />
on to a sself-driven<br />
robot that moves m and nnavigates<br />
th he room with h the help oof<br />
two stepp per motors<br />
and an uultrasound.<br />
On top of th he robot theere<br />
is a LED D dot matrix x that displaays<br />
the curre ent time<br />
and scroolling<br />
text mmessages.<br />
Setting<br />
the al alarm and what<br />
time it is i does withh<br />
the help of f a<br />
stationaary<br />
base stattion<br />
with a touch t screenn.<br />
The comm munication between thhe<br />
devices operates o via<br />
Bluetoooth.<br />
At the eend<br />
a workin ng prototyppe<br />
was const tructed as a "proof of cconcept”<br />
with<br />
a base<br />
station mmade<br />
out off<br />
Plexiglas and a a robot made out of o bent alum minum.
En självgående väckarklocka<br />
<strong>med</strong> ställbart larm från en<br />
<strong>basstation</strong><br />
André Berglund<br />
Joanna Fredriksson Larsson<br />
Annie Gustafsson<br />
Mazda Imani<br />
Ola Johannesson<br />
Kandidatarbete i Mekatronik<br />
Stockholm 2011
Sammanfattning<br />
Denna rapport är resultatet av ett projektarbete i en grundkurs i mekatronik. Målet var att<br />
integrera moduler från grupp<strong>med</strong>lemmarnas expertområden till en funktionsduglig prototyp.<br />
Temat för projektet var att göra en tråkig vardagssyssla roligare. Temat tolkades till att det<br />
aldrig är kul att försova sig, vilket resulterade att en ny typ av väckarklocka konstruerades.<br />
Det speciella <strong>med</strong> denna är att stoppknappen för alarmet flyttar på sig under natten, vilket<br />
innebär att den som ska väckas både måste kliva upp ur sängen och leta reda på<br />
avstängningsknappen.<br />
Avstängningsknappen monterades på en självgående robot, som förflyttar och navigerar i<br />
rummet <strong>med</strong> hjälp av stegmotorer och ultraljud. På roboten finns det en LED-matris som<br />
visar den aktuella tiden och text<strong>med</strong>delanden. Inställning av tid och alarm sker via en<br />
stationär <strong>basstation</strong> <strong>med</strong> en pekskärm. Kommunikationen mellan enheterna sker via blåtand.<br />
Slutligen tillverkades en fungerande prototyp som ”proof of concept” <strong>med</strong> en <strong>basstation</strong> i<br />
plexiglas och robot i bockat aluminium.
Abstract<br />
This report is the result of a project in an introductory course in mechatronics. The objective<br />
was to integrate modules from each group members' areas of expertise into a functioning<br />
prototype. The theme for the project was to make a dire daily activity more fun. The theme<br />
was interpreted that it is never fun to oversleep, which arrived at a new type of alarm clock<br />
being constructed. What is special about is that the off button for the alarm moves during the<br />
night, which means that the person who needs to wake up has to get out of bed and find it.<br />
The off button was rigged on to a self-driven robot that moves and navigates the room with<br />
the help of two stepper motors and an ultrasound. On top of the robot there is a LED dot<br />
matrix that displays the current time and scrolling text messages. Setting the alarm and what<br />
time it is does with the help of a stationary base station with a touch screen. The<br />
communication between the devices operates via Bluetooth.<br />
At the end a working prototype was constructed as a "proof of concept” with a base station<br />
made out of Plexiglas and a robot made out of bent aluminum.
Innehåll<br />
Inledning ..................................................................................................................................... 1<br />
Problemdefinition ....................................................................................................................... 1<br />
Problemlösning ........................................................................................................................... 2<br />
Basstation ................................................................................................................................ 2<br />
Pekskärm ............................................................................................................................. 2<br />
Robot ...................................................................................................................................... 3<br />
Stegmotorerna ..................................................................................................................... 4<br />
Ultraljud .............................................................................................................................. 5<br />
LED-matris ......................................................................................................................... 8<br />
Kommunikation mellan modulerna ...................................................................................... 11<br />
Kommunikation mellan LED-kontrollern och baskontrollern .......................................... 12<br />
Kommunikation LED-kontrollern och rörelsekontrollern ................................................ 13<br />
Prototypen ............................................................................................................................. 14<br />
Roboten ............................................................................................................................. 15<br />
Basstationen ...................................................................................................................... 17<br />
Färdig lösning ........................................................................................................................... 18<br />
Erfarenheter/ Problem under gång ........................................................................................... 19<br />
Ultraljudsmodulen ................................................................................................................ 19<br />
Pekskärm .............................................................................................................................. 19<br />
Slutsatser och förslag till förbättringar ..................................................................................... 20<br />
Referenser ................................................................................................................................. 22<br />
Bilagor<br />
Bilaga A. Kravspecifikation<br />
Bilaga B. Komponentlista och kostnadsredovisning
Bilaga C. Använda portpinnar hos AVR:en<br />
Bilaga D. Blåtand- kommunikationsprotokoll<br />
Bilaga E. Elektroniska ritningar - kretsschema/ layout<br />
Bilaga F. Mekaniska ritningar <strong>med</strong> måttsättning<br />
Bilaga G. Programlistningar<br />
Bilaga H. Anslutningar mellan moduler och kretskort<br />
Bilaga I. LED punktmatris<br />
Bilaga J. Ultraljudslinjal – Avståndsmätning <strong>med</strong> ultraljud<br />
Bilaga K. Stegmotorer – Funktion och tillämpning<br />
Bilaga L. Stegmotor – Ett fördjupningsarbete i mekatronik<br />
Bilaga M. LCD <strong>med</strong> touchpanel
Inledning<br />
Denna rapport beskriver det projekt en grupp om fem teknologer från <strong>KTH</strong> har genomfört<br />
som kandidatarbete inom Mekatronik. Projektet avser att kombinera grupp<strong>med</strong>lemmarnas<br />
tidigare arbeten <strong>med</strong> varsin modul (deras olika expertområden) för att ta fram en produkt på<br />
temat ”Att göra en tråkig vardagssyssla roligare”.<br />
Alla grupp<strong>med</strong>lemmar hade tidigare jobbat <strong>med</strong> att sätta in sig i olika moduler. De olika<br />
expertområdena som fanns inom gruppen var följande:<br />
Stegmotor (2 personer)<br />
Ultraljud<br />
Pekskärm<br />
LED-matris<br />
Den produkt som valdes att ta fram var en ny typ av väckarklocka, <strong>med</strong> motiveringen att<br />
dagen blir mycket roligare om du inte försover dig. Den sammanlagda extrakostnaden för att<br />
färdigställa prototypen, utöver kostanden för de individuella projekten, fick inte överstiga<br />
1500 kr.<br />
Problemdefinition<br />
Det som i rapporten föreslås är en möjlig teknisk lösning till problemet <strong>med</strong> svårigheten att<br />
komma upp ur sängen när väckarklockan ringer på morgonen. En vanlig väckarklocka har två<br />
huvudfunktioner, dels att under natten visa tid och dels att väcka den sovande på morgonen.<br />
Erfarenheter från flera av gruppens <strong>med</strong>lemmar tyder dock på att konventionella<br />
väckarklockor brister i sin effektivitet på den andra punkten. Även om de väcker den sovande<br />
personen så finns risk att denne somnar om.<br />
Ett vanligt problem <strong>med</strong> konventionella väckarklockor är man oftast kan stänga av dem på<br />
rutin utan att riktigt vakna till. Detta kan hända även om väckarklockan placeras utom<br />
räckhåll. En möjlig lösning är att ha en väckarklocka som befinner sig på ett nytt ställe i<br />
rummet varje gång den ska stängas av.<br />
Det var denna idé som låg till grund för detta projekt och sammanställdes i<br />
kravspecifikationen (se Bilaga A).
Problemlösning<br />
Projektet består av två separata delar, en stationär <strong>basstation</strong> och en självgående robot, som<br />
kommunicerar <strong>trådlös</strong>t <strong>med</strong> varandra. Basstationen fungerar som en normal väckarklocka; den<br />
visar tid och kan ställa alarmtid. Skillnaden mot en normal väckarklocka är att<br />
avstängningsknappen sitter på roboten, vilket tvingar användaren att gå upp för att stänga av<br />
den. För att möjliggöra att <strong>basstation</strong>en bestämmer larmtiden för roboten och att roboten<br />
stänger av väckarklockan är den <strong>trådlös</strong>a kommunikationen mellan dessa dubbelriktad.<br />
Basstation<br />
Figur 1 <strong>basstation</strong> och robot, <strong>trådlös</strong> kommunikation<br />
Basstationen består av en mikrokontroller till vilken en pekskärm och en modul för <strong>trådlös</strong><br />
kommunikation är inkopplade. Tanken bakom <strong>basstation</strong>en är att den ska efterlikna en vanlig<br />
digital väckarklocka som man kan ställa bredvid sängen. Med hjälp av en pekskärm kan<br />
användaren navigera runt i gränssnittet <strong>med</strong> en pekpenna alternativt sitt finger.<br />
Huvudfunktionen hos <strong>basstation</strong>en är att användaren ska kunna ställa in aktuell tid och önskad<br />
tid för alarm.<br />
Pekskärm<br />
Figur 2 Principskiss <strong>basstation</strong><br />
Vid påslagning möts användaren av en startsida innehållandes huvudmenyn som består av tre<br />
alternativ. Det ena kallas för ”TIME” och är inställningen av aktuell tid. Det andra
alternativet, ”ALARM”, liknar ”TIME” men är inställning av önskad tid för alarmet. Tid och<br />
alarm ställs in genom att bläddra fram rätt tid (timme, minut och sekund) <strong>med</strong> hjälp av två<br />
pilar för vardera tidsenhet. Då användaren är nöjd <strong>med</strong> inställningen trycker denna på ”SET”<br />
vilket verkställer inställningen och tar sig tillbaka till startsidan <strong>med</strong> ”BACK”. Roboten går<br />
även att styra <strong>trådlös</strong>t från <strong>basstation</strong>en genom det tredje alternativet ”MOVE”. Text för<br />
respektive riktning och en stoppknapp styr roboten.<br />
Klocka<br />
Den viktigaste funktionen, klockan, drivs genom mikrokontrollerns Real Time Counter, RTC.<br />
En extern kristall om 32,768kHz sitter mellan två dedikerade pinnar på basmikrokontrollern<br />
och används för att räkna klockcykler och göra sekunder så exakta som möjligt. Kristallens<br />
klockcykler räknas av en inbyggd timer i basmikrokontrollern <strong>med</strong> en viss förinställning (pre-<br />
scaler) om att öka ett steg var 1024:e cykel. Detta ger att timern ökar 32 gånger per sekund.<br />
Då timern når 32 återställs den till noll och ett interrupt utlöses, som ökar sekundvariabeln<br />
<strong>med</strong> ett. Denna procedur upprepas gång på gång och ger en tid motsvarande en sekund.<br />
Strömförsörjning<br />
Basstationen använder sig av en nätadapter för sin strömförsörjning, vilket innebär att den får<br />
sin el via vägguttaget och på så vis eliminerar behovet av batterier samt att man inte behöver<br />
oroa sig för att strömmen ska ta slut i batterierna. Nätadaptern omvandlar nätspänningen till<br />
likspänning om 12V. Eftersom flera komponenter i systemet är specificerade för 3,3V sitter<br />
även en spänningsregulator på <strong>basstation</strong>en strax efter anslutningen för nätadaptern.<br />
Robot<br />
Roboten har ett antal skilda uppgifter,<br />
Visa tiden på en LED-matris<br />
Kunna stänga av larmet <strong>med</strong> en knapp<br />
Kunna förflytta sig autonomt.<br />
Figur 3 Principskiss för tidsinställning
Funktionerna i roboten har av praktiska skäl delats upp på två mikrokontroller. En som har det<br />
övergripande ansvaret för robotens beteende samt LED-matrisen (LED-kontrollern) och en<br />
som styr rörelsen (rörelsekontrollern).<br />
Till LED-kontrollern är en LED-matris, en <strong>trådlös</strong> kommunikationsmodul och en knapp<br />
inkopplad. En anslutning för kommunikation <strong>med</strong> rörelsekontrollern finns också, och via<br />
denna styr LED-kontrollern vad rörelsekontrollern ska göra.<br />
Figur 4 principskiss LED-kontrollern<br />
Till rörelsekontrollern är två stegmotorer och en avståndssensor <strong>med</strong> ultraljud kopplad, samt<br />
kommunikationen från LED-kontrollern. De två stegmotorerna används för framdrivningen<br />
av roboten, och avståndssensorn används för att den på egen hand ska kunna undvika att köra<br />
in i föremål.<br />
Stegmotorerna<br />
Figur 5 principskiss rörelsekontrollern<br />
Bilen drivs av två stegmotorer, för att underlätta styrningen av roboten. Varje motor driver<br />
varsitt hjul och där<strong>med</strong> kan roboten vrida på sig. De stegmotorer som används är två bipolära<br />
hybrida stegmotorer, modell 6540-13-2-9 från Sonceboz.
Drivning<br />
För att styra de båda stegmotorerna individuellt används två dubbla H-bryggor av modell<br />
UDN2916B-T från Allegro. Dessa är ihopkopplade <strong>med</strong> stegmotorerna på ett sådant sätt att<br />
de styr varsin motor (se Bilaga E). En dedikerad mikrokontroller används för att styra H-<br />
bryggorna eftersom de tar många pinnar i anspråk (se Bilaga C).<br />
Figur 6 H-bryggornas kretskort<br />
Ett program skrevs för att kunna styra båda motorerna samtidigt, där en timer används för att<br />
styra vinkelhastigheten för hjulen. Då halvsteg gav tillräckligt jämn gång valdes den som<br />
stegtyp. Se Bilaga L för stegsekvenser, komponentval och byggbeskrivning av H-bryggan.<br />
Ultraljud<br />
För att roboten ska kunna köra omkring på egen hand behövs någon typ av sensor som kan<br />
göra den <strong>med</strong>veten om sin omgivning. Valet föll på en färdig modul <strong>med</strong> ultraljudssensor, en<br />
SRF04 från Devantech. Denna skickar information i form av pulsbredd. Till modulen skickas<br />
en styrpuls, som sedan returnerar en puls <strong>med</strong> längden proportionell mot avståndet till<br />
närmaste objekt. Både genereringen och mätningen av dessa pulser tas om hand av en timer,<br />
Timer1. I en ATMega16 är detta en 16-bitars timer <strong>med</strong> dubbla komparatorer. Runt denna<br />
timer är en tillståndsmaskin uppbyggd, som fungerar enligt Figur 7.
De olika tillstånden är:<br />
Figur 7 Timerdiagram för ultraljudsmodulen SRF04<br />
Figur 8 Ultraljudets olika tillstånd<br />
Ready<br />
Ultraljudssensorn är redo att göra en mätning<br />
Signal<br />
Styrpinnen till ultraljudsmodulen är dragen hög, puls skickas till sensorn<br />
Waitreturn<br />
Pulsen till ultraljudsmodulen skickad, väntar på att modulen ska starta den<br />
returnerade pulsen<br />
Running<br />
Den returnerade pulsen har påbörjats, väntar på att den avslutas<br />
Waiting<br />
Väntar 10 ms, vilket modulen kräver mellan mätningarna
I början av mikrokontrollens program initieras alla nödvändiga register för Timer1, de båda<br />
komparatorerna samt det externa interruptet. Sedan görs ett försök att påbörja mätningarna,<br />
enligt Figur 9.<br />
Figur 9 Flödesschema för initieringen av ultraljudet<br />
Tillståndsmaskinen körs i roboten i ett läge som kallas 'Free Running mode', för att<br />
programmet ska fungera oberoende av ultraljudssensorn. Detta innebär att tillståndsmaskinen<br />
hämtar nya mätvärden från ultraljudsmodulen så fort den klarar av det. Tillståndsmaskinen<br />
fungerar sedan genom följande interrupts:<br />
Externt interrupt<br />
Kopplad till ultraljudsmodulens utgångspinne, känner av alla förändringar och<br />
används för att få start- och slutpunkt på den returnerade pulsen<br />
CompA interrupt<br />
En av jämförelseinterrupten för Timer1, används för att mäta tid tills styrpinnen<br />
ska sänkas<br />
CompB interrupt<br />
Den andra jämförelseinterrupten för Timer1, används för att <strong>med</strong>dela när<br />
tillräckligt lång tid passerat efter slutet på den returnerade pulsen för att man ska<br />
kunna påbörja en ny mätning (mer än 10 ms, se Figur 7)<br />
Overflow interrupt<br />
Om tillståndsmaskinen hamnar i ett ogiltigt tillstånd nollställs den när Timer1 når<br />
overflow. Ska normalt aldrig behövas.
LED-matris<br />
Figur 10 Flödesschema för de olika ultraljuds interrupten<br />
Roboten har en LED-matris för att visa tiden och en rullande text då larmet går. LED-<br />
matrisen tillverkades om 8 rader och 16 kolumner, för att kunna visa klockan digitalt, vilket<br />
ger en matris <strong>med</strong> 128 lysdioder.<br />
Bygget av modulen<br />
Det beslutades att LED-matrisen skulle tillverkas i aluminiumplåt, eftersom aluminium är<br />
både snyggt, tåligt och relativt lättbearbetat. 128 hål borrades in i en 10 cm bred och 22 cm<br />
lång aluminiumplåt.
Figur 11 LED-matrisen<br />
När lysdioderna löddes ihop var det viktigt att se till att det blev bra isolerat för att undvika<br />
kortslutning, speciellt <strong>med</strong> tanke på att LED-matrisen tillverkas i aluminium.<br />
Figur 12 Lysdioderna löds ihop<br />
Idealt ska matrisen uppdatera sig så snabbt som möjligt för att undvika flimmer. Därför tänds<br />
de 8 raderna växelvis istället för de 16 kolumnerna vid multiplexing (se Bilaga I).<br />
Styrkortet gjordes på ett separat etsat kretskort. Till port B och port C på mikrokontrollern<br />
kopplades de 16 kolumnerna in via förkopplingsmotstånd, och till port A kopplades de 8<br />
raderna in via MOSFETs.<br />
Anoder<br />
Katoder
Program<br />
Figur 13 Styrkrets för LED-displayen<br />
Programmet består av två delar, klockan och den rullande texten. Då larmet aktiveras går den<br />
rullande texten igång tills dess att avstängningsknappen trycks ner och klockan börjar visas<br />
igen.<br />
Mode = 1 <br />
Initiering av visa<br />
klocka<br />
Initiering av timer<br />
Hämta värden från timern.<br />
Använd dessa för att tända<br />
LEDsen så att de visar<br />
önskad bokstav.<br />
Tänd raderna i LED<br />
matrisen en i taget i en<br />
snabb följ efter varandra<br />
för att få en synlig bild på<br />
displayen.<br />
Tryck på avstängningsknappen<br />
Alarm går igång<br />
Interrupt<br />
Mode = 1 <br />
Minuterna ökas och<br />
tiden justeras.<br />
Mode = 2 <br />
Initiering av rulla<br />
text<br />
Mode = 2 <br />
Skifta plats för varje<br />
bokstav. Detta görs 8<br />
ggr, så det ser ut som<br />
att den rullar förbi på<br />
displayen. Byt sedan<br />
till nästa bokstav i<br />
textsträngen.<br />
Figur 14 Flödesdiagram över LED-matrisens funktioner
Klocka<br />
LED-matrisen visar klockan i timmar och minuter. I programmet används en timer som<br />
kontrollerar en minut- och timvariabel. Denna timer är alltid igång oavsett vad som visas på<br />
displayen.<br />
Rullande text<br />
Figur 15 LED-matrisens klocka<br />
Då larmet går igång rullar en text fram på displayen som ses när man vaknar. Denna funktion<br />
använder en annan timer som går igenom en textsträng <strong>med</strong> de bokstäver som ska skrivas ut<br />
på LED-matrisen.<br />
Kommunikation mellan modulerna<br />
Figur 16 LED-matrisens text "vakna" rullar<br />
Då LED-kontrollern alltid ska vara igång, för att kunna visa den aktuella tiden, fattades<br />
beslutet att låta kommunikationen ske mellan LED-kontrollern och baskontrollern. LED-<br />
kontrollern vidarebefordrar därefter kommandona till rörelsekontrollern.
Kommunikation mellan LED-kontrollern och baskontrollern<br />
Den typ av data som <strong>basstation</strong>en kan skicka till fordonet är signaler om aktuell tid, larmning,<br />
att starta automatisk förflyttning och att styra fordonet manuellt. Då projektgruppen saknade<br />
specialistkompetens inom kommunikation valdes seriekommunikation som<br />
kommunikationsprotokoll. Detta är relativt enkelt att implementera i mikrokontrollerna<br />
samtidigt som det går att skicka långa <strong>med</strong>delanden och kommandon.<br />
Eftersom kommunikationen sker <strong>trådlös</strong>t var ett alternativ att bygga en RF-modulator <strong>med</strong><br />
sändare och mottagare. Denna typ av kommunikation har dock ett antal nackdelar, den har<br />
oskyddad frekvens och det finns ingen inbyggd felkontroll. Därför valdes blåtand, eftersom<br />
denna teknik har inbyggd felkontroll, stöd för seriekommunikation samt är relativt enkel att<br />
implementera. Dessutom skulle även datorer och mobiltelefoner <strong>med</strong> blåtand kunna användas<br />
för att kontrollera fordonet. Blåtandsmodulen som valdes heter Parani ESD-210 och är från<br />
Sena technologies. Denna valdes då den var det billigaste alternativet som gick att få tag på<br />
<strong>med</strong> kort varsel, samt att den hade ett enkelt gränssnitt.<br />
Figur 17 Blåtandsmodulen ansluten till adapterkortet<br />
Blåtandsmodulen fungerar så att den styrs <strong>med</strong> AT-kommandon via seriekommunikation (se<br />
datablad för blåtanden). Varje modul har en unik adress och genom att göra den ena modulen<br />
synlig och anslutningsbar samtidigt som den andra försöker ansluta kan en anslutning<br />
upprättas. Därefter kommer blåtandsmodulerna att automatiskt vidarebefordra de kommandon<br />
som matas in.
Eftersom seriekommunikation bara skickar 1 byte åt gången skapades ett<br />
kommunikationsprotokoll för styrning av roboten (se Bilaga D).<br />
Slutligen tillverkades ett adapterkort <strong>med</strong> spänningsregulator och spänningsdelare så att<br />
blåtandsmodulen <strong>med</strong> spänningen 3,3 V kan kommunicera <strong>med</strong> mikroprocessorn på 5 V<br />
(Figur 7).<br />
Kommunikation LED-kontrollern och rörelsekontrollern<br />
Den typ av kommunikation som sker mellan LED- och rörelsekontrollern är<br />
envägskommunikation, där LED-kontrollern skickar kommandon om vilket driftläge roboten<br />
skall ha. Följande kommandon används:<br />
Kör runt automatiskt<br />
Larma<br />
Kör framåt<br />
Kör bakåt<br />
Sväng vänster<br />
Sväng höger<br />
Stå stilla<br />
Då LED-kontrollern är av typen ATMega16 har den endast stöd för seriekommunikation <strong>med</strong><br />
en enhet. Eftersom kommunikationen till rörelsekontrollern endast består utav sju olika<br />
envägskommandon togs beslutet att styra rörelsekontrollern <strong>med</strong> 3-bitars<br />
parallellkommunikation som ger olika kommandon genom att höja och sänka de tre pinnarna<br />
på mikrokontrollern. Då 3-bitar totalt kan ge åtta kombinationer behövs inget avancerat<br />
kommunikationsprotokoll (Tabell 1 Lista över de olika utgående kommandona), utan<br />
rörelsekontrollern ”lyssnar” hela tiden på inkommande kommandon.<br />
Utgående bitar Kommando nr Kommando<br />
000 0 Stå stilla/gör inget<br />
001 1 Kör runt automatiskt<br />
010 2 Larma<br />
011 3 Kör framåt
100 4 Kör bakåt<br />
101 5 Sväng vänster<br />
110 6 Sväng höger<br />
111 7 Stå stilla/gör inget<br />
Tabell 1 Lista över de olika utgående kommandona<br />
Eftersom H-bryggorna, ultraljudsmodulen och rörelsekontrollern inte används större delen av<br />
tiden, men ändå drar ström i vänteläge, fattades beslutet att <strong>med</strong> hjälp av LED-kontrollern<br />
styra när dessa moduler ska slås på eller av. Detta görs genom att styra en MOSFET av typ<br />
BUZ 71 i pull-down-läge <strong>med</strong> hjälp av en ledig utgång på LED-kontrollern.<br />
Slutligen tillverkades ett adapterkort (Figur 18) <strong>med</strong> anslutningar för seriekommunikationen<br />
till blåtandsmodulen, 3-bitarskommunikationen till rörelsekontrollern, strömförsörjningen till<br />
de moduler som ska stängas av när de inte behövs och en avstängningsknapp för alarmet. Allt<br />
detta kopplades därefter till port D på LED-kontrollern.<br />
Prototypen<br />
Figur 18 Adapterkortet <strong>med</strong> MOSFET i förgrunden<br />
En prototyp av roboten och <strong>basstation</strong>en byggdes. Hur detta gjordes beskrivs nedan.
Roboten<br />
Chassit till roboten är en fyrkantig låda <strong>med</strong> två hjul som sticker ut på sidan och ett stödhjul<br />
under lådan. Ultraljudsmodulen sitter på framsidan och LED-matrisen sitter fast i locket<br />
tillsammans <strong>med</strong> avstängningsknappen för larmet, bilens Bluetooth-antenn och<br />
vippströmbrytaren. För ritningar på chassit, se Bilaga F.<br />
Chassit (Figur 19) till bilen är gjort i 1,5 mm tjock aluminiumplåt. De fyra hörnen på<br />
aluminiumbiten sågades bort <strong>med</strong> en bandsåg och de fyra sidorna bockades till en lådform.<br />
Fyra vinklar bockades och skruvades fast i lådan så att den blev stabil. Sedan borrades hål på<br />
vardera långsida där de två stegmotorerna träddes igenom och skruvades fast och ett hål på<br />
undersidan för stödhjulet gjordes. På stegmotorernas axel sattes hjulen fast <strong>med</strong> muttrar.<br />
Stödhjulet (Figur 20) träddes igenom från undersidan och sattes fast <strong>med</strong> hjälp av en bockad<br />
plåt. Två hål borrades även på framsidan av bilen där ultraljudets två sensorer sticker ut.<br />
Ultraljudsmodulen limmades därefter fast i chassit. Slutligen kläddes insidan av chassit <strong>med</strong><br />
antistatisk och elektriskt isolerande plast.<br />
Figur 19 Robotens chassi
Figur 20 Stödhjulet<br />
Locket gjordes av en 1 mm tjock aluminiumplåt stor nog att den kan ligga på insidan av lådan<br />
och få stöd av vinklarna. I mitten av aluminiumbiten sågades ett rektangulärt hål för<br />
lysdioderna. Kanten på LED-displayen limmades fast på undersidan av locket. Sedan<br />
borrades hål för avstängningsknappen för larmet, vippströmsbrytaren till batteriet och<br />
blåtandsmodulen.<br />
Roboten får sin strömförsörjning från ett batteripack <strong>med</strong> 6 AA batterier som ger en spänning<br />
på 7,2 V. Till detta är en spänningsregulator inkopplad som sänker spänningen till 5 V för de<br />
logiska kretsarna. Stegmotorerna matas direkt <strong>med</strong> 7,2 V för att förhindra onödiga<br />
effektförluster i spänningsregulatorn.<br />
De färdiga kretskorten och modulerna kopplades samman och funktionstestades innan de<br />
monterades in i roboten (Figur 21).<br />
Figur 21 Samtliga komponenter i bilen
Basstationen<br />
Konstruktionen består av en böjd plexiglasskiva och två kretskort anslutna via en flatkabel.<br />
För att underlätta monteringen av pekskärmen (ståendes och så nära plexiglaset som möjligt),<br />
ansågs det bäst att flytta över övriga komponenter till ett annat kretskort som monterades<br />
liggandes nedanför. Då kretskorten var färdiga sågades en passande bit plexiglas ut. Ett större<br />
rektangulärt hål borrades ut och filades till för pekskärmen och åtta små hål borrades för<br />
distanserna som kretskorten fästes på. Sedan bockades plexiglaset <strong>med</strong> hjälp av en<br />
varmluftspistol och ett skruvstäd (Figur 22). Slutligen skruvades distanserna in och<br />
självhäftande gummifötter sattes fast på undersidan för att motverka att <strong>basstation</strong>en glider<br />
runt på underlaget.<br />
Figur 22 Basstationens plexiglas bockas
Färdig lösning<br />
När både roboten och <strong>basstation</strong>en var färdigbyggda testades den verkliga funktionaliteten.<br />
Räckvidden av den <strong>trådlös</strong>a kommunikationen var över förväntan och prototypen kommer<br />
utan problem att kunna i den miljö som den är avsedd för.<br />
Det autonoma driftläget fungerar enligt förväntan och roboten fastnar sällan i en normal miljö.<br />
Figur 23 Den färdiga prototypen
Erfarenheter/ Problem under gång<br />
Att jobba <strong>med</strong> ett större projekt i grupp innebär att det är viktigare att ha en planering <strong>med</strong><br />
tydliga delmål för att alla i gruppen skall ligga i fas. Regelbundna avstämningar i gruppen<br />
möjliggör detta.<br />
I detta projekt har det även varit viktigt <strong>med</strong> en tydlig kravspecifikation <strong>med</strong> väl definierade<br />
gränssnitt modulerna emellan eftersom bygget av modulerna sker parallellt.<br />
Vad vi har lärt oss i gruppen är att man ska undvika att låsa in sig på ett problem alltför<br />
mycket, utan istället finna alternativa lösningar, men för den delen inte vara för snabb <strong>med</strong> att<br />
ge upp när något krånglar.<br />
Några av de sakerna som har krånglat under projektets gång är:<br />
Ultraljudsmodulen<br />
Vår första tanke var att använda den krets för avståndsmätning <strong>med</strong> ultraljud som byggts<br />
under en av de individuella delarna (se Bilaga J), men att modifiera denna så att den istället<br />
mätte avstånd <strong>med</strong> hjälp av ljudreflexer. Vi lyckades efter några dagars arbete få den att göra<br />
detta <strong>med</strong> acceptabel precision, men det visade sig att kretsen var alltför störningskänslig och<br />
att man där<strong>med</strong> inte kunde vara säker på att den inte skulle orsaka problem när roboten senare<br />
byggdes ihop.<br />
För att undvika detta valdes istället en färdig modul, SRF04 från Devantech, för<br />
avståndsmätning då en sådan är mer robust. Att implementera denna modul i roboten<br />
orsakade inga problem, utan var gjort på ett fåtal arbetstimmar.<br />
Pekskärm<br />
Själva pekfunktionen hos pekskärmen tog lång tid att justera. Värdena från A/D-<br />
omvanldingen i x- och y-led stämde inte överens i proportion till skärmen. Ett annat problem<br />
var att omvandlingen skedde ständigt, även vid ingen beröring och gav till synes olika värden.<br />
Risken att värdena skulle ”pricka rätt” och motsvara en knapptryckning ansågs finnas. Ett sätt<br />
att lösa detta skulle vara att göra ett interrupt som registrerade en spänningsförändring på de<br />
analoga kanalerna, men en av interruptpinnarna var redan upptagen. Lösningen blev istället<br />
att skapa en array där värdena sparades i och om tre på varandra lika efterföljande värden,<br />
registrerades det som en beröring av pekskärmen.
Slutsatser och förslag till förbättringar<br />
Efter att ha färdigställt en första prototyp finns det lite olika saker som borde åtgärdas till en<br />
eventuell andra prototyp.<br />
Motorerna: De stegmotorerna som användes i fordonet är ganska svaga och vid lite större<br />
hinder som trösklar eller mattor kör fordonet lätt fast. Lite starkare stegmotorer skulle<br />
underlätta driften.<br />
Eventuellt kan stegmotorerna bytas ut mot en annan typ av motor eftersom stegmotorer, i<br />
förhållande till storlek och vikt, vanligtvis både är dyrare och svagare jämfört <strong>med</strong> exempelvis<br />
en likströmsmotor. Nackdelen <strong>med</strong> användandet av en likströmsmotor är att något typ av<br />
återkopplat system krävs för att veta hur mycket roboten har rört sig.<br />
H-bryggorna: Istället för den egna lösningen <strong>med</strong> två stycken dubbla H-bryggor för styrning<br />
av stegmotorerna skulle en redan färdig lösning kunna användas. Detta för att både spara tid<br />
och pinnar på mikrokontrollern. Eventuellt skulle det då räcka <strong>med</strong> endast en mikrokontroller<br />
i fordonet. Nackdelen är att dessa färdiga drivare vanligtvis är väldigt dyra.<br />
Stödhjulet: Stödhjulet som användes skramlar rätt högt i vissa lägen. Eftersom fordonet ska<br />
börja åka runt en stund innan larmet går borde detta åtgärdas <strong>med</strong> ett tystare stödhjul.<br />
Chassit: Då chassit består av tunn aluminiumplåt fortplantas stegmotorernas vibrationer i<br />
chassit och ger upphov till oljud. Detta skulle kunna lösas genom att montera stegmotorerna<br />
på vibrationsdämpare och att försöka få en stummare låda.<br />
I den nuvarande prototypen är inte korten fastspända på något bra sätt, utan är fasttejpade så<br />
att de inte kommer i kontakt <strong>med</strong> varandra. Även om fordonet fungerar måste detta självklart<br />
åtgärdas om den ska klara en längre tids bruk.<br />
LED-displayen: Lysdioderna bör möjligtvis kunna vara dimbara för att kunna justera<br />
ljusstyrkan så de syns i dagsljus men inte är för störande på natten. Om det hade önskats<br />
skulle displayen kunna göras större. Detta hade då krävt externa minneskretsar för att kunna<br />
ge mer ström och minska antalet inkopplade pinnar på mikrokontrollern.<br />
Automatiska driftläget: Eftersom fordonet endast, <strong>med</strong> hjälp utav ultraljudsmodulen, kan<br />
mäta hur nära något är precis framför fordonet är det svårt att avgöra om den ska svänga
vänster, höger eller backa. Om fler ultraljudsmoduler skulle monteras kring bilen skulle ett<br />
smartare och mer avancerat driftläge kunna skrivas.<br />
Moderkort: Eftersom det nästan aldrig går som man vill på första försöket när man designar<br />
nya kretsar, fattades beslutet att göra prototypen modulbaserad, dvs <strong>med</strong> separata kretskort för<br />
varje funktion. Detta eftersom felsökningen förenklas avsevärt om man vet att en modul redan<br />
fungerar. Tyvärr resulterar detta i att mycket kablar måste dras runt i fordonet. En lösning på<br />
detta är att när allting fungerar som det ska så tillverkas ett gemensamt moderkort för samtliga<br />
komponter som egentligen bör sitta ihop.<br />
Basstation: En möjlig förbättring vore att montera en batteribackup som skulle ta över<br />
strömförsörjningen vid ett eventuellt strömavbrott. En högljud högtalare i <strong>basstation</strong>en skulle<br />
effektivisera alarmet då roboten kan åka så långt bort att dess oljud inte hörs längre, i<br />
kombination <strong>med</strong> att om en ny prototyp skulle tas fram skulle den utformas på ett sådant sätt<br />
att robotens oljud från början minimerades.<br />
Även om det finns många möjliga förbättringar är många av dessa sådana som inte går att<br />
förutse innan en prototyp har tillverkats. Några av förslagen är även sådant som skulle kunna<br />
ha gjorts om mer tid hade funnits.
Referenser<br />
H-brygga, Allegro UDN2916B-T<br />
http://www.allegromicro.com/en/Products/Part_Numbers/2916/2916.pdf (2011-05-15)<br />
Blåtand, Parani ESD-210<br />
http://www.sena.com/download/manual/manual_parani_esd-v1.1.6.pdf (2011-05-15)<br />
Ultraljud, Devantech SRF04<br />
http://faculty.kfupm.edu.sa/COE/masud/RichText/R93-SRF04p%20UltraSonic.pdf (2011-05-<br />
15)<br />
Pekskärm, EA DOGM128S-6, EA TOUCH128-1, EA LED5x46-R<br />
http://www.lcd-module.com/eng/pdf/grafik/dogm128e.pdf (2011-05-15)<br />
UART-kommunikation<br />
http://www.md.kth.se/edu/mda/4F1822/utdelat/johansusart.c (2011-05-15)
Bilagor<br />
Bilaga A. Kravspecifikation<br />
Ett av de allmänna kraven för projektet är att samtliga specialiseringsområden inom<br />
projektgruppen ska implementeras i prototypen. Vilket innebär att följande moduler skall<br />
användas:<br />
Stegmotorer<br />
Pekskärm<br />
Ultraljud för bestämning av avstånd<br />
LED-matris<br />
Förutom dessa moduler är det fritt att implementera andra.<br />
Det som önskas av prototypen är att den skall:<br />
1. Ha en <strong>basstation</strong> där man kan ställa tid och larm.<br />
2. Ha ett självgående fordon <strong>med</strong> stoppknapp för larmet.<br />
3. Ha en larmsignal som är så pass hög att den kan väcka en sovande person.<br />
4. Automatisk kunna flytta fordonet slumpmässigt i rummet en tid innan larmet går.<br />
5. Ha en LED-display som visar aktuell tid på fordonet.<br />
6. Ha ett larmläge där fordonet försöker ”smita undan”.<br />
Prototypen skall gärna kunna:<br />
1. Styras manuellt från <strong>basstation</strong>en.<br />
2. Skriva personliga <strong>med</strong>delanden på LED-displayen.
Bilaga B. Komponentlista och kostnadsredovisning<br />
Komponent Antal (st) Ca pris. (kr/st)<br />
Resistor 30 kΩ 3 0,25<br />
Resistor 1 kΩ 4 0,25<br />
Resistor 0,82 Ω 4 5<br />
Resistor 10 kΩ 2 0,25<br />
Resistor 130 kΩ 16 0,25<br />
Resistor 56 kΩ 4 0,25<br />
Kondensator 0,1 µF 4 2<br />
Kondensator 10 µF 2 5<br />
Kondensator 100 µF 1 5<br />
Kondensator 820 pF 4 2<br />
Kondensator 1 nF 4 2<br />
Kondensator 47 µF 1 2<br />
Spänningsregulator LM7805 1 10<br />
Tryckknapp 1 5<br />
LED 128 1<br />
ATMega16 2 40<br />
Motordrivare 2916 2 50<br />
MOSFET BUZ71 9 15<br />
Ultraljudsmodul 1 ????<br />
Bluetooth, Parani ESD-210 2 500<br />
Stegmotor 2 500 (osäkert värde)<br />
Enkelsidigt kretskort ~3 50<br />
Aluminiumplåt ~0.25 m 2<br />
ATMega644p 1 75<br />
EA DOGM128S-6 1 200<br />
EA Touch128-1 1 130<br />
EA LED55x46-R 1 45<br />
Kondensator 1µF 10 2<br />
Resistor 51kΩ 3 0,25<br />
Klockkristall 32.768kHz 1 4<br />
Spänningsregulator LM2937E 1 20<br />
Plexiglasskiva 200x110x6mm 1 50<br />
100 (osäkert värde)
Bilaga C. Använda portpinnar hos AVR:en<br />
Anslutningar till LED-matrisens mikrokontroller<br />
Pinne Ansluten till<br />
(XCK/T0) PB0 Kolumn 16 i matrisen.<br />
(T1) PB1 Kolumn 15 i matrisen.<br />
(INT2/AIN0)<br />
PB2<br />
(OC0/AIN1)<br />
PB3<br />
Kolumn 14 i matrisen.<br />
Kolumn 13 i matrisen.<br />
(SS) PB4 Kolumn 12 i matrisen.<br />
(MOSI) PB5 Kolumn 11 i matrisen.<br />
(MISO) PB6 Kolumn 10 i matrisen.<br />
(SCK) PB7 Kolumn 9 i matrisen.<br />
RESET Programmering<br />
VCC Power in /Programmering<br />
GND Power in/ Programmering<br />
XTAL2 -<br />
XTAL1 -<br />
(RXD) PD0 Kommunikation ut<br />
(TXD) PD1 Kommunikation ut<br />
(INT0) PD2 Kommunikation ut<br />
(INT1) PD3 Kommunikation ut<br />
(OC1B) PD4 Kommunikation ut<br />
(OC1A) PD5 Kommunikation ut<br />
(ICP1) PD6 Kommunikation ut<br />
PD7 (OC2) Kommunikation ut<br />
PC0 (SCL) Kolumn 8 i matrisen.<br />
PC1 (SDA) Kolumn 7 i matrisen.<br />
PC2 (TCK) Kolumn 6 i matrisen.<br />
PC3 (TMS) Kolumn 5 i matrisen.<br />
PC4 (TDO) Kolumn 4 i matrisen.<br />
PC5 (TDI) Kolumn 3 i matrisen.<br />
PC6 (TOSC1) Kolumn 2 i matrisen.<br />
PC7 (TOSC2) Kolumn 1 i matrisen.<br />
AVCC Vcc<br />
GND GND<br />
AREF Vcc<br />
PA7 (ADC7) Rad 1 i matrisen.<br />
PA6 (ADC6) Rad 2 i matrisen.<br />
PA5 (ADC5) Rad 3 i matrisen.
PA4 (ADC4) Rad 4 i matrisen.<br />
PA3 (ADC3) Rad 5 i matrisen.<br />
PA2 (ADC2) Rad 6 i matrisen.<br />
PA1 (ADC1) Rad 7 i matrisen.<br />
PA0 (ADC0) Rad 8 i matrisen.<br />
Anslutningar till H-bryggornas mikrokontroller<br />
Pinne Ansluten till<br />
(XCK/T0) PB0 H-brygga 1<br />
(T1) PB1 H-brygga 1<br />
(INT2/AIN0)<br />
PB2 H-brygga 1<br />
(OC0/AIN1) H-brygga 1<br />
PB3<br />
(SS) PB4 H-brygga 1<br />
(MOSI) PB5 H-brygga 1/<br />
Programmering<br />
(MISO) PB6 Programmering<br />
(SCK) PB7 Programmering<br />
RESET Programmering<br />
VCC Power in /Programmering<br />
GND Power in/ Programmering<br />
XTAL2 -<br />
XTAL1 -<br />
(RXD) PD0 -<br />
(TXD) PD1 Ultraljud ut<br />
(INT0) PD2 Ultraljud in<br />
(INT1) PD3 Kommunikation, används<br />
ej<br />
(OC1B) PD4 Kommunikation 3-bitars<br />
(OC1A) PD5 Kommunikation 3-bitars<br />
(ICP1) PD6 Kommunikation 3-bitars<br />
PD7 (OC2) -<br />
PC0 (SCL) H-brygga 2<br />
PC1 (SDA) H-brygga 2<br />
PC2 (TCK) H-brygga 2<br />
PC3 (TMS) H-brygga 2<br />
PC4 (TDO) H-brygga 2<br />
PC5 (TDI) H-brygga 2
PC6 (TOSC1) -<br />
PC7 (TOSC2) -<br />
AVCC Vcc<br />
GND GND<br />
AREF Vcc<br />
PA7 (ADC7) Extra in/ut, används ej<br />
PA6 (ADC6) Extra in/ut, används ej<br />
PA5 (ADC5) Extra in/ut, används ej<br />
PA4 (ADC4) Extra in/ut, används ej<br />
PA3 (ADC3) Extra in/ut, används ej<br />
PA2 (ADC2) Extra in/ut, används ej<br />
PA1 (ADC1) Extra in/ut, används ej<br />
PA0 (ADC0) Extra in/ut, används ej<br />
Anslutningar till <strong>basstation</strong>ens mikrokontroller ATMega644p<br />
Pinne Ansluten till<br />
(XCK/T0) PB0 DOGM128, RST<br />
(T1) PB1 -<br />
(INT2/AIN0)<br />
PB2<br />
-<br />
(OC0/AIN1)<br />
PB3 DOGM128, A0<br />
(SS) PB4 DOGM128, CS1B<br />
(MOSI) PB5 DOGM128, SI<br />
(MISO) PB6 -<br />
(SCK) PB7 DOGM128, SCL<br />
RESET Programmering<br />
VCC Power in /Programmering<br />
GND Power in/ Programmering<br />
XTAL2 -<br />
XTAL1 -<br />
(RXD) PD0 Bluetooth, RXD<br />
(TXD) PD1 Bluetooth, TXD<br />
(INT0) PD2 -<br />
(INT1) PD3 -<br />
(OC1B) PD4 -<br />
(OC1A) PD5 -<br />
(ICP1) PD6 -
PD7 (OC2) -<br />
PC0 (SCL) -<br />
PC1 (SDA) -<br />
PC2 (TCK) -<br />
PC3 (TMS) -<br />
PC4 (TDO) -<br />
PC5 (TDI) -<br />
PC6 (TOSC1) Klockkristall 32.768kHz<br />
PC7 (TOSC2) Klockkristall 32.768kHz<br />
AVCC VCC<br />
GND GND<br />
AREF VCC<br />
PA7 (ADC7) -<br />
PA6 (ADC6) -<br />
PA5 (ADC5) -<br />
PA4 (ADC4) -<br />
PA3 (ADC3) Touch128-1, Right<br />
PA2 (ADC2) Touch128-1, Top<br />
PA1 (ADC1) Touch128-1, Left<br />
PA0 (ADC0) Touch128-1, Bottom
Bilaga D. Blåtand- kommunikationsprotokoll<br />
Blåtand - kommunikationsprotokoll:<br />
första byte:<br />
254 - alla +<br />
andra byte:<br />
0 - sekunder är +1*<br />
1 - minuter är +1*<br />
2 - timmar är +1*<br />
3 - börja åka<br />
4 - sluta åka<br />
5 - larma<br />
6 - visa text +1*<br />
7 - visa sträng +2*<br />
8 - åk +3*<br />
9 - stäng av larm (åt andra håĺllet)<br />
tredje byte:<br />
1* siffra - data for info<br />
2* char - data for text +2*<br />
3* 0 - åk fram<br />
3* 1 - åk höger<br />
3* 2 - åk vänster<br />
3* 3 - åk bakĺt<br />
3* 4 - åk stop<br />
sista byte:<br />
253 - bryter sträng<br />
Kommandon<br />
void sendTime(char loc_timmar, char loc_minuter, char loc_sekunder){<br />
bluetoothSend(254);<br />
bluetoothSend(2);<br />
bluetoothSend(loc_timmar);<br />
}<br />
bluetoothSend(254);<br />
bluetoothSend(1);<br />
bluetoothSend(loc_minuter);<br />
bluetoothSend(254);<br />
bluetoothSend(0);<br />
bluetoothSend(loc_sekunder);<br />
void sendStartMoving(){<br />
bluetoothSend(254);<br />
bluetoothSend(3);<br />
}<br />
void sendStopMoving(){<br />
bluetoothSend(254);<br />
bluetoothSend(4);<br />
}<br />
void sendAlarm(){
}<br />
bluetoothSend(254);<br />
bluetoothSend(5);<br />
void sendStopAlarm(){<br />
bluetoothSend(254);<br />
bluetoothSend(9);<br />
}<br />
Bilaga E. Elektroniska ritningar - kretsschema/ layout<br />
Bilaga F. Mekaniska ritningar <strong>med</strong> måttsättning<br />
Bilaga G. Programlistningar<br />
Bilaga H. Anslutningar mellan moduler och kretskort<br />
Bilaga I. LED punktmatris<br />
Bilaga J. Ultraljudslinjal – Avståndsmätning <strong>med</strong> ultraljud<br />
Bilaga K. Stegmotorer – Funktion och tillämpning<br />
Bilaga L. Stegmotor – Ett fördjupningsarbete i mekatronik<br />
Bilaga M. LCD <strong>med</strong> touchpanel
Bilaga E.<br />
Elektroniska ritningar – kretsschema/layout
0<br />
0<br />
1<br />
1<br />
2<br />
2<br />
3<br />
3<br />
4<br />
A A<br />
MISO<br />
SCK<br />
J1<br />
B B<br />
Reset<br />
HDR2X3<br />
VCC<br />
5V<br />
MOSI<br />
J3<br />
HDR1X6<br />
Control_Hbrige1<br />
U1<br />
1<br />
PB0<br />
2<br />
PB1<br />
3<br />
PB2<br />
4<br />
PB3<br />
C 5<br />
PB4<br />
C<br />
6<br />
PB5(MOSI)<br />
7<br />
PB6(MISO)<br />
8<br />
PB7(SCK)<br />
9<br />
Reset<br />
10<br />
VCC<br />
11<br />
GND<br />
12<br />
XTAL2<br />
13<br />
XTAL1<br />
14<br />
PD0(RXD)<br />
15<br />
D<br />
PD1(TXD)<br />
16<br />
D<br />
PD2(INT0)<br />
17<br />
PD3(INT1)<br />
18<br />
PD4(OC1B)<br />
19<br />
PD5(OC1A)<br />
20<br />
PD6(ICP1) PD7(OC2) 21<br />
PC0 22<br />
PC1 23<br />
PC2 24<br />
PC3 25<br />
PC4 26<br />
PC5 27<br />
PC6 28<br />
PC7 29<br />
AVCC 30<br />
GND2 31<br />
AREF 32<br />
PA7(ADC7) 33<br />
PA6(ADC6) 34<br />
PA5(ADC5) 35<br />
PA4(ADC4) 36<br />
PA3(ADC3) 37<br />
PA2(ADC2) 38<br />
PA1(ADC1) 39<br />
PA0(ADC0) 40<br />
MISO MOSI<br />
SCK<br />
Reset<br />
R1<br />
J4<br />
VCC 30kΩ<br />
VCC<br />
5V<br />
5V<br />
Ultra_out<br />
HDR2X8 HDR1X8<br />
Ultra_in<br />
VCC<br />
J7<br />
5V<br />
ATMega16<br />
E E<br />
F F<br />
J5<br />
HDR1X2<br />
Power_in<br />
HDR1X5<br />
C1<br />
47µF<br />
VCC<br />
5V<br />
J6<br />
HDR1X2<br />
Power_Hbridge<br />
4<br />
HDR1X6<br />
Control_Hbridge2<br />
5<br />
5<br />
J2<br />
6<br />
Ultra_out<br />
Ultra_in<br />
VCC<br />
HDR1X5<br />
Ultrasound<br />
5V<br />
J8<br />
6<br />
J9<br />
7<br />
7<br />
8<br />
Mikrokontroller till H-bryggorna<br />
8<br />
9<br />
9
0<br />
0<br />
1<br />
1<br />
2<br />
2<br />
3<br />
3<br />
4<br />
4<br />
5<br />
5<br />
6<br />
6<br />
7<br />
7<br />
8<br />
8<br />
9<br />
9<br />
10<br />
10<br />
11<br />
11<br />
12<br />
12<br />
13<br />
13<br />
14<br />
14<br />
A A<br />
B B<br />
C C<br />
D D<br />
E E<br />
F F<br />
G G<br />
H H<br />
I I<br />
J J<br />
U1<br />
2916<br />
OUT_1A<br />
OUT_2A<br />
E_2<br />
Sense_2<br />
OUT_2B<br />
GND<br />
GND<br />
I_02<br />
I_12<br />
PHASE_2<br />
V_REF2<br />
RC_2 Vcc<br />
RC_1<br />
V_REF1<br />
PHASE_1<br />
I_11<br />
GND<br />
GND<br />
I_01<br />
OUT_1B<br />
SENSE_1<br />
E_1<br />
LOAD_SUPPLY<br />
R1<br />
0.82Ω<br />
C1<br />
1nF<br />
C3<br />
820pF<br />
R3<br />
56kΩ<br />
Mikrokontroller<br />
HDR1X8<br />
GND<br />
VCC<br />
5V<br />
V_Motor<br />
HDR1X2<br />
Motor<br />
HDR1X4<br />
R4<br />
1kΩ<br />
GND<br />
GND<br />
GND<br />
GND<br />
GND<br />
GND<br />
GND GND<br />
VCC<br />
5V<br />
VCC<br />
5V<br />
C5<br />
100µF<br />
C6<br />
820pF<br />
R7<br />
56kΩ<br />
R2<br />
1kΩ<br />
C2<br />
1nF<br />
R5<br />
0.82Ω<br />
U2<br />
2916<br />
OUT_1A<br />
OUT_2A<br />
E_2<br />
Sense_2<br />
OUT_2B<br />
GND<br />
GND<br />
I_02<br />
I_12<br />
PHASE_2<br />
V_REF2<br />
RC_2 Vcc<br />
RC_1<br />
V_REF1<br />
PHASE_1<br />
I_11<br />
GND<br />
GND<br />
I_01<br />
OUT_1B<br />
SENSE_1<br />
E_1<br />
LOAD_SUPPLY<br />
R6<br />
0.82Ω<br />
C4<br />
1nF<br />
C7<br />
820pF<br />
R8<br />
56kΩ<br />
Mikrokontroller2<br />
HDR1X8<br />
GND<br />
GND<br />
GND<br />
GND<br />
GND<br />
GND<br />
GND GND<br />
VCC<br />
5V<br />
VCC<br />
5V<br />
VCC<br />
5V<br />
Motor2<br />
HDR1X4<br />
R9<br />
1kΩ<br />
C9<br />
820pF<br />
R10<br />
56kΩ<br />
R11<br />
1kΩ<br />
C10<br />
1nF<br />
R12<br />
0.82Ω<br />
GND<br />
Dubbla H-bryggor
0<br />
0<br />
1<br />
1<br />
2<br />
2<br />
3<br />
3<br />
4<br />
A A<br />
B B<br />
C C<br />
J3<br />
HDR1X2<br />
D D<br />
5V<br />
J1<br />
HDR1X4<br />
COMMON<br />
VOLTAGE<br />
LINE VREG<br />
VCC U1<br />
LM2937ES-3.3<br />
3.3V<br />
VDD<br />
3.3V<br />
VDD<br />
E E<br />
F F<br />
G G<br />
4<br />
J2<br />
HDR1X4<br />
J4<br />
TXD<br />
HDR1X3<br />
5<br />
RXD<br />
TXD<br />
5<br />
R1<br />
68kΩ<br />
R2<br />
115kΩ<br />
6<br />
6<br />
RXD<br />
7<br />
Adapterkort bluetooth<br />
7<br />
8<br />
8
0<br />
0<br />
1<br />
1<br />
2<br />
2<br />
3<br />
3<br />
4<br />
A A<br />
B B<br />
C C<br />
D D<br />
VCC<br />
5V<br />
E E<br />
30kΩ<br />
R2<br />
R1<br />
31kΩ<br />
J3<br />
HDR1X3<br />
Uart<br />
VCC<br />
5V<br />
Q1<br />
BUZ71<br />
HDR1X2<br />
Knapp<br />
J4<br />
F F<br />
G G<br />
4<br />
J5<br />
HDR1X2<br />
VTG-out<br />
VCC<br />
5V<br />
5<br />
J1<br />
HDR2X5<br />
5<br />
J2<br />
6<br />
6<br />
HDR1X5<br />
Kommunikation<br />
7<br />
Adapterkort till LED-kontroller<br />
7<br />
8<br />
8
0<br />
0<br />
1<br />
1<br />
2<br />
2<br />
3<br />
3<br />
4<br />
A A<br />
B B<br />
Touch<br />
Kopplingsschema<br />
<strong>basstation</strong> krets 1<br />
C C<br />
D D<br />
GND<br />
VCC<br />
51Ω<br />
4<br />
1<br />
2<br />
3<br />
E E<br />
F F<br />
1µF<br />
40<br />
39<br />
38<br />
37<br />
36<br />
35<br />
34<br />
33<br />
32<br />
31<br />
30<br />
29<br />
28<br />
27<br />
26<br />
25<br />
24<br />
23<br />
22<br />
5<br />
5<br />
18<br />
19<br />
20 21<br />
6<br />
6<br />
DOGM128S<br />
7<br />
7<br />
8<br />
8<br />
9<br />
9
0<br />
0<br />
1<br />
1<br />
2<br />
2<br />
3<br />
3<br />
4<br />
4<br />
5<br />
5<br />
6<br />
6<br />
7<br />
7<br />
8<br />
8<br />
9<br />
9<br />
A A<br />
B B<br />
C C<br />
D D<br />
E E<br />
F F<br />
LM2937ES<br />
LINE<br />
VREG<br />
COMMON<br />
VOLTAGE<br />
VCC<br />
1µF<br />
10µF<br />
644p<br />
PB0<br />
PB1<br />
PB2<br />
PB3<br />
PB4<br />
PB5<br />
PB6<br />
PB7<br />
RES<br />
VCC<br />
GND.<br />
XTAL2<br />
XTAL1<br />
PD0<br />
PD1<br />
PD2<br />
PD3<br />
PD4<br />
PD5<br />
PD6 PD7<br />
PC0<br />
PC1<br />
PC2<br />
PC3<br />
PC4<br />
PC5<br />
PC6<br />
PC7<br />
AVCC<br />
GND<br />
AREF<br />
PA7<br />
PA6<br />
PA5<br />
PA4<br />
PA3<br />
PA2<br />
PA1<br />
PA0<br />
ISP6PIN<br />
MISO<br />
SCK<br />
~RES<br />
MOSI<br />
VCC<br />
12V<br />
GND<br />
GND<br />
GND<br />
GND<br />
GND<br />
10kΩ<br />
VCC<br />
~RES<br />
Bluetooth<br />
GND<br />
VCC<br />
Kopplingsschema<br />
<strong>basstation</strong> krets 2
0<br />
0<br />
1<br />
1<br />
2<br />
2<br />
3<br />
3<br />
4<br />
4<br />
5<br />
5<br />
6<br />
6<br />
7<br />
A A<br />
B B<br />
C C<br />
J4<br />
D D<br />
HDR2X5<br />
J1<br />
HDR2X5<br />
E E<br />
F F<br />
G G<br />
H H<br />
I I<br />
J J<br />
7<br />
8<br />
8<br />
9<br />
9<br />
10<br />
10<br />
11<br />
J3<br />
HDR2X5<br />
LED1 LED2 LED3 LED4 LED5 LED6 LED7 LED8 LED9 LED10 LED11 LED12 LED13 LED14 LED15 LED16<br />
LED17 LED18 LED19 LED20 LED21 LED22 LED23 LED24 LED25 LED26 LED27 LED28 LED29 LED30 LED31 LED32<br />
LED33 LED34 LED35 LED36 LED37 LED38 LED39 LED40 LED41 LED42 LED43 LED44 LED45 LED46 LED47 LED48<br />
LED49 LED50 LED51 LED52 LED53 LED54 LED55 LED56 LED57 LED58 LED59 LED60 LED61 LED62 LED63 LED64<br />
LED65 LED66 LED67 LED68 LED69 LED70 LED71 LED72 LED73 LED74 LED75 LED76 LED77 LED78 LED79 LED80<br />
LED81 LED82 LED83 LED84 LED85 LED86 LED87 LED88 LED89 LED90 LED91 LED92 LED93 LED94 LED95 LED96<br />
LED97 LED98 LED99 LED100 LED101 LED102 LED103 LED104 LED105 LED106 LED107 LED108 LED109 LED110 LED111 LED112<br />
LED113 LED114 LED115 LED116 LED117 LED118 LED119 LED120 LED121 LED122 LED123 LED124 LED125 LED126 LED127 LED128<br />
11<br />
12<br />
12<br />
13<br />
LED matris<br />
13<br />
14<br />
14
0<br />
0<br />
1<br />
1<br />
2<br />
2<br />
3<br />
3<br />
4<br />
A A<br />
B B<br />
C1<br />
0.1µF<br />
J2<br />
HDR1X2<br />
VCC<br />
GND<br />
5V<br />
Q1<br />
BUZ71<br />
R1<br />
130Ω<br />
R2<br />
R3 130Ω<br />
C C<br />
1<br />
2 PB0<br />
3 PB1<br />
4 PB2<br />
5 PB3<br />
6 PB4<br />
7 PB5<br />
8 PB6<br />
9 PB7<br />
D 10 RESET<br />
D<br />
11 VCC<br />
12 DGND<br />
13 XTAL2<br />
14 XTAL1<br />
15 PD0<br />
16 PD1<br />
17 PD2<br />
18 PD3<br />
19 PD4<br />
20 PD5<br />
E PD6 PD7 E<br />
21 PC0 22 PC1 23 PC2 24 PC3 25 PC4 26 PC5 27 PC6 28 PC7 29 AVCC 30 GND 31 AREF 32 PA7 33 PA6 34 PA5 35 PA4 36 PA3 37 PA2 38 PA1 39 PA0 40<br />
130Ω R4<br />
130Ω<br />
R12<br />
130Ω<br />
R5<br />
130Ω<br />
130Ω<br />
R6<br />
R13<br />
130Ω<br />
R7<br />
130Ω<br />
130Ω<br />
R8<br />
R14<br />
J1<br />
J3<br />
MOSI<br />
MISO<br />
HDR2X5<br />
R15 130Ω<br />
RESET<br />
SCK<br />
HDR2X5<br />
R17<br />
10kΩ<br />
Q2<br />
BUZ71<br />
130Ω<br />
Q3<br />
BUZ71<br />
F F<br />
4<br />
J6<br />
HDR2X5<br />
U1<br />
5<br />
J4<br />
HDR2X5<br />
Q4<br />
BUZ71<br />
ATMega16<br />
5<br />
Q5<br />
BUZ71<br />
R9<br />
6<br />
Q6<br />
BUZ71<br />
130Ω R10<br />
R11<br />
6<br />
130Ω<br />
130Ω R16<br />
MISO<br />
SCK<br />
RESET<br />
130Ω<br />
J5<br />
HDR2X3<br />
Q7<br />
BUZ71<br />
7<br />
VCC<br />
7<br />
Q8<br />
BUZ71<br />
5V<br />
MOSI<br />
GND<br />
8<br />
Styrkort för LED-displayen<br />
8<br />
9<br />
9
Bilaga F.<br />
Mekaniska ritningar <strong>med</strong> måttsättning<br />
Figur 1 Bild på chassits design
110,4<br />
163,5<br />
110,4<br />
15<br />
O 4<br />
146,3<br />
O 28<br />
15 O 5<br />
15<br />
O 4<br />
15<br />
A<br />
O 3<br />
O 5<br />
110,4 237 110,4<br />
O 3<br />
O 3<br />
94<br />
78,5<br />
O 3<br />
63<br />
78,5<br />
94<br />
63<br />
Skapad av<br />
mazda<br />
10,5<br />
72,5<br />
O 16<br />
72,5<br />
88<br />
Godkänd av Material<br />
Skala<br />
Ersätter Ersatt av<br />
MF1046<br />
88<br />
103,5<br />
81,5<br />
103,5<br />
Aluminum, 1060<br />
Chassi<br />
Toleranser där ej annat anges : ISO2768-m<br />
1,5<br />
1<br />
2,3<br />
1<br />
2,3<br />
DETAIL A<br />
Datum<br />
Ritningsnr<br />
2011-05-05
45<br />
1,5<br />
15<br />
O 4<br />
10<br />
Skapad av<br />
mazda<br />
92<br />
Godkänd av Material<br />
Skala<br />
Ersätter Ersatt av<br />
MF1046<br />
Aluminum, 1060<br />
Vinkel<br />
Datum<br />
Ritningsnr<br />
2011-05-05
Bluetooth.h – LEDkontrollern<br />
#ifndef Oo_BLUETOOTH_oO<br />
#define Oo_BLUETOOTH_oO<br />
void usart_init(unsigned int ubrr);<br />
void usart_send(char * msg);<br />
void USART_Transmit(unsigned char data);<br />
void sendAlarm();<br />
void BluetoothInit();<br />
#endif
Bluetooth.c – LEDkontrollern<br />
// Grundkod av Johan Egneblad<br />
// 2010-03-02<br />
#define F_CPU 8000000 // Define the processor clock frequency<br />
#define BAUD 9138 // No crystal is used FCPU is approximate. The baud rate<br />
(bits per second) of the communication<br />
#define BAUD_REG F_CPU/16/BAUD-1 // The settings for the usart register<br />
#define BUFFER_SIZE 32 // Maximum message length<br />
#include "reciever.h"<br />
#include <br />
#include <br />
#include <br />
// Global variables for RX buffering<br />
volatile char rx_buffer[BUFFER_SIZE]; // A text buffer for incoming text<br />
volatile unsigned char rx_recieved_bytes; // A byte counter for the incomming<br />
text<br />
volatile unsigned char rx_eol; // An "end of line" indicator that is set to<br />
one ones a full line is read<br />
// Interrupt vector for USART Recieve Complete<br />
ISR(USART_RXC_vect) {<br />
unsigned char data;<br />
// Read the USART buffer<br />
data = UDR;<br />
// Check if the old msg has been read (rx_eol should be cleared)<br />
/*if (rx_eol == 0) {<br />
rx_buffer[rx_recieved_bytes] = data;<br />
rx_recieved_bytes++;<br />
// If there is a line break or null character<br />
if (data==0x0d || data==0x0a || data==0x00 || rx_recieved_bytes >=<br />
(BUFFER_SIZE-1)) {<br />
rx_eol = 1; // Tell the end of line is reached<br />
rx_buffer[rx_recieved_bytes] = 0; // Terminate the string<br />
correctly<br />
rx_recieved_bytes = 0; // Clear the received bytes counter<br />
}<br />
}*/<br />
dataRecieved((unsigned char)data);<br />
}<br />
// Initialization function for usart<br />
// inputs:<br />
// ubrr - (unsigned int) the future contents of the UBRR register<br />
void usart_init(unsigned int ubrr) {<br />
// Set the communication speed register UBRR<br />
UBRRH = (unsigned char)(ubrr>>8); // the most significant byte<br />
UBRRL = (unsigned char)ubrr; // the least significant byte<br />
// Clear the usart status register
UCSRA = 0x00;<br />
// Enable the Reciveing, Transmitting and Recieve completion interrupt<br />
UCSRB = (1
Initialize USART<br />
usart_init(BAUD_REG);<br />
_delay_ms(10000);<br />
//usart_send("AT+BTSCAN");<br />
//usart_send("+++");<br />
_delay_ms(50);<br />
//USART_Transmit(0x0D); //enter<br />
// USART_Transmit(0x0A);<br />
// usart_send("ATH");<br />
// _delay_ms(50);<br />
// USART_Transmit(0x0D); //enter<br />
// USART_Transmit(0x0A);<br />
_delay_ms(100);<br />
usart_send("ATD0001950C0812"); //<br />
_delay_ms(10);<br />
USART_Transmit(0x0D); //enter<br />
USART_Transmit(0x0A);<br />
DDRD=0xf8;<br />
// Start recieving<br />
rx_eol = 0;<br />
}
LED_KLOCKA_ATMEGA16.h– LEDkontrollern<br />
#ifndef M_LED<br />
#define M_LED<br />
/////////////////////// FUNKTIONER<br />
////////////////////////////////////////////////////<br />
void text();<br />
void tid();<br />
void setHours(unsigned char data);<br />
void setMinutes(unsigned char data);<br />
#endif
LED_KLOCKA_ATMEGA16.c– LEDkontrollern<br />
//#include "LED_ATMEGA16.h"<br />
#include "LED_KLOCKA_ATMEGA16.h"<br />
#include "LED_Variables.h"<br />
#include "bluetooth.h"<br />
#include <br />
#include <br />
#include <br />
#include <br />
#include "reciever.h"<br />
/////////////////////////////////////////////// INTERRUPT<br />
//////////////////////////////////<br />
// Varje sekund ska man gå in i denna interrupt-vektor<br />
ISR(TIMER1_COMPA_vect){<br />
// Klocka - ska alltid ticka upp så den visar rätt när man går tillbaka<br />
till klockan<br />
//if(mode==1){<br />
// m = (m+1)%60;<br />
// if(!m)<br />
// h = (h+1)%24;<br />
//}<br />
}<br />
// Rulla text if(mode== 2){<br />
z++;<br />
if(z==8){<br />
// Byt bokstav: t1=t2 och t2=nästa bokstav<br />
z=0;<br />
bokstav++; // Bestämmer den bokstav som ska plockas ur ord<br />
if (bokstav==( strlen(ord)-1))<br />
// Antal bokstäver i ord<br />
bokstav=1; // Börjar om från början av strängen igen.<br />
bokstav2++;<br />
if(bokstav2==( strlen(ord)-2))<br />
bokstav2=0;<br />
}<br />
}<br />
//Timer interrupt for time keeping<br />
ISR(TIMER2_COMP_vect){<br />
timekeeping_counter++;<br />
if(timekeeping_counter>=31){<br />
timekeeping_counter-=31;<br />
s = ( s+10)%60;<br />
//USE s+1 FOR FINAL VERSION, THIS IS 10x TO FAST<br />
if(!s){<br />
m = (m+1)%60;<br />
if(!m)<br />
h = (h+1)%24;
}<br />
}<br />
}<br />
//////////////////////////////// PROGRAM<br />
////////////////////////////////////////////////<br />
void text(void){<br />
// 16-bit timer<br />
SREG = 0x80; // Enable global interrupt, alt sei()<br />
TIMSK |= ( 1
}<br />
}<br />
}<br />
void tid(void){<br />
// 16-bit timer<br />
// SREG = 0x80; // Enable global interrupt, alt sei()<br />
// TIMSK |= (1
if(precis innan ringning)<br />
skicka sígnal att bilen ska flytta på sig;<br />
//if(ringning) // Rulla text*/<br />
//if((h==12 && m==59) || (h==15 && m==4)) // Ex. Hämta h och m från<br />
<strong>basstation</strong>.<br />
if(command==2)<br />
// Initiera rulla text<br />
mode=2;<br />
//if(PIND == trycks ner) // tills man trycker på knapp.<br />
// mode=1;<br />
//if((h==14 && m==20) || (h==17 && m==40)){<br />
//if( (PIND & & 0x0 4) = = 0){<br />
if(!(PIND & (1
}<br />
}<br />
tid();<br />
if(mode==2)<br />
text();<br />
//////////////////////////////////// Timer set functions<br />
///////////////////////////'<br />
void setHours(unsigned char data){<br />
h = data;<br />
}<br />
void setMinutes(unsigned char data){<br />
m = data;<br />
}
LEDvariables.h – LEDkontrollern<br />
#ifndef V_LED<br />
#define V_LED<br />
#define antal_kolumner 8 // Antal kolumner i den fysiska matrisen<br />
unsigned char mode=1;<br />
volatile unsigned char letters[][8] = {<br />
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // mellanslag<br />
{0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x00}, // !<br />
{0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00}, // " //<br />
{0x00, 0x00, 0x00, 0x24, 0xFF, 0x24, 0xFF, 0x24}, // #<br />
{0x00, 0x00, 0x00, 0x12, 0x2A, 0x7F, 0x2A, 0x24}, // $<br />
{0x01, 0x02, 0x24, 0x08, 0x10, 0x24, 0x40, 0x80}, // %<br />
{0x00, 0x00, 0x00, 0x76, 0x89, 0x95, 0x62, 0x05}, // &<br />
{0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00}, // '<br />
{0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x81, 0x00}, // (<br />
{0x00, 0x00, 0x00, 0x00, 0x81, 0x42, 0x3C, 0x00}, // )<br />
{0x00, 0x00, 0x00, 0x50, 0xE0, 0x50, 0x00, 0x00}, // *<br />
{0x00, 0x00, 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08}, // "+"<br />
{0x00, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0x00}, // ´<br />
{0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08}, // -<br />
{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // .<br />
{0x00, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x00}, // /<br />
{0x00, 0x07, 0x05, 0x05, 0x05, 0x05, 0x07, 0x00}, // 0_<br />
{0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00}, // 1_<br />
{0x00, 0x07, 0x04, 0x07, 0x01, 0x01, 0x07, 0x00}, // 2_<br />
{0x00, 0x07, 0x01, 0x07, 0x01, 0x01, 0x07, 0x00}, // 3_<br />
{0x00, 0x01, 0x01, 0x07, 0x05, 0x05, 0x05, 0x00}, // 4_<br />
{0x00, 0x07, 0x01, 0x07, 0x04, 0x04, 0x07, 0x00}, // 5_<br />
{0x00, 0x07, 0x05, 0x07, 0x04, 0x04, 0x07, 0x00}, // 6_<br />
{0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x00}, // 7_<br />
{0x00, 0x07, 0x05, 0x07, 0x05, 0x05, 0x07, 0x00}, // 8_<br />
{0x00, 0x01, 0x01, 0x07, 0x05, 0x05, 0x07, 0x00}, // 9_<br />
{0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00}, // :<br />
{0x00, 0x00, 0x02, 0x24, 0x00, 0x00, 0x00, 0x00}, // ;<br />
{0x00, 0x00, 0x00, 0x10, 0x28, 0x44, 0x00, 0x00}, // <<br />
{0x00, 0x00, 0x00, 0x14, 0x14, 0x14, 0x14, 0x14}, // =<br />
{0x00, 0x00, 0x00, 0x44, 0x28, 0x10, 0x00, 0x00}, // ><br />
{0x00, 0x00, 0x00, 0x60, 0x80, 0x8D, 0x90, 0x60}, // ?<br />
{0x00, 0x00, 0x00, 0x66, 0x89, 0x8F, 0x81, 0x7E}, // @<br />
{0x11, 0x11, 0x11, 0x1F, 0x11, 0x11, 0x11, 0x0E}, // A_<br />
{0x0F, 0x11, 0x11, 0x0F, 0x11, 0x11, 0x11, 0x0F}, // B<br />
{0x0E, 0x11, 0x01, 0x01, 0x01, 0x01, 0x11, 0x0E}, // C<br />
{0x00, 0x00, 0x00, 0xFF, 0x81, 0x81, 0x42, 0x3C}, // D<br />
{0x00, 0x00, 0x00, 0xFF, 0x91, 0x91, 0x91, 0x81}, // E<br />
{0x00, 0x00, 0x00, 0xFF, 0x90, 0x90, 0x90, 0x80}, // F<br />
{0x00, 0x00, 0x00, 0x7E, 0x81, 0x89, 0x89, 0x4E}, // G<br />
{0x00, 0x00, 0x00, 0xFF, 0x10, 0x10, 0x10, 0xFF}, // H<br />
{0x00, 0x00, 0x00, 0x81, 0x81, 0xFF, 0x81, 0x81}, // I<br />
{0x00, 0x00, 0x00, 0x06, 0x01, 0x01, 0x01, 0xFE}, // J<br />
{0x11, 0x12, 0x14, 0x18, 0x18, 0x14, 0x12, 0x11}, // K_<br />
{0x00, 0x00, 0x00, 0xFF, 0x01, 0x01, 0x01, 0x01}, // L<br />
{0x00, 0x00, 0x00, 0xFF, 0x40, 0x30, 0x40, 0xFF}, // M<br />
{0x11, 0x11, 0x11, 0x13, 0x15, 0x19, 0x11, 0x11}, // N_
{0x00, 0x00, 0x00, 0x7E, 0x81, 0x81, 0x81, 0x7E}, // O<br />
{0x00, 0x00, 0x00, 0xFF, 0x88, 0x88, 0x88, 0x70}, // P<br />
{0x00, 0x00, 0x00, 0x7E, 0x81, 0x85, 0x82, 0x7D}, // Q<br />
{0x00, 0x00, 0x00, 0xFF, 0x88, 0x8C, 0x8A, 0x71}, // R<br />
{0x00, 0x00, 0x00, 0x61, 0x91, 0x91, 0x91, 0x8E}, // S<br />
{0x00, 0x00, 0x00, 0x80, 0x80, 0xFF, 0x80, 0x80}, // T<br />
{0x00, 0x00, 0x00, 0xFE, 0x01, 0x01, 0x01, 0xFE}, // U<br />
{0x04, 0x0A, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, // V_<br />
{0x00, 0x00, 0x00, 0xFF, 0x02, 0x0C, 0x02, 0xFF}, // W<br />
{0x00, 0x00, 0x00, 0xC3, 0x24, 0x18, 0x24, 0xC3}, // X<br />
{0x00, 0x00, 0x00, 0xE0, 0x10, 0x0F, 0x10, 0xE0}, // Y<br />
{0x00, 0x00, 0x00, 0x83, 0x85, 0x99, 0xA1, 0xC1}, // Z<br />
/*{0x00, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00, 0x00}, // [<br />
{0x00, 0x00, 0x00, 0x80, 0x20, 0x08, 0x02, 0x00}, //<br />
{0x00, 0x00, 0x00, 0x81, 0xFF, 0x00, 0x00, 0x00}, // ]<br />
{0x00, 0x00, 0x20, 0x40, 0x80, 0x40, 0x20, 0x00}, // ^<br />
{0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00}, // _<br />
{0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00}, // `<br />
{0x00, 0x00, 0x00, 0x06, 0x29, 0x29, 0x29, 0x1F}, // a<br />
{0x00, 0x00, 0x00, 0xFF, 0x09, 0x11, 0x11, 0x0E}, // b<br />
{0x00, 0x00, 0x00, 0x1E, 0x21, 0x21, 0x21, 0x12}, // c<br />
{0x00, 0x00, 0x00, 0x0E, 0x11, 0x11, 0x09, 0xFF}, // d<br />
{0x00, 0x00, 0x00, 0x0E, 0x15, 0x15, 0x15, 0x0C}, // e<br />
{0x00, 0x00, 0x00, 0x08, 0x7F, 0x88, 0x80, 0x40}, // f<br />
{0x00, 0x00, 0x00, 0x30, 0x49, 0x49, 0x49, 0x7E}, // g<br />
{0x00, 0x00, 0x00, 0xFF, 0x08, 0x10, 0x10, 0x0F}, // h<br />
{0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00}, // i<br />
{0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0xBE, 0x00}, // j<br />
{0x00, 0x00, 0x00, 0xFF, 0x04, 0x0A, 0x11, 0x00}, // k<br />
{0x00, 0x00, 0x00, 0x00, 0x81, 0xFF, 0x01, 0x00}, // l<br />
{0x00, 0x00, 0x00, 0x3F, 0x20, 0x18, 0x20, 0x1F}, // m<br />
{0x00, 0x00, 0x00, 0x3F, 0x10, 0x20, 0x20, 0x1F}, // n<br />
{0x00, 0x00, 0x00, 0x0E, 0x11, 0x11, 0x11, 0x0E}, // o<br />
{0x00, 0x00, 0x00, 0x3F, 0x24, 0x24, 0x24, 0x18}, // p<br />
{0x00, 0x00, 0x00, 0x10, 0x28, 0x28, 0x18, 0x3F}, // q<br />
{0x00, 0x00, 0x00, 0x1F, 0x08, 0x10, 0x10, 0x08}, // r<br />
{0x00, 0x00, 0x00, 0x09, 0x15, 0x15, 0x15, 0x02}, // s<br />
{0x00, 0x00, 0x00, 0x20, 0xFE, 0x21, 0x01, 0x02}, // t<br />
{0x00, 0x00, 0x00, 0x1E, 0x01, 0x01, 0x02, 0x1F}, // u<br />
{0x00, 0x00, 0x00, 0x1C, 0x02, 0x01, 0x02, 0x1C}, // v<br />
{0x00, 0x00, 0x00, 0x1E, 0x01, 0x0E, 0x01, 0x1E}, // w<br />
{0x00, 0x00, 0x00, 0x11, 0x0A, 0x04, 0x0A, 0x11}, // x<br />
{0x00, 0x00, 0x00, 0x00, 0x39, 0x05, 0x05, 0x3E}, // y<br />
{0x00, 0x00, 0x00, 0x11, 0x13, 0x15, 0x19, 0x11}, // z<br />
{0x00, 0x00, 0x00, 0x10, 0xFF, 0x81, 0x00, 0x00}, // {<br />
{0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00}, // |<br />
{0x00, 0x00, 0x00, 0x81, 0xEF, 0x10, 0x00, 0x00}, // }<br />
{0x00, 0x00, 0x00, 0x08, 0x10, 0x08, 0x10, 0x00}, // ~<br />
{0x00, 0x00, 0x00, 0x10, 0x10, 0x54, 0x38, 0x10}, // R arrow<br />
{0x00, 0x00, 0x00, 0x08, 0x1C, 0x2A, 0x08, 0x08}, // L arrow*/<br />
{0x00, 0x00, 0x00, 0x3F, 0x44, 0xC4, 0x44, 0x3F}, // Å<br />
{0x00, 0x00, 0x00, 0x3F, 0xC4, 0x44, 0xC4, 0x3F}, // Ä<br />
{0x00, 0x00, 0x1C, 0xA2, 0x41, 0x41, 0xA2, 0x1C}, // Ö<br />
};
Rulla text<br />
///////////////////////////////////////////<br />
unsigned char z=0; // Används vid skiftning av bokstäverna.<br />
// PORTB<br />
unsigned char bokstav = 1; //<br />
unsigned char ascii; // Ascii för nuvarande bokstav<br />
unsigned char nasta; // Ascii för nästa bokstav<br />
unsigned char b1; // Nuvarande bokstavs kod<br />
unsigned char n1; // Nästa bokstavs kod<br />
// PORTC<br />
unsigned char ascii2;<br />
unsigned char nasta2;<br />
unsigned char b2;<br />
unsigned char n2;<br />
unsigned char bokstav2 = 0; // För matris nummer 2 (PORTB). Börjar en bokstav<br />
bakom.<br />
// Skriv ord<br />
char ord[] = " VAKNA "; // char ord[] = " HEJ " alt. char ord[] = {32, 72,<br />
69, 74, 32, 0};<br />
////////////////////////////////////////////// KLOCKA<br />
///////////////////////////////////////<br />
// Ascii för siffran<br />
unsigned char tim1;<br />
unsigned char tim2;<br />
unsigned char min1;<br />
unsigned char min2;<br />
// Definition för varje kolumn för siffran från rätt rad i letters-matrisen<br />
unsigned char h1;<br />
unsigned char h2;<br />
unsigned char m1;<br />
unsigned char m2;<br />
// Ange start-tid<br />
unsigned char h = 12;<br />
unsigned char m = 51;<br />
unsigned char s = 0;<br />
//Counter for the timekeeping<br />
unsigned char timekeeping_counter=0;<br />
// Plocka ascii för siffra<br />
char siffra[] = "0123456789"; // char ord[] = " HEJ " alt. char ord[] = {32,<br />
72, 69, 74, 32, 0};<br />
#endif
eciever.h – LEDkontrollern<br />
#ifndef Oo_RECIEVER_oO<br />
#define Oo_RECEIVER_oO<br />
void dataRecieved(unsigned char data);<br />
void sendStopAlarm();<br />
int command;<br />
#endif
eciever.c – LEDkontrollern<br />
#include <br />
#include <br />
#include <br />
#include <br />
#include "LED_KLOCKA_ATMEGA16.h"<br />
#include "reciever.h"<br />
#define RECIEVER_WAITING_START 255<br />
#define RECIEVER_WAITING_DATATYPE 254<br />
#define RECIEVER_WAITING_SEC 0<br />
#define RECIEVER_WAITING_MIN 1<br />
#define RECIEVER_WAITING_HOUR 2<br />
#define RECIEVER_WAITING_MOVE 3<br />
#define PROTOCOL_START 254<br />
#define PROTOCOL_SEC 0<br />
#define PROTOCOL_MIN 1<br />
#define PROTOCOL_HOUR 2<br />
#define PROTOCOL_MOVEAROUND 3<br />
#define PROTOCOL_STOPMOVE 4<br />
#define PROTOCOL_ALARM 5<br />
#define PROTOCOL_MOVE 8<br />
#define MOVE_FORWARD 0<br />
#define MOVE_RIGHT 1<br />
#define MOVE_LEFT 2<br />
#define MOVE_BACK 3<br />
#define MOVE_STOP 4<br />
static unsigned char reciever_state=255;<br />
static unsigned char seconds=0;<br />
static unsigned char minutes=0;<br />
static unsigned char hours=0;<br />
void dataReciev ed(unsigned<br />
char data){<br />
if (data == PROTOCOL_START) {<br />
reciever_state = RECIEVER_WAITING_DATATYPE;<br />
} else {<br />
switch (reciever_state) {<br />
case RECIEVER_WAITING_DATATYPE:<br />
switch ( data)<br />
{<br />
case PROTOCOL_SEC:<br />
reciever_state = RECIEVER_WAITING_SEC;<br />
break;<br />
case PROTOCOL_MIN:<br />
reciever_state = RECIEVER_WAITING_MIN;<br />
break;<br />
case PROTOCOL_HOUR:<br />
reciever_state = RECIEVER_WAITING_HOUR;<br />
break;<br />
case PROTOCOL_MOVEAROUND:<br />
command = 1;<br />
reciever_state = RECIEVER_WAITING_START;<br />
break;<br />
case PROTOCOL_STOPMOVE:
}<br />
}<br />
}<br />
command = 7;<br />
// DO SOMETHING, STOP!<br />
reciever_state = RECIEVER_WAITING_START;<br />
break;<br />
case PROTOCOL_ALARM:<br />
command = 2;<br />
// DO SOMETHING, WAKE UP!<br />
reciever_state = RECIEVER_WAITING_START;<br />
break;<br />
case PROTOCOL_MOVE:<br />
reciever_state = RECIEVER_WAITING_MOVE;<br />
default:<br />
break;<br />
}<br />
break;<br />
case RECIEVER_WAITING_SEC:<br />
seconds = (unsigned char)data;<br />
reciever_state = RECIEVER_WAITING_START;<br />
break;<br />
case RECIEVER_WAITING_MIN:<br />
minutes = (unsigned char)data;<br />
setMinutes(minutes);<br />
reciever_state = RECIEVER_WAITING_START;<br />
break;<br />
case RECIEVER_WAITING_HOUR:<br />
hours = (unsigned char)data;<br />
setHours(hours);<br />
reciever_state = RECIEVER_WAITING_START;<br />
break;<br />
case RECIEVER_WAITING_MOVE:<br />
switch (data){<br />
case MOVE_FORWARD:<br />
command = 3;<br />
break;<br />
case MOVE_RIGHT:<br />
command = 6;<br />
break;<br />
case MOVE_LEFT:<br />
command = 5;<br />
break;<br />
case MOVE_BACK:<br />
command = 4;<br />
break;<br />
case MOVE_STOP:<br />
command = 7;<br />
break;<br />
default:<br />
break;<br />
}<br />
reciever_state = RECIEVER_WAITING_START;<br />
default:<br />
break;
Stegmotorer.c – Rörelsekontrollern<br />
#include <br />
#include <br />
#include <br />
#include <br />
int Allstep[2][8] = {{0x0F, 0x2D, 0x31, 0x25,0x06, 0x24,0x38, 0x2C},\<br />
{0x0F, 0x0F, 0x31, 0x31,0x06,0x06,0x38, 0x38}}; // Hel och halvsteg<br />
fördefinierade i en matris.<br />
unsigned int step0 = 0;<br />
unsigned int motsatt0 =0;<br />
unsigned int step2 = 0;<br />
unsigned int motsatt2 =0;<br />
int motorDriv(int ut, double steg, int hastighet);//Ställer in hur fort och<br />
långt motorerna ska vrida sig.<br />
int kommando(void); //3-bitars kommunikation om vad roboten ska göra.<br />
int ultraTime = 0;<br />
char ultraMode = 0;<br />
char ultraStart();<br />
unsigned char ultraRead();<br />
void ultraTimerReset();<br />
char ultraRand(char max);<br />
int Run_automatic(void);<br />
void Run_alarm(void);<br />
#define ULTRA_SIGNAL 1<br />
#define ULTRA_RUNNING 2<br />
#define ULTRA_WAITING 3<br />
#define ULTRA_WAITRETURN 4<br />
#define ULTRA_READY 0<br />
ISR(SIG_OUTPUT_COMPARE0){<br />
if (motsatt0 == 0){<br />
PORTB=Allstep[0][step0];<br />
}else{<br />
PORTB=Allstep[0][7-step0];<br />
}<br />
step0++;<br />
if (step0==8)<br />
step0=0;<br />
}<br />
ISR(SIG_OUTPUT_COMPARE2){<br />
if (motsatt2 == 0){<br />
PORTC=Allstep[0][step2];<br />
}else{<br />
PORTC=Allstep[0][7-step2];<br />
}<br />
step2++;
}<br />
if (step2==8)<br />
step2=0;<br />
//wake up<br />
ISR(SIG_INTERRUPT1){ //interrupt.<br />
//cli();<br />
//sleep_disable();<br />
}<br />
/* START OF ULTRASOUD */<br />
ISR(INT0_vect){<br />
if( PIND&0x04 ){<br />
if( ultraMode==ULTRA_WAITRETURN ){ //if PINB 2 (INT0) = 1<br />
ultraTimerReset();<br />
ultraMode = ULTRA_RUNNING;<br />
}<br />
}<br />
else{<br />
ultraTime = TCNT1;<br />
ultraMode = ULTRA_WAITING;<br />
ultraTimerReset();<br />
}<br />
}<br />
ISR(TIMER1_COMPA_vect){<br />
if(ultraMode == ULTRA_SIGNAL){<br />
PORTD&=~0x02;<br />
ultraMode = ULTRA_WAITRETURN;<br />
ultraTimerReset();<br />
}<br />
}<br />
ISR(TIMER1_COMPB_vect){<br />
if(ultraMode == ULTRA_WAITING){<br />
ultraMode = ULTRA_READY;<br />
ultraStart();<br />
}<br />
}<br />
ISR(TIMER1_OVF_vect){<br />
ultraMode = ULTRA_READY;<br />
}<br />
char ultraStart(){<br />
if(ultraMode == ULTRA_READY){<br />
PORTD|=0x02;<br />
ultraTimerReset();<br />
ultraMode = ULTRA_SIGNAL;<br />
return 0;<br />
}<br />
return 1;<br />
}<br />
unsigned char ultraRead(){<br />
//PORT A = (ultraTime/ 1024);<br />
return (unsigned char)(ultraTime/1024);<br />
}
void ultraTimerReset(){<br />
TCNT1H=0;<br />
TCNT1L=0;<br />
}<br />
char ultraRand(char ma x){<br />
return ultraTime%max;<br />
}<br />
/* END OF ULTRASOUD */<br />
int main(void){<br />
DDRB=0xFF;<br />
DDRD=0b10000011; //All output but port 2 and 3<br />
DDRA=0xFF;<br />
DDRC=0xFF;<br />
TCCR0=0x0D; //Konfigurerar timern; CTC-mode, inget händer vid<br />
match och 256 prescaler<br />
TCCR2=0x0F; //Konfigurerar timer2; CTC-mode, inget händer vid<br />
match och 256 prescaler<br />
TIMSK|=0x00;<br />
/* START OF ULTRASOUD */<br />
// Set up timer1 for time measurement<br />
TCCR1A = 0x00; //00000000; No output ports, no force output compare,<br />
TCCR1B = 0x02; //00000010; No noise canselation, trigger on positive<br />
edge, normal mode, clk/8<br />
TIMSK |= 0x1C; //xxx111xx; Output compare A and B, and overflow enable<br />
//Set up timer 1 compare vectors<br />
OCR1AH = 0; //For 20 micro s delay, for output pulse<br />
OCR1AL = 20;<br />
OCR1BH = 0x27; //For 10 ms delay after return<br />
OCR1BL = 0x10;<br />
MCUCR |= 0x0 1;<br />
GICR |= 0x40;<br />
/* END OF ULTRASOUD */<br />
sei(); //Global enable<br />
while(1){<br />
kommando();<br />
}<br />
}<br />
int kommando(void){<br />
int signal = PIND&0x70;<br />
signal= signal / 16;<br />
if (signal == 1){ //Smyg omkring<br />
Run_automatic();<br />
} else if (signal == 2){ //Alarm
Run_alarm();<br />
}else if (signal == 3){ //åk fram<br />
motorDriv(1, 10, 25);<br />
}else if (signal == 4){ //bak<br />
motorDriv(2, 10, 25);<br />
}else if (signal == 5){ //vänster<br />
motorDriv(3, 10, 25);<br />
}else if (signal == 6){ //höger<br />
motorDriv(4, 10, 25);<br />
}else{ //Stå stilla<br />
TIMSK&=~0xC2;<br />
PORTB=0x7F;<br />
PORTC=0x7F;<br />
}<br />
}<br />
int Run_automatic(void){<br />
int ut=0;<br />
ultraStart();<br />
unsigned char ultra = ultraRead();<br />
int hastighet = 25;<br />
double steg;<br />
double varv;<br />
if (ultra==0){<br />
ut=2; //kommando för att köra bakåt<br />
steg=100; //Överlappning 100 steg<br />
}<br />
else if(ultra==1){ //Svänga<br />
varv=0.4; //Vinkel bestäms av hjulen<br />
steg=varv*80/1*5; //Gör som så att motorn stegar den<br />
önskade vinkeln.<br />
if (ultraRand(2)==0){ //slump<br />
//if (1==0){<br />
ut=3; //Höger<br />
}else{<br />
ut=4; //Vänster<br />
}<br />
}<br />
else{<br />
ut=1; //kommando för att köra<br />
framåt<br />
steg = 100; //Överlappning 100 steg<br />
}<br />
}<br />
motorDriv(ut, steg, hastighet);<br />
return (1);<br />
void Run_alarm(void){<br />
ultraStart();<br />
unsigned char ultra = ultraRead();<br />
int hastighet = 7;<br />
int steg = 10;<br />
int ut=3; //Svänger hela tiden höger<br />
if (ultra
akåt<br />
}<br />
}<br />
ut=2; //kommando för att köra<br />
hastighet=8;<br />
steg=800;<br />
motorDriv(ut, steg, hastighet);<br />
int motorDriv(int ut, double steg, int hastighet){<br />
}<br />
int stepMade = 0;<br />
int stepBefore = -1;<br />
OCR0=hastighet; //Flagga för timer0<br />
OCR2=hastighet; //Flagga för timer2<br />
if (ut == 1){ //Frammåt<br />
motsatt0 = 0;<br />
motsatt2 = 0;<br />
}else if (ut == 2){ //Bakåt<br />
motsatt0 = 1;<br />
motsatt2 = 1;<br />
}else if (ut == 3){ //Vänster<br />
motsatt0 = 0;<br />
motsatt2 = 1;<br />
}else if (ut == 4){ //Höger<br />
motsatt0 = 1;<br />
motsatt2 = 0;<br />
}<br />
TIMSK&=~0xC2;<br />
TIMSK|=0xC2;<br />
while(stepMade
luetooth.h Baskontrollern<br />
#ifndef Oo_BLUETOOTH_oO<br />
#define Oo_BLUETOOTH_oO<br />
void usart_init(unsigned int ubrr);<br />
void usart_send(char * msg);<br />
void USART_Transmit(unsigned char data);<br />
void BluetoothInit();<br />
#endif
LCD_Font.h – baskontrollern<br />
const char ASCII5_7[] = //prog_uint8_t<br />
{<br />
0x00, 0x00, 0x00, 0x00, 0x00,// (space)<br />
0x00, 0x00, 0x5F, 0x00, 0x00,// !<br />
0x00, 0x07, 0x00, 0x07, 0x00,// "<br />
0x14, 0x7F, 0x14, 0x7F, 0x14,// #<br />
0x24, 0x2A, 0x7F, 0x2A, 0x12,// $<br />
0x23, 0x13, 0x08, 0x64, 0x62,// %<br />
0x36, 0x49, 0x55, 0x22, 0x50,// &<br />
0x00, 0x05, 0x03, 0x00, 0x00,// '<br />
0x00, 0x1C, 0x22, 0x41, 0x00,// (<br />
0x00, 0x41, 0x22, 0x1C, 0x00,// )<br />
0x08, 0x2A, 0x1C, 0x2A, 0x08,// *<br />
0x08, 0x08, 0x3E, 0x08, 0x08,// +<br />
0x00, 0x50, 0x30, 0x00, 0x00,// ,<br />
0x08, 0x08, 0x08, 0x08, 0x08,// -<br />
0x00, 0x60, 0x60, 0x00, 0x00,// .<br />
0x20, 0x10, 0x08, 0x04, 0x02,// /<br />
0x3E, 0x51, 0x49, 0x45, 0x3E,// 0<br />
0x00, 0x42, 0x7F, 0x40, 0x00,// 1<br />
0x42, 0x61, 0x51, 0x49, 0x46,// 2<br />
0x21, 0x41, 0x45, 0x4B, 0x31,// 3<br />
0x18, 0x14, 0x12, 0x7F, 0x10,// 4<br />
0x27, 0x45, 0x45, 0x45, 0x39,// 5<br />
0x3C, 0x4A, 0x49, 0x49, 0x30,// 6<br />
0x01, 0x71, 0x09, 0x05, 0x03,// 7<br />
0x36, 0x49, 0x49, 0x49, 0x36,// 8<br />
0x06, 0x49, 0x49, 0x29, 0x1E,// 9<br />
0x00, 0x36, 0x36, 0x00, 0x00,// :<br />
0x00, 0x56, 0x36, 0x00, 0x00,// ;<br />
0x00, 0x08, 0x14, 0x22, 0x41,// <<br />
0x14, 0x14, 0x14, 0x14, 0x14,// =<br />
0x41, 0x22, 0x14, 0x08, 0x00,// ><br />
0x02, 0x01, 0x51, 0x09, 0x06,// ?<br />
0x32, 0x49, 0x79, 0x41, 0x3E,// @<br />
0x7E, 0x11, 0x11, 0x11, 0x7E,// A<br />
0x7F, 0x49, 0x49, 0x49, 0x36,// B<br />
0x3E, 0x41, 0x41, 0x41, 0x22,// C<br />
0x7F, 0x41, 0x41, 0x22, 0x1C,// D<br />
0x7F, 0x49, 0x49, 0x49, 0x41,// E<br />
0x7F, 0x09, 0x09, 0x01, 0x01,// F<br />
0x3E, 0x41, 0x41, 0x51, 0x32,// G<br />
0x7F, 0x08, 0x08, 0x08, 0x7F,// H<br />
0x00, 0x41, 0x7F, 0x41, 0x00,// I<br />
0x20, 0x40, 0x41, 0x3F, 0x01,// J<br />
0x7F, 0x08, 0x14, 0x22, 0x41,// K<br />
0x7F, 0x40, 0x40, 0x40, 0x40,// L<br />
0x7F, 0x02, 0x04, 0x02, 0x7F,// M<br />
0x7F, 0x04, 0x08, 0x10, 0x7F,// N<br />
0x3E, 0x41, 0x41, 0x41, 0x3E,// O<br />
0x7F, 0x09, 0x09, 0x09, 0x06,// P<br />
0x3E, 0x41, 0x51, 0x21, 0x5E,// Q<br />
0x7F, 0x09, 0x19, 0x29, 0x46,// R<br />
0x46, 0x49, 0x49, 0x49, 0x31,// S
};<br />
0x01, 0x01, 0x7F, 0x01, 0x01,// T<br />
0x3F, 0x40, 0x40, 0x40, 0x3F,// U<br />
0x1F, 0x20, 0x40, 0x20, 0x1F,// V<br />
0x7F, 0x20, 0x18, 0x20, 0x7F,// W<br />
0x63, 0x14, 0x08, 0x14, 0x63,// X<br />
0x03, 0x04, 0x78, 0x04, 0x03,// Y<br />
0x61, 0x51, 0x49, 0x45, 0x43,// Z<br />
0x00, 0x00, 0x7F, 0x41, 0x41,// [<br />
0x02, 0x04, 0x08, 0x10, 0x20,// "\"<br />
0x41, 0x41, 0x7F, 0x00, 0x00,// ]<br />
0x04, 0x02, 0x01, 0x02, 0x04,// ^<br />
0x40, 0x40, 0x40, 0x40, 0x40,// _<br />
0x00, 0x01, 0x02, 0x04, 0x00,// `<br />
0x20, 0x54, 0x54, 0x54, 0x78,// a<br />
0x7F, 0x48, 0x44, 0x44, 0x38,// b<br />
0x38, 0x44, 0x44, 0x44, 0x20,// c<br />
0x38, 0x44, 0x44, 0x48, 0x7F,// d<br />
0x38, 0x54, 0x54, 0x54, 0x18,// e<br />
0x08, 0x7E, 0x09, 0x01, 0x02,// f<br />
0x08, 0x14, 0x54, 0x54, 0x3C,// g<br />
0x7F, 0x08, 0x04, 0x04, 0x78,// h<br />
0x00, 0x44, 0x7D, 0x40, 0x00,// i<br />
0x20, 0x40, 0x44, 0x3D, 0x00,// j<br />
0x00, 0x7F, 0x10, 0x28, 0x44,// k<br />
0x00, 0x41, 0x7F, 0x40, 0x00,// l<br />
0x7C, 0x04, 0x18, 0x04, 0x78,// m<br />
0x7C, 0x08, 0x04, 0x04, 0x78,// n<br />
0x38, 0x44, 0x44, 0x44, 0x38,// o<br />
0x7C, 0x14, 0x14, 0x14, 0x08,// p<br />
0x08, 0x14, 0x14, 0x18, 0x7C,// q<br />
0x7C, 0x08, 0x04, 0x04, 0x08,// r<br />
0x48, 0x54, 0x54, 0x54, 0x20,// s<br />
0x04, 0x3F, 0x44, 0x40, 0x20,// t<br />
0x3C, 0x40, 0x40, 0x20, 0x7C,// u<br />
0x1C, 0x20, 0x40, 0x20, 0x1C,// v<br />
0x3C, 0x40, 0x30, 0x40, 0x3C,// w<br />
0x44, 0x28, 0x10, 0x28, 0x44,// x<br />
0x0C, 0x50, 0x50, 0x50, 0x3C,// y<br />
0x44, 0x64, 0x54, 0x4C, 0x44,// z<br />
0x00, 0x08, 0x36, 0x41, 0x00,// {<br />
0x00, 0x00, 0x7F, 0x00, 0x00,// |<br />
0x00, 0x41, 0x36, 0x08, 0x00,// }<br />
0x08, 0x08, 0x2A, 0x1C, 0x08,// -><br />
0x08, 0x1C, 0x2A, 0x08, 0x08 //
alarm.h – baskontrollern<br />
const char alarm[][128] = {<br />
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x<br />
00,0x00,0x00,0xE0,0xF0,0xF8,0x3C,0x1E,0x0E,0x0E,0x06,0x07,0x07,0x07,0x07,0x07,<br />
0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x0<br />
7,0x07,0x07,0x07,0x07,0x07,0x0E,0x0E,0x1E,0x1C,0x7C,0xF8,0xF0,0xE0,0x00,0x00,0<br />
x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00<br />
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x<br />
00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,<br />
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0<br />
0,0x00,0x00,0x00},<br />
{0x00,0x00,0x00,0x00,0x00,0x80,0x80,0xC0,0xE0,0xF0,0xF0,0xF8,0xF8,0xFC,0xFC,0x<br />
FC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFE,0xFC,0xF8,<br />
0xE0,0x38,0x38,0x38,0x38,0x38,0x38,0x1C,0x1C,0x1C,0x00,0x00,0x00,0x00,0x00,0xE<br />
0,0xF8,0xFC,0xFE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFE,0<br />
xFC,0xFC,0xFC,0xF8,0xF8,0xF0,0xF0,0xE0,0xC0,0x80,0x80,0x00,0x00,0x00,0x00,0x00<br />
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x<br />
00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,<br />
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0<br />
0,0x00,0x00,0x00},<br />
{0x80,0xF0,0xF8,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x<br />
FF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x7F,0x3F,0x1F,0x1F,0x0F,0x07,0x83,<br />
0x81,0x80,0x80,0x80,0x80,0x80,0xCF,0xC0,0xC0,0xC0,0x80,0x80,0x80,0x80,0x80,0x8<br />
1,0x83,0x07,0x0F,0x1F,0x1F,0x3F,0x7F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0<br />
xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xF8,0xF0,0x80<br />
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x<br />
00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,<br />
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0<br />
0,0x00,0x00,0x00},<br />
{0x0F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x7F,0x3F,0x3F,0x1F,0x9F,0x<br />
CF,0xCF,0xE7,0xF7,0xFB,0x7B,0x7D,0x3C,0x3C,0x1E,0x1E,0x1F,0x0F,0x0F,0x0F,0x07,<br />
0x07,0x07,0x07,0x07,0x03,0x03,0x03,0x63,0x03,0x03,0x03,0x03,0x07,0x07,0x07,0x0<br />
7,0x07,0x0F,0x0F,0x0F,0x1E,0x1E,0x1E,0x3C,0x3C,0x7D,0xFB,0xFB,0xF7,0xE7,0xCF,0<br />
xCF,0x9F,0x1F,0x3F,0x3F,0x7F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x0F<br />
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x<br />
00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,<br />
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0<br />
0,0x00,0x00,0x00},<br />
{0x00,0x00,0x00,0x01,0x01,0x01,0x00,0xC0,0xE0,0xF0,0xF8,0xFC,0x3E,0x1F,0x0F,0x<br />
07,0x43,0x83,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,<br />
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0<br />
0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x83,0x47,0<br />
x0F,0x0F,0x1F,0x7E,0xFC,0xF8,0xF0,0xE0,0x80,0x00,0x01,0x01,0x01,0x00,0x00,0x00<br />
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x<br />
00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,<br />
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0<br />
0,0x00,0x00,0x00},<br />
{0x00,0x00,0x00,0xE0,0xF8,0xFE,0xFF,0x3F,0x0F,0x03,0x01,0x00,0x00,0x00,0x00,0x<br />
00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFE,0xFE,<br />
0xFC,0xF8,0x70,0x30,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0
0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0<br />
x00,0x00,0x00,0x00,0x00,0x01,0x07,0x0F,0x3F,0xFF,0xFC,0xF0,0xC0,0x00,0x00,0x00<br />
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x<br />
00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,<br />
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0<br />
0,0x00,0x00,0x00},<br />
{0x00,0xF8,0xFF,0xFF,0x7F,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x<br />
00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,<br />
0x00,0x03,0x0F,0x3C,0xF0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0<br />
0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0xF0,0xF0,0<br />
xF0,0xE0,0xE0,0xE0,0x60,0x00,0x00,0x00,0x00,0x01,0x0F,0xFF,0xFF,0xFF,0xF0,0x00<br />
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x<br />
00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,<br />
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0<br />
0,0x00,0x00,0x00},<br />
{0xFE,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x<br />
00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,<br />
0x00,0x00,0x00,0x00,0x00,0x07,0x7F,0x7C,0x78,0x78,0x30,0x18,0x18,0x18,0x08,0x0<br />
C,0x0C,0x0C,0x06,0x06,0x06,0x06,0x03,0x03,0x03,0x03,0x01,0x01,0x01,0x01,0x07,0<br />
x07,0x03,0x01,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x01,0xFF,0xFF,0xFF,0x70<br />
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x<br />
00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,<br />
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0<br />
0,0x00,0x00,0x00},<br />
};
dogm128s.c – baskontrollern<br />
//************************************************************<br />
// dogm128s.c<br />
// //<br />
//************************************************************<br />
#include <br />
#include // itoa();<br />
#include <br />
#include <br />
#include <br />
#include "LCD_Font.h"<br />
#include "alarm.h"<br />
//------------------------------------------------------------<br />
// portdef<br />
//------------------------------------------------------------<br />
#define MOSI PB5<br />
#define SCK PB7<br />
#define CS PB4<br />
#define A0 PB3<br />
#define RES PB0<br />
#define BOTTOM PA0<br />
#define LEFT PA1<br />
#define TOP PA2<br />
#define RIGHT PA3<br />
#define DATA (PORTB |= (1
------------------------------------------------------------<br />
// initiering av disp och basfunktioner<br />
//------------------------------------------------------------<br />
void init_spi(void){<br />
DDRB = (1
}<br />
_delay_ms(200);<br />
send_spi(DISP_START_LINE);<br />
send_spi(ADC_SET);<br />
send_spi(COM_OUT_MODE);<br />
send_spi(DISP_NORM);<br />
send_spi(LCD_BIAS);<br />
send_spi(PWR_CTRL);<br />
send_spi(BOOST1);<br />
send_spi(BOOST2);<br />
_delay_ms(200);<br />
send_spi(CONTRAST1);<br />
send_spi(CONTRAST2);<br />
send_spi(CONTRAST3);<br />
send_spi(INDICATOR1);<br />
send_spi(INDICATOR2);<br />
send_spi(DISP_ON);<br />
DISABLE; // CS high, disable display<br />
void clear_disp(){<br />
}<br />
ENABLE;<br />
uint8_t page;<br />
for (page = 0; page < 8; page++){<br />
COMMAND;<br />
send_spi(0xB0 + page);<br />
send_spi(0x10); // column adress of 4 MSB<br />
send_spi(0x00); // column adress of 4 LSB<br />
uint8_t column;<br />
for (column = 0; column < 128; column++){<br />
DATA;<br />
send_spi(0x00);<br />
}<br />
}<br />
DISABLE;<br />
// x = 0-127, y = 0-7<br />
void goto_xy(char xcol, char ypage)<br />
{<br />
char set[] = {0xB0, 0x10, 0x00};<br />
set[0] = set[0] + ypage;<br />
set[2] = set[2] + (xcol & 0x0F);<br />
set[1] = set[1] + (xcol >> 4);<br />
COMMAND;
}<br />
send_spi(set[0]);<br />
send_spi(set[2]);<br />
send_spi(set[1]);<br />
void text(char *str, int xcol, int ypage){<br />
goto_xy(xcol, ypage);<br />
int a, i;<br />
int j = xcol;<br />
char c, dots;<br />
char *ptr = str; // pointer<br />
while(*ptr != 0){ // untill null (end of text)<br />
DATA;<br />
send_spi(0x00); // space between letters<br />
c = *ptr; // present letter<br />
a = (c - 32)*5; // get ascii equivelent of char,<br />
substract 32 for table address<br />
ptr++;<br />
}<br />
for(i = 0; i < 5; i++){<br />
dots = ASCII5_7[a+i]; // font 5x7<br />
send_spi(dots);<br />
}<br />
j += 6;<br />
if(j == 123){<br />
goto_xy(xcol, ypage++);<br />
}<br />
}<br />
//------------------------------------------------------------<br />
// ADC<br />
//------------------------------------------------------------<br />
volatile unsigned char xpos(){ // get x-coordinate<br />
DDRA = 0x00; // "reset"<br />
PORTA = 0x00;<br />
_delay_ms(20);<br />
DDRA = (1
}<br />
volatile unsigned char x,x1,x2;<br />
while ((ADCSRA & 0x40) == 0x40){} // while ADC active<br />
x1 = ADCH; // save result<br />
PORTA = (1
struct retarr touch(){ // returns coords of x and y, checks 3 a/d readings<br />
}<br />
struct retarr xy;<br />
char x, y, xarray [3], yarray [3];<br />
xarray[0] = xpos();<br />
yarray[0] = ypos();<br />
for(int i=1; i
------------------------------------------------------------<br />
// Bluetooth/USART<br />
//------------------------------------------------------------<br />
// USART Example Application<br />
// Johan Egneblad<br />
// 2010-03-02<br />
// modified for MJAAO-project 2011<br />
#define F_CPU 8000000 // Define the processor clock frequency<br />
#define BAUD 9138 // The baud rate (bits per second) of the communication<br />
#define BAUD_REG F_CPU/16/BAUD-1 // The settings for the usart register<br />
#define BUFFER_SIZE 32 // Maximum message length<br />
#include "transmitter.h"<br />
// Global variables for RX buffering<br />
volatile char rx_buffer[BUFFER_SIZE]; // A text buffer for incoming text<br />
volatile unsigned char rx_recieved_bytes; // A byte counter for the incomming<br />
text<br />
volatile unsigned char rx_eol; // An "end of line" indicator that is set to<br />
one ones a full line is read<br />
// Interrupt vector for USART Recieve Complete<br />
ISR(USART0_RX_vect) {<br />
unsigned char data;<br />
// Read the USART buffer<br />
data = UDR0;<br />
// Check if the old msg has been read (rx_eol should be cleared)<br />
/*if (rx_eol == 0) {<br />
rx_buffer[rx_recieved_bytes] = data;<br />
rx_recieved_bytes++;<br />
// If there is a line break or null character<br />
if (data==0x0d || data==0x0a || data==0x00 || rx_recieved_bytes >=<br />
(BUFFER_SIZE-1)) {<br />
rx_eol = 1; // Tell the end of line is reached<br />
rx_buffer[rx_recieved_bytes] = 0; // Terminate the string correctly<br />
rx_recieved_bytes = 0; // Clear the received bytes counter<br />
}<br />
}*/<br />
//dataRecieved((unsigned char)data);<br />
}<br />
// Initialization function for usart<br />
// inputs:<br />
// ubrr - (unsigned int) the future contents of the UBRR register<br />
void usart_init(unsigned int ubrr) {<br />
// Set the communication speed register UBRR<br />
UBRR0H = (unsigned char)(ubrr>>8); // the most significant byte<br />
UBRR0L = (unsigned char)ubrr; // the least significant byte
Clear the usart status register<br />
UCSR0A = 0x00;<br />
// Enable the Reciveing, Transmitting and Recieve completion interrupt<br />
UCSR0B = (1
}<br />
PORTC = 0x10;<br />
usart_init(BAUD_REG);<br />
_delay_ms(10000); // 10000<br />
PORTC = 0x20;<br />
usart_send("AT+BTSCAN");<br />
_delay_ms(10);<br />
PORTC = 0x30;<br />
USART_Transmit(0x0D); //enter<br />
USART_Transmit(0x0A);<br />
PORTC = 0x70;<br />
DDRD=0xf8;<br />
// Start recieving<br />
rx_eol = 0;<br />
#include "bluetooth.h"<br />
#define RECIEVER_WAITING_START 255<br />
#define RECIEVER_WAITING_DATATYPE 254<br />
#define RECIEVER_WAITING_SEC 0<br />
#define RECIEVER_WAITING_MIN 1<br />
#define RECIEVER_WAITING_HOUR 2<br />
#define PROTOCOL_START 254<br />
#define PROTOCOL_SEC 0<br />
#define PROTOCOL_MIN 1<br />
#define PROTOCOL_HOUR 2<br />
#define PROTOCOL_MOVEAROUND 3<br />
#define PROTOCOL_STOPMOVE 4<br />
#define PROTOCOL_ALARM 5<br />
#define PROTOCOL_MOVE 8<br />
#define MOVE_FORWARD 0<br />
#define MOVE_RIGHT 1<br />
#define MOVE_LEFT 2<br />
#define MOVE_BACK 3<br />
#define MOVE_STOP 4<br />
void sendTime(char loc_timmar, char loc_minuter, char loc_sekunder){<br />
USART_Transmit(PROTOCOL_START);<br />
USART_Transmit(PROTOCOL_HOUR);<br />
USART_Transmit(loc_timmar);<br />
}<br />
USART_Transmit(PROTOCOL_START);<br />
USART_Transmit(PROTOCOL_MIN);<br />
USART_Transmit(loc_minuter);<br />
USART_Transmit(PROTOCOL_START);<br />
USART_Transmit(PROTOCOL_SEC);<br />
USART_Transmit(loc_sekunder);
void sendStartMoving(){<br />
USART_Transmit(PROTOCOL_START);<br />
USART_Transmit(PROTOCOL_MOVEAROUND);<br />
}<br />
void sendStopMoving(){<br />
USART_Transmit(PROTOCOL_START);<br />
USART_Transmit(PROTOCOL_STOPMOVE);<br />
}<br />
void sendAlarm(){<br />
USART_Transmit(PROTOCOL_START);<br />
USART_Transmit(PROTOCOL_ALARM);<br />
}<br />
void sendMoveForward(){<br />
USART_Transmit(PROTOCOL_START);<br />
USART_Transmit(PROTOCOL_MOVE);<br />
USART_Transmit(MOVE_FORWARD);<br />
}<br />
void sendMoveRight(){<br />
USART_Transmit(PROTOCOL_START);<br />
USART_Transmit(PROTOCOL_MOVE);<br />
USART_Transmit(MOVE_RIGHT);<br />
}<br />
void sendMoveLeft(){<br />
USART_Transmit(PROTOCOL_START);<br />
USART_Transmit(PROTOCOL_MOVE);<br />
USART_Transmit(MOVE_LEFT);<br />
}<br />
void sendMoveBack(){<br />
USART_Transmit(PROTOCOL_START);<br />
USART_Transmit(PROTOCOL_MOVE);<br />
USART_Transmit(MOVE_BACK);<br />
}<br />
void sendMoveStop(){<br />
USART_Transmit(PROTOCOL_START);<br />
USART_Transmit(PROTOCOL_MOVE);<br />
USART_Transmit(MOVE_STOP);<br />
}<br />
//------------------------------------------------------------<br />
// Clock<br />
//------------------------------------------------------------<br />
volatile char timmar;<br />
volatile char minuter;<br />
volatile char sekunder;<br />
volatile char atim;<br />
volatile char amin;<br />
volatile char asek;<br />
void adjustTime();<br />
void initRealtime();<br />
void alarmclock();
ISR(TIMER2_COMPA_vect){ // interrupt when timer hits 32<br />
sekunder ++;<br />
adjustTime();<br />
}<br />
void adjustTime(){<br />
while(sekunder >= 60){<br />
sekunder -=60;<br />
minuter ++;<br />
while(minuter >= 60){<br />
minuter -= 60;<br />
timmar++;<br />
while(timmar >= 24){<br />
timmar -= 24;<br />
}<br />
}<br />
}<br />
}<br />
void initRealtime(){<br />
ASSR |= 0b00100000; // Timer/Counter2 is clocked from a crystal<br />
oscillator 32.768kHz<br />
_delay_ms(100);<br />
TCCR2A = 0b00000010; // counting sequence of the counter<br />
TCCR2B = 0b00000111; // clk/1024 -> 32768/1024 = 32 cycles/sec<br />
OCR2A = 32; // reset timer every 32 cycle<br />
TIMSK2 =0b0000010; // Timer/Counter2 Output Compare Match A<br />
Interrupt Enable<br />
}<br />
void numpad(){<br />
}<br />
text(" 1 2 3",0,1);<br />
text(" 4 5 6",0,3);<br />
text(" 7 8 9",0,5);<br />
text(" clr 0 set",0,7);<br />
void updatetime(char tim, char min, char sek){<br />
char t[4], m[4], s[4];<br />
itoa(tim, t, 10);<br />
if(tim < 10){<br />
t[1] = ' ';<br />
t[2] = 0;<br />
}<br />
text(t,12,3);<br />
itoa(min, m, 10);<br />
if(min < 10){<br />
m[1] = ' ';
}<br />
m[2] = 0;<br />
}<br />
text(m,42,3);<br />
itoa(sek, s, 10);<br />
if(sek < 10){<br />
s[1] = ' ';<br />
s[2] = 0;<br />
}<br />
text(s,72,3);<br />
void settime(){<br />
char tim = 0;<br />
char min = 0;<br />
char sek = 0;<br />
char set = 0, x, y;<br />
text(" # # #",0,1); // "arrows"<br />
text(" # # #",0,6);<br />
text("SET",95,2);<br />
text("BACK",95,5);<br />
updatetime(tim, min, sek);<br />
while(set != 1){<br />
struct retarr xy;<br />
xy = touch();<br />
x = xy.values[0];<br />
y = xy.values[1];<br />
if(y == 8){ // +1 tim/min/sek<br />
}<br />
if(x == 20){<br />
tim += 1;<br />
if(tim == 24){<br />
tim = 0;<br />
}<br />
}<br />
if(x == 15){<br />
min += 1;<br />
if(min == 60){<br />
min = 0;<br />
}<br />
}<br />
if(x == 10){<br />
sek += 1;<br />
if(sek == 60){<br />
sek = 0;<br />
}<br />
}<br />
updatetime(tim, min, sek);
if(y == 3){ // -1 tim/min/sek<br />
}<br />
} // while<br />
return;<br />
} // func<br />
void setalarm(){<br />
if(x == 20){<br />
tim -= 1;<br />
if(tim == 255){<br />
tim = 23;<br />
}<br />
}<br />
if(x == 15){<br />
min -= 1;<br />
if(min == 255){<br />
min = 59;<br />
}<br />
}<br />
if(x == 10){<br />
sek -= 1;<br />
if(sek == 255){<br />
sek = 59;<br />
}<br />
}<br />
updatetime(tim, min, sek);<br />
if(y == 7){ // set time<br />
if(x >= 40 && x = 40 && x
struct retarr xy;<br />
xy = touch();<br />
x = xy.values[0];<br />
y = xy.values[1];<br />
if(y == 8){ // +1 tim/min/sek<br />
}<br />
if(x == 20){<br />
tim += 1;<br />
if(tim == 24){<br />
tim = 0;<br />
}<br />
}<br />
if(x == 15){<br />
min += 1;<br />
if(min == 60){<br />
min = 0;<br />
}<br />
}<br />
if(x == 10){<br />
sek += 1;<br />
if(sek == 60){<br />
sek = 0;<br />
}<br />
}<br />
if(y == 3){ // -1 tim/min/sek<br />
}<br />
if(x == 20){<br />
tim -= 1;<br />
if(tim == 255){<br />
tim = 23;<br />
}<br />
}<br />
if(x == 15){<br />
min -= 1;<br />
if(min == 255){<br />
min = 59;<br />
}<br />
}<br />
if(x == 10){<br />
sek -= 1;<br />
if(sek == 255){<br />
sek = 59;<br />
}<br />
}<br />
if(y == 7){ // set alarm<br />
if(x >= 40 && x
} // while<br />
return;<br />
} // func<br />
void alarmclock(){<br />
}<br />
if(y == 4){<br />
if(x >= 40 && x
}<br />
text("stop",48,3);<br />
text("right",96,3);<br />
text("down",48,5);<br />
text("BACK",95,7);<br />
if (x == 10) { // up & down<br />
if (y == 8) {<br />
sendMoveForward();<br />
}<br />
if (y == 3) {<br />
sendMoveBack();<br />
}<br />
}<br />
if (y == 6) { // left, right & stop<br />
if (x == 10) {<br />
sendMoveLeft();<br />
}<br />
if (x == 10) {<br />
sendMoveRight();<br />
}<br />
if (x == 10) {<br />
sendMoveStop();<br />
}<br />
if(y == 4){<br />
if(x >= 40 && x
}<br />
}<br />
}<br />
text("TIME",95,1);<br />
text("ALARM",95,3);<br />
text("MOVE", 95,5);<br />
char x,y;<br />
struct retarr xy;<br />
xy = touch();<br />
x = xy.values[0];<br />
y = xy.values[1];<br />
showxy(x,y);<br />
send_spi(dots);<br />
if(y == 8 || y == 9){ // TIME<br />
if(x < 7 && x > 2){<br />
clear_disp();<br />
settime();<br />
}<br />
}<br />
if(y == 6 || y == 7){ // ALARM<br />
if(x < 7 && x >= 2){<br />
setalarm();<br />
}<br />
}<br />
if(y == 4 || y == 5){ // MOVE<br />
if(x < 7 && x >= 2){<br />
move();<br />
}<br />
}<br />
//------------------------------------------------------------<br />
// main<br />
//------------------------------------------------------------<br />
int main(void){<br />
init_spi(); // initiate communication through SPI, SPI_MasterInit<br />
init_disp(); // initiate display<br />
_delay_ms(100);<br />
clear_disp(); // all pixels active, empty screen
eturn 0;<br />
}<br />
initRealtime(); // initiate RTC (time)<br />
sei(); // enable interrupts<br />
alarmclock();<br />
text("ABCDEFGHIJKLMN",0,1);<br />
text("OPQRSTUVXYZ",0,2);<br />
text("abcdefghijklmn",0,3); // power-on test<br />
text("opqrstuvxyz",0,4);<br />
text("1234567890",0,5);<br />
text("!#$%&/()=?",0,6);<br />
_delay_ms(500);<br />
BluetoothInit();<br />
text("bluetooth init",0,0);<br />
_delay_ms(500);<br />
clear_disp();<br />
while(1){<br />
}<br />
startscreen();
Batteri<br />
Kretskort <strong>med</strong><br />
Mikrokontroller 1<br />
Bilaga H. Anslutningar mellan moduler och kretskort<br />
Spänningsregulator<br />
till 5 V<br />
PORT D<br />
LED-display<br />
5 V<br />
Adapterkort 1<br />
UART<br />
3-bitars<br />
kommunikation<br />
Till motorer<br />
Touch-display<br />
Adapterkort 2<br />
Knapp<br />
5 V<br />
Kretskort <strong>med</strong><br />
Mikrokontroller 2<br />
Styrsignal<br />
Kretskort <strong>med</strong><br />
Mikrokontroller 3<br />
UART<br />
5 V<br />
Blåtand<br />
Kretskort <strong>med</strong><br />
dubbla H-bryggor<br />
Styrsignal<br />
UART<br />
Styrsignal<br />
Stegmotor 1 Stegmotor 2<br />
Ultraljud<br />
Blåtand
Bilaga I.<br />
Individuell rapport, LED punktmatris<br />
Av Joanna Fredriksson Larsson
Sammanfattning<br />
Efter den snabba utvecklingen av lysdioder, eller LEDs, de senaste åren har de blivit ett hett ämne<br />
och börjar integreras i fler och fler saker. De kan nu lysa otroligt starkt, och är en väldigt liten och<br />
tålig komponent. De finns i allt från skyltar som berättar när SJ tågen går till stora poängtavlor. I detta<br />
projekt har en färdig modul använts för att kunna få en fördjupad kunskap om hur man styr en matris<br />
av lysdioder.<br />
Syftet <strong>med</strong> detta projekt var att använda en färdig LED-matris som skulle fungera som en<br />
informationsdisplay som rullar fram önskad text. Ett annat syfte var att också göra ett Pong-spel för<br />
två spelare, där de tävlande ges två knappar för att styra ett varsitt racket upp och ned. Dessa<br />
används för att spela en boll fram och tillbaka. För att kunna styra alla lysdioder som man önskar<br />
används en metod som kallas multiplexing. Det innebär att du delar upp din matris i lika många delar<br />
som du har kolumner kopplade till jord. Kolumnerna tänds en i taget, och varje ny kolumn som tänds<br />
kan lysa precis som du vill. Om dessa tänds och släcks snabbt nog så hinner inte ögat registrera att<br />
bara en kolumn lyser i taget, och den bild du önskar lyser på LED-matrisen.<br />
Projektet avslutades <strong>med</strong> att bygga ihop en egen ED-matris som var 8x10 stor istället för 8x8 stor<br />
som den givna modulen.<br />
Abstract<br />
Following the rapid development in recent years, LEDs have become a hot topic. They are being<br />
integrated into more and more things. They can now shine very brightly, and it is a very small and<br />
robust component. They are found in everything from signs that tell you when the SJ trains are<br />
arriving and departing to big score boards. In this project, an already existing module was used to get<br />
a deeper knowledge of how to control a LED dot matrix.<br />
The purpose of this project was to use a LED dot matrix that would serve as an informing display and<br />
scroll a desired text across it. Another purpose for this project was to also make a Pong game for two<br />
players, where the contenders are given two buttons they can use to control a paddle up and down.<br />
They are used to play a ball back and forth. To be able to light up only the LEDs you wish you use a<br />
method called multiplexing. This means that you divide your matrix into as many parts as you have<br />
columns connected to ground. The columns are lit one at a time, and each new column can lit up as<br />
you wish. If they are being turned on and off quickly enough, the eyes cannot register that only one<br />
column is lit at a time, and you can show any picture on the display the way you want it to.<br />
The project ended with the building of an 8x10 LED dot matrix, instead of being 8x8 as the given<br />
module.
Innehåll<br />
1. Inledning 1<br />
2. Fördjupningsstudie 1<br />
2.1 Lysdioden 1<br />
2.1.1 Lysdiodteknologi 2<br />
2.2 Omvärldsanalys 3<br />
3. Hårdvara 4<br />
3.1 Mikrokontroller 4<br />
3.2 ELM-2882GWA 2.3” 8x8 Punktmatrisdisplay 4<br />
4. Inkoppling av modul på breadboard 5<br />
4.1 Motstånd 5<br />
4.2 Testa en lampa 5<br />
5. Få en lampa att lysa i LED-matrisen 6<br />
5.1 Multiplexing 6<br />
5.2 Rita en bild på displayen 7<br />
6. Mjukvara 8<br />
6.1 Timers och interrupts 8<br />
6.2 Rulla text på displayen 9<br />
6.3 Pong 10<br />
7. Löda ihop en egen LED-matris 12<br />
7.1 Prototypen 12<br />
8. Arbetssätt och problem under projektets gång 13<br />
9. Slutsats 14<br />
Referenser 14<br />
Bilagor 15<br />
A. Kopplingsschema på breadboard 15<br />
B. Kopplingsschema för kretskortet 16<br />
C. Ekonomianalys 17<br />
D. Använda portpinnar på ATMega16 19<br />
E. Programkod 20
1. Inledning<br />
En LED punktmatris är en form av display <strong>med</strong> lite större pixlar. Den består av ett antal lysdioder som<br />
sitter i en matris-formation. I dagens samhälle återfinns LED-punktmatriser på många olika ställen.<br />
De används vid busshållplatser och i tunnelbanan för att visa hur lång tid det är till nästa buss eller<br />
tunnelbana, vid vägarbeten för att tydligt varna folk att köra mer försiktigt och som displayer som<br />
blinkar i häftiga mönster, <strong>med</strong> mera.<br />
Syftet <strong>med</strong> detta projekt är att specialisera sig på LED-matriser. Funktionen för hur man styr en större<br />
LED-matris <strong>med</strong> många lysdioder som ska tändas flera i taget i olika mönster ska undersökas. Till<br />
förfogande står en 8x8 stor LED-matris och en ATMega16 mikrokontroller. Prototypen som ska<br />
tillverkas ska fungera som en informationsdisplay där en text kan rulla fram och som ett spelbräde<br />
för Pong där två spelare kan tävla mot varandra.<br />
2. Fördjupningsstudie<br />
För att få en större förståelse för produkten gjordes en fördjupningsstudie om tekniken bakom<br />
lysdioden. Det gjordes även en omvärldsanalys för att få en bild av var någonstans i dagens samhälle<br />
man använder dessa LED-matriser.<br />
2.1 Lysdioden<br />
En diod är en elektrisk komponent som endast leder ström i en riktning. Den består av två elektroder,<br />
en anod och en katod. Strömmen kan bara gå från anoden, som är pluspolen, till katoden, som är<br />
minuspolen. Dioden nuförtiden består av halvledare. De leder inte elektrisk ström riktigt lika bra som<br />
en ledare, men den utesluter inte heller strömledning som en isolator gör. Dioder kan användas till<br />
mycket, men den typen av diod som har undersöks i denna rapport är den som används för att<br />
producera ljus.<br />
Lysdioden, på engelska kallad LED (Light Emitting Diode), utstrålar ljus i form av fotoner då materialet<br />
den är gjord av utsätts för en elektriskt framåtriktad spänning. Färgen på ljuset beror på hur mycket<br />
energi fotonen består av, och olika halvledare producerar fotoner <strong>med</strong> olika energinivåer. Den första<br />
lysdioden uppfanns i mitten av 1920-talet av ryssen Vladimirovitj Losev. Men den kom då aldrig till<br />
någon praktisk nytta. År 1961 upptäcktes en halvledare, GaAs, som bara utstrålade infrarött ljus när<br />
man skickade en ström igenom den. Inte förrän år 1962 tillverkades den första lysdioden som kunde<br />
utstråla synligt ljus av Nick Holonyak Jr, som därför brukar kallas lysdiodens fader. Då kunde den bara<br />
utstråla svagt rött ljus, men idag har vi hittat material för att utstråla ultraviolett ljus, infrarött ljus<br />
och hela det synliga spektret.<br />
Figur 1 Elektriska schemasymbolen för en lysdiod. Anoden (+) är till vänster, katoden (-) är till höger<br />
1
2.1.1 Lysdiodteknologi<br />
En lysdiod (se Figur 2) är en halvledardiod. Den består av halvledare som i ena ändan är P-dopad och<br />
i den andra änden N-dopad. Att de har blivit dopade innebär att vissa störämnen har tillförts för att<br />
öka halvledarens ledningsförmåga. Genom att tillföra ett störämne <strong>med</strong> färre valenselektroner än<br />
ämnet den är gjord av bildas det positivt laddade hål, och halvledaren blir P-dopad. Den kallas även<br />
för en anod. Tillför du ett störämne <strong>med</strong> fler valenselektroner blir det negativt laddade elektroner i<br />
excess, och du får en N-dopad halvledare, även kallad en katod.<br />
Hålen och elektronerna kallas för elektriska laddningsbärare. Då det flyter en ström genom lysdioden<br />
strömmar elektroner mot P-området och hål mot N-området (hålen blir fyllda av elektroner och<br />
”flyttar”) för att försöka skapa jämvikt. Men det elektriska fältet mellan dem bromsar<br />
genomströmningen och gör så att laddningsbärarna stannar en bit in på andra sidan. Denna process,<br />
då elektronerna strömmar över mittgränsen och binds till hål, kallas rekombination.<br />
Vid spärrskiktet, det område där de två halvledartyperna möts, bildas en laddningsbarriär som kallas<br />
en PN-övergång. Denna PN-övergång är det som gör att elektriska kretsarna bara leder ström i en<br />
riktning men inte i den motsatta. Då du ansluter en spänningskälla <strong>med</strong> pluspolen till P-ända och<br />
minuspolen till N-änden så kan spänningen pressa ner laddningsbarriären så att en ström kan flyta<br />
igenom. Dioder har ett framspänningsfall, som är det spänningsfall som uppträder i ledriktningen då<br />
en spänning tillsätts. Alltså behövs minst en spänning lika stor som framspänningsfallet för att en<br />
diod ska kunna leda ström. Framspänningsfallet beror på materialet som dioden är uppbyggd av.<br />
Därför kallas denna riktning, från anod till katod, för ledriktningen. Om du däremot ansluter<br />
minuspolen till kristallens P-ände och pluspolen till N-änden förstärks laddningsbarriären och ström<br />
kan inte passera genom. Denna motsatta riktning från katod till anod kallas spärriktningen, eftersom<br />
den har en hög resistans för ström.<br />
I processen som kallades rekombination vid PN-övergången, då de fria elektronerna kunde falla<br />
tillbaka i hål då en ström flöt igenom lysdioden, kan energi i form av fotoner frigöras. Detta på grund<br />
av att när elektronen byter tillstånd till en lägre energinivå, och alltså tappar potentiell energi, så<br />
genereras en foton <strong>med</strong> en lika stor energimängd som elektronen förlorade. Under detta tillstånd<br />
kan då dioden lysa.<br />
Fotoner är ljuskvanta, och ljus har såväl våg- som partikelegenskaper. Olika frekvenser på ljusets<br />
våglängd ger olika synliga färger. Vilken frekvens som dioden avger, och där<strong>med</strong> vilken färg det blir<br />
på ljuset, beror på vilken förening som används i dioden. Olika halvledare har olika stort bandgap,<br />
alltså olika stor minsta energi som krävs för att föra en elektron från det högsta tillståndet till det<br />
lägsta, då den sen kan avge en foton. Så beroende på det ämne som dioden är gjord av avges olika<br />
frekvenser på ljuset, och där<strong>med</strong> olika färger. Ett visst ljus blir därför väldigt karakteristiskt för det<br />
ämnet som används.<br />
Några exempel på ljus som konventionella lysdioder (gjorda av oorganiska mineral) ger är AlGaAs<br />
som ger rött och infrarött ljus, GaAsP som ger rött, orange och gult ljus, GaN som ger grönt ljus, ZnSe<br />
och InGaN som ger blått ljus, och diamant som ger ultraviolett ljus. Kisel släpper ut en foton i form av<br />
långvågig värmestrålning, och släpper därför inte ut något synlig ljus.<br />
2
Figur 2 En lysdiod i genomskärning [1]<br />
2.2 Omvärldsanalys<br />
När lysdioderna började komma var de fortfarande inte så ljusstarka och de första lyste bara rött, så<br />
de användes mest som indikator-lampor till saker som labb-utrustningar, infraröda fjärrkontrollers,<br />
radion, telefoner, miniräknare och till och <strong>med</strong> klockor. Sen dess har tekniken utvecklats väldigt<br />
mycket och lysdioder kan nu även ta glödlampans plats som ljuskälla. Det är en tacksam teknik<br />
eftersom det är en liten komponent som kan lysa i många olika färger, ger ett starkare sken per watt<br />
än glödlampan, är energisnål och har en lång hållbarhet. Dock är den lite dyrare än de vanliga<br />
glödlamporna.<br />
Idag finns det många intressanta applikationer som använder sig av lysdioder. De kan till exempel<br />
användas för att dra uppmärksamhet. Vid vägarbeten används en stor LED-matris som blinkar<br />
varningsljus istället för bara en enkel skylt <strong>med</strong> en bild på. Den drar betydligt större uppmärksamhet<br />
än den vanliga skylten och fler varnas i god tid för att det är vägarbete.<br />
För att lätt kunna informera om olika saker är LED-matriser otroligt nyttiga. Meddelandetavlor<br />
innehållande många lysdioder finns på bussar där text på vilken nästa station är rullar förbi. Dessa<br />
<strong>med</strong>delandetavlor visar även om någon har tryckt på stoppknappen. LED displayerna kan också<br />
finnas vid parkeringshus, för att visa om det är ledigt eller fullt, och ute på stan finns stora displayer<br />
där mycket reklam rullar förbi.<br />
Lysdioder kan även användas som effektbelysning. Till exempel när världsartister uppträder på scen<br />
kan de ha en stor LED-matris display som visar människor som dansar eller flashar coola mönster.<br />
Scenlamporna <strong>med</strong> lysdioder i kan också blinka i häftiga mönster, och de blir inte lika varma som<br />
vanliga scenlampor.<br />
Eftersom lysdioder är så pass ljusstarka och väldigt hållbara är de ett bra alternativ för att visa<br />
signaler. Till exempel så har nästan alla trafikljusen i Stockholm bytts ut från att ha haft en glödlampa<br />
för grönt, rött och gult ljus som ofta gick sönder och var tvungen att bytas ut, till många små<br />
lysdioder som lyser mycket starkare. Detta är speciellt viktigt i trafiken så att det är säkert att köra.<br />
Om någon lampa skulle gå sönder gör det inte så mycket eftersom det finns fortfarande många kvar.<br />
3
Stockholm var den första staden i världen som började <strong>med</strong> detta. Det har även gjorts samma sak för<br />
själva bilarna, där många av lamporna både i fram och i bak har blivit utbytta till många små LEDs.<br />
En annan tillämpning som har blivit väldigt populär de senaste åren är LED TV. Där används LEDs för<br />
bakgrundsbelysning. Det gör att TVn får bilder <strong>med</strong> högre kontrast och fler färger, gör mindre skada<br />
på naturen samt sänker energianvändandet. Att använda LED-teknik till TVn möjliggör även att kunna<br />
göra en TV som är väldigt tunn. Denna LED-teknik används även på andra skärmar, som till exempel<br />
datorskärmar, vilket har gjort att även dessa har blivit mycket tunnare än de var för bara några år<br />
sedan.<br />
3. Hårdvara<br />
I projektets första del användes en färdig LED-matris modul för att experimentera <strong>med</strong>. Till hjälp<br />
användes mikrokontroller ATMega16.<br />
3.1 Mikrokontroller<br />
Till projektet har mikrokontroller AVR ATMega16 används. Den ansågs vara tillräcklig ty den hade<br />
tillräckligt <strong>med</strong> portar för att kunna utföra projektet, och en mer minneskraftig kontroller skulle inte<br />
behövas.<br />
Figur 3 Portarna på ATMega16 [2]<br />
3.2 ELM-2882GWA 2.3” 8x8 Punktmatrisdisplay<br />
Denna modul består av 64 lysdioder placerade i en 8x8 matris. Dioderna består av föroreningen<br />
galliumfosfat, GaP. Det betyder att fotonerna som avges av denna förorening kommer ge ett grönt<br />
ljus.<br />
Modulen har 16 utgående pinnar. Varje rad och varje kolumn i LED-matrisen har en pinne kopplad till<br />
sig. Till de 8 raderna är pinnar 9, 14, 8, 12, 1, 7, 2 respektive 5 kopplade, och alla raderna är katoder.<br />
Det betyder att de 8 LEDsen på varje rad är negativt ihopkopplade, och raderna leder till jord. Till de<br />
8 kolumnerna så är pinnar 13, 3, 4, 10, 6, 11, 15 respektive 16 kopplade, och alla kolumnerna är<br />
anoder. Det betyder att de är positivt ihopkopplade, och kolumnerna ansluts till VCC.<br />
4
Figur 4 Bild ovanifrån på LED-displayen [3]<br />
4. Inkoppling av modul på breadboard<br />
För att kunna styra vilka lampor som ska lysa så kopplas modulen till STK500-kortet. På kortet sitter<br />
en ATMega16-kontroller som används för att programmera LEDsen. Raderna kopplas in till PORT A<br />
(rad 1 till PA0 … rad 8 till PA7), och kolumnerna kopplas in till PORT C (kolumn 8 till PC0 … kolumn 1<br />
till PC7).<br />
4.1 Motstånd<br />
Lysdiodernas ljusstyrka bestäms av strömmen. Ju högre ström som flyter igenom, desto starkare<br />
lyser dioderna. Men om den maximala strömmen i framriktningen för dioderna skulle överskridas så<br />
förstörs dem istället. Så för att lysdioderna på modulen inte ska förstöras när vi kopplar in 5 V<br />
spänning behöver vi koppla in ett motstånd i serie <strong>med</strong> de pinnar som leder ström till de positivt<br />
kopplade lysdiod-kolumnerna för att strömbegränsa. Enligt databladet [3] har modulen en<br />
framspänning ( ) på 2,1 V som är definierat vid 20 mA ström i framriktningen ( ). Om vi förser<br />
modulen <strong>med</strong> en spänning på 5 V så kommer spänningen över hela kretsen vara 5 V minus<br />
framspänningsfallet över dioden. Alltså blir den spänning som ska gå över motståndet –<br />
. Ohm’s lag ger oss att motståndet ska ha storleken<br />
5<br />
. För att<br />
vara på den säkra sidan kopplas åtta -motstånd in till pinnarna 13, 3, 4, 10, 6, 11, 15 och 16<br />
som är kopplade till de positivt kopplade raderna. Eftersom STK500-kortet inte kan ge tillräckligt<br />
<strong>med</strong> ström utan att överhettas så kopplas en extern spänningsskälla <strong>med</strong> 5 V in.<br />
4.2 Testa en lampa<br />
Innan modulen kopplas på breadboard bör det även testas att alla lampor fungerar. Detta görs<br />
genom att koppla in 5 V via ett motstånd till en av kolumnernas pinnar och koppla jord till en<br />
av radernas pinnar. Detta tänder den lampa som är kopplad mellan dessa. Exempelvis om du lägger<br />
motståndet mot pin 16 och kopplar pin 9 till jord så ser du i BILAGA A. Kopplingsschema för<br />
breadboard, att lysdioden högst upp till höger kommer lysa. Så här testar du samtliga lysdioder.
Figur 5 Modulen monterad på breadboard<br />
5. Få en lampa att lysa i LED-matrisen<br />
För att tända en lampa i matrisen måste man som tidigare nämnts låta en ström passera igenom<br />
lysdioden. DDRA- och DDRC registren sätts på ATMega16 till utgångar. Om du då sätter den pinne på<br />
PORT A för den önskade raden som du vill ska lysa till en nolla så kommer den pinnen drivas ner till<br />
, alltså jord, och det kommer att kunna ledas en ström genom den. Om du sätter den till en etta<br />
så kommer den raden inte att lysa. För att sedan bestämma hur raden ska lysa sätter du pinnarna på<br />
PORT C för alla kolumnerna som ska lysa till ett. Då drivs de pinnarna högt till , och en ström<br />
kommer kunna ledas in på kolumnen. Sätter du pinnen till noll förblir kolumnen släckt. Eftersom<br />
varje rad och varje kolumn är ihopkopplade betyder det att man styr hela kolumnerna och hela<br />
raderna var för sig. Så nu kan du få en enskild lysdiod att lysa, eller hela rader och kolumner.<br />
5.1 Multiplexing<br />
När man definierar de rader och vilka kolumnerna på dessa rader som ska lysa kan man inte låta<br />
varje rad lysa olika. Samma kolumner och samma rader kommer alltid lysa. För att få alla dioder att<br />
lysa som man ville skulle man behöva 64 ingångar till mikrokontrollern, och det skulle för det första<br />
vara ett mycket jobbigt sätt att behöva styra alla lampor på, och för det andra vara svårt för då räcker<br />
inte alla pinnarna på mikrokontrollern till. Lösningen för att kunna visa en statisk bild på displayen,<br />
där alla raderna lyser olika utan att behöva koppla varje lampa till varsin port, kallas multiplexing.<br />
Med denna metod räcker det <strong>med</strong> att alla kolumnerna och alla raderna är ihopkopplade och bara går<br />
att styra kolumn för kolumn och rad för rad, precis som vår givna modul är. Det innebär att det då<br />
bara behövs 16 pinnar lediga till mikrokontrollern, 8 pinnar för anoderna (kolumnerna i LED<br />
matrisen) och 8 pinnar för katoderna (raderna i matrisen), istället för 64. Det multiplexing gå ut på är<br />
att du delar upp LED-matrisen i lika många delar som det finns rader som är kopplade till jord, och<br />
sedan låter varje rad i matrisen som är kopplade till jord lysa en i taget. Varje gång en ny rad tänds<br />
kan du lätt ändra hur lamporna lyser. För den ihopkopplade bredboarden skapar du en loop där du<br />
sätter en nolla först till port PA0, sen PA1, ända fram till PA7 så att ström kan flyta igenom och alla<br />
åtta raderna en chans att lysa en i taget. För varje rad som lyser ger du den LED i varje kolumn som<br />
har chans att tändas en etta på dess pinne på PORTC för att den ska tändas. Men att se en rad lysa i<br />
6
taget ger inte ett så stort grepp om vilken bild som ska visas på skärmen. Därför använder man<br />
pulsbreddsmodulering (PWM) för att lura ögat att se alla raderna samtidigt. Pulsbreddsmodulering<br />
betyder att du låter en LED blinka <strong>med</strong> så pass hög frekvens så att det mänskliga ögat inte hinner<br />
uppfatta att det blinkar. Man uppfattar inte att det blinkar därför att när du flashar en LED tillräckligt<br />
snabbt kommer skenet från LEDen fastna på din näthinna en kort stund, och om det går tillräckligt<br />
fort ser du bara ett fast sken. För att vi inte ska hinna se att det blinkar bör frekvensen lysdioden<br />
blinkar <strong>med</strong> vara högre än . Detta applicerar vi på vår LED-matris och loopar igenom alla<br />
raderna så pass fort och <strong>med</strong> en så hög frekvens så att men inte reagerar på att raderna inte visas<br />
samtidigt, och du ser en fast bild på skärmen. Programmet som har gjorts till denna modul blinkar<br />
<strong>med</strong> en delay på , alltså är . Eftersom varje rad bara är tänd en<br />
åttondel av tiden var, så betyder det att vi har en duty-cycle för varje rad på .<br />
Då man använder PWM och varje lysdiod bara lyser en åttondel av tiden kan lysdioderna klara av åtta<br />
gånger så mycket ström än när de utsätts för en konstant ström. Eftersom bara en lysdiod i varje<br />
kolumn är tänd samtidigt så går hela strömmen som kommer in i kolumnen genom den.<br />
5.2 Rita en bild på displayen<br />
Eftersom vi senare även vill kunna rulla fram en text på matrisen är det mer praktiskt att vi nu tänker<br />
oss att PORT C är kopplad till raderna istället, och PORT A är kopplad till kolumnerna. Detta för att då<br />
tänder vi kolumnen till vänster först och slutar <strong>med</strong> kolumnen till höger. När vi då skiftar texten<br />
kommer vi lättare att kunna skifta texten från höger till vänster. Så det vi gjort nu i princip är att vi<br />
har vridit på modulen ett kvarts varv <strong>med</strong>sols när vi tittar på den. Detta passar bra eftersom den<br />
ändå var tvungen att vridas ett kvarts varv <strong>med</strong>sols för att kunna kopplas in på breadboard tidigare.<br />
För att rita ut en bild på displayen tänker du alla de 64 LEDsen på matrisen som ettor och nollor, se<br />
Figur 6. Där du vill att det ska lysa en lampa sätter du en etta, alla andra lampor är nollor. Sen tittar<br />
du på varje kolumn som nu är kopplade till PORTC och skriver ut i en vektor de hexadecimala värden<br />
som de kolumner som lyser ger varje rad.<br />
Det går att skriva detta värde binärt <strong>med</strong> ettor och nollor i den ordning som du tänker dig att lampor<br />
ska vara tända och släckta. Detta kan skrivas om till det decimala systemet eftersom det binära<br />
talsystemet är en representation för tal som har talbasen två. Så första pinnen, PC0 eller PA0, får<br />
värdet , andra pinnen , tredje pinnen blir fyra, fram till sista åttonde pinnen som är<br />
värd 128. Alla pinnars binära tal, vare sig det är en etta eller nolla, multipliceras <strong>med</strong> det värde som<br />
deras 8 pinnar representeras av och adderas ihop och blir värdet som används till vektorn. Men det<br />
är behändigt att skriver om det till det hexadecimala talsystemet, eftersom det gör det enkelt att<br />
gruppera in heltal i enskilda byte. Talsystemet är ett positionssystem <strong>med</strong> de sexton siffrorna 0, 1, 2,<br />
3, 4, 5, 6, 7, 8, 9, A, B, C, D, E och F. Bokstäverna A-F representerar siffrorna 10-15. Men varje<br />
hexadecimal siffra representeras av 4 bitar. Så våra åtta rader och kolumner delas upp på två och<br />
pinnarna 4-7 representeras av ett hexadecimalt tal och pinnarna 0-3 representeras av ett annat<br />
hexadecimalt tal. Pinnarnas binära tal görs om till decimala tal och summan blir det hexadecimala<br />
talet. Till exempel så blir värdet på det första hexadecimala talet om pinne 4 och 7 är en etta och port<br />
5 och 6 en nolla .<br />
Med Figur 6 illustreras ett exempel för att rita ut en bild på LED-matrisen.<br />
7
Figur 6 Illustration för hur du tänker när du ska tända lampor<br />
Vektorn för att kunna visa detta A kommer bli: A[8] = {0x7F,0x88,0x88,0x88,0x7F,0x00,0x00,0x00};<br />
I en loop aktiverar du sista kolumnen till höger (PA0) och plockar sista värdet från vektorn (A[7]) på<br />
vilka rader som ska lysa, sen aktiverar du näst sista kolumnen från höger och plockar det näst sista<br />
värdet från vektorn på hur kolumnerna ska lysa, och så vidare tills alla åtta rader har loopats igenom<br />
och visats. Om du gör detta till en oändlig loop som loopar igenom kolumnerna tillräckligt snabbt ser<br />
ögonen bara en statisk bild.<br />
6. Mjukvara<br />
Denna modul har fått tre funktioner. Den kan antingen visa lite effekter, där först varje lampa blinkar<br />
var för sig, och sen så visas några olika figurer efter varandra. Men de två större funktionerna, som<br />
här kommer förklaras mer utförligt, är att den kan fungera som en informationsdisplay där en text<br />
rullar fram, eller så kan den användas som en spelplan för att spela Pong på. Men först kommer<br />
ATMega16s inbyggda timers att förklaras lite grundligt eftersom de har varit vitala för att skapa de<br />
två funktionerna. Mjukvaran är skriven i C <strong>med</strong> hjälp av utvecklingshjälp<strong>med</strong>let Atmel AVR Studio 4.<br />
6.1 Timers och interrupts<br />
ATMega16 AVR mikrokontroller har tre inbyggda timers, en 16-bit timer och två 8-bit timers. De kan<br />
användas för att göra många olika saker, men deras huvudfunktion är att göra vad det låter som de<br />
gör, de räknar hur lång tid som förflutit. De kan operera separat från ditt main-program och<br />
kommunicerar <strong>med</strong> hjälp av olika register och interrupts för att veta exakt vad den ska göra och efter<br />
hur lång tid den ska utföra det.<br />
En timer använder en intern klocka för att kunna veta hur lång tid som passerat och när den ska göra<br />
någonting nästa gång. Det kortaste tidsintervall som en timer kan räkna är en period, eller 1 ”tick”, av<br />
den inkommande klocksignalen. Hur lång tid ett tick tar kan man ställa in. Välj först vilken frekvens<br />
du vill att din timer ska ticka <strong>med</strong>. Fördröjning mellan varje gång timern ska göra någonting ska då<br />
vara (1 / Önskad frekvens) sekunder för att få den önskade frekvensen. Tiden mellan timerns varje<br />
tick bestäms som sagt av den interna klockfrekvensen. Den interna klockfrekvensen, Fcpu för<br />
mikrokontrollern, kan bestämmas till 1, 2, 4, eller 8 MHz. Varje tick för timern kommer ta (1 /<br />
Klockfrekvensen) sekunder. En 8-bit timer kan räkna upp till 255 tick, och 16-bit timern kan räkna upp<br />
till 65 536 tick, så där kan du justera efter hur många tick som timern ska göra någonting. Du kan<br />
8
äkna ut hur många tick du behöver för att uppnå den önskade frekvensen genom att dela (1 /<br />
Önskad frekvens) <strong>med</strong> (1 / Klockfrekvensen).<br />
Ibland kan det bli väldigt många tick som behövs, mer än var till exempel 8-bit timern kan ticka om<br />
det är den man ska använda. Man kan då använda en pre-scaler för att skala ner den interna timerklockan.<br />
Man kan använda en pre-scaler på 8, 64, 256 och 1024. Då multipliceras (1 / Önskad<br />
frekvens) <strong>med</strong> den givna pre-scalern och antalet tick som behövs minskas. Om man även sätter en<br />
lägre Fcpu så minskas antalet nödvändiga tick.<br />
De tre olika timerna har alla olika register, men de bestämmer samma funktioner. I ett av timerns<br />
register väljer man vilket mode den ska jobba i; Normal, PWM, Clear Timer on Compare Match (CTC)<br />
eller Fast PWM. I detta projekt har det mode som används varit CTC, där en jämförelse har skett och<br />
sen har timern nollställts och börjat om igen. I samma register ställer man in om man vill ha en prescaler.<br />
Antalet tick innan varje jämförelse sker specificerar i ett annat register. Varje gång timern har räknat<br />
upp till det givna antalet tick så vill vi att den ska gå in i ett interrupt, där den gör vad som är<br />
specificerat, nollställer timern, och hoppar sen tillbaka till main-programmet. Det finns flera olika<br />
typer av interrupts, det finns external interrupts och A/D-interrupt, men i detta projekt har då timerinterrupts<br />
används. För att aktivera interrupt måste man ställa in i ett tredje register aktivera CTC<br />
interrupt, och i ett fjärde register ett-ställa en bit för att sätta igång interrupts över huvud taget.<br />
Beroende på vilken timer du använder skiljer sig interrupt-vektorn för Compare Match som man ska<br />
använda lite, så det måste tittas upp när du ska programmera din interrupt.<br />
I detta projekt har interrupten används för att efter att en bild på LED-matrisen har visats ett tag så<br />
går man in i interruptet för att ändrar vilka lampor som ska lysa. I main-delen har i princip den enda<br />
funktionen varit att varje kolumn ska loppas igenom jättesnabbt hela tiden <strong>med</strong> en frekvens på för<br />
att visa den önskade bilden, och i interruptet som aktiveras ändras bilden efter att man hunnit<br />
registrera den tidigare bild som visats på LED-matrisen.<br />
De timers som används i detta projekt har haft inställningarna Fcpu 8 MHz för att få en snabb timer,<br />
och en pre-scaler på 1024 för att minska behovet av antalet tick. Antalet tick beror på hur snabbt<br />
bilden på displayen har behövt bytas, och har oftast experimenterats fram vilken hastighet som har<br />
varit bekväm.<br />
6.2 Rulla text på displayen<br />
Principen för att få en bokstav eller figur att rulla förbi på LED-displayen är att du visar flera olika<br />
bilder efter varandra, där bilden efter visar bokstaven förskjuten ett steg. När man bara har en<br />
bokstav som ska skiftas räcker det <strong>med</strong> att för varje gång som bokstaven ska skiftas börjar du din<br />
loopning av bokstavs-vektorn en kolumn åt höger. Så första bilden på bokstaven börjar från<br />
kolumnen för PA0, men när du ska visa nästa bild börjar du din loop på kolumnen näst längst bort till<br />
höger, på platsen för PA1, och visar samma bild på bara 7 kolumner denna gång. Du börjar<br />
fortfarande på sista platsen i bokstavsvektorn, så då kommer det se ut som att bokstaven har skiftat<br />
ett steg.<br />
Eftersom det går så otroligt snabbt att loopa igenom alla kolumnerna så skulle det gå alldeles för fort<br />
för att hinna se när bokstaven skiftas om det skulle skiftas direkt efter bokstavens första position har<br />
9
visats klart. Därför lägger vi till en timer <strong>med</strong> ett interrupt som säger att efter en viss tid ska man gå<br />
in i denna interrupt, och där skiftas värdet för vilken kolumn man ska börja visa bokstaven på. Då<br />
hinner man se varje bild en stund innan den ändras.<br />
När du vill ha en text som rullar förbi gör du i princip samma sak. Det du gör då är att du istället för<br />
att ha bara en vektor, gör du en matris där varje rad är definierad som en bild <strong>med</strong> de bokstäver du<br />
vill skriva ut, och bokstäverna kommer i den ordning i matrisen som du vill skriva ut dem på. Den<br />
första bilden som kommer skrivas ut på matrisen, säg ett mellanslag för att börja <strong>med</strong> en ren bild,<br />
kommer vara vektorn som är högst upp i matrisen. Men när du sen ska skifta bild så vill du att en<br />
bokstav ska komma direkt efter, och inte när du har skiftat klart en bokstav i taget som ovan. Det vi<br />
gör nu är att vi skiftar plats i matrisen, istället för att skifta kolumner. Tänk dig matrisen som en enda<br />
lång vektor. Då kommer det där att stå ett helt ord på hexadecimal form efter varandra. Vi lägger ett<br />
förstoringsglas över de första åtta talen, så vi har ett hexadecimalt tal för varje kolumn i LEDmatrisen<br />
att skriva ut. Om du sen skulle dra förstoringsglaset ett steg åt höger i denna långa vektor<br />
kommer du här bara se 7/8-delar av den första bokstaven, men du har nu också fått 1/8-del av nästa<br />
bokstav. Om vi nu skriver ut dessa åtta hexadecimala tal så får vi att första bokstaven har skiftats<br />
bort ett steg och nästa bokstav har skiftats in, och helt plötsligt så har ordet börjat rulla förbi.<br />
Fortsätt att skifta igenom matrisen på detta sätt tills alla bokstäver du vill skriva ut har skrivits ut.<br />
Här används samma typ av interrupt som säger att efter en viss tid ska man gå in i den för att skifta<br />
plats i matrisen så att texten inte rullar förbi i ett för snabbt tempo. Det som är bra <strong>med</strong> detta<br />
interrupt är det helt upp till dig hur snabbt du vill att din text ska rullas förbi på LED-matrisen.<br />
Initiering av timer<br />
Varje rad loopas igenom<br />
och tänds var för sig i en<br />
snabb frevens. En<br />
bokstav blir synlig.<br />
Initiering av<br />
interrupt<br />
Figur 7 Flödesdiagram för att rulla text<br />
6.3 Pong<br />
En LED-matris är en display <strong>med</strong> stora pixlar, och <strong>med</strong> en display kan man göra mycket roligt, inte<br />
bara skriva ut texter på. Man kan till exempel koppla in några knappar och programmera ett spel till<br />
den. I detta projekt har spelet Pong gjorts. Pong var det första kommersiellt framgångsrika<br />
arkadspelet. Idén är att spelet ska fungera för två spelare som spelar mot varandra. De står på varsin<br />
sida av en mittlinje och båda har en ”paddle”, ett racket som de kan styra upp och ned <strong>med</strong> hjälp av<br />
två knappar var. Med sitt racket ska de hindra en boll som bollas fram och tillbaka över spelplanen<br />
från att komma förbi dem. Om man missar att stoppa bollen får motståndaren ett poäng. Högst<br />
poäng vinner.<br />
10<br />
Skiftar position ett steg i<br />
matrisen som är<br />
uppbyggd av<br />
bokstäverna som ska<br />
skrivas ut. Ger intrycket<br />
att bokstaven har flyttat<br />
på sig.
För att programmera detta har två olika timers används, en 16-bit timer och en 8-bit timer. I mainprogrammet<br />
är det som händer att en vektor, där vilka lampor som ska representera de två<br />
racketarna och bollen som studsar fram och tillbaka ska lysa definieras, rullas igenom och visas på<br />
skärmen. Även i main-programmet finns reset av spelet ifall någon av spelarna skulle missa. För att<br />
ändra vilka lampor som ska lysa, ifall någon av spelarna flyttar på sitt racket och för att släcka lampan<br />
där bollen lyser och tända en ny lampa för att representera att bollen har flyttat på sig, använder<br />
man de två olika timers.<br />
8-bit timern styr racketerna. Den har ett interrupt som man går in i hela tiden efter en viss<br />
specificerad tid och tittar om någon av de två spelarna trycker ner någon av sina knappar. Om de gör<br />
det ändras vilka lampor i högra eller vänstra kolumnen som lyser för att representera att racketerna<br />
har flyttat på sig. Positionen för racketerna ändras ända tills spelaren släpper sin knapp eller man har<br />
nått positionerna högst upp eller längst ner på displayen. Positionerna är fördefinierade i en vektor<br />
där ett nytt värde hämtas vid varje knapptryckning för att tända nya lampor och på så sätt flytta<br />
racketerna.<br />
16-bit timerns interrupt styr bollens studsbana. Det den gör är att efter en specificerad tid aktiveras<br />
interruptet och flyttar fram bollen en position genom att släcka lampan för den gamla positionen för<br />
bollen och tända en ny lampa som representerar den nya positionen för bollen. Det jämförs hela<br />
tiden om en LED är tänd eller släckt på positionen för nästa boll. Om den är tänd betyder det att<br />
racketen träffar bollen och spelet fortsätter och bollen studsar tillbaka åt andra hållet. Beroende på<br />
hur bollen träffar racketerna bestäms det åt vilket håll bollen ska studsa tillbaka åt, om den ska flytta<br />
sig snett diagonalt uppåt eller nedåt eller rakt fram. Om lysdioden för bollens nästa position är släckt<br />
maskas en etta in på den platsen så att den börjar lysa. Om det skulle vara så att bollen maskas in på<br />
någon av kolumnerna längst ut så betyder det att någon av spelarna har missat, och spelat startas<br />
om. Det ses även till att bollen byter håll när den når taket eller golvet så att den inte studsar utanför<br />
spelplanen.<br />
Flyttar spelarnas racketar om<br />
någon trycker ner sin knapp<br />
varje gång 8-bit timerns<br />
interrupt aktiveras<br />
Interrupt<br />
aktiveras<br />
Initiering av timers<br />
Varje kolumn börjar loopas<br />
igenom och tändas var för<br />
sig <strong>med</strong> en snabb frekvens<br />
Figur 8 Flödesdiagram för Pong<br />
11<br />
Interrupt<br />
aktiveras<br />
Träff<br />
Flyttar bollen varje gång<br />
16-bit timerns interrupt<br />
aktiveras. Ligger också och<br />
kollar om spelarna träffar<br />
eller missar bollen<br />
Miss<br />
Reset för spelplanen
7. Löda ihop en egen LED-matris<br />
För att kunna visa på en djupare förståelse hur den färdiga LED-modulen som tillgetts fungerar<br />
löddes en egen LED-matris-modul ihop. Denna gjordes lite större än den ursprungliga för att kunna<br />
uppvisa goda kunskaper om hur man kontrollerar olika stora LED-matriser. Målsättningen var att<br />
löda ihop alla nödvändiga komponenter på ett experimentkort för att göra en 8x10 stor LED-matris.<br />
Idén var att även denna skulle kunna uppvisas som både en informationsskylt <strong>med</strong> en text som rullar<br />
förbi, och som ett spelbräde <strong>med</strong> ett pong spel, precis som den lite mindre 8x8 LED-matrisen kunde<br />
göra.<br />
Eftersom så pass många lödningar skulle behöva göras byggdes prototypen på ett experimentkort, då<br />
man där har man chans att enklare ändra om man skulle ha lött på någonting fel. Det märktes också<br />
att det ändå skulle ha blivit svårt att få plats <strong>med</strong> alla komponenter på ett etsat kretskort då<br />
kopplingsschemat gjordes i utvecklingshjälpprogrammet Multisim.<br />
7.1 Prototypen<br />
En del komponenter behövs när man ska löda ihop denna prototyp. Det behövs först och främst åttio<br />
lysdioder för att kunna åstadkomma att göra en matris som har 8 rader och 10 kolumner. Alla<br />
testades först för att se att de lyste innan de löddes fast.<br />
Det behövs åtta motstånd framför alla raderna. Det fanns inget datablad för de LEDs som användes,<br />
men gula LEDs brukar ha en framspänning mellan 1,8 V – 2,1 V och får inte överskridas av en ström<br />
större än 20mA. Om vi räknar <strong>med</strong> att den gula dioden har en framspänning på 1,8 V, eftersom det<br />
kommer ge störst utslag, så får vi att motstånden ska vara (5V – 1,8V)/0,02A = 160 ohm. Eftersom<br />
strömmen är det som begränsar ljusstyrkan så vi vill ha så litet strömbegränsande motstånd som<br />
möjligt, och eftersom varje kolumn bara lyser en tiondel av tiden så tar vi ett motstånd på 130 ohm<br />
för varje rad.<br />
När varje kolumn aktiveras ska de få tillräckligt <strong>med</strong> ström så att de får lysa så stark som möjligt.<br />
Därför används transistorer till varje kolumn som fungerar som strömbrytare. Vi väljer en MOSFET,<br />
som idag är den vanligaste transistortypen, <strong>med</strong> benämning BUZ100. Den är av typ N-kanal, och den<br />
har tre ben, source, drain och gate, där source kopplas till jord, drain till LEDsen och gate kopplas till<br />
mikrokontrollern. För att nu tända en kolumn sätter du på transistorn för den kolumnen genom att<br />
ge den en etta. Då kopplas den till jord, och en ström kan flyta genom endast denna kolumn. För att<br />
sedan låta nästa kolumn lysa stänger vi av strömbrytaren till den första kolumnen genom att sätta<br />
den till en nolla, och sätter på transistorn till nästa kolumn på samma sätt, osv tills alla 10 kolumner<br />
har fått lysa. Sen börjas det om igen i ett väldigt snabbt tempo för att få en synlig bild på displayen.<br />
Varje MOSFET måste klara av den maximala strömmen som kan komma från varje kolumn, vilket är<br />
8 lysdioder*20 mA = 160mA. BUZ100 klarar av 60A.<br />
Knappar behövs för att kunna byta mellan de olika programmen och då man vill spela Pong. Fyra<br />
knappar används till Pong och tre knappar behövs för att välja mellan de tre olika programmen. Till<br />
dessa kopplas ett pull-up motstånd på 30k ohm. Ett pull-up motstånd kopplades även till reset på 10k<br />
ohm. Det behövs även en sockel för att kunna placera in ATMega16 i, och du behöver kunna koppla<br />
in en spänning.<br />
Den största skillnaden när man går över från en 8x8 stor matris till en 8x10 stor matris är att du<br />
behöver två till pinnar för de två extra kolumnerna. PB0 och PB1 väljs för detta. Här har transistorer<br />
12
också används för att få en matris som fungerar så bra som möjligt. Programmen har anpassats så att<br />
du ska behöva göra så få ändringar på variabelvärden som möjligt när du byter mellan dem. Men om<br />
du kan principen för hur du tänder en liten display, är det ingen större skillnad för att tända en större<br />
display. Det blir bara fler pinnar som måste kontrolleras. Om den blir mycket större måste det kanske<br />
börjas tänka på ifall det behövs mer ström till kretsen. Efter att ha tänkt ut hur allt skulle kopplas<br />
genom att förstå hur den givna modulen fungerade ritades ett kretsschema som du kan se i BILAGA B<br />
– Kopplingsschema för kretskortet, och sen var det bara att löda fast.<br />
Figur 9 Slutgiltiga ihoplödda produkten<br />
8. Arbetssätt och problem under projektets gång<br />
Arbetet har flutit på bra under projektets gång fram till slutet. Innan har jag kommit på någonting jag<br />
vill göra, och har tagit mig fram dit genom att dela upp det jag vill åstadkomma i små steg och har<br />
lyckats komma igenom det. Som till exempel när jag ville få en text att rulla fram över LED-matrisen<br />
så började jag först <strong>med</strong> att bara lyckas tända och släcka de lampor jag önskade. Sen skrev jag ut en<br />
bokstav. När jag lyckats <strong>med</strong> det fick jag den enskilda bokstaven att flytta på sig. När det fungerade<br />
började jag experimentera hur jag skulle få en hel text att rulla förbi. Att tända och släcka en LED var<br />
inte så svårt, men när det kom till att få en text att rulla fram blev det lite klurigare att tänka ut hur<br />
man skulle göra. När man väl kom på ett bra sätt var det inte så svårt att utföra.<br />
Där jag stötte på problem var i slutet när jag bestämde mig för att löda ihop en egen LED-matris. När<br />
den var klar testade jag att alla lysdioder fungerade genom att koppla in alla var för sig till 5V och sen<br />
till jord. Alla lyste, men när jag sen flashade över mitt anpassade program för att rulla text till 8x10<br />
matrisen, som fungerade perfekt på 8x8-matrisen, så ville inte alla rader och kolumner lysa. Men när<br />
jag rörde på några sladdar på baksidan så började dessa rader och kolumner att lysa och programmet<br />
fungerade perfekt där också. Det var fyra kolumner och en rad som envisades att bara synas ibland.<br />
Jag misstänkte att det var lödningsfel någonstans, för de fyra kolumnerna lyste antingen<br />
allesammans eller ingen av dem. Jag felsökte och försökte hitta var felen kunde vara, och lödde om<br />
vissa lödningar igen, och jag fick dem att börja lysa igen hela tiden. Men det verkar som att det finns<br />
någon kallödning någonstans. Eftersom programmet har visat sig fungera när lamporna fungerade,<br />
och att det alltid är samma kolumner och rad som kan försvinna tyder det på att det är lödningsfel i<br />
alla fall och inte något kopplingsfel.<br />
13
När sedan alla lamporna lös igen skulle jag testa pong-spelet för 8x10-matrisen, men då fungerade<br />
inte de fyra knapparna så bra. Racketerna rörde sig, men de gjorde inte det varje gång när man<br />
tryckte. Eftersom tiden började rinna ut för att bli klar <strong>med</strong> projektet, så togs beslutet att det var<br />
viktigare att hinna skriva klart rapporten istället för att börja sitta och felsöka knapparna också.<br />
Därför kommer redovisningen för pong ske på den lånade modulen under redovisningen. Till nästa<br />
gång ska jag försöka göra prototypen i ännu mer god tid för att ha en större chans att den ska<br />
fungera perfekt.<br />
9. Slutsats<br />
Att tända och släcka precis de lampor du önskar är inte så svårt när du väl känner till tekniken för att<br />
göra det. Det som är klurigt är när du skapar program som Pong så måste du själv bestämma hur, när<br />
och var du vill att lamporna ska lysa och programmera det på bästa och enklast möjliga sätt. Under<br />
projektets gång har jag gjort om samma sak flera gånger, just för att man alltid kan komma på ett<br />
bättre sätt att göra det på.<br />
Men om jag bara reflekterar på hur jag kände mig i början av projektet, jag kunde nästan ingenting<br />
om hur man tänder och släcker lysdioder, så känner jag att jag har kommit en bra bit på vägen under<br />
projektets gång. Mycket kunskap om hur man styr en matris <strong>med</strong> lysdioder har införskaffats. Det<br />
enda jag önskat hade fungerat bättre var den modul som jag satte och lödde ihop. Men man lär sig<br />
från det också, och nästa gång ska jag inte löda ihop alla komponenterna så pass nära när de är så<br />
pass många.<br />
Referenser<br />
1. http://www.lampor-belysning.se/led/ 2011-05-04<br />
2. http://www.datasheetcatalog.org/datasheet/siemens/C67078-S1348-A2.pdf 2011-05-04<br />
3. http://www.elcomag.ru/uploads/tdpdf/07550635.pdf 2011-05-04<br />
4. http://en.wikipedia.org/wiki/LED 2011-03-28<br />
5. http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=50106 2011-03-28<br />
6. http://www.instructables.com/id/810-LED-Matrix-with-4017/ 2011-03-28<br />
7. http://www.atmel.com/dyn/resources/prod_documents/doc2466.pdf 2011-03-28<br />
8. http://en.wikipedia.org/wiki/MOSFET 2011-03-28<br />
14
Bilagor<br />
A. Kopplingsschema på breadboard<br />
Raderna är katoder<br />
(negativa)<br />
Kolumnerna är anoder<br />
(positiva)<br />
ATMega16<br />
P<br />
C<br />
7<br />
Figur 10 Kopplingsschema för modulen på breadboard<br />
P<br />
C<br />
6<br />
P<br />
C<br />
5<br />
15<br />
P<br />
C<br />
4<br />
P<br />
C<br />
3<br />
P<br />
C<br />
2<br />
P<br />
C<br />
1<br />
P<br />
C<br />
0<br />
ATMega16<br />
PA0<br />
PA1<br />
PA2<br />
PA3<br />
PA4<br />
PA5<br />
PA6<br />
PA7
B. Kopplingsschema för kretskortet<br />
Mode3<br />
Key = Space<br />
Mode2<br />
Key = Space<br />
ATMega16<br />
HDR2X4<br />
Mode1<br />
Key = Space<br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
10<br />
11<br />
12<br />
13<br />
14<br />
15<br />
16<br />
17<br />
18<br />
19<br />
20<br />
PB0<br />
PB1<br />
PB2<br />
PB3<br />
PB4<br />
PB5<br />
PB6<br />
PB7<br />
RESET<br />
VCC<br />
DGND<br />
XTAL2<br />
XTAL1<br />
PD0<br />
PD1<br />
PD2<br />
PD3<br />
PD4<br />
PD5<br />
PD6 PD7 21 PC0 22 PC1 23 PC2 24 PC3 25 PC4 26 PC5 27 PC6 28 PC7 29 AVCC 30 GND 31 AREF 32 PA7 33 PA6 34 PA5 35 PA4 36 PA3 37 PA2 38 PA1 39 PA0 40<br />
GND<br />
J4<br />
HDR1X2<br />
30.0kΩ<br />
Key = Space<br />
10kΩ<br />
R9<br />
Spelare2Nedåtknapp<br />
J1<br />
C1<br />
0.1µF<br />
Kopplingar till ATMega16<br />
16<br />
R10<br />
5V<br />
Spelare2Uppåtknapp<br />
Key = Space<br />
U1<br />
VCC<br />
HDR1X2<br />
J3<br />
HDR2X4<br />
Spelare1Nedåtknapp<br />
Key = Space<br />
J2<br />
Spelare1Uppåtknapp<br />
Key = Space
GND<br />
Q1<br />
BUZ100<br />
Q2<br />
BUZ100<br />
Q3<br />
BUZ100<br />
Q4<br />
BUZ100<br />
Q5<br />
BUZ100<br />
Q6<br />
BUZ100<br />
Q7<br />
BUZ100<br />
Q8<br />
BUZ100<br />
Q9<br />
BUZ100<br />
Q10<br />
BUZ100<br />
J3<br />
HDR2X4<br />
130Ω<br />
LED71 LED72 LED73 LED74 LED75 LED76 LED77 LED78 LED79 LED80<br />
R8<br />
130Ω<br />
HDR1X2<br />
LED61 LED62 LED63 LED64 LED65 LED66 LED67 LED68 LED69 LED70<br />
R7<br />
J2<br />
130Ω<br />
LED51 LED52 LED53 LED54 LED55 LED56 LED57 LED58 LED59 LED60<br />
R6<br />
LEDsen kopplade till ATMega16<br />
17<br />
130Ω<br />
HDR2X4<br />
LED41 LED42 LED43 LED44 LED45 LED46 LED47 LED48 LED49 LED50<br />
R5<br />
130Ω<br />
LED31 LED32 LED33 LED34 LED35 LED36 LED37 LED38 LED39 LED40<br />
R4<br />
J4<br />
130Ω<br />
LED21 LED22 LED23 LED24 LED25 LED26 LED27 LED28 LED29 LED30<br />
R3<br />
130Ω<br />
LED11 LED12 LED13 LED14 LED15 LED16 LED17 LED18 LED19 LED20<br />
R2<br />
130Ω<br />
LED1 LED2 LED3 LED4 LED5 LED6 LED7 LED8 LED9 LED10<br />
R1
C. Ekonomianalys<br />
En ekonomianalys gjordes för att få en överblick på hur mycket projektet har kostat. Den totala<br />
kostnaden uppgick till 466,1 kr.<br />
Breadboard<br />
Komponent Antal Kostnad/st [kr]<br />
300 Ω motstånd 8 0,60<br />
8x8 LED punktmatris 1 50<br />
ATMega16 1 40<br />
94,8<br />
Prototyp<br />
Komponent Antal Kostnad/st [kr]<br />
130 Ω motstånd 8 0,60<br />
BUZ100 10 35,50<br />
LED 80 0,60<br />
Knapp 7 0,50<br />
ATMega16 1 40<br />
451,3<br />
Total kostnad<br />
18<br />
556,1
D. Använda portpinnar på ATMega16<br />
Följande pinnar på mikroprocessorn ATMega16 används vid inkoppling på breadboard<br />
PORTA 0~7 är kopplade till LED-modulens pinnar 13, 3, 4, 10, 6, 11, 15 och 16.<br />
PORTC 0~7 är kopplad till LED-modulens pinnar 9, 14, 8, 12, 1, 7, 2 och 5.<br />
PORTD 0~1 och 6~7 är kopplade till de fyra knapparna som används i Pong.<br />
PORTD 3~5 är kopplade till de tre knapparna som används för att byta program.<br />
Följande pinnar på mikroprocessorn ATMega16 används vid inkoppling på prototypen<br />
PORTA 0~7 och PORTB 0~1 är kopplade till LED-matrisens 10 kolumner (katoder).<br />
PORTC 0~7 är kopplad till LED-matrisens 8 rader (anoder).<br />
PORTD 0~1 och 6~7 är kopplade till de fyra knapparna som används i Pong.<br />
PORTD 3~5 är kopplade till de tre knapparna som används för att byta program.<br />
19
E. Programkod<br />
Eftersom samtliga program använder samma 16-bit timer så gick det inte att separera programmen,<br />
så de fick skrivas Funktioner.c och Funktioner.h fick skrivas ihop <strong>med</strong> alla programmen.<br />
############################ Huvudprogram.c ############################<br />
#include "Funktioner.h"<br />
#define F_CPU 8000000 // Definiera processorns klockfrekvens<br />
int main(void){<br />
}<br />
}<br />
// Beroende på vilken knapp som trycks ner väljs olika program som körs<br />
// mode bestämmer vad som händer i 16-bit timern i Funktioner.c<br />
if(!(PIND & (1
unsigned char placering[] = {start_pos_player1, 0, 0, 0, 0, 0, 0, start_pos_player2}; // Vilka lampor som<br />
// lyser på varje rad. Först lyser bara racketerna längst ut, sen initieras även en boll. Lägg till 2 nollor i<br />
// mitten för 8x10 matris.<br />
#################################################################################<br />
// Rulla_text<br />
unsigned char kolumn_position = 7; // Vilken kolumn i letters-matrisen man befinner sig. 7 för 8x8, 1<br />
//för 8x10<br />
unsigned char bokstav = 0; // Vilken rad man befinner sig på i letters-matrisen. 0 för 8x8, 1 för 8x10<br />
//(hoppat upp en rad för att ha 10 värden att loopa igenom, ett värde för varje kolumn)<br />
unsigned char ascii; // Ascii-koden för bokstäverna man vill skriva<br />
unsigned char pos_nedraknare; // Flyttar position i matrisen när nästa kolumn ska visas<br />
volatile unsigned char letters[][8] = { // Varje hexadecimalt tal anger vilka lampor som ska lysa på den<br />
// kolumn man befinner sig på. Första talet ger första kolumnen, andra värdet ger andra kolumnen osv.<br />
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // mellanslag<br />
{0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x00}, // !<br />
{0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00}, // " //<br />
{0x00, 0x00, 0x00, 0x24, 0xFF, 0x24, 0xFF, 0x24}, // #<br />
{0x00, 0x00, 0x00, 0x12, 0x2A, 0x7F, 0x2A, 0x24}, // $<br />
{0x01, 0x02, 0x24, 0x08, 0x10, 0x24, 0x40, 0x80}, // %<br />
{0x00, 0x00, 0x00, 0x76, 0x89, 0x95, 0x62, 0x05}, // &<br />
{0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00}, // '<br />
{0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x81, 0x00}, // (<br />
{0x00, 0x00, 0x00, 0x00, 0x81, 0x42, 0x3C, 0x00}, // )<br />
{0x00, 0x00, 0x00, 0x50, 0xE0, 0x50, 0x00, 0x00}, // *<br />
{0x00, 0x00, 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08}, // "+"<br />
{0x00, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0x00}, // ¥<br />
{0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08}, // -<br />
{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // .<br />
{0x00, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x00}, // /<br />
{0x00, 0x00, 0x00, 0x7E, 0x89, 0x91, 0xA1, 0x7E}, // 0<br />
{0x00, 0x00, 0x00, 0x00, 0x41, 0xFF, 0x01, 0x00}, // 1<br />
{0x00, 0x00, 0x00, 0x43, 0x85, 0x89, 0x91, 0x61}, // 2<br />
{0x00, 0x00, 0x00, 0x42, 0x81, 0x91, 0x91, 0x6E}, // 3<br />
{0x00, 0x00, 0x00, 0x18, 0x28, 0x48, 0xFF, 0x08}, // 4<br />
{0x00, 0x00, 0x00, 0xF2, 0x91, 0x91, 0x91, 0x8E}, // 5<br />
{0x00, 0x00, 0x00, 0x1E, 0x29, 0x49, 0x89, 0x86}, // 6<br />
{0x00, 0x00, 0x00, 0x80, 0x8F, 0x90, 0xA0, 0xC0}, // 7<br />
{0x00, 0x00, 0x00, 0x6E, 0x91, 0x91, 0x91, 0x6E}, // 8<br />
{0x00, 0x00, 0x00, 0x70, 0x89, 0x89, 0x8A, 0x7C}, // 9<br />
{0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00}, // :<br />
{0x00, 0x00, 0x02, 0x24, 0x00, 0x00, 0x00, 0x00}, // ;<br />
{0x00, 0x00, 0x00, 0x10, 0x28, 0x44, 0x00, 0x00}, // <<br />
{0x00, 0x00, 0x00, 0x14, 0x14, 0x14, 0x14, 0x14}, // =<br />
{0x00, 0x00, 0x00, 0x44, 0x28, 0x10, 0x00, 0x00}, // ><br />
{0x00, 0x00, 0x00, 0x60, 0x80, 0x8D, 0x90, 0x60}, // ?<br />
{0x00, 0x00, 0x00, 0x66, 0x89, 0x8F, 0x81, 0x7E}, // @<br />
{0x00, 0x00, 0x00, 0x7F, 0x88, 0x88, 0x88, 0x7F}, // A<br />
{0x00, 0x00, 0x00, 0xFF, 0x91, 0x91, 0x91, 0x6E}, // B<br />
{0x00, 0x00, 0x00, 0x7E, 0x81, 0x81, 0x81, 0x42}, // C<br />
{0x00, 0x00, 0x00, 0xFF, 0x81, 0x81, 0x42, 0x3C}, // D<br />
{0x00, 0x00, 0x00, 0xFF, 0x91, 0x91, 0x91, 0x81}, // E<br />
{0x00, 0x00, 0x00, 0xFF, 0x90, 0x90, 0x90, 0x80}, // F<br />
{0x00, 0x00, 0x00, 0x7E, 0x81, 0x89, 0x89, 0x4E}, // G<br />
{0x00, 0x00, 0x00, 0xFF, 0x10, 0x10, 0x10, 0xFF}, // H<br />
{0x00, 0x00, 0x00, 0x81, 0x81, 0xFF, 0x81, 0x81}, // I<br />
{0x00, 0x00, 0x00, 0x06, 0x01, 0x01, 0x01, 0xFE}, // J<br />
{0x00, 0x00, 0x00, 0xFF, 0x18, 0x24, 0x42, 0x81}, // K<br />
21
{0x00, 0x00, 0x00, 0xFF, 0x01, 0x01, 0x01, 0x01}, // L<br />
{0x00, 0x00, 0x00, 0xFF, 0x40, 0x30, 0x40, 0xFF}, // M<br />
{0x00, 0x00, 0x00, 0xFF, 0x40, 0x30, 0x08, 0xFF}, // N<br />
{0x00, 0x00, 0x00, 0x7E, 0x81, 0x81, 0x81, 0x7E}, // O<br />
{0x00, 0x00, 0x00, 0xFF, 0x88, 0x88, 0x88, 0x70}, // P<br />
{0x00, 0x00, 0x00, 0x7E, 0x81, 0x85, 0x82, 0x7D}, // Q<br />
{0x00, 0x00, 0x00, 0xFF, 0x88, 0x8C, 0x8A, 0x71}, // R<br />
{0x00, 0x00, 0x00, 0x61, 0x91, 0x91, 0x91, 0x8E}, // S<br />
{0x00, 0x00, 0x00, 0x80, 0x80, 0xFF, 0x80, 0x80}, // T<br />
{0x00, 0x00, 0x00, 0xFE, 0x01, 0x01, 0x01, 0xFE}, // U<br />
{0x00, 0x00, 0x00, 0xF0, 0x0C, 0x03, 0x0C, 0xF0}, // V<br />
{0x00, 0x00, 0x00, 0xFF, 0x02, 0x0C, 0x02, 0xFF}, // W<br />
{0x00, 0x00, 0x00, 0xC3, 0x24, 0x18, 0x24, 0xC3}, // X<br />
{0x00, 0x00, 0x00, 0xE0, 0x10, 0x0F, 0x10, 0xE0}, // Y<br />
{0x00, 0x00, 0x00, 0x83, 0x85, 0x99, 0xA1, 0xC1}, // Z<br />
{0x00, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00, 0x00}, // [<br />
{0x00, 0x00, 0x00, 0x80, 0x20, 0x08, 0x02, 0x00}, //<br />
{0x00, 0x00, 0x00, 0x81, 0xFF, 0x00, 0x00, 0x00}, // ]<br />
{0x00, 0x00, 0x20, 0x40, 0x80, 0x40, 0x20, 0x00}, // ^<br />
{0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00}, // _<br />
{0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00}, // `<br />
{0x00, 0x00, 0x00, 0x06, 0x29, 0x29, 0x29, 0x1F}, // a<br />
{0x00, 0x00, 0x00, 0xFF, 0x09, 0x11, 0x11, 0x0E}, // b<br />
{0x00, 0x00, 0x00, 0x1E, 0x21, 0x21, 0x21, 0x12}, // c<br />
{0x00, 0x00, 0x00, 0x0E, 0x11, 0x11, 0x09, 0xFF}, // d<br />
{0x00, 0x00, 0x00, 0x0E, 0x15, 0x15, 0x15, 0x0C}, // e<br />
{0x00, 0x00, 0x00, 0x08, 0x7F, 0x88, 0x80, 0x40}, // f<br />
{0x00, 0x00, 0x00, 0x30, 0x49, 0x49, 0x49, 0x7E}, // g<br />
{0x00, 0x00, 0x00, 0xFF, 0x08, 0x10, 0x10, 0x0F}, // h<br />
{0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00}, // i<br />
{0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0xBE, 0x00}, // j<br />
{0x00, 0x00, 0x00, 0xFF, 0x04, 0x0A, 0x11, 0x00}, // k<br />
{0x00, 0x00, 0x00, 0x00, 0x81, 0xFF, 0x01, 0x00}, // l<br />
{0x00, 0x00, 0x00, 0x3F, 0x20, 0x18, 0x20, 0x1F}, // m<br />
{0x00, 0x00, 0x00, 0x3F, 0x10, 0x20, 0x20, 0x1F}, // n<br />
{0x00, 0x00, 0x00, 0x0E, 0x11, 0x11, 0x11, 0x0E}, // o<br />
{0x00, 0x00, 0x00, 0x3F, 0x24, 0x24, 0x24, 0x18}, // p<br />
{0x00, 0x00, 0x00, 0x10, 0x28, 0x28, 0x18, 0x3F}, // q<br />
{0x00, 0x00, 0x00, 0x1F, 0x08, 0x10, 0x10, 0x08}, // r<br />
{0x00, 0x00, 0x00, 0x09, 0x15, 0x15, 0x15, 0x02}, // s<br />
{0x00, 0x00, 0x00, 0x20, 0xFE, 0x21, 0x01, 0x02}, // t<br />
{0x00, 0x00, 0x00, 0x1E, 0x01, 0x01, 0x02, 0x1F}, // u<br />
{0x00, 0x00, 0x00, 0x1C, 0x02, 0x01, 0x02, 0x1C}, // v<br />
{0x00, 0x00, 0x00, 0x1E, 0x01, 0x0E, 0x01, 0x1E}, // w<br />
{0x00, 0x00, 0x00, 0x11, 0x0A, 0x04, 0x0A, 0x11}, // x<br />
{0x00, 0x00, 0x00, 0x00, 0x39, 0x05, 0x05, 0x3E}, // y<br />
{0x00, 0x00, 0x00, 0x11, 0x13, 0x15, 0x19, 0x11}, // z<br />
{0x00, 0x00, 0x00, 0x10, 0xFF, 0x81, 0x00, 0x00}, // {<br />
{0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00}, // |<br />
{0x00, 0x00, 0x00, 0x81, 0xEF, 0x10, 0x00, 0x00}, // }<br />
{0x00, 0x00, 0x00, 0x08, 0x10, 0x08, 0x10, 0x00}, // ~<br />
{0x00, 0x00, 0x00, 0x10, 0x10, 0x54, 0x38, 0x10}, // R arrow<br />
{0x00, 0x00, 0x00, 0x08, 0x1C, 0x2A, 0x08, 0x08}, // L arrow<br />
{0x00, 0x00, 0x00, 0x3F, 0x44, 0xC4, 0x44, 0x3F}, // Å<br />
{0x00, 0x00, 0x00, 0x3F, 0xC4, 0x44, 0xC4, 0x3F}, // Ä<br />
{0x00, 0x00, 0x1C, 0xA2, 0x41, 0x41, 0xA2, 0x1C}, // Ö<br />
};<br />
// Skriv den mening du vill ska rulla på displayen<br />
char ord[] = " "; // alt. char ord[] = {32, 72, 69, 74, 32, 0}; som är ascii-värdena<br />
22
#################################################################################<br />
// Effekt<br />
unsigned char i; // Räknare i en for-slinga<br />
unsigned char k; // Räknare i nästa for-slinga<br />
unsigned char effect = 0;<br />
unsigned char rad;<br />
unsigned char kolumn;<br />
volatile unsigned char figures[][10] = {<br />
{0xC0, 0xC2, 0x01, 0x19, 0x19, 0x01, 0xC2, 0xC0, 0x00, 0x00}, // Smiley<br />
{0x18, 0x18, 0x18, 0x18, 0x99, 0x5A, 0x3C, 0x18, 0x00, 0x00}, // Högerpil<br />
{0x18, 0x3C, 0x5A, 0x99, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00}, // Vänsterpil<br />
{0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81, 0x00, 0x00}, // Kryss<br />
};<br />
char effects[] = {1,2,3,4}; // Skriv vilka effekter du vill skriva ut<br />
############################### INTERRUPTS ################################<br />
// 8-bit timer interrupt<br />
ISR(TIMER0_COMP_vect){<br />
if(mode==1){ // Pong ska spelas<br />
// Padsen i Pong<br />
if(stopp == 0){ // Så länge ingen har missat är stopp = 0 och denna interrupt körs<br />
sakta_ner_counter++; // Interrupt körs bara varannan gång för att sakta ner racketerna<br />
if(sakta_ner_counter==2){<br />
if(miss == 1){ // Bryter nu istället så att den andra interrupten hinner köra klart<br />
bryt = 1;<br />
sakta_ner_counter = 0;<br />
}<br />
else{ // Om ingen har missat<br />
if(!(PIND & (1
}<br />
}<br />
}<br />
}<br />
else<br />
// 16-bit timer interrupt<br />
ISR(TIMER1_COMPA_vect){<br />
// Bollen i Pong<br />
if(mode == 1){<br />
}<br />
P2l_intryckt = 0;<br />
placering[pad_right] = position[PLAYER_1]; // Om racketen har flyttats så ändras<br />
placering[pad_left] = position[PLAYER_2]; // lampor som lyser.<br />
sakta_ner_counter = 0;<br />
}<br />
if(stopp > 0){<br />
stopp--; // Om någon missat avbryts interrupten ett tag tills stopp = 0<br />
}<br />
else { // Inget avbrott<br />
placering[boll] = 0; // Nollställ efter bollen innan<br />
// Bollens skickas fram och tillbaka mellan padsen<br />
boll+=dir_pos; // Ändrar position för bollen<br />
if(boll==pad_left) // Längst ut till vänster.<br />
dir_pos = -1; // Höger<br />
if(boll==pad_right) // Längst ut till höger<br />
dir_pos = 1; // Vänster<br />
// Bestämmer nästa position för bollen (upp/ner/rakt på)<br />
if(dir_hojd==0) // Bollen kommer rakt på<br />
pos_boll = temp_boll; // Fortsätter på samma nivå<br />
if(dir_hojd==1) // Boll kommer nerifrån<br />
pos_boll = temp_boll*2; // Fortsätt 45 grader upp;<br />
if(dir_hojd==255) // Boll kommer uppifrån<br />
pos_boll = temp_boll/2; // Fortsätt 45 grader ner;<br />
// Tittar om det är träff eller miss<br />
if(pos_boll & placering[boll]){ // Den lyser – träff<br />
// Bollen får tillbaka föregående värden<br />
boll = t_boll;<br />
pos_boll = temp_boll;<br />
if(dir_hojd == 0)<br />
dir_hojd = hall[rand() % 1]; // Ändrar riktning om bollen kommer rakt på<br />
}<br />
else{ // Den är släckt<br />
placering[boll] |= pos_boll; // Maska in 1:a så att bollen lyser på ny position<br />
if(boll == pad_left || boll == pad_right){ // Det lyser inte på bollens pos längst ut<br />
miss = 1;<br />
}<br />
}<br />
if(boll==(pad_left-1) || boll == (pad_right+1)){ // Anta träff nästa gång<br />
// Kollar hur bollen ska studsa efteråt vid träff<br />
// Höger<br />
24
}<br />
}<br />
}<br />
}<br />
if((dir_hojd == 1 && P2r_intryckt == 1) || (dir_hojd == 255 && P2l_intryckt == 1))<br />
// Boll påväg upp och racket påväg upp<br />
// eller boll påväg ner och racket påväg ner<br />
dir_hojd = 0; // Boll åker rakt fram<br />
// Vänster<br />
if((dir_hojd == 1 && P1r_intryckt == 1) || (dir_hojd == 255 && P1l_intryckt == 1))<br />
dir_hojd = 0;<br />
// Tittar ifall bollen slår i taken eller golvet och byter då riktning<br />
if(!(pos_boll == temp_boll) && (pos_boll == 1))<br />
dir_hojd = 1; // Kommer byta hÂll<br />
if(!(pos_boll == temp_boll) && (pos_boll == 128))<br />
dir_hojd = 255; // Kommer byta hÂll<br />
temp_boll = pos_boll; // Sparar gamla v‰rdet<br />
t_boll = boll; // Sparar gamla v‰rdet<br />
dir_pos_temp = dir_pos; // Sparar gamla v‰rdet. Anv‰nds vid reset<br />
// Rulla_text<br />
if(mode == 2){<br />
// Flytta position<br />
kolumn_position++; // Flytta kolumn-position varje gång bokstaven ska flytta ett steg<br />
if(kolumn_position==antal_kolumner){ // Om längst ut på raden<br />
kolumn_position=0; Hoppa tillbaka till början och<br />
// byta bokstav.<br />
bokstav++; // Bestämmer nästa bokstav som ska plockas ur ord<br />
if (bokstav==strlen(ord)){ // Är på sista bokstaven,<br />
bokstav=0; // börja om från början av strängen.1 för 8x10.<br />
kolumn_position=7; // Börja längst ut i kolumnen igen.1 för 8x10.<br />
}<br />
}<br />
}<br />
// Effekter<br />
if(mode==3)<br />
effect++; // Rad-position i figures-matrisen<br />
############################# PROGRAMMEN ##############################<br />
############################## EFFEKTER ####################################<br />
void skiftning(){<br />
for(i = 0; i < antal_kolumner; i++) {<br />
if(j < 8) {<br />
PORTA = ~(1 7) {<br />
PORTB = ~(1
}<br />
}<br />
}<br />
void effekter(){<br />
// Plocka effekter från matris<br />
rad = effects[effect]; // Bestämmer rad i figures-matrisen<br />
for(kolumn = 0; kolumn < antal_kolumner; kolumn++) {<br />
if(kolumn < 8) {<br />
PORTA = ~(1 7) {<br />
PORTB = ~(1
}<br />
TCCR1B |= (1
}<br />
}<br />
for(j = 0; j < antal_kolumner; j++) {<br />
if(j < 8) {<br />
PORTA = ~(1 7) {<br />
PORTB = ~(1
void text(void);<br />
#endif<br />
29
Bilaga J.<br />
Individuell rapport, Ultraljudslinjal – Avståndsmätning <strong>med</strong> ultraljud<br />
Av Ola Johannesson
Ola Johannesson FiM 11-03-28<br />
890502-0635 Handledare: Martin Grimheden 1(16)<br />
Ultraljudslinjal<br />
Avståndsmätning <strong>med</strong> ultraljud<br />
Ola Johannesson<br />
890502-0535<br />
FiM 2011<br />
Handledare: Martin Grumheden
Ola Johannesson FiM 11-03-28<br />
890502-0635 Handledare: Martin Grimheden 2(16)<br />
Innehåll<br />
Abstract....................................................................................................................................... 3<br />
Sammanfattning.......................................................................................................................... 3<br />
Inledning..................................................................................................................................... 4<br />
Teoretisk fördjupning.................................................................................................................. 4<br />
Ultraljud..................................................................................................................................4<br />
Problemdefinition och -lösning.............................................................................................. 5<br />
Utvecklingshjälp<strong>med</strong>el...........................................................................................................6<br />
Hårdvara................................................................................................................................. 6<br />
ATmega16..........................................................................................................................6<br />
Sändare.............................................................................................................................. 6<br />
Mottagare...........................................................................................................................7<br />
Display.............................................................................................................................13<br />
Programvara......................................................................................................................... 13<br />
Problem under gång.................................................................................................................. 14<br />
Förslag till förbättringar............................................................................................................ 15<br />
Slutsats...................................................................................................................................... 15<br />
Referenser................................................................................................................................. 15<br />
Datablad.................................................................................................................................... 15<br />
Bilagor.......................................................................................................................................16<br />
Bilaga 1: Kod........................................................................................................................16<br />
Bilaga 2: Kopplingsschema huvudkort................................................................................ 16<br />
Bilaga 3: Kopplingsschema sändare.....................................................................................16<br />
Bilaga 4: Kopplingsschema mottagare.................................................................................16<br />
Bilaga 5: Kretskort huvudkort..............................................................................................16<br />
Bilaga 6: Kretskort sändare.................................................................................................. 16<br />
Bilaga 7: Breadboard mottagare...........................................................................................16<br />
Bilaga 8: Komponentförteckning och ekonomi................................................................... 16<br />
Bilaga 9: Använda portpinnar...............................................................................................16
Ola Johannesson FiM 11-03-28<br />
890502-0635 Handledare: Martin Grimheden 3(16)<br />
Abstract<br />
Distance measurement using ultrasound is usually employed to determine the distance from a<br />
sensor to a solid object, creating reflexes which one can measure. In this report an alternative<br />
to measuring distance directly between a transmitter and a reciever, with millimeter precision<br />
is presented. The practical use of the module presented here is a digital ruler. An extension of<br />
this project, using three transmitters instead of one, is to create a position sensor in three<br />
dimensions, with sustained precision. In the report large emphasies are put on the design of<br />
the analogue amplification nessecary for the ultrasound reciever.<br />
Sammanfattning<br />
Avståndsmätning <strong>med</strong> ultraljud sker normalt för att bestämma avståndet från sensorn till ett<br />
fast objekt som skapar reflektioner. Här presenteras ett alternativ för mätning av avstånd<br />
mellan en sändare och en mottagare, <strong>med</strong> precision ner på millimeternivå. Det praktiska<br />
användningsområdet är, i den form som presenteras här, en digital linjal. I en utökning av<br />
projektet skulle samma metod, fast då <strong>med</strong> tre sändare och en mottagare, kunna användas för<br />
att positionsbestämma mottagaren i tre dimensioner <strong>med</strong> bibehållen noggrannhet. Stor vikt<br />
läggs i rapporten på designen av den analoga förstärkningen som krävs för<br />
ultraljudsmottagaren.
Ola Johannesson FiM 11-03-28<br />
890502-0635 Handledare: Martin Grimheden 4(16)<br />
Inledning<br />
Denna rapport, som undersöker avståndsmätning <strong>med</strong> ultraljud, är en del av ett<br />
kandidatexamensarbetet i mekatronik. Ultraljud kan användas för att mäta avstånd, där det<br />
vanligaste användningsområdet är att mäta avstånd mellan en kombinerad ultraljudssändare/-<br />
mottagare och någon ljudreflekterande yta. I denna rapport förklaras dock användandet av<br />
ultraljud för att mäta direkt avstånd mellan två punkter, <strong>med</strong> mål att kunna använda ultraljud<br />
som metod för positionsbestämning i rummet. En krets som ger en precision på ca 1 mm och<br />
klarar av att mäta avstånd på flertalet meter pressenteras, och en förklaring ges till hur en<br />
utvidgning till positionsbestämning i tre dimensioner skulle gå till.<br />
Då ljud färdas <strong>med</strong> en relativt låg hastighet, ca 340 meter per sekund, kan man lätt utnytja det<br />
till avståndsberäkning. På den tid en mikrokontroller utför en klockcykel hinner ljudet färdas<br />
ungefär 40 µm. Ljudets låga hastighet gör det där<strong>med</strong> lämpligt som metod för att mäta<br />
avstånd <strong>med</strong> en mikrokontroller. I realiteten uppnår man aldrig denna typ av precision, då<br />
avläsning och analys av en ljudsignal kräver ett antal klockcykler.<br />
En avståndsmätare som arbetar <strong>med</strong> ljud har uppenbara nackdelar om den arbetar inom det<br />
hörbara området av ljudspektrat, framför allt att mätningarna blir störande. För att undvika<br />
detta väljer man att använda sig av ljud över högsta hörbara frekvens på 20 kHz, så kallat<br />
ultraljud. Vanligast är att frekvenser i området 40-45 kHz används. Ultraljud kan detekteras på<br />
relativt långa avstånd då man vid dessa frekvenser kan använda mycket höga ljudnivåer,<br />
vanligt är att ultraljudssändare klarar av att skicka ut över 100 dB, vilket är samma<br />
storleksordning som de ljudnivåer man uppnår under rockkonserter.<br />
Teoretisk fördjupning<br />
Ultraljud<br />
Ljud är, när man normalt pratar om det, tryckvågor som utbreder sig i luft som kan uppfattas<br />
av det mänskliga örat. För ett ungt och friskt öra kan ljudvågor <strong>med</strong> frekvenser mellan 20 Hz<br />
och 20 kHz läggas in i denna kategori, som brukar kallas hörbart ljud. Vågor <strong>med</strong> frekvens<br />
under 20 Hz kallas infraljud och ljud <strong>med</strong> frekvenser från 20 kHz och uppåt kalls ultraljud.<br />
För att undvika att störa människors hörsel lägger man sig på frekvenser en bit över detta.
Ola Johannesson FiM 11-03-28<br />
890502-0635 Handledare: Martin Grimheden 5(16)<br />
20 Hz 20 kHz<br />
Infraljud Hörbart ljud Ultraljud<br />
Figur 1: Ljudets områden<br />
Att arbeta <strong>med</strong> höga frekvenser har andra positiva bieffekter än att det är ohörbart för<br />
människor. Ju högre frekvens man arbetar <strong>med</strong>, desto mindre kan man göra högtalar- och<br />
mikrofonelementen. Detta har två positiva följder. Den första att man <strong>med</strong> mindre element<br />
kan bygga mindre enheter, något som oftast är eftersträvansvärt. Det andra är att elementen<br />
blir mer responsiva, ett mindre element <strong>med</strong> högre frekvens kommer upp i önskvärd<br />
svängning snabbare än ett större element.<br />
Utifrån dessa egenskaper kan man dra slutsatsen att en så hög frekvens som möjligt på<br />
ultraljudet skulle vara fördelaktigt, och ur rent akustisk synvinkel stämmer detta oftast. Alltför<br />
höga frekvenser för dock <strong>med</strong> sig andra problem. De signaler man använder ska behandlas<br />
både innan de skickas ut ur sändaren och efter att de tagits emot igen av mottagaren. Både<br />
signalgenerering och signalbehandling blir besvärligare <strong>med</strong> högra frekvenser, redan vid 40<br />
kHz ställs krav på operationsförstärkare som gör att många av de vanligaste inte går att<br />
använda.<br />
Sändning och mottagning av ultraljud sker inom avståndsmätning inte <strong>med</strong> hjälp av vanliga<br />
högtalare och mikrofoner, utan sker istället <strong>med</strong> hjälp av speciella ultraljudssändare och<br />
mottagare. Dessa har tydligt definierade resonansfrekvenser vid de frekvenser som man<br />
arbetar runt, detta ger höga känsligheter både för sändare och mottagare. Utanför deras<br />
resonansområden har de å andra sidan väldigt låg känslighet, något som är positivt då det<br />
minskar risken för oönskade störningar från annat ljud i omgivningen.<br />
Problemdefinition och -lösning<br />
Det uppsatta målet <strong>med</strong> projektet var att skapa en modul kapabel att mäta avstånd <strong>med</strong> hjälp<br />
av ultraljud. För att göra detta krävdes att fungerande ultraljudssändare och<br />
ultraljudsmottagare designades, samt att ett program för tidsavläsning skapades. Det visade
Ola Johannesson FiM 11-03-28<br />
890502-0635 Handledare: Martin Grimheden 6(16)<br />
sig senare att både ultraljudssändaren och programmet var enkla att producera, <strong>med</strong>an<br />
mottagaren skulle orsaka stora problem.<br />
Utvecklingshjälp<strong>med</strong>el<br />
Under utvecklingsarbetet användes ett SDK500-kort som bas för processorn. Till detta<br />
kopplades de olika kringmodulerna, såsom sändar- och mottagarmodulerna. All kodutveckling<br />
är gjord i AVR Studio 4. För design av scheman och kretskort har National Instruments<br />
Multisim respektive Ultiboard använts.<br />
Under utvecklingsarbetet <strong>med</strong> förstärkarkretsarna för mottagaren användes även en<br />
frekvensgenerator byggd kring en 555-timerkrets för att driva ultraljudssändaren konstant.<br />
Den kretsen presenteras dock inte i denna rapport.<br />
Hårdvara<br />
ATmega16<br />
Projektet bygger kring en ATmega16, en mikrokontroller från Atmel. Det är en mycket<br />
kompetent mikrokontroller, och endast en liten del av dess potential används i detta projekt.<br />
Ett antal egenskaper och inbyggda pereferienheter har dock varit nödvändiga för projektet.<br />
Mikrokontrollern har ett flertal inbyggda räknare, och i detta projekt används två av dessa:<br />
Timer0 som är en 8-bitars timer/räknare samt Timer1 som är en 16-bitars timer/räknare. Den<br />
förstnämnda används för att generera den 40 kHz-våg som sändaren drivs av och den senare<br />
för att mäta tiden som passerar innan ljudpulsen nått mottagaren.<br />
ATmega16 har även en inbyggd komparator, som används för att mäta utgången från<br />
ultraljudsmottagarens förstärkarkrets.<br />
Sändare<br />
Den sändare som använts i projektet är av typen UTT4016, en ultraljudssändare <strong>med</strong> diameter<br />
på 16 mm och en optimal frekvens på 40 kHz.Denna fungerar i stort som en högtalare, och för<br />
att fungera optimalt skall den matas <strong>med</strong> en växelspänning <strong>med</strong> rätt frekvens. Ljud kan dock,<br />
mindre effektivt, genereras <strong>med</strong> enkelsidig växelspänning. I Figur 2 ses signalen som sänds ut<br />
från mikrokontrollern till drivsteget för sändaren.
Ola Johannesson FiM 11-03-28<br />
890502-0635 Handledare: Martin Grimheden 7(16)<br />
Figur 2: Utsignal till sändaren<br />
Då mikrokontrollern inte orkar driva en sändare direkt <strong>med</strong> en utgång används ett<br />
förstärkande steg mellan. Som förstärkarsteg valdes en push-pull-konfiguration, kopplingen<br />
ses i Figur 3.<br />
Mottagare<br />
Figur 3: Förstärkare av push-pull-konfiguration<br />
Som mottagare användes UTR4016, vilket är en matchande mottagare till sändaren UTT4016.<br />
Den har stark topp i känslighet vid 40 kHz, och ljud <strong>med</strong> andra frekvenser släcks effektivt ut<br />
så att inga onödiga störningar skapas.En ultraljudsmottagare av denna typ ger, när den tar<br />
emot ljud vid rätt frekvens, utsignaler i storleksordningen några millivolt när förhållandena är<br />
goda. Under sämre förhållanden kan utsignalen från mottagaren ligga så lågt som ett antal<br />
microvolt. För att signalen ska kunna detekteras av mikrokontrollern behöver den alltså<br />
förstärkas avsevärt, mellan 1 000 och 1 000 000 gånger. I Figur 4 visas en typisk utsignal från<br />
ultraljudsmottagaren under goda förhållanden.
Ola Johannesson FiM 11-03-28<br />
890502-0635 Handledare: Martin Grimheden 8(16)<br />
Figur 4: Signal från mottagaren, 40 cm avstånd, 10µs/div och 0,05V/div<br />
Förstärkningen sker <strong>med</strong> hjälp av operationsförstärkare, och för att uppnå den förstärkning<br />
som är nödvändig utan för mycket störningar används förstärkning i tre steg. De första två är<br />
rena förstärkningssteg <strong>med</strong>an det sista är ett kombinerat förstärknings- och likriktningssteg.<br />
Designen av denna förstärkning har som mål att onödiggöra ytterligare signalbehandling i<br />
mikrokontrollern. På grund av den höga frekvensen ställs speciella krav på<br />
operationsförstärkarna, framför allt svängninghastighet och inspänningsområde.<br />
En viktig parameter för operationsförstärkare är dess svängningshastighet (på engelska: ”slew<br />
rate”). Den anger hur snabbt kretsen klarar av att öka spänningen på utgången, i Figur 5 visas<br />
bästa möjliga kurvform, vid 40 kHz, för ett antal svängningshastigheter. En vanlig<br />
operationsförstärkare har oftast en svängningshastighet på 0,5V/µs vilket innebär att de inte<br />
ens under ideala förhållanden klara av att förstärka en 40 kHz-signal till en amplitud på mer<br />
än 6 volt, och då fås en triangelvåg <strong>med</strong> denna amplitud. För detta projekt eftersträvas dock<br />
en vågform som är så lik en fyrkantsvåg som möjligt. För att åstadkomma detta används<br />
förstärkarkretsar <strong>med</strong> en svängningshastighet på 1.9V/µs (OPA27GP) i det första steget och<br />
13V/µs (TL081CP) i de två efterföljande.<br />
Operationsförstärkarna matas alla <strong>med</strong> ± 5V, för att lätt kunna skapa en signal som håller sig
Ola Johannesson FiM 11-03-28<br />
890502-0635 Handledare: Martin Grimheden 9(16)<br />
under de 5V mikrokontrollern maximalt accepterar som inspänning. Även detta ställer krav på<br />
operationsförstärkarna, då inte alla fungerar väl <strong>med</strong> så låga spänningar.<br />
Figur 5: Kurvformer för olika svängningshastigheter<br />
De två första förstärkarstegen är kopplade i inverterande koppling, där principskissen visas i<br />
Figur 6. För dessa gäller, under optimala förhållanden, att signalförstärkningen blir -Rf/<br />
(Rin+Rk) (H. Johansson) där Rk är impedansen för den signalkälla som används. Då en<br />
operationsförstärkare har låg utgångsimpedans kan denna försummas i förstärkningssteg två<br />
och tre. För det första steget, där ultraljudsmottagaren är inkopplad, är dock inte signalkällans<br />
impedans försumbar, utan behöver vara <strong>med</strong> i beräkningarna när förstärkningen ska<br />
bestämmas.
Ola Johannesson FiM 11-03-28<br />
890502-0635 Handledare: Martin Grimheden 10(16)<br />
Figur 6: Inverterad förstärkarkoppling<br />
I Figur 7, 8 och 10 visas utseendet av en typisk signal efter de olika stegen av förstärkning.<br />
Första steget i förstärkningen är en OPA27GP i en inverterad koppling, <strong>med</strong> omkringliggande<br />
komponenter valda så att en förstärkning på -50. fås (Rk=2kΩ vid 40kHz, Rin=2kΩ,<br />
Rf=220kΩ).<br />
Figur 7: Signal efter första förstärkningssteget, 40 cm avstånd, 10µs/div och 1V/div<br />
I det andra steget finns möjlighet att ställa förstärkningen <strong>med</strong> en vridpotentiometer, och <strong>med</strong><br />
de valda komponenterna finns möjlighet att få en förstärkning på upp till 150 gånger.
Ola Johannesson FiM 11-03-28<br />
890502-0635 Handledare: Martin Grimheden 11(16)<br />
Figur 8: Signal efter andra förstärkningssteget, 40 cm avstånd, 10µs/div och 2V/div<br />
I sista steget är operationsförstärkaren kombinerad <strong>med</strong> komponenter som ger en likriktning<br />
av utsignalen. Hur en sådan, kallad precisionslikriktare, ser ut ses i Figur 9. Huvudsyftet <strong>med</strong><br />
likriktningen är att få en signal som håller sig inom TTL-logiknivåer, för att kunna mäta<br />
denna signal <strong>med</strong> mikrokontrollern. Designen är hämtad ur Andersson och Kullbjer.<br />
Figur 9: Precisionslikriktare
Ola Johannesson FiM 11-03-28<br />
890502-0635 Handledare: Martin Grimheden 12(16)<br />
Figur 10: Signal efter tredje förstärkningssteget, 40 cm avstånd, 10µs/div och 2V/div<br />
Utsignalen från tredje steget kopplas sedan in i den inbyggda komparatorn i Atmega16, där<br />
den jämförs <strong>med</strong> en referensnivå.<br />
Figur 11: Utskickad och returnerad signal vid avståndsmätning, 40 cm<br />
I Figur 11 ses den av mikrokontrollern utskickade signalen och den av<br />
mottagningselektroniken returnerade signalen.
Ola Johannesson FiM 11-03-28<br />
890502-0635 Handledare: Martin Grimheden 13(16)<br />
Display<br />
För utskrifter används en display av typ GLK12232-25SM från Matrix Orbital, en grafisk<br />
display <strong>med</strong> 122x32 pixlars upplösning. Displayen är kopplad till en kraftfull drivkrets och<br />
mikrokontrollern kommunicerar <strong>med</strong> displayen via seriekommunikation. Detta sker <strong>med</strong> 8-<br />
databitar och två stopbitar vid en hastighet av 19200 bitar per sekund. Tecken skrivs sedan ut<br />
till displayen genom att skicka motsvarande ASCII-kod till displayen. Ett antal<br />
specialkommandon går att komma åt genom att skicka en sekvens om två till fyra bytes.<br />
Displayen ansluts även till jord och matningsspänningen +5V.<br />
Programvara<br />
På grund av behandlingen av den analoga signalen blir programmeringen väldigt enkel. I<br />
Schema 1 ses ett flödesschema för programmet. Det börjar <strong>med</strong> initiering av nödvändiga<br />
funktioner. Här initieras Timer0 att generera ett interrupt <strong>med</strong> 80 kHz frekvens, som sedan<br />
används för att omväxlande höja och sänka en pinne, och där<strong>med</strong> generera en 40 kHz<br />
fyrkantsvåg. Timer1 initieras till att arbeta <strong>med</strong> en frekvens av 1 MHz, och att skicka ett<br />
interrupt på positiv flank från mikrokontrollerns inbyggda komparator. Usart-kommunikation<br />
initieras sedan <strong>med</strong> en hastighet av 19200 baud.<br />
Eftersom tidtagningen måste vara väldigt precis nollställs alla timers manuellt inför varje<br />
körning av tidtagningsslingan. Detta gör att man kan vara säker på att vågformen som<br />
genereras ser exakt likadan ut varje gång, något som är nödvändigt för att kunna få
Ola Johannesson FiM 11-03-28<br />
890502-0635 Handledare: Martin Grimheden 14(16)<br />
tillförlitliga mätvärden. Resultatet av mätningen skrivs sedan ut till skärmen.<br />
Problem under gång<br />
Start<br />
Initiera processorn<br />
och display<br />
Alltid<br />
Nollställ<br />
signalgenerering<br />
Starta timer<br />
Starta frekvensgenerering<br />
Tid registrerat<br />
eller overflow<br />
Skriv ut avstånd<br />
Nollställ time<br />
Delay<br />
Schema 1: Flödeschema för programmet<br />
Hela svårigheten i detta projekt har legat i mottagardelen, där förstärkning och<br />
signalbehandlingen vållat stora problem. Då den ingående signalen har såpass låga<br />
spänningsnivåer, ner mot fraktioner av millivolt, är störningskänsligheten i systemet väldigt<br />
stor. Dessa problem kvarstår även i den färdiga prototypen, och har omöjliggjort en<br />
överflyttning av systemet från breadboard till ett etsat kretskort. Även <strong>med</strong><br />
mottagningselektroniken placerad på ett från övriga elektroniken avskiljt kretskort <strong>med</strong><br />
separat strömförsörjning var störningarna för stora för att mottagaren skulle fungera.<br />
Troligtvis ligger problemet i att de olika förstärkarstegen stör de ingående signalerna, och då<br />
signalen från ultraljudsmottagaren är såpas svaga störs de ut helt.
Ola Johannesson FiM 11-03-28<br />
890502-0635 Handledare: Martin Grimheden 15(16)<br />
Förslag till förbättringar<br />
Hårdvaran är förberedd för anslutning av ytterligare två ultraljudssändare, något som kan<br />
användas för positionsbestämning i tre dimensioner. Genom att sätta upp de tre sändarna på<br />
olika platser i rummet kan mottagarens position i rummet räknas ut från avståndet till de tre<br />
sändarna. Dessa avstånd bestäms vart och ett individuellt på samma sätt som det enda<br />
avståndet bestäms i detta projekt.<br />
Det vore även önskvärt att förbättra förstärkarelektroniken ytterligare, även om den här<br />
presenterade lösningen fungerade så var den inte helt stabil. Med en mindre störningskänslig<br />
förstärkarkrets skulle hela mätaren kunna monteras på ett kretskort, något som inte var möjligt<br />
<strong>med</strong> detta bygge.<br />
Slutsats<br />
Att designa en krets för avståndsmätning <strong>med</strong> millimeterprecision <strong>med</strong> hjälp av ultraljud<br />
visade sig vara svårt, men inte omöjligt. Den stora svårigheten låg i den digitala<br />
signalbehandlingen som krävdes för att få en mätbar nivå på ultraljudssignalen.<br />
Att detta projekt innefattade att designa en ultraljudsmottagare från grunden berodde mycket<br />
på att de färdiga ultraljudsmoduler som finns att köpa oftast är byggda för reflekterande<br />
mätning och där<strong>med</strong> har både sändare och mottagare på samma kretskort, något som inte var<br />
användbart i detta projekt. Under projektets gång fann jag på en färdig modul som troligtvis<br />
hade fungerat väl i denna tillämpning, nämligen SRF02 från Devantech. Denna modul<br />
kommunicerar <strong>med</strong> seriekommunikation, och kan fungera både som sändare och mottagare i<br />
denna typ av projekt. Två sådana moduler är också billigare än den lösning som presenteras i<br />
denna rapport, och kräver betydligt mindre arbete för att implementeras.<br />
Referenser<br />
Anders Andersson & Arne Kullbjer , Elektronik 1, Linköping<br />
Hans Johansson, Elektroteknik, 2010 Stockholm<br />
Datablad<br />
Datablad UTT4016/UTR4016
Ola Johannesson FiM 11-03-28<br />
890502-0635 Handledare: Martin Grimheden 16(16)<br />
www.cpu.com.tw/kh/sensor/uct/pdf/uttr4016.pdf<br />
Datablad OPA27GP<br />
https://www1.elfa.se/data1/wwwroot/assets/datasheets/dxOPA27_e.pdf<br />
Datablad TL081CP<br />
https://www1.elfa.se/data1/wwwroot/assets/datasheets/ntTL081-to-TL084_e.pdf<br />
Datablad GLK12232-25SM<br />
http://www.matrixorbital.ca/manuals/GLK_series/GLK12232-25-SM/GLK12232-25-<br />
SM_Legacy/GLK12232-25-SM_110.pdf<br />
Bilagor<br />
Bilaga 1: Kod<br />
Bilaga 2: Kopplingsschema huvudkort<br />
Bilaga 3: Kopplingsschema sändare<br />
Bilaga 4: Kopplingsschema mottagare<br />
Bilaga 5: Kretskort huvudkort<br />
Bilaga 6: Kretskort sändare<br />
Bilaga 7: Breadboard mottagare<br />
Bilaga 8: Komponentförteckning och ekonomi<br />
Bilaga 9: Använda portpinnar
Bilaga 1: Kod<br />
ultrasound.c<br />
#include <br />
#include <br />
#include <br />
#include <br />
#include "backend.h"<br />
#define ZERO 118 //zero value, from calibration<br />
#define MULTI 0.319488818 //Multiple value, from calibration<br />
#define f_cpu 8000000<br />
int main(void) {<br />
startProcessor();<br />
);<br />
}<br />
//Setting up USART<br />
DisplayStart();<br />
sei(); //Enables interrupts<br />
while(1){<br />
}<br />
_delay_ms(10);<br />
FreqReset();<br />
_delay_ms(10);<br />
TimerStart();<br />
FreqGenStart();<br />
while(TimerWait);<br />
USART_TransmitDistance( (unsigned int)((double)(getTime()-ZERO)*MULTI)<br />
ResetTime();<br />
_delay_ms(400);<br />
backend.c<br />
#include <br />
#include <br />
#include <br />
#include <br />
char outfreq = 0;<br />
char enable = 0;<br />
unsigned char count = 0;<br />
char start = 0;<br />
char timerOn = 0;<br />
unsigned char timerOverflowCount = 0;<br />
unsigned int time = 0;<br />
ISR(TIMER0_COMP_vect){<br />
if(enable | start)<br />
{<br />
PORTB = outfreq;<br />
outfreq = ~outfreq;<br />
if(start)
}<br />
{<br />
outfreq = 1;<br />
enable = 1;<br />
count = 0;<br />
start = 0;<br />
}<br />
if(count>10)<br />
{<br />
enable = 0;<br />
outfreq = 0;<br />
PORTB = outfreq;<br />
}<br />
count++;<br />
}<br />
ISR(TIMER1_CAPT_vect){<br />
TIFR &= ~0x10;<br />
if(timerOn){<br />
time = TCNT1;<br />
PORTC = PINC +1;<br />
timerOn = 0;<br />
}<br />
}<br />
ISR(TIMER1_OVF_vect){<br />
TIFR &= ~0x04;<br />
//PORTC = PINC +1;<br />
timerOverflowCount = 1;<br />
}<br />
void startProcessor(){<br />
DDRD=0b11111110; //All output but port 0<br />
DDRC=0xff; //All pins output<br />
DDRB=0xf3; //0-1 and 4-7 as output, 2 and 3 as input<br />
}<br />
// Setting up timer0 for 44kHz output<br />
TCCR0 = 0x09; //0b00001001 CTC, OC0 disconnected, clk div = 1<br />
OCR0 = 0x5E; //Counting to 94, gives ~1/44000/2)<br />
TCNT0 = 0; //Starting counting at 0<br />
TIMSK = 0x02; //overflow interrupt from timer0<br />
PORTC=0xff;<br />
_delay_ms(100);<br />
// Set up timer1 for time measurement<br />
TCCR1A = 0x00; //00000000; No output ports, no force output compare,<br />
TCCR1B = 0x22; //00100010; No noise canselation, trigger on positive edge, normal mode, clk/8<br />
TIMSK |= 0x24; //xx1xx1xx; Input capture and overflow enabled<br />
//Setting up analog comparator<br />
ACSR = 0b00100111; //AC on, Analog comparator output (?) on, AC input capture enable, interrupt on rising<br />
void TimerStart(){<br />
TimerReset();<br />
timerOn = 1;<br />
timerOverflowCount = 0;<br />
}<br />
void TimerReset(){<br />
TCNT1H = 0;<br />
TCNT1L = 0;
}<br />
void FreqGenStart(){<br />
TCNT0 = 0; //Starting counting at 0<br />
start = 1;<br />
}<br />
void USART_Init(unsigned int ubrr){ //Example from manual page 150<br />
UBRRH = (unsigned char)(ubrr>>8);<br />
UBRRL = (unsigned char)ubrr;<br />
/* Enable transmitter */<br />
UCSRB |= (1
}<br />
outfreq = 0;<br />
PORTB = outfreq;<br />
char TimerWait(){<br />
return( (char)( (time == 0) & (timerOverflowCount == 0) ) );<br />
}<br />
unsigned int GetTime(){<br />
return time;<br />
}<br />
void ResetTime(){<br />
time = 0;<br />
}<br />
backend.h<br />
void startProcessor();<br />
void FreqGenStart();<br />
void TimerStart();<br />
void TimerReset();<br />
void USART_Init(unsigned int ubrr);<br />
void USART_Transmit(unsigned char data);<br />
void USART_TransmitString(char *data);<br />
void USART_TransmitDistance(unsigned int data);<br />
void DisplayStart();<br />
void FreqReset();<br />
char TimerWait();<br />
unsigned int GetTime();<br />
void ResetTime();
0<br />
0<br />
1<br />
1<br />
2<br />
2<br />
3<br />
3<br />
U1<br />
4<br />
A A<br />
1MΩ<br />
Key=A 25%<br />
VCC<br />
R1 5V OUT_controll<br />
IN_trig<br />
VCC<br />
5V<br />
1_PB0(XCK/T0)<br />
2_PB1(T1)<br />
3_PB2(INT2/AIN0<br />
4_PB3(OC0/AIN1)<br />
5_PB4(!SS)<br />
6_PB5(MOSI)<br />
7_PB6(MISO)<br />
8_PB7(SCK)<br />
B<br />
J5<br />
5V<br />
R9<br />
10kΩ<br />
IN_button OUT_disp<br />
9_!RESET<br />
10_VCC<br />
11_GND<br />
12_XTAL2<br />
13_XTAL1<br />
14_PD0(RXD)<br />
32_AREF<br />
31_GND<br />
30_AVCC<br />
29_PC7(TOSC2)<br />
28_PC6(TOSC1)<br />
27_PC5(TDI)<br />
26_PC4(TDO)<br />
B<br />
C<br />
HDR1X2<br />
15_PD1(TXD)<br />
16_PD2(INT0)<br />
17_PD3(INT1)<br />
18_PD4(OC1B)<br />
19_PD5(OC1A)<br />
20_PD6(ICP1)<br />
25_PC3(TMS)<br />
24_PC2(TCK)<br />
23_PC1(SDA)<br />
22_PC0(SCL)<br />
21_PD7(OC2)<br />
IN_button<br />
C<br />
ATMEGA16<br />
40_PA0(ADC0)<br />
39_PA1(ADC1)<br />
38_PA2(ADC2)<br />
37_PA3(ADC3)<br />
36_PA4(ADC4)<br />
35_PA5(ADC5)<br />
34_PA6(ADC6)<br />
33_PA7(ADC7)<br />
D D<br />
J2<br />
E E<br />
HDR1X4<br />
J6<br />
5V<br />
OUT_disp<br />
VCC<br />
F<br />
LINE<br />
VOLTAGE<br />
VREG<br />
F<br />
COMMON<br />
HDR1X2<br />
VCC<br />
U2<br />
LM7805CT<br />
VCC<br />
5V<br />
J3<br />
HDR1X5<br />
VCC<br />
5V<br />
J1<br />
HDR1X2<br />
4<br />
IN_trig<br />
5<br />
VCC<br />
5V<br />
5<br />
6<br />
OUT_controll_1 OUT_controll_2 OUT_controll_3<br />
OUT_controll_1<br />
OUT_controll_2<br />
OUT_controll_3<br />
J4<br />
HDR1X2<br />
6<br />
7<br />
OUT_controll<br />
7<br />
8<br />
8<br />
9<br />
9
0<br />
0<br />
1<br />
1<br />
2<br />
2<br />
3<br />
3<br />
4<br />
A A<br />
B B<br />
C C<br />
J1<br />
D D<br />
HDR1X5<br />
VCC<br />
5V<br />
R7<br />
VCC<br />
5V<br />
100Ω Q1<br />
E E<br />
R1<br />
Q2<br />
BC547BP<br />
BC557AP<br />
VCC<br />
5V<br />
Q4<br />
100Ω Q3<br />
BC547BP<br />
F F<br />
BC557AP<br />
R2<br />
4<br />
5<br />
VCC<br />
5V<br />
Q6<br />
100Ω Q5<br />
BC547BP<br />
BC557AP<br />
5<br />
6<br />
6<br />
J2<br />
HDR1X2<br />
J3<br />
HDR1X2<br />
J4<br />
HDR1X2<br />
7<br />
7<br />
8<br />
8<br />
9<br />
9
0<br />
0<br />
1<br />
1<br />
2<br />
2<br />
3<br />
3<br />
4<br />
4<br />
5<br />
5<br />
6<br />
6<br />
7<br />
7<br />
8<br />
8<br />
9<br />
9<br />
A A<br />
B B<br />
C C<br />
D D<br />
E E<br />
F F<br />
U2<br />
OP27GP<br />
3<br />
2<br />
4<br />
7<br />
6<br />
8<br />
1 U3<br />
TL081CP<br />
3<br />
2<br />
4<br />
7<br />
6<br />
5<br />
1 U4<br />
TL081CP<br />
3<br />
2<br />
4<br />
7<br />
6<br />
5<br />
1<br />
VCC<br />
5V<br />
VCC<br />
5V<br />
VCC<br />
5V<br />
VEE<br />
-5V<br />
VEE<br />
-5V<br />
VEE<br />
-5V<br />
IN_trig<br />
R2<br />
2kΩ<br />
R3<br />
220kΩ<br />
R4<br />
3kΩ<br />
R5<br />
500kΩ<br />
Key=A<br />
50%<br />
R6<br />
10kΩ<br />
R8<br />
90kΩ<br />
MIC+<br />
C1<br />
470nF<br />
D1<br />
1N3064<br />
D2<br />
1N3064<br />
J3<br />
HDR1X2<br />
MIC+<br />
J1<br />
HDR1X2<br />
R10<br />
560Ω<br />
R11<br />
560Ω<br />
VCC<br />
5V<br />
VEE<br />
-5V<br />
J2<br />
HDR1X2<br />
IN_trig
Bilaga 5<br />
Två huvudkort gjordes, först ett som innehåll samtliga komponenter i konstruktionen, ses i Figur 2.<br />
Det visade sig dock att det blev för mycket störningar på mottagardelen <strong>med</strong> denna lösning, så det<br />
skrotades till förmån för ett nytt huvudkort endast innehållande processorn och de nödvändigaste<br />
delarna. Både sändare och mottagare är helt separata kort som kopplas in <strong>med</strong> sladd. Detta kort syns<br />
i Figur 1.<br />
Figur 1: Huvudkort<br />
Figur 2: Misslyckat huvudkort
Bilaga 6: Kretskort sändare<br />
I den moduluppbyggda andra versionen av kretskorten skapades ett löst kort för förstärkning till<br />
ultraljudssändarna. Det har stöd för upp till tre stycket separata sändare, för att senare kunna<br />
expandera funktionen för modulen.<br />
Figur 1: Kort <strong>med</strong> förstärkningskomponenterna för sändningen
Bilaga 7: Breadboard mottagare<br />
Figur 1 visar den mottagarkrets som slutligen användes. Figur 2 visar en identisk krets fast lött på<br />
ett kretskort. Detta visade sig ge oacceptabla störningar, troligtvis för att de olika stegen låg för nära<br />
varandra, och skrotades därför.<br />
Figur 1: Mottagare på breadboard<br />
Figur 2: Mottagare på kretskort
Bilaga 8: Komponentförteckning och ekonomi<br />
Antal Komponent Pris per styck Pris totalt<br />
1 ATMega16 40,00 kr 40,00 kr<br />
1 UTT4016 50,00 kr 50,00 kr<br />
1 UTR4016 50,00 kr 50,00 kr<br />
1 LM7805 15,00 kr 15,00 kr<br />
1 Trimpotentiometer 1MΩ 15,00 kr 15,00 kr<br />
1 Trimpotentiometer 500kΩ 15,00 kr 15,00 kr<br />
3 BC 547BP 1,00 kr 3,00 kr<br />
3 BC 557AP 1,00 kr 3,00 kr<br />
1 OP27GP 40,00 kr 40,00 kr<br />
2 TL081CP 10,00 kr 20,00 kr<br />
2 1N 064 2,00 kr 4,00 kr<br />
10 2 pin kontakt 2,00 kr 20,00 kr<br />
1 4 pin kontakt 5,00 kr 5,00 kr<br />
2 5 pin kontakt 5,00 kr 10,00 kr<br />
1 GLK12232-25SM 500,00 kr 500,00 kr<br />
1 Motstånd 10kΩ 1,00 kr 1,00 kr<br />
3 Motstånd 1kΩ 1,00 kr 3,00 kr<br />
2 Motstånd 560kΩ 1,00 kr 2,00 kr<br />
1 Motstånd 90kΩ 1,00 kr 1,00 kr<br />
1 Motstånd 10kΩ 1,00 kr 1,00 kr<br />
1 Motstånd 3kΩ 1,00 kr 1,00 kr<br />
1 Motstånd 220kΩ 1,00 kr 1,00 kr<br />
1 Motstånd 2kΩ 1,00 kr 1,00 kr<br />
1 Plastkondensator 470 nF 5,00 kr 5,00 kr<br />
1 Elektrolytkondensator 47μF 1,00 kr 1,00 kr<br />
1 Keramisk kondensator 0,1μF 1,00 kr 1,00 kr<br />
Totalt: 858 kr<br />
Totalt utan display: 358 kr<br />
Diverse, kretskortslaminat + sladdar 50,00 kr 50,00 kr
Bilaga 9: Använda portpinnar<br />
Följande portpinnar, utöver spänningsanslutningar, användes på ATMega16.<br />
Portpinne Funktion<br />
PA0 Utgång till sändare 1<br />
PA1 Utgång till sändare 2<br />
PA2 Utgång till sändare 3<br />
PB0 Utgång till extra sändare<br />
PB2 (AIN0) Insingnal från förstärkarkretsen, till komparatorn<br />
PB3 (AIN1) Referensspänning till komparatorn<br />
PC0 Knapp (bra att ha)<br />
PD1 Utgång till displayen
Bilaga K.<br />
Individuell rapport, Stegmotorer – Funktion och tillämpning<br />
Av Annie Gustafsson
Stegmotorer<br />
- Funktion och tillämpning<br />
Annie Gustafsson, M-08 <strong>KTH</strong><br />
Fördjupningsarbete i Mekatronik, MF106X<br />
Stockholm, 2011-05-13<br />
Handledare: Martin Grimheden
Innehåll<br />
Annie Gustafsson, M-08 <strong>KTH</strong><br />
Fördjupningsarbete i Mekatronik MF106X<br />
Abstract 2<br />
Sammanfattning 4<br />
TEORETISK FÖRDJUPNING 5<br />
Unipolär eller bipolär stegmotor 5<br />
De tre vanligast varianterna av stegmotor 6<br />
Rotation och stegning 8<br />
För- och nackdelar <strong>med</strong> stegmotorer 11<br />
Stegmotorn som användes 11<br />
H-brygga 12<br />
PRAKTISKT GENOMFÖRT 14<br />
Hur önskat resultat uppnåddes 14<br />
Resultat 15<br />
ERFARENHETER 17<br />
FÖRSLAG TILL FÖRBÄTTRINGAR 17<br />
REFERENSER 19<br />
BILAGOR 20<br />
Bilaga 1: Stegmotorns datablad<br />
Bilaga 2: H-bryggans datablad<br />
Bilaga 3: Programkoden<br />
2
Abstract<br />
Annie Gustafsson, M-08 <strong>KTH</strong><br />
Fördjupningsarbete i Mekatronik MF106X<br />
This report shows the stepper motors function and their uses. It explains the<br />
differences and similarities between different stepper motors. A permanent magnet<br />
stepper motor can handle high torque and are well damped however not optimal for<br />
high speeds. The variable reluctance stepper motor are good to use at high speeds but<br />
not if the moment is to high. There are also hybrid stepper motors that combine the<br />
best features from the previously mentioned stepper motors, it can handle high speeds<br />
and relatively high torque.<br />
In the report there are also explained a few different ways of making the motor step<br />
forward for example there is full step drive, halfstepping and microstepping. Full step<br />
drive corresponds to the movement of the rotor when a new set of coil windings is<br />
activated. Halfstepping means that the steps will be half the size compared to full step<br />
drive, this because two coil windings can be activated at the same time and then only<br />
one of them. Using microstepping the motor takes even smaller steps and it occurs<br />
when current in the coil windings changes a little bit at the time, the idea is to<br />
approximate a sinusoidal AC waveform.<br />
The report also describes a way to making this practical. A bipolar hybrid stepper<br />
motor, sonceboz model 6540-13-2-9, and two H-bridges, A3953SB-T, are put<br />
together and the H-bridges will control the current flow.<br />
3
Sammanfattning<br />
Annie Gustafsson, M-08 <strong>KTH</strong><br />
Fördjupningsarbete i Mekatronik MF106X<br />
Denna rapport visar på stegmotorns funktion och användningsområden. Den förklarar<br />
skillnader och likheter mellan olika stegmotorer. Permanentmagnetstegmotorn som<br />
klarar höga moment och är väl dämpad, dock är den inte optimal vid höga hastigheter.<br />
Den reluktansvariabla stegmotorn som är bra att använda vid höga hastigheter men<br />
den klarar inte alltför höga moment. Därutöver finns hybridstegmotorn den<br />
kombinerar de bästa egenskaperna från de tidigare nämnda så den klarar höga<br />
hastigheter och relativt högt moment.<br />
Olika stegtyper för motorn såsom helsteg, halvsteg och mikrosteg förklaras även de.<br />
Helsteg motsvarar den förflyttning rotorn gör då en ny uppsättning lindningar<br />
aktiveras jämfört <strong>med</strong> de nyss aktiverade spolarna. Halvsteg innebär att stegen blir<br />
hälften så stora genom att två spolars lindningar kan vara aktiverade samtidigt för att<br />
sedan bara en av spolarnas lindningar är aktiverade. Mikrosteg är ännu mindre och<br />
uppstår då strömmen i spolarnas lindningar förändras lite åt gången, tanken är att<br />
mikrosteg skall approximera en sinuskurva.<br />
Rapporten beskriver även ett sätt att göra detta rent praktiskt. Då används en bipolär<br />
hybridstegmotor tillverkad av Sonceboz, modell 6540-13-2-9, samt två H-bryggor,<br />
A3953SB-T, som styr strömriktningen.<br />
4
Inledning<br />
Annie Gustafsson, M-08 <strong>KTH</strong><br />
Fördjupningsarbete i Mekatronik MF106X<br />
Tanken <strong>med</strong> denna rapport är att ge ökad förståelse för stegmotorer, hur de fungerar<br />
och styrs. För att kunna styra en stegmotor på önskat sätt är det lämpligt att känna till<br />
hur de fungerar, för att ta reda på detta gjordes en teoristudie om stegmotorer.<br />
Teoristudien skulle sedan användas för att underlätta styrningen och den<br />
programmering som skulle göras för att få motorn att ta helsteg, halvsteg och<br />
mikrosteg.<br />
Teoretisk fördjupning<br />
En stegmotor är en variant av elektriska motorer. De består oftast av flertalet<br />
lindningar som är en del av statorn <strong>med</strong>an i rotorn finns en magnet, vad det är för typ<br />
av magnet beror på motortypen men oftast är det en permanentmagnet. Stegmotorer<br />
finns lite överallt i skrivare, hastighetsmätare <strong>med</strong> mera.<br />
Motorn drivs genom att en eller flera spolars lindningar blir aktiverade (det går en<br />
ström genom dem) och där<strong>med</strong> magnetiska. Detta gör att rotorn <strong>med</strong> sitt egna<br />
magnetfält försöker ställa in sig så att de olika magnetfälten förstärker varandra, vilket<br />
leder till att rotorn roterar, dock bara några grader. Därefter upprepas det hela men<br />
<strong>med</strong> en annan lindning och så fortsätter det så till dess att det hela avbryts. Det finns<br />
olika sätt att aktivera lindningarna vilket gör att motorn rör sig lite olika ryckigt, detta<br />
kallas att motorn stegar sig framåt. För varje gång en ny lindning aktiveras flyttas<br />
rotorn ungefär 1,8° (vanligt för en hybrid stegmotor) hur mycket beror på antalet<br />
lindningar i motorn. Eftersom rotationen för ett helt varv där<strong>med</strong> kan delas in i ett<br />
stort antal mindre steg är det därför möjligt att styra motorn <strong>med</strong> stor precision även<br />
utan återkoppling från systemet.<br />
Unipolär eller bipolär stegmotor<br />
Det finns flera sätt att dela in en stegmotor, ett av dem är om motorn är unipolär eller<br />
bipolär.<br />
En unipolär stegmotor har två lindningar per fas (se figuren nedan) vilket gör att det<br />
utan problem går byta riktning på strömmen. Detta då strömmen går in i mitten av<br />
spolen vid black enligt figuren nedan och sedan kan gå ut genom antingen red eller<br />
red-white, färgerna motsvarar varsin halva av lindningen. Det går nämligen bara att<br />
skicka ström åt ett håll genom lindningarna, därför är lindningarna uppdelade så ena<br />
5
Annie Gustafsson, M-08 <strong>KTH</strong><br />
Fördjupningsarbete i Mekatronik MF106X<br />
halvan kan leda åt ena hållet och andra halvan leder åt andra hållet. Oftast används en<br />
transistor för styrningen av vilket håll strömmen skall gå. Nedan finns en figur som<br />
illustrerar konceptet <strong>med</strong> en unipolär stegmotor.<br />
Figur 1. Konceptuell modell av en unipolär stegmotor 1<br />
En bipolär stegmotor däremot kan upplevas mer svårstyrd då den till skillnad från den<br />
unipolära kan låta strömmen gå åt båda hållen i samma lindning. Vilket gör att det<br />
krävs en H-brygga för att ändra strömriktningen i en av motorns lindningar (till<br />
exempel alla lindningar märkta 1 på figuren nedan), två H-bryggor för hela motorn.<br />
Figur 2. Konceptuell modell av en bipolär stegmotor 2<br />
De tre vanligast varianterna av stegmotor<br />
En variant av stegmotor är permanentmagnetsstegmotorn (PM stegmotor). Istället för<br />
att ha en tandad rotor har denna motor en permanentmagnet integrerad i rotorn enligt<br />
figuren nedan. Den styrs sedan genom att spolarnas lindningar (A i figuren) aktiveras<br />
längs insidan på statorn och då skapar de ett magnetfält som rotorn kan ställa in sig i<br />
1<br />
Bild hämtad från bilaga 1.<br />
2<br />
Bild hämtad från http://www.stepperworld.com/Tutorials/pgBipolarTutorial.htm<br />
6
Annie Gustafsson, M-08 <strong>KTH</strong><br />
Fördjupningsarbete i Mekatronik MF106X<br />
förhållande till och när det är gjort aktiveras de andra lindningarna (B i figuren)<br />
istället. Denna typ av motor är bra dämpad, klarar höga moment men är dock inte ett<br />
bra alternativ om höga hastigheter önskas.<br />
Figur 3. Principskiss PM stegmotor 3<br />
En annan variant av stegmotor är den reluktans (motstånds) variabla stegmotorn. Den<br />
har ett antal lindningar (stegmotorn på figuren nedan har 3 lindningar vilket är<br />
vanligt) som aktiveras var och en efter varandra. En vanlig styrsekvens är därför 1, 2,<br />
3, 1, 2, 3, 1 och så vidare när detta sker ställer statorn in sig så att det blir så lite<br />
motstånd som möjligt mellan lindningarna, därav namnet. Denna motortyp lämpar<br />
sig inte för höga moment men den är däremot väldigt effektiv om snabb rotation<br />
önskas.<br />
Figur 4. Principskiss reluktans-variabla stegmotorer 4<br />
Den tredje varianten som är värd att känna till är hybridmotorn, den är en blandning<br />
av de två ovanstående då den klarar nämligen att förena hög hastighet, styrka och<br />
dämpning. I en hybrid stegmotor består rotorn av två tandade ok som påminner om<br />
kugghjul, inuti dem sitter en permanentmagnet vilket gör att då oken är något vridna i<br />
förhållande till varandra (se figur nedan) blir de olika halvorna syd- respektive<br />
nordpol för hela rotorn. Det är tänderna på rotorn som när spolarnas lindningar<br />
aktiveras och skapar ett magnetfält ställer in sig, men som synes finns det många fler<br />
3 Bild hämtad från<br />
http://www.allmotion.se/UserFiles/AMT_Stegmotorteknik%282%29.pdf<br />
4 bild hämtad från http://www.cs.uiowa.edu/~jones/step/types.html<br />
7
Annie Gustafsson, M-08 <strong>KTH</strong><br />
Fördjupningsarbete i Mekatronik MF106X<br />
poler på denna typ av motor jämfört <strong>med</strong> de tidigare två. Det gör att mycket mindre<br />
steg kan tas och där<strong>med</strong> kan motorn styras mycket noggrannare.<br />
Figur 5. Konceptuell bild av en hybridstegmotors uppbyggnad, rotor och stator 5<br />
Rotation och stegning<br />
Stegvinkel kallas den vinkel en stegmotor förflyttar sig då att en lindning inaktiveras<br />
och en intilliggande aktiveras. För en hybrid stegmotor är denna vinkel ofta 1,8°<br />
<strong>med</strong>an för en permanentmagnets stegmotor är samma vinkel närmare 30°. Att de<br />
skiljer sig så mycket beror på antalet spolar som finns i respektive stator. Detta kan<br />
beräknas enligt följande:<br />
z* = 360<br />
där z är antalet steg/varv och är stegvinkeln.<br />
Då stegvinkel och antalet steg per varv är känt kan även stegfrekvens, varvtal och<br />
vinkelfrekvens beräknas enligt följande formler:<br />
Stegfrekvens f [Hz]: f = (n×z)/60<br />
Varvtal [varv/minut]: n = (f×60)/z<br />
Vinkelfrekvens [rad/sek]: = (f×2× )/z<br />
När en stegmotor drivs så görs det på olika sätt och beroende på hur spolarnas<br />
lindningar aktiveras så kallas det att motorn tar helsteg, halvsteg eller mikrosteg.<br />
5 bild hämtad från<br />
http://www.allmotion.se/UserFiles/AMT_Stegmotorteknik%282%29.pdf<br />
8
Annie Gustafsson, M-08 <strong>KTH</strong><br />
Fördjupningsarbete i Mekatronik MF106X<br />
Skillnaden på dem är precis som namnet antyder hur stort steg de tar åt gången under<br />
ett varv.<br />
Helsteg <strong>med</strong> en fas, vågdrift, innebär att en spole aktiveras åt gången, detta gör att<br />
rotorn gör en rotation som motsvarar stegvinkeln för varje gång en ny uppsättning<br />
spolar aktiveras.<br />
Det är dock väldigt vanligt att två fas används då helsteg skall tas, resultatet blir det<br />
samma bortsett från att nu är alltid två lindningar aktiverade samtidigt men <strong>med</strong> en<br />
fasförskjutning på 90º, det gör att rotorn roterar enligt figuren nedan.<br />
Figur 6. Rotorns förflyttning under rotation <strong>med</strong> helsteg 6<br />
Figur 7. Hur motorns lindningar aktiveras i förhållande till varandra, helsteg 7<br />
6 bild hämtad från<br />
http://www.allegromicro.com/en/Products/Design/compumot/a04a08.pdf<br />
9
Annie Gustafsson, M-08 <strong>KTH</strong><br />
Fördjupningsarbete i Mekatronik MF106X<br />
Halvsteg är då att motorn, som namnet indikerar, tar hälften så stora steg per varv<br />
jämfört <strong>med</strong> de helsteg som togs tidigare (vilket gör att det blir dubbelt så många<br />
steg). Detta görs genom att aktivera lindningen intill innan den först aktiverade<br />
lindningen återställs.<br />
Figur 8. Rotorns förflyttning under rotation <strong>med</strong> halvsteg 7<br />
Figur 9. Hur motorns lindningar aktiveras i förhållande till varandra, halvsteg 7<br />
Halvsteg är bra att använda om motorn skall köras i lägre hastigheter då det ger en<br />
jämnare gång, dock kan stegen fortfarande upplevas tydligt även om de nu är mindre<br />
och betydligt fler.<br />
För att komma ifrån att stegen är väldigt tydliga kan mikrosteg användas. Mikrosteg<br />
har fått namnet av att ännu mindre steg tas, detta genom att ändra styrkan på<br />
strömmen som går igenom lindningarna och där<strong>med</strong> deras magnetfält så att rotorn tar<br />
ännu mindre och jämnare steg. Strömmen får helt enkelt sakta gå upp till sitt<br />
maximala värde för lindningarna för att sedan sjunka igen, detta för att försöka<br />
efterlikna en sinusvåg och då få en jämn rotation, se figuren nedan.<br />
7 bild hämtad från<br />
http://www.allegromicro.com/en/Products/Design/compumot/a04a08.pdf<br />
10
Annie Gustafsson, M-08 <strong>KTH</strong><br />
Fördjupningsarbete i Mekatronik MF106X<br />
Figur 10. Hur motorns lindningar aktiveras i förhållande till varandra, mikrosteg 8<br />
För- och nackdelar <strong>med</strong> stegmotorer<br />
Stegmotorer används framförallt då det är viktigt att veta vilken rörelse motorn skall<br />
göra, att motorn inte går för långt eller för kort. Detta går att göra <strong>med</strong> andra motorer<br />
också men inte lika exakt och då krävs en återkoppling till systemet. Stegmotorn<br />
klarar förhållandevis höga moment även vid låga hastigheter när däremot motorn körs<br />
<strong>med</strong> hög hastighet klarar den bara låga moment. Stegmotorns uppbyggnad gör att den<br />
inte kan överbelastas mekaniskt, den kräver inte heller något underhåll. Vanliga<br />
problem <strong>med</strong> stegmotorn är dock att om den inte styrs på rätt sätt kan det bli stora<br />
vibrationer i motorn, dessa vibrationer gör att det låter väldigt mycket om motorn och<br />
gången är oftast väldigt ryckig då motorn stegar sig framåt.<br />
Stegmotorn som användes<br />
Den stegmotorn som skall användas är en bipolär hybrid stegmotor se figur nedan,<br />
Sonceboz modell 6540-13-2-9.<br />
8 bild hämtad från<br />
http://www.allegromicro.com/en/Products/Design/compumot/a04a08.pdf<br />
11
Annie Gustafsson, M-08 <strong>KTH</strong><br />
Fördjupningsarbete i Mekatronik MF106X<br />
Figur 11. Stegmotorn som användes 9<br />
motorn är 42*42 mm stor, väger 200g, har en stegvinkel på 1,8° och den klarar ett<br />
hållmoment på 130 Nm. För komplett information se bilaga 1.<br />
H-brygga<br />
H-bryggor används för att byta rotationsriktning på motorer och det görs genom att<br />
byta polaritet på spänningen. Motorn kan rotera åt ett håll genom att strömmen tillåts<br />
flyta genom kretsen på olika sätt. Enklaste sättet att göra en H-brygga är att koppla<br />
ihop fyra transistorer enligt nedan och låta strömmen gå genom transistor 1 och 3<br />
alternativt 2 och 4.<br />
9 bild hämtad från bilaga 1.<br />
Figur 12. Principskiss H-brygga<br />
12
Annie Gustafsson, M-08 <strong>KTH</strong><br />
Fördjupningsarbete i Mekatronik MF106X<br />
Den H-bryggan som användes för att styra strömmen i den valda stegmotorn var<br />
A3953SB-T (bilaga 2) och ser ut enligt följande:<br />
Figur 13. H-brygga A3953SB-T 10<br />
När stegmotorn skulle styras var sanningstabell (nedan) till stor nytta.<br />
10 bild hämtad från bilaga 2.<br />
11 tabell hämtad från bilaga 2.<br />
Figur 14. Sanningstabellen för H-bryggan 11<br />
13
Praktiskt genomfört<br />
Annie Gustafsson, M-08 <strong>KTH</strong><br />
Fördjupningsarbete i Mekatronik MF106X<br />
För att verkligen förstå stegmotorer och hur de fungerar, skall en stegmotor (se sidan<br />
12, stegmotorn som används) kopplas till två H-bryggor (se figur 13) och STK500kortet.<br />
Programmet skrivs på mikrokontrollern ATMega16, programmet är tänkt att<br />
det skall styra motorn så att den tar helsteg, halvsteg och helst även mikrosteg. Detta<br />
för att ge en bättre förståelse för hur de olika stegtyperna fungerar i praktiken och<br />
skillnaden på dem. Programmet som skrevs var väldigt simpelt på så sätt att beroende<br />
på vilken knapp som trycktes in körde motorn på olika sätt och en diod tändes för att<br />
visa på vilket sätt som valts. Första knappen tände den första dioden och motor tog<br />
helsteg. Andra knappen tände andra dioden och motorn tog halvsteg. Tredje knappen<br />
tände den tredje dioden och motorn skulle gå <strong>med</strong> mikrosteg. Fjärde knappen tände<br />
fjärde dioden och ställde motorn i standby tills en ny knapp trycktes in. För att<br />
åstadkomma detta kopplades motorn, H-bryggorna etcetera enligt följande:<br />
VCC<br />
VCC<br />
R5<br />
300Ω<br />
R6<br />
300Ω<br />
R7<br />
300Ω<br />
R8<br />
300Ω<br />
R9<br />
10kΩ J2<br />
Key = A<br />
VCC<br />
LED1<br />
PC.0<br />
LED2<br />
PC.1<br />
LED3<br />
PC.2<br />
LED4<br />
PC.3<br />
PA.0<br />
GND<br />
R13<br />
10kΩ<br />
GND<br />
R10<br />
10kΩ J3<br />
Key = A<br />
U1<br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
10<br />
11<br />
12<br />
13<br />
14<br />
15<br />
16<br />
17<br />
18<br />
19<br />
20<br />
PB0<br />
PB1<br />
PB2<br />
PB3<br />
PB4<br />
PB5<br />
PB6<br />
PB7<br />
RESET<br />
VCC<br />
GND1<br />
XTAL2<br />
XTAL1<br />
PD0<br />
PD1<br />
PD2<br />
PD3<br />
PD4<br />
PD5<br />
PD6<br />
PD7 21<br />
PC0 22<br />
PC1 23<br />
PC2 24<br />
PC3 25<br />
PC4 26<br />
PC5 27<br />
PC6 28<br />
PC7 29<br />
AVCC 30<br />
GND2 31<br />
AREF 32<br />
PA7 33<br />
PA6 34<br />
PA5 35<br />
PA4 36<br />
PA3 37<br />
PA2 38<br />
PA1 39<br />
PA0 40<br />
GND<br />
AVR-ATMega16<br />
PA.1<br />
Figur 15. Kopplingsschema för stegmotorn (längst till höger), de två H-bryggorna och ATMega 16<br />
Hur önskat resultat uppnåddes<br />
R11<br />
10kΩ J4<br />
Key = A<br />
PA.2<br />
För att motorn skulle ta helsteg var motorns lindningar tvungna att aktiveras enligt<br />
sekvensen nedan, sladdarna från motorn är kopplade så att grön och grön-vit går till<br />
samma spole men att strömmen måste skickas från antingen grön till grön-vit eller<br />
tvärtom. Detsamma gäller för röd och röd-vit.<br />
C3<br />
470pF<br />
GND<br />
R12<br />
C1<br />
470pF<br />
GND<br />
R1<br />
30kΩ<br />
R3<br />
30kΩ<br />
10kΩ J5<br />
Key = A<br />
VCC<br />
PA.3<br />
VCC<br />
GND GND GND<br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
U2<br />
16<br />
15<br />
14<br />
13<br />
12<br />
11<br />
10<br />
8 9<br />
A3953SBT<br />
U3<br />
16<br />
15<br />
14<br />
13<br />
12<br />
11<br />
10<br />
8 9<br />
A3953SBT<br />
R4<br />
0.5Ω<br />
R2<br />
0.5Ω<br />
14<br />
C4<br />
47µF<br />
GND<br />
C2<br />
47µF<br />
GND<br />
J1<br />
HDR1X4<br />
Stegmotor
Annie Gustafsson, M-08 <strong>KTH</strong><br />
Fördjupningsarbete i Mekatronik MF106X<br />
Grön sladd Grön-vit sladd Röd sladd Röd-vit sladd<br />
1 0 1 0<br />
1 0 0 1<br />
0 1 0 1<br />
0 1 1 0<br />
Tabell 1. Sekvensen som upprepas flertalet gånger för att motorn skall ta helsteg<br />
Halvsteg innebär som tidigare nämnt att det blir dubbelt så många steg, vilket gör att<br />
aktiveringen av lindningarna behöver utformas annorlunda nämligen enligt följande<br />
sekvens:<br />
Grön sladd Grön-vit sladd Röd sladd Röd-vit sladd<br />
1 0 1 0<br />
1 0 0 0<br />
1 0 0 1<br />
0 0 0 1<br />
0 1 0 1<br />
0 1 0 0<br />
0 1 1 0<br />
0 0 1 0<br />
Tabell 2. Sekvensen som upprepas flertalet gånger för att motorn skall ta halvsteg<br />
För att åstadkomma detta är H-bryggorna tvungna att ge och få rätt signaler. Vilka<br />
signaler det var kan läsas ut ur H-bryggans sanningstabell (se figur 14). Eftersom två<br />
H-bryggor användes kopplades en H-brygga till respektive lindning i motorn, vilket<br />
gör att OUTA och OUTB motsvarar grön respektive grön-vit för ena H-bryggan och<br />
röd respektive röd-vit för den andra bryggan(se figur 15). Exakt hur programmet ser<br />
ut går att se i bilaga 3.<br />
Mikrosteg däremot var mycket svårare att åstadkomma då Vref var tvungen att regleras<br />
och för att göra det behövdes en A/D omvandlare, något som tyvärr inte hanns <strong>med</strong> då<br />
det blev tidsbrist mot slutet.<br />
Resultat<br />
Önskat resultat uppnåddes nästintill utan några problem. Motorn kan nu ta helsteg och<br />
halvsteg, däremot mikrosteg var betydligt värre att åstadkomma och något som inte<br />
lyckades. Kopplingen gjordes på ett breadboard som till stor del kopplades samman<br />
15
Annie Gustafsson, M-08 <strong>KTH</strong><br />
Fördjupningsarbete i Mekatronik MF106X<br />
<strong>med</strong> STK500-kortet. Två H-bryggor kopplades in på PORTB (fyra portar vardera)<br />
och beroende på hur signaler skickades till dessa drev motorn på olika sätt, se figur 14<br />
sanningstabell för H-bryggan. För att H-bryggorna skulle fungera kopplades en RC-<br />
krets, ett effektmotstånd och en kondensator till den. RC-kretsen bestod av ett<br />
motstånd på 30k ohm och en kondensator på 470 pF som kopplades in på H-bryggans<br />
3:e och 4:e ben. Effektmotståndet på 0,5 ohm kopplades in mellan ben 11 och 13 på<br />
H-bryggan. Kondensatorn på 47 µF kopplades in mellan H-bryggans ben 13 och 16.<br />
Figur 16. Kopplingen från breadboard, dock saknas +5V och GND till breadboardet<br />
För att se den exakta kopplingen se kopplingsschemat figur 15 och den slutgiltiga<br />
programkoden finns i bilaga 3.<br />
16
Erfarenheter<br />
Annie Gustafsson, M-08 <strong>KTH</strong><br />
Fördjupningsarbete i Mekatronik MF106X<br />
Det har varit väldigt lärorikt att arbeta på det här sättet för att förstå hur stegmotorer<br />
fungerar. Jag började <strong>med</strong> att läsa in teorin vilket jag anser att jag tjänade väldigt<br />
mycket på när jag väl skulle börja koppla de olika komponenterna visste jag redan på<br />
ett ungefär hur det skulle göras. Dock missbedömde jag tidsåtgången för att<br />
programmera framförallt mikrosteg vilket ledde till att det tyvärr inte hanns <strong>med</strong>, även<br />
om jag visste vad som krävdes för att få det att fungera. Mikrostegen hade fungerat<br />
om jag haft tid att koppla in en A/D-omvandlare för att styra referensspänningen Vref,<br />
då hade önskad strömförändring uppnåtts då man hade kunnat öka och minska<br />
strömmen i spolarna så att de påminde om sinusvågor som var 90° fasförskjutna.<br />
När helsteg och halvsteg skulle programmeras var det betydligt lättare, det handlade<br />
enbart om att ha rätt rörelsesekvens och en anpassad fördröjning när den skulle byta<br />
från ett läge till ett annat. Att jag säger väl anpassat beror på att om det inte görs<br />
korrekt riskerar man att det blir stora vibrationer i motorn och att det då låter väldigt<br />
mycket när motorn körs.<br />
Förslag till förbättringar<br />
Det finns flera sätt att förbättra stegmotorers utförande, framförallt gäller det att<br />
anpassa motorn efter ändamålet och i vissa fall kan det vara bättre <strong>med</strong> en servomotor<br />
även om återkoppling från systemet krävs. Stegmotorn är den optimala motorn då<br />
man vill känna till rörelsen utan att behöva ha en återkoppling till systemet, det är<br />
också en av få motorer som är helt elektrisk. Det är också en stor fördel att den inte<br />
kräver underhåll och att den inte kan överbelastas mekaniskt.<br />
Angående det som genomförts och redovisats i denna rapport finns det flertalet saker<br />
man skulle kunna ändra på. Hade tiden planerats bättre hade jag hunnit få ordning på<br />
mikrostegen också. Programkoden hade kunnat utformas annorlunda till exempel<br />
hade det varit mer lämpligt att använda sig av en timer och en interrupt funktion<br />
istället för den delay funktion som nu användes, detta då man i sådant fall hade kunnat<br />
köra flera motorer samtidigt vilket kan vara bra om motorn skall användas i någon<br />
annan tillämpning.<br />
H-bryggorna är en annan del man kan fundera på om det hade varit värt att utforma<br />
17
Annie Gustafsson, M-08 <strong>KTH</strong><br />
Fördjupningsarbete i Mekatronik MF106X<br />
dem annorlunda det finns dubbla H-bryggor vilket hade gjort att det förmodligen<br />
skulle blivit mindre komponenter. Dock är det väldigt enkelt att förstå hur H-<br />
bryggorna styr motorn då en H-brygga kopplades till respektive spolars lindningar.<br />
Vilket också var den huvudsakliga anledningen till att jag valde att ha två H-bryggor<br />
istället för en dubbel H-brygga.<br />
18
Referenser<br />
Information är hämtad från följande sidor:<br />
Annie Gustafsson, M-08 <strong>KTH</strong><br />
Fördjupningsarbete i Mekatronik MF106X<br />
http://www.stepperworld.com/Tutorials/pgBipolarTutorial.htm (2011-03-27)<br />
http://www.cs.uiowa.edu/~jones/step/index.html (2011-03-18)<br />
http://www.allegromicro.com/en/Products/Design/compumot/a04a08.pdf (2011-03-<br />
26)<br />
http://www.ict.kth.se/courses/IL1390/elmotorstyr/hbrygga/ (2011-03-25)<br />
http://www.allmotion.se/UserFiles/AMT_Stegmotorteknik%282%29.pdf (2011-03-<br />
27)<br />
http://ww1.microchip.com/downloads/en/AppNotes/00907a.pdf (2011-03-27)<br />
http://www.drivteknik.nu/skolan/motor/stegmotor (2011-03-27)<br />
figurer är antingen egenhändigt framtagna eller hittade enligt fotnoten.<br />
19
Bilagor<br />
Bilaga 1: Stegmotorns datablad<br />
Bilaga 2: H-bryggans datablad<br />
Bilaga 3: Programkoden<br />
Annie Gustafsson, M-08 <strong>KTH</strong><br />
Fördjupningsarbete i Mekatronik MF106X<br />
20
Technical data<br />
<br />
Dimensions<br />
<br />
<br />
[]<br />
<br />
<br />
[mH]<br />
<br />
<br />
[A]<br />
<br />
<br />
<br />
Hybrid stepper motors<br />
<br />
power<br />
<br />
6540-13-2-2 2 2.7 1.12 130 5<br />
6540-13-2-9 9 13 0.52 130 5<br />
6540-13-2-36 36 37 0.26 130 5<br />
6540-13-4-2 2 1.5 1.12 90 5<br />
6540-13-4-9 9 5.6 0.52 90 5<br />
6540-13-4-36 36 21 0.26 90 5<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Drawing not to scale. All dimensions in mm.<br />
h8<br />
0<br />
Ø 22 - 0.033<br />
h6<br />
0<br />
Ø 5 - 0.008<br />
6 ±0.5<br />
0<br />
2 - 0.25<br />
24 ±0.5<br />
32.5 ±0.5<br />
h6)<br />
0<br />
(Ø 5 -0.008<br />
9.5<br />
42<br />
31 ±0.25<br />
160 ±5<br />
4 ±1<br />
31 ±0.25<br />
42<br />
Cables AWG26 UL1007<br />
M3 (2x)<br />
Steps/rev. <br />
Step accuracy ± 5 %<br />
Rotor inertia <br />
Insulation class <br />
Protection <br />
<br />
Test voltage <br />
Detent torque
Dynamic characteristics<br />
<br />
Md [mNm]<br />
120<br />
100<br />
80<br />
60<br />
40<br />
20<br />
U = 24V<br />
U = 40V<br />
0<br />
0 2000 4000 6000 8000 10000<br />
<br />
Md [mNm]<br />
120<br />
100<br />
80<br />
60<br />
40<br />
20<br />
0<br />
0<br />
<br />
Md [mNm]<br />
120<br />
100<br />
80<br />
60<br />
40<br />
20<br />
Speed [pps]<br />
U = 24 V<br />
U = 40 V<br />
2000 4000 6000 8000 10000<br />
Speed [pps]<br />
0<br />
0 2000 4000 6000 8000 10000<br />
Speed [pps]<br />
SONCEBOZ SA<br />
2605 Sonceboz - Switzerland<br />
Tel. +41(0) 32 488 11 11<br />
Fax +41(0) 32 488 11 00<br />
E-mail : info@sonceboz.com<br />
Internet : www.sonceboz.com<br />
U = 24 V<br />
U = 40 V<br />
<br />
Md [mNm]<br />
120<br />
100<br />
80<br />
60<br />
40<br />
20<br />
0<br />
0 2000 4000 6000 8000 10000<br />
<br />
Md [mNm]<br />
120<br />
100<br />
80<br />
60<br />
40<br />
20<br />
Speed [pps]<br />
Speed [pps]<br />
U = 24 V<br />
U = 40 V<br />
U = 24 V<br />
U = 40 V<br />
0<br />
0 2000 4000 6000 8000 10000<br />
<br />
Md [mNm]<br />
120<br />
100<br />
80<br />
60<br />
40<br />
20<br />
[ Hybrid stepper motors 2/3 ]<br />
0<br />
0 2000 4000 6000 8000 10000<br />
Speed [pps]<br />
U = 24 V<br />
U = 40 V<br />
[pps] = pulses per second<br />
Special requirements upon customer specifications. Right to change reserved. < 1.0 >
MR [mNm]<br />
200<br />
180<br />
160<br />
140<br />
120<br />
100<br />
80<br />
60<br />
40<br />
20<br />
Static characteristics<br />
<br />
0<br />
0 20 40 60 80100 120 140 160<br />
Iph [%]<br />
Electrical Interface<br />
<br />
green<br />
green-white<br />
U 1<br />
red<br />
M<br />
U 2<br />
red-white<br />
SONCEBOZ SA<br />
2605 Sonceboz - Switzerland<br />
Tel. +41(0) 32 488 11 11<br />
Fax +41(0) 32 488 11 00<br />
E-mail : info@sonceboz.com<br />
Internet : www.sonceboz.com<br />
MR [mNm]<br />
200<br />
180<br />
160<br />
140<br />
120<br />
100<br />
80<br />
60<br />
40<br />
20<br />
green<br />
0<br />
white<br />
green-white<br />
0 20 40 60 80<br />
Iph [%]<br />
100 120 140 160<br />
U 1<br />
U 2<br />
[ Hybrid stepper motors 3/3 ]<br />
M<br />
U3 U4 black<br />
red red-white<br />
Special requirements upon customer specifications. Right to change reserved. < 1.0 >
BRAKE<br />
REF<br />
RC<br />
GROUND<br />
GROUND<br />
LOGIC<br />
SUPPLY<br />
PHASE<br />
ENABLE<br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
V CC<br />
LOGIC<br />
V BB<br />
VBB 8 9<br />
MODE<br />
Note the A3953SB (DIP) and the A3953SLB<br />
(SOIC) are electrically identical and share a<br />
common terminal number assignment.<br />
LOAD<br />
SUPPLY<br />
OUT B<br />
GROUND<br />
GROUND<br />
SENSE<br />
OUT A<br />
LOAD<br />
SUPPLY<br />
Dwg. PP-056<br />
ABSOLUTE MAXIMUM RATINGS<br />
Load Supply Voltage, V BB . . . . . . . . . . 50 V<br />
Output Current, I OUT<br />
(Continuous) . . . . . . . . . . . . . . ±1.3 A*<br />
Logic Supply Voltage, V CC . . . . . . . . . 7.0 V<br />
Logic/Reference Input Voltage Range,<br />
V IN . . . . . . . . . . . -0.3 V to V CC + 0.3 V<br />
Sense Voltage, V SENSE<br />
(V CC = 5.0 V) . . . . . . . . . . . . . . . . 1.0 V<br />
(V CC = 3.3 V) . . . . . . . . . . . . . . . . 0.4 V<br />
Package Power Dissipation,<br />
P D . . . . . . . . . . . . . . . . . . . . See Graph<br />
Operating Temperature Range,<br />
T A . . . . . . . . . . . . . . . . -20°C to +85°C<br />
Junction Temperature, T J . . . . . . . +150°C†<br />
Storage Temperature Range,<br />
T S . . . . . . . . . . . . . . . -55°C to +150°C<br />
* Output current rating may be limited by duty<br />
cycle, ambient temperature, and heat sinking.<br />
Under any set of conditions, do not exceed the<br />
specified current rating or a junction temperature<br />
of 150°C.<br />
†Fault conditions that produce excessive junction<br />
temperature will activate the device’s thermal<br />
shutdown circuitry. These conditions can be<br />
tolerated but should be avoided.<br />
16<br />
15<br />
14<br />
13<br />
12<br />
11<br />
10<br />
3953<br />
FULL-BRIDGE PWM MOTOR DRIVER<br />
Designed for bidirectional pulse-width modulated (PWM) current control<br />
of inductive loads, the A3953S— is capable of continuous output currents to<br />
±1.3 A and operating voltages to 50 V. Internal fixed off-time PWM currentcontrol<br />
circuitry can be used to regulate the maximum load current to a desired<br />
value. The peak load current limit is set by the user’s selection of an input<br />
reference voltage and external sensing resistor. The fixed off-time pulse<br />
duration is set by a user- selected external RC timing network. Internal circuit<br />
protection includes thermal shutdown with hysteresis, transient-suppression<br />
diodes, and crossover current protection. Special power-up sequencing is not<br />
required.<br />
With the ENABLE input held low, the PHASE input controls load current<br />
polarity by selecting the appropriate source and sink driver pair. The MODE<br />
input determines whether the PWM current-control circuitry operates in a slow<br />
current-decay mode (only the selected source driver switching) or in a fast<br />
current-decay mode (selected source and sink switching). A user-selectable<br />
blanking window prevents false triggering of the PWM current-control<br />
circuitry. With the ENABLE input held high, all output drivers are disabled.<br />
A sleep mode is provided to reduce power consumption.<br />
When a logic low is applied to the BRAKE input, the braking function is<br />
enabled. This overrides ENABLE and PHASE to turn off both source drivers<br />
and turn on both sink drivers. The brake function can be used to dynamically<br />
brake brush dc motors.<br />
The A3953S— is supplied in a choice of two power packages; a 16-pin<br />
dual-in-line plastic package with copper heat-sink tabs, and a 16-pin plastic<br />
SOIC with copper heat-sink tabs. For both package styles, the power tab is at<br />
ground potential and needs no electrical isolation. Each package type is<br />
available in a lead (Pb) free version (100% matte tin plated leadframe).<br />
FEATURES<br />
■ ±1.3 A Continuous Output Current<br />
■ 50 V Output Voltage Rating<br />
■ 3 V to 5.5 V Logic Supply Voltage<br />
■ Internal PWM Current Control<br />
■ Saturated Sink Drivers (Below 1 A)<br />
■ Fast and Slow Current-Decay Modes<br />
■ Automotive Capable<br />
■ Sleep (Low Current Consumption)<br />
Mode<br />
■ Internal Transient-<br />
Suppression Diodes<br />
■ Internal Thermal-<br />
Shutdown Circuitry<br />
■ Crossover-Current and<br />
UVLO Protection<br />
R R<br />
Part Number Pb-free* θJA<br />
θJT Package Packing<br />
(°C/W) (°C/W)<br />
A3953SB-T Yes 43 6 16-Pin DIP 25 per Tube<br />
A3953SLB-T Yes 43 6 16-Lead SOIC 47 per Tube<br />
A3953SLBTR-T Yes 67 6 16-Lead SOIC 1000 per reel<br />
*Pb-based variants are being phased out of the product line. The variants cited in this<br />
footnote are in production but have been determined to be LAST TIME BUY. This<br />
classification indicates that sale of this device is currently restricted to existing<br />
customer applications. The variants should not be purchased for new design<br />
applications because obsolescence in the near future is probable. Samples are no<br />
longer available. Status change: October 31, 2006. Deadline for receipt of LAST TIME<br />
BUY orders: April 27, 2007. These variants include: A3953SB, A3953SLB, and<br />
A3953SLBTR.<br />
Data Sheet<br />
29319.8e
2<br />
3953<br />
FULL-BRIDGE<br />
PWM MOTOR DRIVER<br />
X = Irrelevant<br />
LOGIC<br />
SUPPLY<br />
MODE<br />
PHASE<br />
ENABLE<br />
BRAKE<br />
GROUND<br />
6<br />
14<br />
7<br />
8<br />
1<br />
VCC<br />
FUNCTIONAL BLOCK DIAGRAM<br />
SLEEP &<br />
STANDBY MODES<br />
INPUT LOGIC<br />
UVLO<br />
& TSD<br />
BLANKING<br />
PWM LATCH<br />
Q<br />
4<br />
VCC<br />
RC + –<br />
12<br />
5 3<br />
2<br />
13<br />
R T<br />
TRUTH TABLE<br />
BRAKE ENABLE PHASE MODE OUT A OUT B DESCRIPTION<br />
H H X H Off Off Sleep Mode<br />
H H X L Off Off Standby<br />
H L H H H L Forward, Fast Current-Decay Mode<br />
H L H L H L Forward, Slow Current-Decay Mode<br />
H L L H L H Reverse, Fast Current-Decay Mode<br />
H L L L L H Reverse, Slow Current-Decay Mode<br />
L X X H L L Brake, Fast Current-Decay Mode<br />
L X X L L L Brake, No Current Control<br />
R<br />
S<br />
LOAD<br />
SUPPLY<br />
VBB<br />
115 Northeast Cutoff, Box 15036<br />
Worcester, Massachusetts 01615-0036 (508) 853-5000<br />
Copyright © 1995, 2000, 2005 Allegro MicroSystems, Inc.<br />
C T<br />
9<br />
V TH<br />
OUT A<br />
+<br />
–<br />
10<br />
15<br />
REF<br />
OUT B<br />
LOAD<br />
SUPPLY<br />
16<br />
11<br />
SENSE<br />
R S<br />
GROUND<br />
Dwg. FP-036-2A
www.allegromicro.com<br />
ALLOWABLE PACKAGE POWER DISSIPATION IN WATTS<br />
5<br />
4<br />
3<br />
2<br />
1<br />
0<br />
25<br />
R = 6.0°C/W<br />
θJT<br />
SUFFIX 'B', R = 43°C/W<br />
θJA<br />
SUFFIX 'LB', R = 63°C/W<br />
θJA<br />
50 75 100 125 150<br />
TEMPERATURE IN °C<br />
Dwg. GP-049-2A<br />
3953<br />
FULL-BRIDGE<br />
PWM MOTOR DRIVER<br />
ELECTRICAL CHARACTERISTICS at TJ = 25˚C, VBB = 5 V to 50 V, VCC = 3.0 V to 5.5 V<br />
(unless otherwise noted.)<br />
Limits<br />
Characteristic Symbol Test Conditions Min. Typ. Max. Units<br />
Power Outputs<br />
Load Supply Voltage Range V BB Operating, I OUT = ±1.3 A, L = 3 mH V CC — 50 V<br />
Output Leakage Current I CEX V OUT = V BB —
3953<br />
FULL-BRIDGE<br />
PWM MOTOR DRIVER<br />
ELECTRICAL CHARACTERISTICS at TJ = 25˚C, VBB = 5 V to 50 V, VCC = 3.0 V to 5.5 V<br />
(unless otherwise noted.)<br />
4<br />
PWM RC Fixed Off-time t OFF RC C T = 680 pF, R T= 30 kΩ, V CC = 3.3 V 18.3 20.4 22.5 µs<br />
PWM Turn-Off Time t PWM(OFF) Comparator Trip to Source Off, — 1.0 1.5 µs<br />
I OUT = 25 mA<br />
Comparator Trip to Source Off, — 1.8 2.6 µs<br />
I OUT = 1.3 A<br />
PWM Turn-On Time t PWM(ON) I RC Charge On to Source On, — 0.4 0.7 µs<br />
I OUT = 25 mA<br />
I RC Charge On to Source On, — 0.55 0.85 µs<br />
I OUT = 1.3 A<br />
PWM Minimum On Time t ON(min) V CC = 3.3 V, R T ≥ 12 kΩ, C T = 680 pF 0.8 1.4 1.9 µs<br />
Propagation Delay Times t pd I OUT = ±1.3 A, 50% to 90%:<br />
V CC = 5.0 V, R T ≥ 12 kΩ, C T = 470 pF 0.8 1.6 2.0 µs<br />
ENABLE On to Source On — 1.0 — µs<br />
ENABLE Off to Source Off — 1.0 — µs<br />
ENABLE On to Sink On — 1.0 — µs<br />
ENABLE Off to Sink Off (MODE = L) — 0.8 — µs<br />
PHASE Change to Sink On — 2.4 — µs<br />
PHASE Change to Sink Off — 0.8 — µs<br />
PHASE Change to Source On — 2.0 — µs<br />
PHASE Change to Source Off — 1.7 — µs<br />
Crossover Dead Time t CODT 1 kΩ Load to 25 V, V BB = 50 V 0.3 1.5 3.0 µs<br />
Maximum PWM Frequency f PWM(max) I OUT = 1.3 A 70 — — kHz<br />
115 Northeast Cutoff, Box 15036<br />
Worcester, Massachusetts 01615-0036 (508) 853-5000<br />
Limits<br />
Characteristic Symbol Test Conditions Min. Typ. Max. Units<br />
AC Timing<br />
Continued next page…
www.allegromicro.com<br />
3953<br />
FULL-BRIDGE<br />
PWM MOTOR DRIVER<br />
ELECTRICAL CHARACTERISTICS at TJ = 25˚C, VBB = 5 V to 50 V, VCC = 3.0 V to 5.5 V<br />
(unless otherwise noted. )<br />
Limits<br />
Characteristic Symbol Test Conditions Min. Typ. Max. Units<br />
Control Circuitry<br />
Thermal Shutdown Temp. T J — 165 — °C<br />
Thermal Shutdown Hysteresis ∆T J — 8.0 — °C<br />
UVLO Enable Threshold 2.5 2.75 3.0 V<br />
UVLO Hysteresis 0.12 0.17 0.25 V<br />
Logic Supply Current I CC(ON) V ENABLE = 0.8 V, V BRAKE = 2.0 V — 42 50 mA<br />
I CC(OFF) V ENABLE = 2.0 V, V MODE = 0.8 V — 12 15 mA<br />
I CC(Brake) V BRAKE = 0.8 V — 42 50 mA<br />
I CC(Sleep) V ENABLE = V MODE = V BRAKE = 2.0 V — 500 800 µA<br />
Motor Supply Current I BB(ON) V ENABLE = 0.8 V — 2.5 4.0 mA<br />
(No Load) I BB(OFF) V ENABLE = 2.0 V, V MODE = 0.8 V — 1.0 50 µA<br />
I BB(Brake) V BRAKE = 0.8 V — 1.0 50 µA<br />
I BB(Sleep) V ENABLE = V MODE = 2.0 V — 1.0 50 µA<br />
Logic Supply Voltage Range V CC Operating 3.0 5.0 5.5 V<br />
Logic Input Voltage V IN(1) 2.0 — — V<br />
V IN(0) — — 0.8 V<br />
Logic Input Current I IN(1) V IN = 2.0 V —
6<br />
3953<br />
FULL-BRIDGE<br />
PWM MOTOR DRIVER<br />
FUNCTIONAL DESCRIPTION<br />
Internal PWM Current Control During Forward and<br />
Reverse Operation. The A3953S— contains a fixed offtime<br />
pulse-width modulated (PWM) current-control circuit<br />
that can be used to limit the load current to a desired<br />
value. The peak value of the current limiting (ITRIP) is set<br />
by the selection of an external current sensing resistor<br />
(RS) and reference input voltage (VREF). The internal<br />
circuitry compares the voltage across the external sense<br />
resistor to the voltage on the reference input terminal<br />
(REF) resulting in a transconductance function approximated<br />
by:<br />
VREF ITRIP ≈ – ISO RS where I SO is the offset due to base drive current.<br />
In forward or reverse mode the current-control circuitry<br />
limits the load current as follows: when the load<br />
current reaches I TRIP, the comparator resets a latch that<br />
turns off the selected source driver or selected sink and<br />
source driver pair depending on whether the device is<br />
operating in slow or fast current-decay mode, respectively.<br />
In slow current-decay mode, the selected source<br />
driver is disabled; the load inductance causes the current<br />
to recirculate through the sink driver and ground clamp<br />
diode. In fast current-decay mode, the selected sink and<br />
source driver pair are disabled; the load inductance<br />
causes the current to flow from ground to the load supply<br />
via the ground clamp and flyback diodes.<br />
Figure 1 — Load-Current Paths<br />
R S<br />
V<br />
BB<br />
DRIVE CURRENT<br />
RECIRCULATION (SLOW-DECAY MODE)<br />
RECIRCULATION (FAST-DECAY MODE)<br />
Dwg. EP-006-13A<br />
The user selects an external resistor (R T) and capacitor<br />
(C T) to determine the time period (t OFF = R T x C T)<br />
during which the drivers remain disabled (see “RC Fixed<br />
Off-Time” below). At the end of the RC interval, the<br />
drivers are enabled allowing the load current to increase<br />
again. The PWM cycle repeats, maintaining the peak<br />
load current at the desired value (see figure 2).<br />
ENABLE<br />
MODE<br />
LOAD<br />
CURRENT<br />
Figure 2<br />
Fast and Slow Current-Decay Waveforms<br />
I TRIP<br />
INTERNAL PWM CURRENT CONTROL<br />
DURING BRAKE-MODE OPERATION<br />
Brake Operation - MODE Input High. The brake circuit<br />
turns off both source drivers and turns on both sink<br />
drivers. For dc motor applications, this has the effect of<br />
shorting the motor’s back-EMF voltage resulting in current<br />
flow that dynamically brakes the motor. If the back-EMF<br />
voltage is large, and there is no PWM current limiting, the<br />
load current can increase to a value that approaches that<br />
of a locked rotor condition. To limit the current, when the<br />
I TRIP level is reached, the PWM circuit disables the<br />
conducting sink drivers. The energy stored in the motor’s<br />
inductance is discharged into the load supply causing the<br />
motor current to decay.<br />
As in the case of forward/reverse operation, the<br />
drivers are enabled after a time given by t OFF = R T x C T<br />
(see “RC Fixed Off-Time” below). Depending on the<br />
back-EMF voltage (proportional to the motor’s decreasing<br />
speed), the load current again may increase to I TRIP. If so,<br />
the PWM cycle will repeat, limiting the peak load current<br />
to the desired value.<br />
115 Northeast Cutoff, Box 15036<br />
Worcester, Massachusetts 01615-0036 (508) 853-5000<br />
RC<br />
RC<br />
Dwg. WP-015-1
During braking, when the MODE input is high, the<br />
peak current limit can be approximated by:<br />
I TRIP BRAKE MH ≈<br />
CAUTION: Because the kinetic energy stored in the motor<br />
and load inertia is being converted into current, which<br />
charges the V BB supply bulk capacitance (power supply<br />
output and decoupling capacitance), care must be taken<br />
to ensure the capacitance is sufficient to absorb the<br />
energy without exceeding the voltage rating of any<br />
devices connected to the motor supply.<br />
Brake Operation - MODE Input Low. During braking,<br />
with the MODE input low, the internal current-control<br />
circuitry is disabled. Therefore, care should be taken to<br />
ensure that the motor’s current does not exceed the<br />
ratings of the device. The braking current can be measured<br />
by using an oscilloscope with a current probe<br />
connected to one of the motor’s leads, or if the back-EMF<br />
voltage of the motor is known, approximated by:<br />
I PEAK BRAKE ML ≈<br />
RC Fixed Off-Time. The internal PWM current-control<br />
circuitry uses a one shot to control the time the driver(s)<br />
remain(s) off. The one-shot time, t OFF (fixed off-time), is<br />
determined by the selection of an external resistor (R T)<br />
and capacitor (C T) connected in parallel from the RC<br />
timing terminal to ground. The fixed off-time, over a range<br />
of values of C T = 470 pF to 1500 pF and R T = 12 kΩ to<br />
100 kΩ, is approximated by:<br />
www.allegromicro.com<br />
V REF<br />
t OFF ≈ R T x C T<br />
The operation of the circuit is as follows: when the<br />
PWM latch is reset by the current comparator, the voltage<br />
on the RC terminal will begin to decay from approximately<br />
0.60V CC. When the voltage on the RC terminal reaches<br />
approximately 0.22V CC, the PWM latch is set, thereby<br />
enabling the driver(s).<br />
R S<br />
V BEMF – 1V<br />
R LOAD<br />
3953<br />
FULL-BRIDGE<br />
PWM MOTOR DRIVER<br />
RC Blanking. In addition to determining the fixed off-time<br />
of the PWM control circuit, the C T component sets the<br />
comparator blanking time. This function blanks the output<br />
of the comparator when the outputs are switched by the<br />
internal current-control circuitry (or by the PHASE,<br />
BRAKE, or ENABLE inputs). The comparator output is<br />
blanked to prevent false over-current detections due to<br />
reverse recovery currents of the clamp diodes, and/or<br />
switching transients related to distributed capacitance in<br />
the load.<br />
During internal PWM operation, at the end of the t OFF<br />
time, the comparator’s output is blanked and C T begins to<br />
be charged from approximately 0.22V CC by an internal<br />
current source of approximately 1 mA. The comparator<br />
output remains blanked until the voltage on C T reaches<br />
approximately 0.60V CC.<br />
When a transition of the PHASE input occurs, C T is<br />
discharged to near ground during the crossover delay<br />
time (the crossover delay time is present to prevent<br />
simultaneous conduction of the source and sink drivers).<br />
After the crossover delay, C T is charged by an internal<br />
current source of approximately 1 mA. The comparator<br />
output remains blanked until the voltage on C T reaches<br />
approximately 0.60V CC.<br />
When the device is disabled, via the ENABLE input,<br />
C T is discharged to near ground. When the device is reenabled,<br />
C T is charged by an internal current source of<br />
approximately 1 mA. The comparator output remains<br />
blanked until the voltage on C T reaches approximately<br />
0.60V CC.<br />
For 3.3 V operation, the minimum recommended<br />
value for C T is 680 pF ± 5 %. For 5.0 V operation, the<br />
minimum recommended value for C T is 470 pF ± 5%.<br />
These values ensure that the blanking time is sufficient to<br />
avoid false trips of the comparator under normal operating<br />
conditions. For optimal regulation of the load current, the<br />
above values for C T are recommended and the value of<br />
R T can be sized to determine t OFF. For more information<br />
regarding load current regulation, see below.<br />
7
8<br />
3953<br />
FULL-BRIDGE<br />
PWM MOTOR DRIVER<br />
LOAD CURRENT REGULATION<br />
WITH INTERNAL PWM<br />
CURRENT-CONTROL CIRCUITRY<br />
When the device is operating in slow current-decay<br />
mode, there is a limit to the lowest level that the PWM<br />
current-control circuitry can regulate load current. The<br />
limitation is the minimum duty cycle, which is a function of<br />
the user-selected value of t OFF and the minimum on-time<br />
pulse t ON(min) max that occurs each time the PWM latch is<br />
reset. If the motor is not rotating (as in the case of a<br />
stepper motor in hold/detent mode, a brush dc motor when<br />
stalled, or at startup), the worst case value of current<br />
regulation can be approximated by:<br />
I AVE ≈<br />
[(V BB – V SAT(source+sink)) x t ON(min)max] – (1.05(V SAT(sink) + V F) x t OFF)<br />
1.05 x (t ON(min)max + t OFF) x R LOAD<br />
where t OFF = R T x C T, R LOAD is the series resistance of the<br />
load, V BB is the motor supply voltage and t ON(min)max is<br />
specified in the electrical characteristics table. When the<br />
motor is rotating, the back EMF generated will influence<br />
the above relationship. For brush dc motor applications,<br />
the current regulation is improved. For stepper motor<br />
applications, when the motor is rotating, the effect is more<br />
complex. A discussion of this subject is included in the<br />
section on stepper motors below.<br />
The following procedure can be used to evaluate the<br />
worst-case slow current-decay internal PWM load current<br />
regulation in the system:<br />
Set V REF to 0 volts. With the load connected and the<br />
PWM current control operating in slow current-decay<br />
mode, use an oscilloscope to measure the time the output<br />
is low (sink on) for the output that is chopping. This is the<br />
typical minimum on time (t ON(min) typ) for the device. The<br />
C T then should be increased until the measured value of<br />
t ON(min) is equal to t ON(min) max as specified in the electrical<br />
characteristics table. When the new value of C T has been<br />
set, the value of R T should be decreased so the value for<br />
t OFF = R T x C T (with the artificially increased value of C T) is<br />
equal to the nominal design value. The worst-case loadcurrent<br />
regulation then can be measured in the system<br />
under operating conditions.<br />
PWM of the PHASE and ENABLE Inputs. The PHASE<br />
and ENABLE inputs can be pulse-width modulated to<br />
regulate load current. Typical propagation delays from<br />
the PHASE and ENABLE inputs to transitions of the<br />
power outputs are specified in the electrical characteristics<br />
table. If the internal PWM current control is used, the<br />
comparator blanking function is active during phase and<br />
enable transitions. This eliminates false tripping of the<br />
over-current comparator caused by switching transients<br />
(see “RC Blanking” above).<br />
Enable PWM. With the MODE input low, toggling the<br />
ENABLE input turns on and off the selected source and<br />
sink drivers. The corresponding pair of flyback and<br />
ground-clamp diodes conduct after the drivers are<br />
disabled, resulting in fast current decay. When<br />
the device is enabled the internal current-control<br />
circuitry will be active and can be used to limit the<br />
load current in a slow current-decay mode.<br />
For applications that PWM the ENABLE input and<br />
desire the internal current-limiting circuit to function in the<br />
fast decay mode, the ENABLE input signal should be<br />
inverted and connected to the MODE input. This prevents<br />
the device from being switched into sleep mode when the<br />
ENABLE input is low.<br />
Phase PWM. Toggling the PHASE terminal selects which<br />
sink/source pair is enabled, producing a load current that<br />
varies with the duty cycle and remains continuous at all<br />
times. This can have added benefits in bidirectional brush<br />
dc servo motor applications as the transfer function<br />
between the duty cycle on the PHASE input and the<br />
average voltage applied to the motor is more linear than in<br />
the case of ENABLE PWM control (which produces a<br />
discontinuous current at low current levels). For more<br />
information see “DC Motor Applications” below.<br />
Synchronous Fixed-Frequency PWM. The internal<br />
PWM current-control circuitry of multiple A3953S—<br />
devices can be synchronized by using the simple circuit<br />
shown in figure 3. A 555 IC can be used to generate the<br />
reset pulse/blanking signal (t 1) for the device and the<br />
period of the PWM cycle (t 2). The value of t 1 should be a<br />
minimum of 1.5 ms. When used in this configuration, the<br />
R T and C T components should be omitted. The PHASE<br />
and ENABLE inputs should not be PWM with this circuit<br />
configuration due to the absence of a blanking function<br />
synchronous with their transitions.<br />
115 Northeast Cutoff, Box 15036<br />
Worcester, Massachusetts 01615-0036 (508) 853-5000
Figure 3<br />
Synchronous Fixed-Frequency Control Circuit<br />
t<br />
2<br />
t 1<br />
Miscellaneous Information. A logic high applied to both<br />
the ENABLE and MODE terminals puts the device into a<br />
sleep mode to minimize current consumption when not in<br />
use.<br />
An internally generated dead time prevents crossover<br />
currents that can occur when switching phase or braking.<br />
Thermal protection circuitry turns off all drivers should<br />
the junction temperature reach 165°C (typical). This is<br />
intended only to protect the device from failures due to<br />
excessive junction temperatures and should not imply that<br />
output short circuits are permitted. The hysteresis of the<br />
thermal shutdown circuit is approximately 15°C.<br />
www.allegromicro.com<br />
APPLICATION NOTES<br />
Current Sensing. The actual peak load current (I PEAK)<br />
will be above the calculated value of I TRIP due to delays in<br />
the turn off of the drivers. The amount of overshoot can<br />
be approximated by:<br />
where V BB is the motor supply voltage, V BEMF is the back-<br />
EMF voltage of the load, R LOAD and L LOAD are the resistance<br />
and inductance of the load respectively, and<br />
t PWM(OFF) is specified in the electrical characteristics table.<br />
The reference terminal has a maximum input bias<br />
current of ±5 µA. This current should be taken into<br />
account when determining the impedance of the external<br />
circuit that sets the reference voltage value.<br />
20 kΩ<br />
2N2222<br />
V CC<br />
1N4001<br />
(VBB – [(ITRIP x RLOAD) + VBEMF]) x tPWM(OFF) IOS ≈<br />
L LOAD<br />
100 kΩ<br />
RC1<br />
RC N<br />
Dwg. EP-060<br />
3953<br />
FULL-BRIDGE<br />
PWM MOTOR DRIVER<br />
To minimize current-sensing inaccuracies caused by<br />
ground trace I x R drops, the current-sensing resistor<br />
should have a separate return to the ground terminal of<br />
the device. For low-value sense resistors, the I x R drops<br />
in the printed wiring board can be significant and should<br />
be taken into account. The use of sockets should be<br />
avoided as their contact resistance can cause variations in<br />
the effective value of R S.<br />
Generally, larger values of R S reduce the aforementioned<br />
effects but can result in excessive heating and<br />
power loss in the sense resistor. The selected value of R S<br />
should not cause the absolute maximum voltage rating of<br />
1.0 V (0.4 V for V CC = 3.3 V operation), for the SENSE<br />
terminal, to be exceeded.<br />
The current-sensing comparator functions down to<br />
ground allowing the device to be used in microstepping,<br />
sinusoidal, and other varying current-profile applications.<br />
Thermal Considerations. For reliable operation it is<br />
recommended that the maximum junction temperature be<br />
kept below 110°C to 125°C. The junction temperature can<br />
be measured best by attaching a thermocouple to the<br />
power tab/batwing of the device and measuring the tab<br />
temperature, T TAB. The junction temperature can then be<br />
approximated by using the formula:<br />
T J ≈ T TAB + (I LOAD x 2 x V F x R θJT)<br />
where V F may be chosen from the electrical specification<br />
table for the given level of I LOAD. The value for R θJT is<br />
given in the package thermal resistance table for the<br />
appropriate package.<br />
The power dissipation of the batwing packages can be<br />
improved by 20% to 30% by adding a section of printed<br />
circuit board copper (typically 6 to 18 square centimeters)<br />
connected to the batwing terminals of the device.<br />
The thermal performance in applications that run at<br />
high load currents and/or high duty cycles can be improved<br />
by adding external diodes in parallel with the<br />
internal diodes. In internal PWM slow-decay applications,<br />
only the two ground clamp diodes need be added. For<br />
internal fast-decay PWM, or external PHASE or ENABLE<br />
input PWM applications, all four external diodes should be<br />
added for maximum junction temperature reduction.<br />
PCB Layout. The load supply terminal, V BB, should be<br />
decoupled with an electrolytic capacitor (>47 µF is recom-<br />
9
10<br />
3953<br />
FULL-BRIDGE<br />
PWM MOTOR DRIVER<br />
mended) placed as close to the device as is physically<br />
practical. To minimize the effect of system ground I x R<br />
drops on the logic and reference input signals, the system<br />
ground should have a low-resistance return to the motor<br />
supply voltage.<br />
See also “Current Sensing” and “Thermal Considerations”<br />
above.<br />
Fixed Off-Time Selection. With increasing values of t OFF,<br />
switching losses will decrease, low-level load-current<br />
regulation will improve, EMI will be reduced, the PWM<br />
frequency will decrease, and ripple current will increase.<br />
The value of t OFF can be chosen for optimization of these<br />
parameters. For applications where audible noise is a<br />
concern, typical values of t OFF are chosen to be in the<br />
range of 15 µs to 35 µs.<br />
Stepper Motor Applications. The MODE terminal can<br />
be used to optimize the performance of the device in<br />
microstepping/sinusoidal stepper-motor drive applications.<br />
When the load current is increasing, slow decay mode is<br />
used to limit the switching losses in the device and iron<br />
losses in the motor. This also improves the maximum rate<br />
at which the load current can increase (as compared to<br />
fast decay) due to the slow rate of decay during t OFF.<br />
When the load current is decreasing, fast-decay mode is<br />
used to regulate the load current to the desired level. This<br />
prevents tailing of the current profile caused by the back-<br />
EMF voltage of the stepper motor.<br />
In stepper-motor applications applying a constant<br />
current to the load, slow-decay mode PWM is typically<br />
used to limit the switching losses in the device and iron<br />
losses in the motor.<br />
DC Motor Applications. In closed-loop systems, the<br />
speed of a dc motor can be controlled by PWM of the<br />
PHASE or ENABLE inputs, or by varying the reference<br />
input voltage (REF). In digital systems (microprocessor<br />
controlled), PWM of the PHASE or ENABLE input is used<br />
typically thus avoiding the need to generate a variable<br />
analog voltage reference. In this case, a dc voltage on the<br />
REF input is used typically to limit the maximum load<br />
current.<br />
In dc servo applications, which require accurate<br />
positioning at low or zero speed, PWM of the PHASE<br />
input is selected typically. This simplifies the servo control<br />
loop because the transfer function between the duty cycle<br />
on the PHASE input and the average voltage applied to<br />
the motor is more linear than in the case of ENABLE<br />
PWM control (which produces a discontinuous current at<br />
low current levels).<br />
With bidirectional dc servo motors, the PHASE<br />
terminal can be used for mechanical direction control.<br />
Similar to when braking the motor dynamically, abrupt<br />
changes in the direction of a rotating motor produces a<br />
current generated by the back-EMF. The current generated<br />
will depend on the mode of operation. If the internal<br />
current control circuitry is not being used, then the maximum<br />
load current generated can be approximated by<br />
I LOAD = (V BEMF + V BB)/R LOAD where V BEMF is proportional to<br />
the motor’s speed. If the internal slow current-decay<br />
control circuitry is used, then the maximum load current<br />
generated can be approximated by I LOAD = V BEMF/R LOAD.<br />
For both cases care must be taken to ensure that the<br />
maximum ratings of the device are not exceeded. If the<br />
internal fast current-decay control circuitry is used, then<br />
the load current will regulate to a value given by:<br />
I LOAD = V REF/R S.<br />
CAUTION: In fast current-decay mode, when the direction<br />
of the motor is changed abruptly, the kinetic energy stored<br />
in the motor and load inertia will be converted into current<br />
that charges the V BB supply bulk capacitance (power<br />
supply output and decoupling capacitance). Care must be<br />
taken to ensure that the capacitance is sufficient to absorb<br />
the energy without exceeding the voltage rating of any<br />
devices connected to the motor supply.<br />
See also “Brake Operation” above.<br />
BRAKE<br />
470 pF<br />
REF<br />
PHASE<br />
ENABLE<br />
30 kΩ<br />
Figure 4 — Typical Application<br />
+5 V<br />
115 Northeast Cutoff, Box 15036<br />
Worcester, Massachusetts 01615-0036 (508) 853-5000<br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
V CC<br />
LOGIC<br />
V BB<br />
16<br />
15<br />
14<br />
13<br />
12<br />
11<br />
10<br />
VBB 8 9<br />
V BB<br />
+<br />
47 µF<br />
0.5 Ω<br />
MODE<br />
Dwg. EP-047-2A
Soldering Considerations. The lead (Pb) free (100%<br />
matte tin) plating on lead terminations is 100% backwardcompatible<br />
for use with traditional tin-lead solders of any<br />
composition, at any temperature of soldering that has<br />
been traditionally used for that tin-lead solder alloy.<br />
Further, 100% matte tin finishes solder well with tin-lead<br />
solders even at temperatures below 232°C. This is because<br />
the matte tin dissolves easily in the tin-lead. Additional<br />
information on soldering is available on the Allegro<br />
Web site, www.allegromicro.com.<br />
www.allegromicro.com<br />
3953<br />
FULL-BRIDGE<br />
PWM MOTOR DRIVER<br />
11
0.280<br />
0.240<br />
0.210<br />
MAX<br />
7.11<br />
6.10<br />
5.33<br />
MAX<br />
0.015<br />
MIN<br />
0.39<br />
MIN<br />
www.allegromicro.com<br />
16<br />
16<br />
A3953SB<br />
Dimensions in Inches<br />
(controlling dimensions)<br />
1 8<br />
0.070<br />
0.045<br />
Dimensions in Millimeters<br />
(for reference only)<br />
1 8<br />
1.77<br />
1.15<br />
0.022<br />
0.014<br />
0.558<br />
0.356<br />
NOTE 4<br />
0.775<br />
0.735<br />
NOTE 4<br />
19.68<br />
18.67<br />
0.100<br />
BSC<br />
NOTES: 1. Exact body and lead configuration at vendor’s option within limits shown.<br />
2. Lead spacing tolerance is non-cumulative.<br />
3. Lead thickness is measured at seating plane or below.<br />
4. Webbed lead frame. Leads 4, 5, 12, and 13 are internally one piece.<br />
5 Supplied in standard sticks/tubes of 25 devices.<br />
2.54<br />
BSC<br />
9<br />
9<br />
0.005<br />
MIN<br />
0.150<br />
0.115<br />
0.13<br />
MIN<br />
3.81<br />
2.93<br />
3953<br />
FULL-BRIDGE<br />
PWM MOTOR DRIVER<br />
0.020<br />
0.008<br />
0.508<br />
0.204<br />
0.430<br />
MAX<br />
0.300<br />
BSC<br />
Dwg. MA-001-17A in<br />
7.62<br />
BSC<br />
10.92<br />
MAX<br />
Dwg. MA-001-17A mm<br />
12
13<br />
3953<br />
FULL-BRIDGE<br />
PWM MOTOR DRIVER<br />
0.2992<br />
0.2914<br />
0.020<br />
0.013<br />
0.0926<br />
0.1043<br />
7.60<br />
7.40<br />
0.51<br />
0.33<br />
2.65<br />
2.35<br />
16 9<br />
1 2 3<br />
0.0040 MIN.<br />
16<br />
1<br />
2 3<br />
0.10 MIN.<br />
0.4133<br />
0.3977<br />
10.50<br />
10.10<br />
A3953SLB<br />
Dimensions in Inches<br />
(for reference only)<br />
0.050<br />
BSC<br />
Dimensions in Millimeters<br />
(controlling dimensions)<br />
0.419<br />
0.394<br />
0° TO 8°<br />
0° TO 8°<br />
0.0125<br />
0.0091<br />
0.050<br />
0.016<br />
Dwg. MA-008-17A in<br />
NOTES: 1. Exact body and lead configuration at vendor’s option within limits shown.<br />
2. Lead spacing tolerance is non-cumulative.<br />
3. Webbed lead frame. Leads 4, 5, 12, and 13 are internally one piece.<br />
4. Supplied in standard sticks/tubes of 47 devices or add “TR” to part number for tape and reel.<br />
9<br />
1.27<br />
BSC<br />
10.65<br />
10.00<br />
0.32<br />
0.23<br />
1.27<br />
0.40<br />
Dwg. MA-008-17A mm<br />
115 Northeast Cutoff, Box 15036<br />
Worcester, Massachusetts 01615-0036 (508) 853-5000
14<br />
3953<br />
FULL-BRIDGE<br />
PWM MOTOR DRIVER<br />
The products described here are manufactured under one or more<br />
U.S. patents, including U. S. Patent No. 5,684,427, or U.S. patents<br />
pending.<br />
Allegro MicroSystems, Inc. reserves the right to make, from time to<br />
time, such departures from the detail specifications as may be required<br />
to permit improvements in the performance, reliability, or<br />
manufacturability of its products. Before placing an order, the user is<br />
cautioned to verify that the information being relied upon is current.<br />
Allegro products are not authorized for use as critical components<br />
in life-support devices or systems without express written approval.<br />
The information included herein is believed to be accurate and<br />
reliable. However, Allegro MicroSystems, Inc. assumes no responsibility<br />
for its use; nor for any infringement of patents or other rights of<br />
third parties which may result from its use.<br />
115 Northeast Cutoff, Box 15036<br />
Worcester, Massachusetts 01615-0036 (508) 853-5000
14<br />
3953<br />
FULL-BRIDGE<br />
PWM MOTOR DRIVER<br />
115 Northeast Cutoff, Box 15036<br />
Worcester, Massachusetts 01615-0036 (508) 853-5000<br />
MOTOR DRIVERS<br />
Function Output Ratings* Part Number †<br />
INTEGRATED CIRCUITS FOR BRUSHLESS DC MOTORS<br />
3-Phase Power MOSFET Controller — 28 V 3933<br />
3-Phase Power MOSFET Controller — 50 V 3932<br />
3-Phase Power MOSFET Controller — 50 V 7600<br />
2-Phase Hall-Effect Sensor/Driver 400 mA 26 V 3626<br />
Bidirectional 3-Phase Back-EMF Controller/Driver ±600 mA 14 V 8906<br />
2-Phase Hall-Effect Sensor/Driver 900 mA 14 V 3625<br />
3-Phase Back-EMF Controller/Driver ±900 mA 14 V 8902–A<br />
3-Phase Controller/Drivers ±2.0 A 45 V 2936 & 2936-120<br />
INTEGRATED BRIDGE DRIVERS FOR DC AND BIPOLAR STEPPER MOTORS<br />
Dual Full Bridge with Protection & Diagnostics ±500 mA 30 V 3976<br />
PWM Current-Controlled Dual Full Bridge ±650 mA 30 V 3966<br />
PWM Current-Controlled Dual Full Bridge ±650 mA 30 V 3968<br />
PWM Current-Controlled Dual Full Bridge ±750 mA 45 V 2916<br />
PWM Current-Controlled Dual Full Bridge ±750 mA 45 V 2919<br />
PWM Current-Controlled Dual Full Bridge ±750 mA 45 V 6219<br />
PWM Current-Controlled Dual Full Bridge ±800 mA 33 V 3964<br />
PWM Current-Controlled Full Bridge ±1.3 A 50 V 3953<br />
PWM Current-Controlled Dual Full Bridge ±1.5 A 45 V 2917<br />
PWM Current-Controlled Microstepping Full Bridge ±1.5 A 50 V 3955<br />
PWM Current-Controlled Microstepping Full Bridge ±1.5 A 50 V 3957<br />
PWM Current-Controlled Dual DMOS Full Bridge ±1.5 A 50 V 3972<br />
Dual Full-Bridge Driver ±2.0 A 50 V 2998<br />
PWM Current-Controlled Full Bridge ±2.0 A 50 V 3952<br />
DMOS Full Bridge PWM Driver ±2.0 A 50 V 3958<br />
Dual DMOS Full Bridge ±2.5 A 50 V 3971<br />
UNIPOLAR STEPPER MOTOR & OTHER DRIVERS<br />
Voice-Coil Motor Driver ±500 mA 6 V 8932–A<br />
Voice-Coil Motor Driver ±800 mA 16 V 8958<br />
Unipolar Stepper-Motor Quad Drivers 1 A 46 V 7024 & 7029<br />
Unipolar Microstepper-Motor Quad Driver 1.2 A 46 V 7042<br />
Unipolar Stepper-Motor Translator/Driver 1.25 A 50 V 5804<br />
Unipolar Stepper-Motor Quad Driver 1.8 A 50 V 2540<br />
Unipolar Stepper-Motor Quad Driver 1.8 A 50 V 2544<br />
Unipolar Stepper-Motor Quad Driver 3 A 46 V 7026<br />
Unipolar Microstepper-Motor Quad Driver 3 A 46 V 7044<br />
* Current is maximum specified test condition, voltage is maximum rating. See specification for sustaining voltage limits or<br />
over-current protection voltage limits. Negative current is defined as coming out of (sourcing) the output.<br />
† Complete part number includes additional characters to indicate operating temperature range and package style.<br />
Also, see 3175, 3177, 3235, and 3275 Hall-effect sensors for use with brushless dc motors.
Bilaga 3: Programkoden<br />
//fördjupningsarbete i mekatronik MF106X, Annie Gustafsson 2011-03-27<br />
//programmet skall styra en stegmotor på olika sätt beroende på vilken knapp som trycks in skall<br />
motsvarande LED tändas och motorn köra på ett specifikt sätt.<br />
#define F_CPU 1000000UL<br />
#include <br />
#include <br />
int main(void)<br />
{<br />
//definierar vilka portar som skall användas och vilka variabler som behövs<br />
DDRB = 0xff; // Port B utgångar, skickar signaler till H-bryggorna om hur motorn skall<br />
köras<br />
DDRA = 0x00; // Port A ingångar, läser av vilken knapp som är intryckt coh ger<br />
instruktioner därefter<br />
DDRC = 0xff; // Port C utgångar, tänder LED som motsvarar vilken knapp som tryckts in<br />
unsigned char stegtyp = -1, intryckt_knapp; //stegtyp bestämmer hur motorn skall köras,<br />
intryckt_knapp talar om vilken knapp som tryckts in<br />
while(1)<br />
{<br />
intryckt_knapp = PINA;<br />
if (intryckt_knapp == 0xFE) //knapp 0 intryckt kör stegmotorn <strong>med</strong> helsteg tills dess en ny knapp<br />
tryckts in<br />
{<br />
stegtyp = 1;<br />
}<br />
if (intryckt_knapp == 0xFD) //knapp 1 intryckt kör stegmotorn <strong>med</strong> halvsteg tills dess en ny<br />
knapp tryckts in<br />
{<br />
stegtyp = 2;<br />
}<br />
if (intryckt_knapp == 0xFB)//knapp 2 intryckt kör stegmotorn <strong>med</strong> mikrosteg tills dess en ny<br />
knapp tryckts in<br />
{<br />
stegtyp = 3;<br />
}<br />
if (intryckt_knapp == 0xF7) //knapp 3 intryckt ställ stegmotorn i standby tills dess en ny knapp<br />
tryckts in<br />
{<br />
stegtyp = 4;<br />
}<br />
switch (stegtyp)<br />
{<br />
case 1: //helsteg<br />
PORTC = 0xFE;<br />
PORTB = 0x9B;<br />
_delay_ms(5);<br />
PORTB = 0xBB;<br />
_delay_ms(5);
PORTB = 0xB9;<br />
_delay_ms(5);<br />
PORTB = 0x99;<br />
_delay_ms(5);<br />
break;<br />
case 2: //halvsteg<br />
PORTC = 0xFD;<br />
PORTB = 0x90;<br />
_delay_ms(5);<br />
PORTB = 0x9B;<br />
_delay_ms(5);<br />
PORTB = 0x0B;<br />
_delay_ms(5);<br />
PORTB = 0xBB;<br />
_delay_ms(5);<br />
PORTB = 0xB0;<br />
_delay_ms(5);<br />
PORTB = 0xB9;<br />
_delay_ms(5);<br />
PORTB = 0x09;<br />
_delay_ms(5);<br />
PORTB = 0x99;<br />
_delay_ms(5);<br />
break;<br />
case 3: //mikrosteg<br />
PORTC = 0xFB;<br />
PORTB = 0x10;<br />
_delay_ms(5);<br />
PORTB = 0x13;<br />
_delay_ms(5);<br />
PORTB = 0x03;<br />
_delay_ms(5);<br />
PORTB = 0x33;<br />
_delay_ms(5);<br />
PORTB = 0x30;<br />
_delay_ms(5);<br />
PORTB = 0x31;<br />
_delay_ms(5);<br />
PORTB = 0x01;<br />
_delay_ms(5);
}<br />
}<br />
}<br />
PORTB = 0x11;<br />
_delay_ms(5);<br />
break;<br />
case 4: //avbryt körning och ställ motorn i standby<br />
PORTC = 0xF7;<br />
PORTB = 0xAA;<br />
break;<br />
default: //blir något fel tänd alla dioder och ställ motorn i standby<br />
PORTC = 0x00;<br />
PORTB = 0xAA;<br />
break;
Bilaga L.<br />
Individuell rapport, Stegmotor – Ett fördjupningsarbete i mekatronik<br />
Av Mazda Imani
KUNGLIGA TEKNISKA HÖGSKOLAN<br />
Stegmotor<br />
Ett fördjupningsarbete i mekatronik<br />
Mazda Imani, 890803-0151<br />
28/3//2011<br />
Institution: <strong>KTH</strong> Maskinkonstruktion<br />
Kurs: MF106X<br />
Handledare: Martin Grimheden
Abstract<br />
This report describes the theory of how a stepper motor works and can be controlled. The<br />
report also describes the development of a working prototype that fulfills the following three<br />
desired main features:<br />
1. The ability to, with the help of a keyboard, control how many degrees the stepper<br />
motor will rotate with a resolution of at least 1 degree. The stepper motor will also<br />
have the possibility to rotate backwards. The rotational velocity should be adjustable<br />
while running.<br />
2. Have a mode where the stepper motor is rotating continuous with the ability of<br />
changing the step modes. The velocity and rotational direction should also be able to<br />
be adjusted while running.<br />
3. A mode with an unusual implementation of the stepper motor, for example the ability<br />
to play a simple song by generating tones.<br />
The part of the report where the prototype is constructed is written as an argumentative text in<br />
which each choice of component is justified by both the pros and cons. The prototype is lastly<br />
built as a standalone unit to demonstrate that everything works as it should.
Sammanfattning<br />
I denna rapport avhandlas teorin om hur en stegmotor fungerar och kan styras. Rapporten<br />
avhandlar även utvecklandet av en fungerande prototyp <strong>med</strong> följande tre huvudfunktioner<br />
som krav:<br />
1. Att <strong>med</strong> hjälp av ett tangentbord kunna mata in hur många grader motorn ska vrida<br />
sig. Detta <strong>med</strong> en upplösning av minst 1 grad. Motorn ska även kunna snurra<br />
baklänges. Hastigheten som motorn vrider sig <strong>med</strong> ska kunna justeras.<br />
2. Ha ett läge där motorn snurrar konstat <strong>med</strong> olika sorters steglägen. Hastigheten ska<br />
kunna ändras och rotationsriktningen ska även kunna vändas.<br />
3. Ett läge <strong>med</strong> en ovanlig användning av stegmotorn, exempelvis att kunna spela en låt<br />
eller toner.<br />
Prototypdelen av rapporten är skriven som en argumenterande text där varje komponentval<br />
motiveras <strong>med</strong> både för och nackdelar. Slutligen byggdes en fristående prototyp på<br />
experimentkort för att kunna demonstrera att allting fungerar.
Innehåll<br />
Innehåll ....................................................................................................................................... 2<br />
Inledning ..................................................................................................................................... 3<br />
Teoretisk fördjupning ................................................................................................................. 4<br />
Vad är en stegmotor? .............................................................................................................. 4<br />
Olika varianter ........................................................................................................................ 5<br />
Variabel reluktansmotor ..................................................................................................... 5<br />
Permanentmagnetiserad stegmotor .................................................................................... 5<br />
Hybrid stegmotor ................................................................................................................ 6<br />
Problemdefinition och lösning ................................................................................................... 7<br />
Kravspecifikation ................................................................................................................... 7<br />
Lösning ................................................................................................................................... 7<br />
Stegmotor ........................................................................................................................... 7<br />
Drivkretsen ......................................................................................................................... 8<br />
Tangentbordet ................................................................................................................... 17<br />
Potentiometern ................................................................................................................. 19<br />
Mikrokontrollern .............................................................. Error! Bookmark not defined.<br />
Spänningsregulatorn ......................................................................................................... 20<br />
Mjukvara .......................................................................................................................... 21<br />
Prototypen ........................................................................................................................ 22<br />
Slutsats och Diskussion ............................................................................................................ 24<br />
Referenser ................................................................................................................................. 25<br />
Källor .................................................................................................................................... 25<br />
Bilder .................................................................................................................................... 25<br />
Bilagor ...................................................................................................................................... 27<br />
Komponentlista .................................................................................................................... 27<br />
Kopplingsschema ................................................................................................................. 28<br />
Mikrokontrollern (Bättre bild finns i slutet) .................................................................... 28<br />
Motordrivaren (Bättre bild finns i slutet) ......................................................................... 29<br />
Flödesschema ....................................................................................................................... 30<br />
Huvudprogrammet ........................................................................................................... 30<br />
Interruptrutiner ................................................................................................................. 31<br />
2
Inledning<br />
Denna rapport är ett resultat av ett individuellt projektarbete gjord under kursen MF106X i<br />
mekatronik. Projektet har varit utformat så att man ska välja någon teknisk modul som har<br />
<strong>med</strong> mekatronik att göra och bli expert på den. Denna expertis ska därefter kunna kombineras<br />
i ett mycket större projekt där varje delttagare är expert på sitt område.<br />
Jag valde att lära mig mer om stegmotorer och det är just detta som rapporten behandlar.<br />
Rapporten är indelad i två delar, en teoretisk del som beskriver hur olika slags stegmotorer<br />
fungerar. Den andra delen är skriven som en argumenterande text där den praktiska<br />
arbetsgången är beskriven.<br />
3
Teoretisk fördjupning<br />
Vad är en stegmotor?<br />
För att förstå nyttan <strong>med</strong> en stegmotor kan man börja <strong>med</strong> att kolla på den enklaste sortens<br />
motor, en helt vanlig likströmsmotor. En likströmsmotor består av en rotor och stator. Rotorn<br />
har en spole på sig som bildar en elektromagnet när ström går igenom den, statorn befinner<br />
sig runt rotorn och ger upphov till ett magnetiskt fält, ofta består statorn av ett<br />
permanentmagnetiserat material. När en ström går igenom spolen kommer den som tidigare<br />
nämnt att bli tillfälligt magnetiserad och samtidigt försöka vrida sig så att det magnetiska<br />
flödet blir så litet som möjligt. När rotorn har vridit sig ett halvt varv vänds polariteten<br />
mekaniskt i motorn och spolen kommer att försöka vrida sig ett halvt varv tillbaka.<br />
(Wikipedia, Brushed DC electric motor) . Denna teknik ger både snabba och små motorer,<br />
problemet är att vid en eventuell styrning av hur fort eller mycket en sådan motor skall vrida<br />
sig krävs det någon sorts återkopplad reglering.<br />
Bild 1. Illustration över en drivcykel för en likströmsmotor. Bild tagen från Wikipedia.<br />
För en stegmotor är däremot grundprincipen att ha en extern styrning av motorn istället för en<br />
automatiskt mekanisk lösning för motordrivningen som likströmsmotorn har. Detta innebär att<br />
en eventuell reglering av en stegmotor inte nödvändigtvis kräver någon form av återkoppling<br />
eftersom det redan är känt hur och när motorn styrs. Detta gäller endast om stegmotorn <strong>med</strong><br />
säkerhet är rätt dimensionerad för lasten, därför är det viktigt att använda rätt stegmotor för<br />
rätt arbete.<br />
Denna egenskap gör att <strong>med</strong> rätt sorts drivning kan en väldigt hög precision av både hastighet<br />
och vinkel nås. En annan egenskap av att styrningen sker separat är att en stegmotor <strong>med</strong><br />
enkelhet kan hållas statisk trots variabel pålagd last.<br />
4
Typiska användningsområden för stegmotorer är där noggrann styrning av mekanik krävs,<br />
exempelvis i skrivare, hårddiskar, CNC-fräsar mm.(Wikipedia, Stepper motor) (Industrial<br />
Circuits Application Note, Stepper Motor Basics)<br />
Olika varianter<br />
Variabel reluktansmotor<br />
Är kanske den enklaste sortens stegmotor. Principmässigt påminner den om likströmsmotorn,<br />
men istället består rotorn av ett grovt tandat svänghjul i järn som påverkas av ett magnetfält<br />
skapat av ett flertal spolar i statorn. Beroende på vilka spolar som det flyter ström igenom<br />
kommer rotorn att ställa in sig så att reluktansen blir så liten som möjligt (Wikipedia,<br />
Reluctance motor ).<br />
Fördelen <strong>med</strong> denna typ av motor är att de både är billiga och kan uppnå hög precision.<br />
Nackdelen <strong>med</strong> dessa motorer är att eftersom rotorn är indelad i grova steg på oftast tiotals<br />
grader, krävs det både avancerad styrning och oftast kombinerad <strong>med</strong> någon sorts återkopplad<br />
reglering för att få bra precision (Wikipedia, Stepper motor)(All About Circuits, Reluctance<br />
motor)<br />
Permanentmagnetiserad stegmotor<br />
En permanentmagnetiserad stegmotor fungerar ganska likt en variabel reluktansmotor. Men<br />
istället för en ferromagnetiskt tandad rotor används istället en cylindrisk<br />
permanentmagnetiserad rotor. Ofta har rotorn fler än bara två poler.<br />
Ett magnetfält, skapat en eller flera spolar, får rotorn att ställa in sig i en viss vinkel. Fördelen<br />
<strong>med</strong> denna design är att eftersom en permanentmagnetiserad kärna används kommer det<br />
magnetiska flödet och där<strong>med</strong> även kraften på rotorn att öka. Detta innebär att<br />
permanentmagnetiserade stegmotorer ofta kan ge ett högre vridmoment än reluktansmoterer.<br />
Denna typ av motor är ofta ett billigare alternativ och kräver vanligtvis ingen återkopplad<br />
reglering.<br />
Nackdelen är att om rotorn inte har tillräckligt många poler kommer en stor steglängd att<br />
uppstå vilket leder till att det är svårt att uppnå hög precision av vinkelutslag utan någon<br />
avancerad styrning. (All About Circuits, Stepper motors)<br />
5
Hybrid stegmotor<br />
En hybrid stegmotor är som namnet kanske antyder en kombination av en reluktansmotor och<br />
permanentmagnetiserade stegmotor. Rotorn består av ett fint tandat magnetiserat hjul omgivet<br />
av vanligtvis två olika spolar. Eftersom rotorn är fint tandat och magnetiserad kan både en<br />
väldigt hög precision av vinkeländringen uppnås, utan vidare avancerad styrning, samtidigt<br />
som motorn blir stark. Dessa motorer är vanligtvis dyrare då de är svårare att tillverka.<br />
Typiskt brukar dessa motorer kunna gå 100-400 helsteg per varv.<br />
(All About Circuits, Stepper motors)<br />
Det finns två vanliga typer av hybrida stegmotorer:<br />
Unipolär motor<br />
Denna typ av hybrida stegmotor har två lindingar per fas. Detta innebär att varje fas, eller<br />
spole, kan köras så att magnetfältet som den ger upphov till går att vända utan att behöva<br />
vända polaritet. Denna lösning innebär att styrkretsen kan vara väldigt enkel, det kan till och<br />
<strong>med</strong> räcka <strong>med</strong> en transistor eller ett relä. Dessvärre kommer en unipolär motor att bli svagare<br />
jämfört <strong>med</strong> en lika stor bipolär motor eftersom endast hälften av varje fas lindingar kan<br />
användas åt gången. (Wikipedia, Stepper motor)<br />
Bild 2. En principskiss äver en unipolär motor. Bilden är tagen från Wikipedia.<br />
Bipolär motor<br />
En bipolär motor har till skillnad från den unipolära motorn endast en lindning per fas. Detta<br />
innebär att om en fas ska kunna vända magnetfältet måste även spänningen göra det.<br />
Styrkretsen kommer att bli något svårare men i gengäld är bipolära motorer vanligtvis starkare<br />
eftersom varje fas kan utnyttjas fullt ut. Vanligtvis sker drivningen <strong>med</strong> någon form av Hbrygga.(Wikipedia,<br />
Stepper motor)<br />
6
Problemdefinition och lösning<br />
Kravspecifikation<br />
I detta projekt har vikt lagts på att <strong>med</strong> stor exakthet kunna styra en stegmotor, mindre vikt<br />
har lagts på att implementera styrningen eller integrera styrningen i ett färdigt paket. Detta då<br />
det hamnar lite utanför projektets huvudområde som är att att lära sig om, behärska och<br />
slutligen kunna utveckla en eller flera moduler.<br />
Tre huvudfunktioner önskades av stegmotorn:<br />
1. Att <strong>med</strong> hjälp av ett tangentbord kunna mata in hur många grader motorn ska vrida<br />
sig. Detta <strong>med</strong> en upplösning av minst 1 grad. Motorn skall även kunna snurra<br />
baklänges. Hastigheten som motorn vrider sig <strong>med</strong> skall kunna justeras.<br />
2. Ha ett läge där motorn snurrar konstat <strong>med</strong> olika sorters steglägen. Hastigheten skall<br />
kunna ändras och rotationsriktningen skall även kunna vändas.<br />
3. Ett läge <strong>med</strong> en ovanlig användning av stegmotorn, exempelvis att kunna spela en låt<br />
eller toner.<br />
Det skall även vara möjligt att kunna bläddra mellan de olika funktionerna och stegläget skall<br />
även också kunna ändras var som helst i programmet. Se bifogat flödesschema över hur<br />
programmet är tänkt att fungera.<br />
En fristående fungerande prototyp skall slutligen tillverkas för att demonstrera<br />
funktionaliteten.<br />
Lösning<br />
För att lösa ett sådant stort projekt utforskades varje del för sig för att slutligen integrera varje<br />
del i en produkt.<br />
Stegmotor<br />
Den stegmotorn som erhölls var av märket Soncebroz <strong>med</strong> serienumret 6540R377, se bilaga.<br />
En sökning på internet gav inga resultat. Hos tillverkarens hemsida hittades till slut en till det<br />
yttre likadan motor <strong>med</strong> samma egenskaper utmärkta på den egna motorn. Enligt databladet<br />
rör det sig som en bipolär hybrid stegmotor. Detta bekräftades även genom att det tydligt går<br />
att känna att motorn hackar i små steg fram när man vrider på den för hand, detta tyder på att<br />
7
det rör sig om något som är permanentmagnetiserat och uppdelat i många småsteg, vilket även<br />
en hybrid stegmotor är. På den fyrpoliga kontakten mättes både resistansen och induktansen<br />
och den framgick att det rör sig om två olika spolar <strong>med</strong> liknande egenskaper, detta gäller<br />
vanligtvis för en bipolär stegmotor.<br />
Enligt databladet klarar motorn av 0.52 A/fas där varje fas har en resistans på 9 ohm. Enligt<br />
ohms lag innebär det att motorn ska drivas <strong>med</strong> en spänning på maximalt ca 5 V. Det har inte<br />
tagits någon hänsyn till eventuell påverkan av spolarnas induktans eftersom motorn ändå ska<br />
klara av att vara statisk.<br />
Drivkretsen<br />
Eftersom stegmotorn är bipolär och har två likadana faser sker drivningen genom att på något<br />
sätt få spänning genom faserna. Då det finns två faser och det även går att vända polariteten<br />
måste motorn kunna drivas genom en kombinering av dessa fyra olika lägen. För att förenkla<br />
dokumenteringen gavs den ena fasen namnet ”fas A” och den andra fasen namnet ”fas B”. De<br />
fyra olika drivsteg är:<br />
fas A positiv<br />
fas A negativ<br />
fas B positiv<br />
fas B negativ<br />
Eftersom en mikrokontroller endast klarar av att ge antingen positiv spänning eller 0 måste<br />
någon typ av spänningsväxlande krets användas. Till att börja <strong>med</strong> byggdes en enkel<br />
spänningsväxlande krets där man manuellt <strong>med</strong> hjälp av tre brytare kan växla spänningen för<br />
båda faserna. Denna gjordes manuell för att in i detalj kunna studera vilken ordning som<br />
drivlägena ska komma i för att få stegmotorn att rotera åt ett håll.<br />
Efter lite experimenterande drogs följade slutsats för en fungerande drivsekvens:<br />
Drivsteg Fas A Fas B<br />
1 Positiv 0<br />
2 0 Positiv<br />
3 Negativ 0<br />
4 0 Negativ<br />
Tabell 1. Drivsekvensen för helsteg.<br />
8
Genom att vända på drivstegen kan även motorn byta riktning. Detta är ett helt rimligt resultat<br />
som även andra har kommit fram till. Denna typ av drivsekvens kallas vanligtvis för<br />
helsteg.(Piclist.com, Driving Bipolar Stepper Motors)<br />
När drivsekvensen hade blivit bestämd var nästa steg att få en automatiskt styrning. En<br />
lämplig krets för detta är en H-brygga eftersom denna typ av krets enkelt klarar av att vända<br />
utgående polaritet. Motordrivaren UDN2916B från Allegro valdes då har två integrerade Hbryggor<br />
som klarar av de utträknade lasterna, vilket behövs för de två faserna. Dessutom<br />
klarar den av att strömbegränsa utgående ström, vilket kom till användning när exaktare<br />
styrning av drivsekvensen krävdes.<br />
Motordrivarens funktionalitet bekräftades <strong>med</strong> en enkel koppling på en s.k ”breadboard”.<br />
Som kopplingsschema användes tillverkarens egna förslag på typisk inkoppling, se bifogat<br />
datablad. Några val av diskreta komponenter för motordrivarens funktionalitet var tvungna<br />
att göras:<br />
Utgående strömbegränsning<br />
Enligt datablad är motorn dimensionerad för 0.52 A/fas. Enligt motordrivarens datablad ska<br />
detta förhållande gälla mellan strömbegränsningen I och det strömbegränsade motståndet Rs.<br />
<br />
Ekvation 1<br />
·<br />
<br />
·,<br />
1,04 Ω Ekvation 2<br />
<br />
Beslutet togs att driva motordrivaren <strong>med</strong> 5 V och ha samma spänning som referenspänning.<br />
Detta då både mikrokontrollern och motordrivaren skulle kunna dela på samma<br />
spänningskälla. Då inga sådana motstånd kunda hittas valdes närmast lägsta tillgängliga<br />
motståndet på 0,82 Ω.<br />
PWM-frekvens<br />
En sorts tidskonstant för motordrivarens PWM-signal var tvungen att väljas. Enligt databladet<br />
skulle dessa väljas så att tidskonstanten toff blir så liten att inga oljud kan höras, dvs<br />
frekvensen blir över den mänskligt hörbara frekvensen på ca 20 kHz. Då:<br />
Och <br />
Ekvation 3<br />
<br />
20 000 Ekvation 4<br />
9
Ger att <br />
50·10 Ekvation 5<br />
Från tillgängliga komponenter valdes RT på 56 Ω och CT på 820 pF vilket ger en frekvens på<br />
ca 22 kHz, dvs en acceptabel nivå.<br />
Lågpassfilter<br />
Enligt databladet rekommenderades det att sätta in ett enkelt lågpassfilter för<br />
strömbegränsningen för att förhindra högfrekventa störningar. För ett lågpassfilter som<br />
använder en resistor Rc och en kondensator Cc gäller förhållandet för brytfrekvensen.<br />
(Wikipedia, Low-pass filter)<br />
<br />
<br />
10<br />
Ekvation 6<br />
Då det var väldigt svårt att veta vilket frekvens som en störning har och <strong>med</strong> vilken frekvens<br />
som h-bryggan skulle styras <strong>med</strong> valdes Rc till 1000 Ω och Cc till 1 nF. Detta ger en<br />
brytfrekvens på ca 160 kHz. Vid behov skulle dessa komponenter eventuellt kunna bytas ut.<br />
Valen av de diskreta komponenterna för motordrivarens funktionalitet visade sig vara<br />
tillfredställande när kretsen provkördes. Inga störande missljud uppstod och stegmotorn<br />
betedde sig som förväntat. När komponenterna på prov en och en togs bort, fungerade motorn<br />
fortfarande, men kunde ibland bete sig konstigt och ryckigt. Därför fattades beslutet att ha<br />
kvar samtliga diskreta komponenter på den slutliga lösningen.<br />
Slutligen löddes en separat krets på ett experimentkort <strong>med</strong> uttag för styrsignaler och<br />
strömförsörjning från mikrokontrollern, uttag strömkällan för drivning av motorn och ett uttag<br />
för motorn. Allting fungerade bra och det färdiga kortet kändes stabilt och rent nog för att inte<br />
behöva göra ett till etsat kort.
Steg<br />
Bild 3. Den färdiga motordrivaren, ansluten till mikrokontrollern i bakgrunden.<br />
Som tidigare nämnt har en drivsekvens för helsteg åstadkommits. Vad som menas <strong>med</strong><br />
helsteg är att kuggarna på den magnetiserade rotorn ställer in sig i ett visst läge när en fas har<br />
en viss polaritet över sig. Eftersom motorn har 2 faser <strong>med</strong> två möjliga polariteter kan totalt 4<br />
helsteg göras per driftsekvens. Närmare undersökning visade att motorn går 200 helsteg eller<br />
50 driftsekvenser för varje varv. Eftersom motorn endast går 200 steg per varv kommer den<br />
att upplevas som ”ryckig” om den rör sig långsamt. En lösning på problemet är att ha<br />
mellansteg. Dvs. istället för att hoppa från ett steg till ett annat gör motorn små hopp<br />
däremellan. För att åstadkomma detta görs det övergångar mellan de fyra huvudstegen. Detta<br />
går att göra genom att antingen stegvis höja och sänka spänningen eller strömmen, istället för<br />
att göra direkta hopp. Om motorn anses vara linjär kommer motorns moment att bero linjärt<br />
på den tillförda effekten. Om spolarnas induktans försummas kommer enligt ohms lag den<br />
inmatade effekten att bero kvadratiskt på en inmatade strömmen eller spänningen. Spolarnas<br />
induktans valdes att försummas eftersom det ännu inte är känt <strong>med</strong> vilket hastighet som<br />
stegmotorn ska snurra.<br />
Med andra ord måste den kvadratiska summan av de tillförda strömmarna eller spänningarna<br />
över faserna vara så konstant som möjligt för att få ett jämnt moment.<br />
11
Ekvation 7<br />
Ekvation 8<br />
Som tidigare observerats i tabell 1 ligger fas A alltid, beroende på hur motorn ska snurra,<br />
antingen en kvarts drivsekvens före eller efter fas B.<br />
Med detta som underlag drogs slutsatsen att det antagligen rör sig om en sinusfunktion<br />
eftersom likt en sinusfunktion ändrar sig spänningen eller strömmen för varje fas i<br />
drivsekvensen cykliskt, där den går från 0 till ett positivt värde till 0 igen och därefter ett<br />
negativt värde för att slutligen ändras gå tillbaka till 0. Detta jämnt fördelat över hela<br />
drivsekvensen. Dessutom är fasförskjutningen mellan en sinus och cosinusfunktion en<br />
fjärdedels cykel och enligt definition gäller:<br />
1 Ekvation 9<br />
Vilket även gäller för ekvation 7 och 8.<br />
Vidare studier visade att antagandet att stegmotorn idealt bör matas <strong>med</strong> en sinus- eller<br />
cosinus-formad ström eller spänning varit helt korrekt (StepperWorld.com, Stepper Motors<br />
and Control). För att göra jämförelserna <strong>med</strong> de trigonometriska funktionerna lättare gjordes<br />
definitionen att en driftcykel, likt en trigonometrisk funktion, går på 360 grader istället för 4<br />
steg. Se bild 4 och 5 som är plottar på hur strömmen kan varieras för att kunna få helsteg. Den<br />
ideala sinusfunktionen är även utritad. Observera att ingen enhet angivits i plottarna, utan 1<br />
har satts till det maximala värdet.<br />
Bild 4. En plott över helsteg för Fas A.<br />
12
Figur 5. En plott över helsteg för Fas B.<br />
Eftersom den valda motordrivaren har en inbyggd möjlighet att strömbegränsa till 2/3 eller<br />
1/3 av maximala strömmen togs beslutet att försöka få mellansteg <strong>med</strong> hjälp av<br />
strömbegränsningen.<br />
Drivsteg IFas A IFas B<br />
1 (0°- 45°) 100 % 0<br />
2(45°- 90°) 66 % 66 %<br />
3 (90°- 135°) 0 % 100 %<br />
4(135°- 180°) - 66 % 66 %<br />
5 (180°- 225°) -100 % 0 %<br />
6(225°- 270°) -66 % -66 %<br />
7 (270°- 315°) 0 -100 %<br />
8(315°- 360°) 66 % -66%<br />
Tabell 2. Schematisk skiss över halvsteg.<br />
I tabell 2 har halvsteg använts. Dvs. mellan varje helsteg har ett mellansteg satts in.<br />
Idealt borde fasströmmarna i mellanstegen ha storleken sin(45°) ≈ 0.71 för att motorn ska<br />
kunna snurra så jämnt som möjligt. I bild 7 har storleken på avvikelsen i effekt ritats ut som<br />
funktion av drivsekvensensen. I den kan det ses att den största avvikelsen blir ca 10 %. Detta<br />
ansågs som acceptabla nivåer.<br />
13
Bild 6. En plott över halvsteg för Fas A<br />
Bild 7. En plott över effektavvikelsen för halvsteg<br />
Eftersom stegmotorn går 200 helsteg för varje varv, innebär det att den går 400 halvsteg per<br />
varv. Detta är ett fullt acceptabelt resultat då kravet är att kunna styra motorn <strong>med</strong> en<br />
noggrannhet av 1°, <strong>med</strong> halvsteg är noggrannheten 0,9°. Trots detta testades även<br />
tredjedelssteg som har en teoretisk noggrannhet på 0,6°.<br />
14
Drivsteg IFas A IFas B<br />
1 (0°- 30°) 100% 0<br />
2 (30°- 45°) 66% 33%<br />
3 (45°- 60°) 33% 66%<br />
4 (60°- 90°) 0% 100%<br />
5 (90°- 120°) -33% 66%<br />
6 (120°- 150°) -66% 33%<br />
7 (150°- 180°) -100% 0<br />
8 (180°- 210°) -66% -33%<br />
9 (210°- 240°) -33% -66%<br />
10 (270°- 300°) 0 -100%<br />
11 (300°- 330°) 33% -66%<br />
12 (330°- 360°) 66% -33%<br />
Tabell 3. Schematisk skiss över tredjedelssteg.<br />
Tabell 3 visar hur tredjedelssteg har använts. Dvs. mellan varje helsteg tas nu 2 delsteg och<br />
där<strong>med</strong> är ett motorvarv uppdelat i 600 småsteg. Problemet som uppstod här var att även om<br />
noggrannheten har ökats har även effektavvikelsen i mellanstegen ökat till över 40 % (se bild<br />
9). Detta innebär att om stegmotorn belastas <strong>med</strong> en större last kan en viss ojämnhet i gången<br />
uppstå. I praktiken uppstod faktiskt inga större ojämnhetsproblem och eftersom<br />
noggrannheten trots allt blivit högre, fattades beslutet att även ta <strong>med</strong> denna drivsekvens.<br />
Bild 8. En plott över tredjedelssteg för Fas A. Lägg märke till den trekantsvågiga formen.<br />
15
Mikrosteg<br />
Bild 9. En plott över effektavvikelsen för halvsteg.<br />
Som tidigare konstaterat kommer en sinusformad funktion på driftströmmen att ge den bästa<br />
drivsekvensen. Korrekt utfört kommer motorn att gå så mjukt att inga steg kommer att<br />
märkas. Problemet är att eftersom styrningen sker digitalt av en mikrokontroller, går det inte<br />
att få ut en rent analog sinussignal. En lösning är att ”hacka” upp en sinusvåg i flera delar.<br />
Detta är en okej då signalen blir väldigt sinuslik redan vid 32 uppdelningar per period. Vid<br />
128 kan utsignalen i stort sett betraktas som en sinus eller cosinusvåg, se bild 10 och 11.<br />
Bild 10. En plott över mikrosteg <strong>med</strong> 32 bitars upplösning.<br />
16
Bild 11. En plott över mikrosteg <strong>med</strong> 128 bitars upplösning.<br />
Enligt ekvation 1 beror den utmatade strömmen I på vad referensspänningen Vref för<br />
motordrivaren ligger på. En rimlig lösning vore att <strong>med</strong> hjälp av PWM ändra Vref så att I får<br />
blir sinusformad.<br />
Eftersom detta inte var <strong>med</strong> i den formulerade kravspecifikationen fattades beslutet att inte<br />
implementera mikrosteg i prototypen, men förutsättningarna finns i alla fall att <strong>med</strong> relativt<br />
små ingrepp att implementera mikrosteg.<br />
Tangentbordet<br />
Ett av kraven var att <strong>med</strong> hjälp av ett tangentbord kunna mata in numeriska värden för att<br />
styra motorn. Ett upphittat alfanumeriskt tangentbord passade perfekt för den uppgiften, se<br />
bild 12 och 14.<br />
För att slippa att ha lika många pinnar ut på tangentbordet som det finns tangenter, använder<br />
de flesta tangentbord en speciell teknik. Tekniken går ut på att istället ha knapparna ordnat i<br />
ett rutnät, där varje pinne motsvarar en rad eller kolumn. Tangenterna fungerar som brytare<br />
mellan raderna och kolumnerna. Om exempelvis knapp 1 trycks ner kommer rad 1 och<br />
kolumn 1 att kopplas samman.<br />
17
Bild 12. Det valda tangentbordet.<br />
Bild 13. En möjlig inkoppling till AVRen.<br />
Lägg märke till rutnätet i tangentbordet.<br />
©2001-2010 by Gerhard Schmidt<br />
Inkopplingen mot mikrokontrollern skedde genom att i en loop jorda<br />
kolumnerna 1 till 3 en och en samtidigt som samtliga rader blev<br />
ettställa <strong>med</strong> hjälp av mikrokontrollerns interna pullup. Om en<br />
tangent trycks ner samtidigt som dess kolumn är nollställd kommer<br />
även motsvarande rad att nollställas. Genom att ha koll på vilka<br />
kolumner och rader som är ettställda respektive nollställda går det<br />
att räkna ut vilken tangent som har blivit nedtryckt.<br />
Eftersom tangentbordet saknade datablad identifierades vilken pinne<br />
som går till vad <strong>med</strong> hjälp av en multimeter, se tabell 4. Pinnarna<br />
kopplades till port B på mikrokontrollern. därefter räknades det ut<br />
vilket värde på port B som varje tangent motsvarar. Då detta<br />
skiljer sig mellan tangentbord skrevs dessa värden in som<br />
definitioner, som lätt kan bytas ut, i en header-fil.<br />
Bild 14. Tangentbordets<br />
numrerade utgångar.<br />
18
Pinne på tangentbordet Funktion Kopplad till pinne på mikrokontroller<br />
0 Rad 2 (4, 5, 6) PA0<br />
1 Rad 3 (7, 8, 9) PA1<br />
2 Kolumn 3 (3, 6, 9, #) PA4<br />
3 Rad4 (#, 0, *) PA2<br />
4 Kolumn 1 (*, 7, 4, 1) PA5<br />
5 Rad 1 (1, 2, 3) PA3<br />
6 Kolumn 2 (2, 5, 8 0) PA6<br />
Tabell 4. Identifiering över vilka pinnar på tangentbordet som går vart och hur de är<br />
kopplade till kontrollern.<br />
Potentiometern<br />
För att kunna studera hur motorn stegar sig fram när vinkeländringen styrs av tangentbordet,<br />
anslöts en skjutpotentiometer för att steglöst kunna justera hastigheten. Det bedömdes att en<br />
8-bitars AD-omvandling var fullt tillräckligt.<br />
Bild 15. Den valda skjutpotentiometern ansluten till den färdiga prototypen.<br />
Mikrokontrollern<br />
För att kunna styra samtliga moduler och logik krävs det någon form av mikrokontroller eller<br />
dator. Eftersom kursen huvudsakligen har behandlat grundläggande kunskaper om Atmels 8bitars<br />
mikrokontroller från ATMega-serien, var denna det självklara valet att börja arbeta<br />
<strong>med</strong>. Mikrokontrollern ATMega16 visade sig vara fullt tillräcklig då det inbyggda minnet på<br />
19
16 kB rymde programmet samtidigt som antalet analoga och digitala utgångar, timers och<br />
interrupts räckte till.<br />
Bild 16. Schematisk skiss över<br />
mikrokontrollerns utgångar.<br />
Bilden är tagen från Atmel.<br />
Spänningsregulatorn<br />
Bild 17. Taget foto över den valda<br />
mikrokontrollern.<br />
Både kontrollern och motordrivarens logik kräver ström <strong>med</strong> rätt spänning för att fungera.<br />
Eftersom mikrokontrollern maximalt kan matas <strong>med</strong> 5,5 V och motordrivaren <strong>med</strong> 7 V valdes<br />
5 V som ett lämpligt värde. Eftersom det inte är helt säkert att alla spänningskällor är<br />
reglerade togs beslutet att använda en spänningsregulator.<br />
Spänningsregulatorn TS7805, se bilaga, valdes då den reglerar ingående spänning till 5 V och<br />
kräver relativt få komponenter. Som underlag för komponentval och kopplingsschema<br />
användes ett kopplingsschema från en tidigare övning gjord under kursens gång, (NI Design<br />
Suite Lathund / AK) .<br />
20
Bild 18. Spänningsregulatorn och tillhörande komponenter <strong>med</strong> mikrokontrollern i<br />
bakgrunden.<br />
Mjukvara<br />
För att mikrokontrollern ska fungera måste den självklart även programmeras. Eftersom<br />
grundkursen hittills endast har behandlat AVR-programmering <strong>med</strong> språket C och<br />
programmeringskunskaperna i lågnivåspråket Assembler var väldigt begränsade, fattades<br />
beslutet att skriva programmen till mikrokontrollern i språket C.<br />
Experimentkortet och programmeraren STK 500 användes för att programmera kontrollern då<br />
den klarar ISP (in circuit programming). Det <strong>med</strong>följande programmet AVR studio 4 från<br />
Atmel användes som utvecklingsmiljö. Med WinAVR som kompilator.<br />
Programmet är uppbyggt kring ett huvudprogram som i en evighetsloop växlar mellan de fyra<br />
olika efterfrågade lägena. Växlingen av program och steglägena sker genom två externa<br />
interrupts. Ett separat program skrevs för inmatning från tangentbordet.<br />
Läge 1-Stega motorn <strong>med</strong> hjälp av ett tangentbord<br />
Detta löstes genom att anropa inmatningsfunktionen som registrerar och sparar intryckta<br />
tangenter i en variabel av typen ”double”. Om man trycker på fyrkant returnerar funktionen<br />
variabeln.<br />
21
Läge2-Kontinuerlig drift.<br />
Här användes istället en 16-bitars timer <strong>med</strong> intern interrupt där interrupflaggan bestäms av<br />
inmatningsfunktionen.<br />
Läge3-musik<br />
Det bestämdes att göra ett läge där stegmotorn kan ”spela” toner genom att den stegas så pass<br />
fort att istället för att börja snurra börjar den vibrera och där<strong>med</strong> även ger ifrån sig en<br />
fyrkantsliknande ton. Detta ska kunna styras genom att knapparna på tangentbordet ska<br />
motsvara de vita tangenterna på ett piano.<br />
Även här användes samma timer som i läge 2. Genom att ta hänsyn till kontrollerns<br />
klockfrekvens på 8 MHz och en prescaler på 1 räknades ett värde ut vad interruptflaggan<br />
måste vara på för att få A-ton på 440 Hz, denna användes som grundton för att generera<br />
resterande toner. En oktav på ett piano består av 12 svarta och vita tangenter där den<br />
multiplicerande faktorn mellan varje hopp är lika stort mellan varje tangent. Då frekvensen<br />
ökar <strong>med</strong> en faktor 2 för varje oktav innebär detta innebär att frekvensen skiljer sig <strong>med</strong> en<br />
faktor 2 mellan varje tangetsteg.<br />
Bild 19. Schematisk bild över en oktav från ett piano och faktorn som varje tangent skiljer sig<br />
från grundtangenten A (till vänster). Bild tagen och ändrad från Wikipedia.<br />
Prototypen<br />
När samtliga moduler blivit bestämda och testade skapades en prototyp på ett experimentkort.<br />
För att ha möjligheten att kunna byta ut motordrivaren mot någon annan fattades beslutet att<br />
22
göra motordrivkretsen till separat enhet som sedan kan styras av mikrokontrollern från ett<br />
annat kretskort. Denna lösning gjorde även testning och utveckling av resten av<br />
komponenterna enklare då en redan färdig motordrivare kunde användas. Resten av<br />
modulerna monterades på samma kort som mikrokontrollern, dessutom lades två knappar för<br />
meny och stegval dit och lysdioder för att visa vilka val som har gjorts.<br />
Bild 20. Den färdiga prototypen, <strong>med</strong> samtliga moduler inkopplade.<br />
23
Slutsats och Diskussion<br />
Möjliga Förbättringar<br />
Efter att ha färdigställt prototypen finns några möjliga förbättringar som skulle kunna göras<br />
om mer tid skulle finnas.<br />
Mikrosteg – Trots att tredjedelssteg används rör sig stegmotorn fortfarande lite hackigt vid<br />
lägre hastigheter. Om mikrosteg skulle implementeras måste en funktion skrivas för att kunna<br />
skapa en sinussignal, lämpligtvis <strong>med</strong> hjälp utav PWM och en interrupttimer.<br />
Prototypen – Eftersom målet var att kunna demonstrera att det är möjligt att uppfylla<br />
kravspecifikationen lades inte så mycket tid ner på att få en ren och fin prototyp, om en andra<br />
version skulle tillverkas skulle den både kunna etsats och ha kontakter för knapparna och<br />
lysdioderna för att kunna bygga in den i en låda.<br />
Tangentbordet – Den nuvarande lösningen, där tangentbordets knappar är hårdkodade i en<br />
header-fil, är en ganska tidsödande lösning. Eventuellt skulle ett identifieringsprogram kunna<br />
skrivas där man i tur och ordning trycker på knapparna för att programmera in deras värde.<br />
Erfarenheter<br />
Projektets mål har varit att förstå hur en stegmotor fungerar och att därefter kunna<br />
implementera den kunskapen i en prototyp. Eftersom den färdiga prototypen uppfyller de<br />
tidigare uppsatta kraven görs bedömningen att projektets mål har blivit uppfyllda.<br />
Erfarenheter från detta projekt är att saker och ting som vanligt tar längre tid att göra än vad<br />
man från början tror. Sedan har man varit tvungen att läsa in sig på hur varje komponent och<br />
modul fungerar, förstå databladens oftast väldigt kortfattade tekniska jargong, att kunna inse<br />
både möjligheterna och begränsningarna och slutligen kunna använda sig av den kunskapen<br />
för att skapa något annat. Detta har varit väldigt bra att göra eftersom i verkligheten finns det<br />
oftast ingen lärare som man kan fråga utan det gäller att kunna lösa problemet själv.<br />
Ett exempel var användningen av tangentbordet, denna modul visade sig svårare att använda<br />
än förväntat, men genom både infosökning och experimenterande kunde modulen till slut<br />
behärskas. Detta gav även en djupare insikt om hur vanliga tangentbord fungerar.<br />
24
Referenser<br />
Källor<br />
Wikipedia, Brushed DC electric motor, 20/3-2011<br />
http://en.wikipedia.org/wiki/Brushed_DC_electric_motor<br />
Wikipedia, Stepper motor, 20/3-2011<br />
http://en.wikipedia.org/wiki/Stepper_motor<br />
Industrial Circuits Application Note, Stepper Motor Basics, 20/3-2011<br />
http://www.solarbotics.net/library/pdflib/pdf/motorbas.pdf<br />
Wikipedia, Reluctance motor, 22/3-2011<br />
http://en.wikipedia.org/wiki/Reluctance_motor).<br />
All About Circuits, Reluctance motor, 22/3-2011<br />
http://www.allaboutcircuits.com/vol_2/chpt_13/4.html<br />
All About Circuits, Stepper motors, 20/3-2011<br />
http://www.allaboutcircuits.com/vol_2/chpt_13/5.html<br />
Piclist.com, Driving Bipolar Stepper Motors, 24/3-2011<br />
http://www.piclist.com/techref/piclist/jal/DrivingBipolarStepperMotors.htm)<br />
Wikipedia, Low-pass filter, 24/3-2011<br />
http://en.wikipedia.org/wiki/Low-pass_filter<br />
StepperWorld.com, Stepper Motors and Control, 24/3-2011<br />
http://www.stepperworld.com/Tutorials/pgMicrostepping.htm<br />
Bilder<br />
Bilder som inte är källhänvisade är antingen producerade eller tagna av artikelförfattaren.<br />
Bild 1. Wikipedia, Brushed DC electric motor, 20/3-2011<br />
http://en.wikipedia.org/wiki/Brushed_DC_electric_motor<br />
25
Bild 2. Wikipedia, Stepper motor, 20/3-2011<br />
http://en.wikipedia.org/wiki/Stepper_motor<br />
Bild 13. Avr-asm-tutorial.net, Connecting a keypad to an AVR, 24/3-2011<br />
http://www.avr-asm-tutorial.net/avr_en/keypad/keyboard.html<br />
Med uttalad tillåtelse från upphovsmannen förutsatt att även copyrightinformationen tas <strong>med</strong>.<br />
Bild 16. Databladet från Atmel.<br />
Bild 19. Wikipedia, Musical keyboard,, 26/3-2011<br />
http://en.wikipedia.org/wiki/Musical_keyboard<br />
26
Bilagor<br />
Komponentlista<br />
Komponent Antal (st) Ca pris. (kr/st)<br />
Resistor 10 kΩ 4 0,25<br />
Resistor 30 kΩ 3 0,25<br />
Resistor 1 kΩ 7 0,25<br />
Resistor 0,82 Ω 2 5<br />
Resistor 56 kΩ 2 0,25<br />
Kondensator 0,1 µF 2 2<br />
Kondensator 10 µF 1 5<br />
Kondensator 100 µF 2 5<br />
Kondensator 820 pF 2 2<br />
Kondensator 1 nF 2 2<br />
Spänningsregulator LM7805 1 10<br />
Tryckknapp 2 5<br />
LED 7 2<br />
Skjutpotentiometer 10kΩ 1 30<br />
ATMega16 1 40<br />
Motordrivare 2916 1 50<br />
Stegmotor 1 500 (osäkert värde)<br />
Tangentbord 1 100<br />
Experimentkort 1 50<br />
Kablar, kontakter, lödtenn, etc -- 50<br />
Total kostnad: ca 900 kr. Vad man måste ta hänsyn till är att vissa av komponenterna<br />
antagligen är återvunna delar som inte har inneburit någon direkt kostnad.<br />
27
Kopplingsschema<br />
Mikrokontrollern (Bättre bild finns i slutet)<br />
28
Motordrivaren (Bättre bild finns i slutet)<br />
29
Flödesschema<br />
Huvudprogrammet<br />
Start<br />
Nej<br />
Nej<br />
State=0?<br />
State=1?<br />
State=2?<br />
Nej<br />
Läge 3 –<br />
Musikläge<br />
Ja<br />
Ja<br />
Ja<br />
Läge 0 - Paus<br />
Läge 1 – mata in<br />
hur mycket<br />
motorn ska vrida<br />
sig<br />
Nej<br />
State<br />
ändrad?<br />
Läge 2 –<br />
Kontinuerlig drift,<br />
mata in hur fort<br />
motorns ska röra<br />
sig.<br />
Nej<br />
State<br />
ändrad?<br />
Ja<br />
Ja<br />
30
Interruptrutiner<br />
Extern interrupt 0<br />
state=state+1<br />
State=4?<br />
state=0<br />
Ja<br />
Extern interrupt 1<br />
stegläge= stegläge +1<br />
stegläge =4?<br />
stegläge =0<br />
Ja<br />
31
C:\Documents and Settings\mazda\My Documents\Stegmotor16\Stegmotor.h<br />
#ifndef STEGMOTOR__H<br />
#define STEGMOTOR__H<br />
#define F_CPU 8000000<br />
#include <br />
#include <br />
#include <br />
volatile int state;<br />
extern int knapptryck(void);<br />
extern double inmatning(void);<br />
#endif<br />
Page: 1
C:\Documents and Settings\mazda\My Documents\Stegmotor16\keyboard.h<br />
#ifndef KEYBOARD__H<br />
#define KEYBOARD__H<br />
#define TGB0 59 // Definerar vad varje kod från tangentborde innebär.<br />
#define TGB1 87 //<br />
#define TGB2 55 //<br />
#define TGB3 103<br />
#define TGB4 94<br />
#define TGB5 62<br />
#define TGB6 110<br />
#define TGB7 93<br />
#define TGB8 61<br />
#define TGB9 109<br />
#define TGBfyr 107<br />
#define TGBstj 91<br />
#endif<br />
Page: 1
C:\Documents and Settings\mazda\My Documents\Stegmotor16\Stegmotor.c<br />
#include "Stegmotor.h"<br />
int Allstep[3][24] = {{0x0F, 0x0F,0x2B, 0x2B,0x1D, 0x1D,0x31, 0x31,0x15, 0x15,0x23, 0x2<br />
3,0x06, 0x06,0x22, 0x22,0x14, 0x14,0x38, 0x38,0x1C, 0x1C,0x2A, 0x2A},<br />
{0x0F, 0x0F, 0x0F,0x2D, 0x2D,0x2D, 0x31, 0x31,0x31,0x25, 0x25,0x25,0x06, 0x06,0x06,<br />
0x24, 0x24,0x24,0x38, 0x38,0x38,0x2C, 0x2C, 0x2C},<br />
{0x0F,0x0F,0x0F, 0x0F,0x0F,0x0F, 0x31,0x31,0x31, 0x31,0x31,0x31,0x06, 0x06, 0x06,<br />
0x06, 0x06, 0x06,0x38, 0x38, 0x38,0x38, 0x38, 0x38}};//Sparar de tre steglägena i en st<br />
egmatris. 24 är den minsta gemensamma nämnaren.<br />
unsigned int step=0; //För Timer 1. Håller koll på var i stegvektorn man är.<br />
int motsatt=0; //Håller koll på riktningen som motorn snurrar åt. Används i Timer 1. st<br />
älls i inmatning.<br />
volatile int stepmode=0; //stegsätt, 0=12-steg. 1=8-steg, 2=4-steg. Interrupt 2.<br />
ISR(SIG_OUTPUT_COMPARE1A){<br />
if (motsatt==1){<br />
PORTB=Allstep[stepmode][step];<br />
}else{PORTB=Allstep[stepmode][23-step];<br />
}<br />
step++;<br />
if (step==24)<br />
step=0;<br />
}<br />
ISR(SIG_INTERRUPT1){ //växlar state<br />
state++;<br />
if (state==4){<br />
state=0;<br />
}<br />
PORTC|=0x0F; //Ändrar Lysdioder som indikerar menyval<br />
if (state == 0){<br />
PORTC&=~8;<br />
}else if(state==1){<br />
PORTC&=~1;<br />
}else if(state==2){<br />
PORTC&=~2;<br />
}else{<br />
PORTC&=~4;<br />
}<br />
}<br />
ISR(SIG_INTERRUPT0){ //växlar mellan 4,8-och 12-steg<br />
stepmode++;<br />
if(stepmode==3){<br />
stepmode=0;<br />
}<br />
}<br />
PORTC|=0xF0;<br />
if(stepmode==0){ //Ändrar Lysdioder som indikerar stegval<br />
PORTC&=~32;<br />
}else if(stepmode==1){<br />
PORTC&=~64;<br />
}else{<br />
PORTC&=~128;<br />
}<br />
int main(void){<br />
double vinkel=0;<br />
int j=0;<br />
state = 0; //Menyval<br />
DDRA=0x70; //Tangentbord och potentiometer<br />
DDRD=0x00; //Används av de externa interrupterna<br />
DDRC=0xFF; //Lysdioder<br />
DDRB=0xFF; //Utgång till H-brygga<br />
PORTA=0x0F; //Íntern Pullup<br />
PORTD=0xFF;<br />
Page: 1<br />
PORTC=~0x00;<br />
PORTC&=~8; //Tänder lysdioderna för att visa vad startvärdena är.<br />
PORTC&=~128;
C:\Documents and Settings\mazda\My Documents\Stegmotor16\Stegmotor.c<br />
igt<br />
Page: 2<br />
MCUCR|=0x0A; //Konfigurera interrupten,<br />
GICR|=0xC0; //Lokal enable INT0<br />
TCCR1A=0x00; //Timer 1<br />
TCCR1B=0x09;<br />
OCR1A=20;<br />
TIMSK|=0x00; //Timer disable<br />
sei(); //Global enable<br />
ADMUX = 0x27; //00100111 porta7<br />
while(1){<br />
int adcdata;<br />
ADCSRA = 0xC0; //11000000<br />
adcdata = ADCH;<br />
if (state==0){ //MENYVAL 0: Paus<br />
TIMSK=0x00;<br />
PORTB=0x7F; //allt avstängt<br />
}else if (state == 1){ //MENYVAL 1: styra vridningen <strong>med</strong> tangentbord<br />
TIMSK=0x00; //timer disable<br />
double konst=360/5;<br />
int steg = 23;<br />
double inmatadvinkel=inmatning();<br />
vinkel=inmatadvinkel*10/konst;<br />
if (vinkel0; i=i){<br />
ADCSRA = 0xC0; //11000000<br />
adcdata = ADCH;<br />
if (steg >0){<br />
PORTB=Allstep[stepmode][steg-j];<br />
}else{<br />
PORTB=Allstep[stepmode][j];<br />
}<br />
j++;<br />
i--;<br />
if (adcdata>0){<br />
_delay_ms(adcdata/4);<br />
}else{<br />
_delay_us(400);<br />
}<br />
if (j==24){<br />
j=0;<br />
}<br />
if(state_before!=state){<br />
break;<br />
}<br />
}<br />
}else if(state==2){ //MENYVAL 2 : Motorn snurrar kontinuerl<br />
TCCR1B=0x0C; //ändrar prescaler till 256<br />
TIMSK=0x10; //Timer enable<br />
double intryckt = inmatning();<br />
if (intryckt!=0){<br />
if (intryckt65535){ //Maxgräns för timer2.<br />
intryckt = 65535;
C:\Documents and Settings\mazda\My Documents\Stegmotor16\Stegmotor.c<br />
}<br />
OCR1A=intryckt*5.2; //Vill att det det man matar in ska vara delayen me<br />
llan varje helsteg<br />
//En frekvens på 8 MHz prescaler på 256 och 6 st upprepning<br />
ar för 4-steg. Ger en faktor på 5.2.<br />
}<br />
}<br />
}<br />
}<br />
Page: 3<br />
}else if(state==3){ //MENYVAL 3:Musikläge<br />
TCCR1B=0x09; //Ändrar prescaler till snabbaste<br />
int tonerPot[]={0, 2, 3, 5, 7, 8, 10, 12, 14}; //Potenserna för tonerna.<br />
double Grundton= 379;<br />
signed int intryckt = knapptryck();<br />
if (intryckt>0 && intryckt
C:\Documents and Settings\mazda\My Documents\Stegmotor16\keyboard.c<br />
#include "Stegmotor.h"<br />
#include "keyboard.h" //Drivrutinerna för tangentbordet<br />
int knapp;<br />
double vinkel=0;<br />
int j=0;<br />
extern int knapptryck(void){<br />
knapp = -1; //retunderar -1 om ingen tangent är nedtryckt<br />
PORTA=0x5F; //Kolumn 1 aktiverad<br />
_delay_ms(5);//Kort delay för att det ska hinna att komma spänning raden. Utan dela<br />
y fungerar tangentbordets översta rad konstigt.<br />
if ((PINA&0x7F)==TGB1)//Om nedtryck och där<strong>med</strong> jordad<br />
knapp=1;<br />
else if ((PINA&0x7F)==TGB4)//Om nedtryck och där<strong>med</strong> jordad<br />
knapp=4;<br />
else if ((PINA&0x7F)==TGB7)<br />
knapp=7;<br />
else if ((PINA&0x7F)==TGBstj)<br />
knapp=128;<br />
PORTA=0x3F; //Kolumn 2 aktiverad<br />
_delay_ms(5);<br />
if ((PINA&0x7F)==TGB2)//Om nedtryck och där<strong>med</strong> jordad<br />
knapp=2;<br />
else if ((PINA&0x7F)==TGB5)//Om nedtryck och där<strong>med</strong> jordad<br />
knapp=5;<br />
else if ((PINA&0x7F)==TGB8)<br />
knapp=8;<br />
else if ((PINA&0x7F)==TGB0)<br />
knapp=0;<br />
PORTA=0x6F; //Kolumn 3 aktiverad<br />
_delay_ms(5);<br />
if ((PINA&0x7F)==TGB3)//Om nedtryck och där<strong>med</strong> jordad<br />
knapp=3;<br />
else if ((PINA&0x7F)==TGB6)<br />
knapp=6;<br />
else if ((PINA&0x7F)==TGB9)<br />
knapp=9;<br />
else if ((PINA&0x7F)==TGBfyr)<br />
knapp=64; //fyrkant<br />
return knapp;<br />
}<br />
extern double inmatning(void){<br />
int intryckt = knapptryck();<br />
//int i=0;<br />
double registrering = 0;<br />
int riktning = 1;<br />
int state_before = state; //Kollar om staten byts i interupen.<br />
while(intryckt !=64){ //En evighetsslinga som hela tiden tar emot nya kna<br />
pptryck. Avbryts genom att man trycke på fyrkant.<br />
if (state_before !=state){ //Kollar om staten byts i interupen.<br />
break;<br />
}<br />
intryckt=knapptryck();<br />
Page: 1<br />
if (intryckt !=-1 && intryckt!=64){<br />
}<br />
if(intryckt==128){ //Om man har tryckt på minus.<br />
riktning=-1*riktning;<br />
}else{<br />
registrering = registrering*10;<br />
registrering = registrering + intryckt;<br />
}<br />
while (knapptryck()==intryckt){} //Väntar på knappsläpp<br />
_delay_ms(20); //mot knappstuds.<br />
}<br />
if (riktning>0){
C:\Documents and Settings\mazda\My Documents\Stegmotor16\keyboard.c<br />
}<br />
Page: 2<br />
return (registrering);<br />
}else{<br />
return (-1*registrering);<br />
}
0<br />
0<br />
1<br />
1<br />
2<br />
2<br />
3<br />
3<br />
4<br />
A A<br />
GND<br />
Motordrivare<br />
B B<br />
C<br />
D<br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
10<br />
11<br />
12<br />
13<br />
14<br />
15<br />
16<br />
17<br />
18<br />
19<br />
20<br />
PB0<br />
PB1<br />
PB2<br />
PB3<br />
PB4<br />
PB5(MOSI)<br />
PB6(MISO)<br />
PB7(SCK)<br />
Reset<br />
VCC<br />
GND<br />
XTAL2<br />
XTAL1<br />
PD0(RXD)<br />
PD1(TXD)<br />
PD2(INT0)<br />
PD3(INT1)<br />
PD4(OC1B)<br />
PD5(OC1A)<br />
PD6(ICP1) PD7(OC2)<br />
C<br />
D<br />
21<br />
PC0 22<br />
PC1 23<br />
PC2 24<br />
PC3 25<br />
PC4 26<br />
PC5 27<br />
PC6 28<br />
PC7 29<br />
AVCC 30<br />
GND2 31<br />
AREF 32<br />
PA7(ADC7) 33<br />
PA6(ADC6) 34<br />
PA5(ADC5) 35<br />
PA4(ADC4) 36<br />
PA3(ADC3) 37<br />
PA2(ADC2) 38<br />
PA1(ADC1) 39<br />
PA0(ADC0) 40<br />
HDR1X8<br />
VCC R6<br />
5V 30kΩ<br />
R4<br />
30kΩ<br />
R5<br />
30kΩ<br />
R1<br />
10kΩ<br />
R2<br />
10kΩ<br />
R3 HDR1X8<br />
10kΩ<br />
LED1<br />
LED5<br />
E VCC<br />
Key = A<br />
E<br />
J2<br />
U2<br />
LM7805CT<br />
GND<br />
5V<br />
C3 C1<br />
C2 C4<br />
F<br />
HDR1X2<br />
100µF 0.1µF<br />
0.1µF 10µF<br />
LED3<br />
LED7<br />
F<br />
GND<br />
4<br />
J4<br />
Key = A<br />
U1<br />
5<br />
R8<br />
10kΩ<br />
Key=A<br />
ATMega16<br />
J3<br />
5<br />
40%<br />
VCC<br />
GND<br />
5V<br />
6<br />
6<br />
LED4<br />
LED2<br />
7<br />
7<br />
R7<br />
200 Ω<br />
8<br />
8<br />
LED6<br />
J1<br />
9<br />
9
0<br />
0<br />
1<br />
1<br />
2<br />
2<br />
3<br />
3<br />
4<br />
4<br />
5<br />
5<br />
6<br />
6<br />
7<br />
7<br />
8<br />
8<br />
9<br />
9<br />
A A<br />
B B<br />
C C<br />
D D<br />
E E<br />
F F<br />
U1<br />
2916<br />
OUT_1A<br />
OUT_2A<br />
E_2<br />
Sense_2<br />
OUT_2B<br />
GND<br />
GND<br />
I_02<br />
I_12<br />
PHASE_2<br />
V_REF2<br />
RC_2 Vcc<br />
RC_1<br />
V_REF1<br />
PHASE_1<br />
I_11<br />
GND<br />
GND<br />
I_01<br />
OUT_1B<br />
SENSE_1<br />
E_1<br />
LOAD_SUPPLY<br />
R1<br />
0.82Ω<br />
C1<br />
1nF<br />
C2<br />
820pF<br />
C3<br />
820pF<br />
R2<br />
56kΩ<br />
R3<br />
56kΩ<br />
Mikrokontroller<br />
HDR1X8<br />
GND<br />
VCC<br />
5V<br />
V_Motor<br />
HDR1X2<br />
Motor<br />
HDR1X4<br />
R4<br />
1kΩ<br />
GND<br />
GND<br />
GND<br />
R5<br />
0.82Ω<br />
C4<br />
1nF<br />
R6<br />
1kΩ<br />
GND<br />
GND<br />
GND<br />
GND GND<br />
VCC<br />
5V<br />
VCC<br />
5V<br />
C5<br />
100µF
Recommended Substitutions:<br />
Dual Full-Bridge PWM Motor Driver<br />
This device is in production, however, it has been dee<strong>med</strong> Pre-End<br />
of Life. The product is approaching end of life. Within a minimum of<br />
6 months, the device will enter its final, Last Time Buy, order phase.<br />
Date of status change:<br />
UDN2916B-T, UDN2916EBTR-T: November 1, 2010<br />
UDN2916LBTR-T, UDQ2916LBTR-T: January 31, 2011<br />
For existing customer transition, and for new customers or new applications,<br />
contact Allegro Sales.<br />
NOTE: For detailed information on purchasing options, contact your<br />
local Allegro field applications engineer or sales representative.<br />
2916<br />
Allegro MicroSystems, Inc. reserves the right to make, from time to time, revisions to the anticipated product life cycle plan<br />
for a product to accommodate changes in production capabilities, alternative product availabilities, or market demand. The<br />
information included herein is believed to be accurate and reliable. However, Allegro MicroSystems, Inc. assumes no responsibility<br />
for its use; nor for any infringements of patents or other rights of third parties which may result from its use.
Features and Benefits<br />
750 mA continuous output current<br />
45 V output sustaining voltage<br />
Internal clamp diodes<br />
Internal PWM current control<br />
Low output saturation voltage<br />
Internal thermal shutdown circuitry<br />
Similar to dual PBL3717 or UC3770<br />
Packages<br />
Package B 24-pin<br />
Batwing DIP<br />
Package LB 24-pin<br />
Batwing SOICW<br />
Package EB 44-pin PLCC<br />
with internally-fused leads<br />
29319.20R<br />
Not to scale<br />
'B' PACKAGE,<br />
CHANNEL 1<br />
PIN NUMBERS<br />
SHOWN.<br />
I 20<br />
0<br />
I 1<br />
17<br />
VREF 15<br />
40 k<br />
Dual Full-Bridge PWM Motor Driver<br />
Description<br />
The UDx2916 motor drivers drive both windings of a bipolar<br />
stepper motor or bidirectionally control two DC motors.<br />
Both bridges are capable of sustaining 45 V and include<br />
internal pulse-width modulation (PWM) control of the<br />
output current to 750 mA. The outputs have been optimized<br />
for a low output saturation voltage drop (less than 1.8 V<br />
total source plus sink at 500 mA).<br />
For PWM current control, the maximum output current is<br />
determined by user selection of a reference voltage and sensing<br />
resistor. Two logic-level inputs select output current limits of<br />
0%, 33%, 67%, or 100% of the maximum level. A PHASE<br />
input to each bridge determines load current direction.<br />
The bridges include both ground-clamp and flyback diodes for<br />
protection against inductive transients. Internally generated<br />
delays prevent crossover currents when switching current<br />
direction. Special power-up sequencing is not required. Thermal<br />
protection circuitry disables the outputs if the chip temperature<br />
exceeds safe operating limits.<br />
The device is supplied in a 24-pin dual in-line plastic (DIP,<br />
package B) with two pairs of batwing leads as heat-sinkable<br />
tabs for enhanced power dissipation capabilities. The LB<br />
package is a 24-lead surface-mount wide SOIC with two pairs<br />
Continued on the next page…<br />
PWM Current-Control Circuitry<br />
20 k<br />
10 k<br />
1<br />
OUT A<br />
10<br />
R S<br />
V BB<br />
24<br />
23<br />
E<br />
OUTB 21<br />
R C<br />
SENSE<br />
22<br />
–<br />
+<br />
C C<br />
R T<br />
ONE<br />
SHOT<br />
14 RC<br />
C T<br />
SOURCE<br />
DISABLE<br />
Dwg. EP-007B<br />
2916
2916<br />
Description (continued)<br />
of batwing leads. The EB package is a 44-lead power PLCC with 11<br />
internally-fused leads on two sides. Their webbed-lead construction<br />
provides for maximum package power dissipation in the smallest<br />
possible construction.<br />
The devices are available for operation from –20°C to 85°C (range N),<br />
and from –40°C to 105°C (range Q). All packages are lead (Pb) free,<br />
with 100% matte tin leadframe plating.<br />
Selection Guide<br />
Part Number Package Packing<br />
UDN2916B-T 1 24-pin batwing DIP 15 per tube<br />
Dual Full-Bridge Motor Driver<br />
Ambient Temperature<br />
(°C)<br />
UDN2916EBTR-T –20 to 85<br />
1 44-pin internally fused lead PLCC 450 per reel<br />
UDN2916LBTR-T2 24-pin batwing SOICW 1000 per reel<br />
UDQ2916LBTR-T2 24-pin batwing SOICW 1000 per reel –40 to 105<br />
1This variant is in production, however, it has been dee<strong>med</strong> Pre-End of Life. The product is approaching end of life. Within<br />
a minimum of 6 months, the device will enter its fi nal, Last Time Buy, order phase. Status change: November 1, 2010.<br />
2This variant is in production, however, it has been dee<strong>med</strong> Pre-End of Life. The product is approaching end of life. Within<br />
a minimum of 6 months, the device will enter its fi nal, Last Time Buy, order phase. Status change: January 31, 2011.<br />
Absolute Maximum Ratings<br />
Characteristic Symbol Notes Rating Units<br />
Motor Supply Voltage VBB 45 V<br />
Logic Supply Voltage VCC 7.0 V<br />
Input Voltage VIN –0.3 to VCC + 0.3 V<br />
Output Emitter Voltage VE 1.5 V<br />
Output Current* I OUT<br />
Peak Output current rating may be limited by duty<br />
cycle, ambient temperature, and heat sinking.<br />
Under any set of conditions, do not exceed the<br />
1.0 A<br />
Continuous specified current rating or TJ (max)<br />
750 mA<br />
Package Power Dissipation PD See graph — W<br />
Operating Ambient Temperature TA Range N<br />
Range Q<br />
–20 to 85<br />
–40 to 105<br />
ºC<br />
ºC<br />
Maximum Junction Temperature TJ(max) 150 ºC<br />
Storage Temperature Tstg –55 to 150 ºC<br />
Allegro MicroSystems, Inc.<br />
115 Northeast Cutoff, Box 15036<br />
Worcester, Massachusetts 01615-0036 (508) 853-<br />
5000<br />
www.allegromicro.com<br />
2
2916<br />
GND<br />
GND<br />
7<br />
8<br />
9<br />
10<br />
11<br />
12<br />
13<br />
14<br />
15<br />
I<br />
02<br />
I<br />
12<br />
PHASE 2<br />
V REF 2<br />
RC 2<br />
GROUND<br />
GROUND<br />
LOGIC SUPPLY<br />
RC 1<br />
V REF 1<br />
PHASE 1<br />
I 11<br />
OUT 1A<br />
6<br />
18<br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
10<br />
11<br />
12<br />
5<br />
19<br />
1<br />
2<br />
V CC<br />
1<br />
4<br />
20<br />
3<br />
2<br />
21<br />
PWM 2<br />
PWM 1<br />
V BB<br />
2<br />
22<br />
1<br />
23<br />
2<br />
1<br />
44<br />
24<br />
43<br />
PWM 1<br />
16<br />
PWM 2<br />
30<br />
17 29<br />
OUT 2A<br />
E 1<br />
NO CONNECTION<br />
EB Package (PLCC)<br />
SENSE 1<br />
E 2<br />
OUT 1B<br />
SENSE 2<br />
VBB<br />
LOAD SUPPLY<br />
NC NC<br />
NO CONNECTION<br />
I 01<br />
OUT 2B<br />
I 11<br />
I 02<br />
PHASE 1<br />
1<br />
25<br />
I 12<br />
LB Package (SOIC)<br />
24<br />
23<br />
22<br />
21<br />
20<br />
19<br />
18<br />
17<br />
16<br />
15<br />
14<br />
13<br />
V REF 1<br />
42<br />
2<br />
26<br />
PHASE 2<br />
RC 1<br />
41<br />
27<br />
V REF 2<br />
LOAD SUPPLY<br />
OUT2B<br />
SENSE 2<br />
E2<br />
OUT 2A<br />
GROUND<br />
GROUND<br />
OUT1A<br />
E1<br />
SENSE 1<br />
OUT1B<br />
I 01<br />
LOGIC SUPPLY<br />
40<br />
VCC<br />
28<br />
RC 2<br />
Dwg. PP-047<br />
39<br />
38<br />
37<br />
36<br />
35<br />
34<br />
33<br />
32<br />
31<br />
GND<br />
GND<br />
Dwg. PP-006A<br />
ALLOWABLE PACKAGE POWER DISSIPATION IN WATTS<br />
5<br />
4<br />
3<br />
2<br />
1<br />
Dual Full-Bridge Motor Driver<br />
0<br />
25<br />
SUFFIX 'EB', R = 30°C/W<br />
JA<br />
SUFFIX 'LB', R JA = 55°C/W*<br />
R = 6.0°C/W<br />
JT<br />
SUFFIX 'B', R = 40°C/W<br />
JA<br />
50 75 100 125 150<br />
TEMPERATURE IN °C<br />
Dwg. GP-035B<br />
*Measured on a single-layer board, with 1 sq. in. of 2 oz copper area.<br />
For additional information, refer to the Allegro Web site.<br />
OUT1A<br />
OUT2A<br />
E 2<br />
SENSE 2<br />
OUT2B<br />
GROUND<br />
GROUND<br />
I<br />
02<br />
I<br />
12<br />
PHASE 2<br />
V REF 2<br />
RC 2<br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
10<br />
11<br />
12<br />
Power Dissipation<br />
B Package (DIP)<br />
2<br />
2<br />
PWM 2<br />
V BB<br />
1<br />
PWM 1<br />
1<br />
V CC<br />
24<br />
23<br />
22<br />
21<br />
20<br />
19<br />
18<br />
17<br />
16<br />
15<br />
14<br />
13<br />
LOAD<br />
SUPPLY<br />
E 1<br />
SENSE 1<br />
OUT1B<br />
I 01<br />
GROUND<br />
GROUND<br />
I<br />
11<br />
PHASE 1<br />
V REF 1<br />
RC 1<br />
LOGIC<br />
SUPPLY<br />
Dwg. PP-005<br />
Allegro MicroSystems, Inc.<br />
115 Northeast Cutoff, Box 15036<br />
Worcester, Massachusetts 01615-0036 (508) 853-<br />
5000<br />
www.allegromicro.com<br />
3
2916<br />
Dual Full-Bridge Motor Driver<br />
ELECTRICAL CHARACTERISTICS at TA = +25°C, TJ 150°C, VBB = 45 V, VCC = 4.75 V to 5.25<br />
V, VREF = 5.0 V (unless otherwise noted).<br />
Limits<br />
Characteristic Symbol Test Conditions Min. Typ. Max. Units<br />
Output Drivers (OUT A or OUT B )<br />
Motor Supply Range V BB 10 — 45 V<br />
Output Leakage Current I CEX V OUT = V BB — < 1.0 50 A<br />
V OUT = 0 —
2916<br />
PWM CURRENT CONTROL<br />
The UDx2916 dual bridges drive both windings of a bipolar<br />
stepper motor. Output current is sensed and controlled<br />
independently in each bridge by an external sense resistor, RS ,<br />
internal comparator, and monostable multivibrator.<br />
When the bridge is turned on, current increases in the motor<br />
winding and it is sensed by the external sense resistor until the<br />
sense voltage, VSENSE , reaches the level set at the comparator<br />
input:<br />
ITRIP = VREF /10 RS The comparator then triggers the monostable, which turns off<br />
the source driver of the bridge.<br />
The actual load current peak will be slightly higher than the<br />
trip point (especially for low-inductance loads) because of the<br />
internal logic and switching delays. This delay, td , is typically<br />
2 s. After turn-off, the motor current decays, circulating<br />
through the ground-clamp diode and sink transistor. The<br />
source driver off-time (and therefore the magnitude of the<br />
current decrease) is determined by the external RC timing<br />
components of the monostable:<br />
toff = RTCT where:<br />
RT = 20 to 100 k, and<br />
CT = 100 to 1000 pF.<br />
The xed off-time should be short enough to keep the current<br />
chopping above the audible range (< 46 s) and long enough<br />
to properly regulate the current. Because only slow-decay<br />
current control is available, short off times (< 10 s) require<br />
additional efforts to ensure proper current regulation. Factors<br />
that can negatively affect the ability to properly regulate the<br />
current when using short off times include: higher motorsupply<br />
voltage, light load, and longer than necessary blank<br />
time.<br />
When the source driver is re-enabled, the winding current (the<br />
sense voltage) is again allowed to rise to the comparator’s<br />
threshold. This cycle repeats itself, maintaining the average<br />
motor winding current at the desired level.<br />
Loads with high distributed capacitances may result in high<br />
turn-on current peaks. This peak (appearing across RS) will<br />
attempt to trip the comparator, resulting in erroneous current<br />
control or high-frequency oscillations. An external RCCC time delay should be used to further delay the action of the<br />
comparator. Depending on load type, many applications will<br />
not require these external components (SENSE connected to E).<br />
APPLICATIONS INFORMATION<br />
Dual Full-Bridge Motor Driver<br />
V PHASE<br />
I OUT<br />
+<br />
0<br />
–<br />
PWM OUTPUT CURRENT WAVE FORM<br />
LOAD CURRENT PATHS<br />
R S<br />
t d<br />
V<br />
BB<br />
I<br />
TRIP<br />
Dwg. WM-003-1A<br />
Allegro MicroSystems, Inc.<br />
115 Northeast Cutoff, Box 15036<br />
Worcester, Massachusetts 01615-0036 (508) 853-<br />
5000<br />
www.allegromicro.com<br />
t off<br />
BRIDGE ON<br />
SOURCE OFF<br />
ALL OFF<br />
Dwg. E P-006-1<br />
5
2916<br />
LOGIC CONTROL OF OUTPUT CURRENT<br />
Two logic level inputs (I0 and I1) allow digital selection of the motor<br />
winding current at 100%, 67%, 33%, or 0% of the maximum level per the<br />
table. The 0% output current condition turns off all drivers in the bridge and<br />
can be used as an OUTPUT ENABLE function.<br />
CURRENT-CONTROL TRUTH TABLE<br />
l 0 I 1 Output Current<br />
L L V REF /10 R S = I TRIP<br />
H L V REF /15 R S = 2/3 I TRIP<br />
L H V REF /30 R S = 1/3 I TRIP<br />
H H 0<br />
These logic level inputs greatly enhance the implementation of microprocessor<br />
controlled drive formats.<br />
During half-step operations, the I 0 and I 1 allow the microprocessor to<br />
control the motor at a constant torque between all positions in an eight-step se-<br />
FROM<br />
P<br />
V REF<br />
56 kΩ<br />
R T<br />
R S<br />
C C<br />
R C<br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
10<br />
11<br />
12<br />
820 pF<br />
C<br />
T<br />
TYPICAL APPLICATION<br />
θ 2<br />
2<br />
PWM 2<br />
V BB<br />
1<br />
PWM 1<br />
θ 1<br />
V CC<br />
24<br />
23<br />
22<br />
21<br />
20<br />
19<br />
18<br />
17<br />
16<br />
15<br />
14<br />
13<br />
R C<br />
+5 V<br />
R S<br />
C C<br />
V REF<br />
FROM<br />
P<br />
STEPPER<br />
MOTOR<br />
+<br />
820 pF 56 kΩ<br />
C<br />
T<br />
R<br />
T<br />
Dwg. EP-008B1<br />
Dual Full-Bridge Motor Driver<br />
V BB<br />
quence. This is accomplished by digitally selecting<br />
100% drive current when only one phase is on and<br />
67% drive current when two phases are on. Logic<br />
highs on both I 0 and I 1 turn-off all drivers to allow<br />
rapid current decay when switching phases. This<br />
helps to ensure proper motor operation at high step<br />
rates.<br />
The logic control inputs can also be used to<br />
select a reduced current level (and reduced power<br />
dissipation) for "hold" conditions and/or increased<br />
current (and available torque) for start-up conditions.<br />
GENERAL<br />
The PHASE input to each bridge determines<br />
the direction motor winding current ows. An internally<br />
generated dead time (approximately 2 s)<br />
prevents crossover currents that can occur when<br />
switching the PHASE input.<br />
All four drivers in the bridge output can be<br />
turned-off between steps (I0 = I1 2.4 V), resulting<br />
in a fast current decay through the internal<br />
output clamp and yback diodes. The fast current<br />
decay is desirable in half-step and high-speed applications.<br />
The PHASE, I0,and I1 inputs oat high.<br />
Varying the reference voltage, VREF , provides<br />
continuous control of the peak load current<br />
for micro-stepping applications.<br />
Thermal protection circuitry turns-off all<br />
drivers when the junction temperature reaches<br />
+170°C. It is only intended to protect the device<br />
from failures due to excessive junction temperature<br />
and should not imply that output short circuits<br />
are permitted. The output drivers are re-enabled<br />
when the junction temperature cools to +145°C.<br />
The UDx2916 output drivers are optimized<br />
for low output saturation voltages—less than 1.8 V<br />
total (source plus sink) at 500 mA. Under normal<br />
operating conditions, when combined with the excellent<br />
thermal properties of the package designs,<br />
this allows continuous operation of both bridges<br />
simultaneously at 500 mA.<br />
TRUTH TABLE<br />
PHASE OUTA OUTB H H L<br />
L L H<br />
Allegro MicroSystems, Inc.<br />
115 Northeast Cutoff, Box 15036<br />
Worcester, Massachusetts 01615-0036 (508) 853-<br />
5000<br />
www.allegromicro.com<br />
6
2916<br />
APPLICATION NOTES<br />
Current Sensing<br />
To minimize current sensing inaccuracies caused by ground trace<br />
IR drops, each current-sensing resistor should have a separate<br />
return to the ground terminal of the device. For low-value sense<br />
resistors, the IR drops in the PCB can be signi cant and should<br />
be taken into account. The use of sockets should be avoided as<br />
their contact resistance can cause variations in the effective value<br />
of RS .<br />
Generally, larger values of RS reduce the aforementioned effects<br />
but can result in excessive heating and power loss in the sense<br />
resistor. The selected value of RS should not cause the absolute<br />
maximum voltage rating of 1.5 V, for the SENSE terminal, to be<br />
exceeded. The recommended value of RS is in the range of:<br />
RS = 0.75 / ITRIP (max) ± 50% .<br />
If desired, the reference input voltage can be ltered by placing<br />
a capacitor from REFIN to ground. The ground return for this<br />
capacitor as well as the bottom of any resistor divider used<br />
should be independent of the high-current power-ground trace to<br />
avoid changes in REFIN due to IR drops.<br />
Thermal Considerations<br />
For reliable operation, it is recommended that the maximum<br />
junction temperature be kept below 110°C to 125°C. The<br />
junction temperature can be measured best by attaching a<br />
thermocouple to the power tab or batwing of the device and<br />
measuring the tab temperature, TTAB. The junction temperature<br />
can then be approximated by using the formula:<br />
TJ = TTAB + (2 × ILOAD × VF × RJT ) ,<br />
where VF can be chosen from the electrical speci cation table<br />
Dual Full-Bridge Motor Driver<br />
for the given level of I LOAD. The value for R JT is approximately<br />
6°C/W for both package styles.<br />
The power dissipation of the batwing packages can be improved<br />
20% to 30% by adding a section of printed circuit board copper<br />
(typically 6 to 18 square centimeters) connected to the batwing<br />
terminals of the device.<br />
The thermal performance in applications that run at high load<br />
currents, high duty cycles, or both, can be improved by adding<br />
external diodes from each output to ground in parallel with the<br />
internal diodes. Fast-recovery (200 ns) diodes should be used to<br />
minimize switching losses.<br />
Load Supply Terminal<br />
The load supply terminal, VBB, should be decoupled with an<br />
electrolytic capacitor (47 F is recommended), placed as close<br />
to the device as is physically practical. To minimize the effect of<br />
system ground IR drops on the logic and reference input signals,<br />
the system ground should have a low-resistance return to the<br />
load supply voltage.<br />
Fixed Off-Time Selection<br />
With increasing values of t OFF, switching losses decrease, lowlevel<br />
load current regulation improves, EMI reduces, PWM<br />
frequency decreases, and ripple current increases. The value of<br />
t OFF can be chosen for optimization of these parameters. For<br />
applications where audible noise is a concern, typical values of<br />
t OFF should be chosen in the range of 15 to 35 s.<br />
Allegro MicroSystems, Inc.<br />
115 Northeast Cutoff, Box 15036<br />
Worcester, Massachusetts 01615-0036 (508) 853-<br />
5000<br />
www.allegromicro.com<br />
7
2916<br />
24X<br />
0.10 C<br />
0.41 ±0.10<br />
24<br />
1<br />
A<br />
2<br />
A<br />
1.27 MIN<br />
1.52 +0.25<br />
–0.38<br />
24<br />
1<br />
Package B, 24-pin DIP<br />
External batwings, Pins 6, 7, 18, and 19 are fused internally<br />
2<br />
15.40±0.20<br />
0.018<br />
0.46 ±0.12<br />
30.10 +0.25<br />
–0.64<br />
2.54<br />
Dual Full-Bridge Motor Driver<br />
6.35 +0.76<br />
–0.25<br />
5.33 MAX<br />
3.30 +0.51<br />
–0.38<br />
10.92 +0.38<br />
–0.25<br />
For Reference Only<br />
(reference JEDEC MS-001 BE)<br />
Dimensions in millimeters<br />
7.62<br />
0.38 +0.10<br />
–0.05<br />
Dimensions exclusive of mold flash, gate burrs, and dambar protrusions<br />
Exact case and lead configuration at supplier discretion within limits shown<br />
A Terminal #1 mark area<br />
Package LB, 24-pin SOICW<br />
External batwings, Pins 6, 7, 18, and 19 are fused internally<br />
1.27<br />
7.50±0.10<br />
SEATING<br />
PLANE<br />
2.65 MAX<br />
0.20 ±0.10<br />
10.30±0.33<br />
C<br />
4° ±4<br />
0.25<br />
0.27 +0.07<br />
–0.06<br />
0.84 +0.44<br />
–0.43<br />
SEATING PLANE<br />
GAUGE PLANE<br />
2.20<br />
24<br />
B PCB Layout Reference View<br />
For Reference Only<br />
External batwings, Pins 6, 7, 18, and 19 are fused internally<br />
(Reference JEDEC MS-013 AD)<br />
Dimensions exclusive of mold flash, gate burrs, and dambar protrusions<br />
Exact case and lead configuration at supplier discretion within limits shown<br />
A Terminal #1 mark area<br />
B Reference pad layout (reference IPC SOIC127P1030X265-24M)<br />
All pads a minimum of 0.20 mm from all adjacent pads; adjust as necessary<br />
to meet application process requirements and PCB layout tolerances<br />
1<br />
2<br />
0.65<br />
Allegro MicroSystems, Inc.<br />
115 Northeast Cutoff, Box 15036<br />
Worcester, Massachusetts 01615-0036 (508) 853-<br />
5000<br />
www.allegromicro.com<br />
9.60<br />
1.27<br />
8
2916<br />
UDN2916EB<br />
Dual Full-Bridge Motor Driver<br />
Package EB, 44-pin PLCC<br />
External batwings, Pins 7 through 17 and 29 through 39 are fused internally<br />
17.53 ±0.13<br />
44X<br />
16.59 ±0.08<br />
0.10<br />
0.74 ±0.08<br />
C<br />
0.43 ±0.10<br />
7.75 ±0.36<br />
17.53 ±0.13<br />
16.59 ±0.08<br />
2 1 44<br />
For Reference Only<br />
(reference JEDEC MS-018 AC)<br />
Dimensions in inches, metric dimensions (mm) in brackets, for reference only<br />
Dimensions exclusive of mold flash, gate burrs, and dambar protrusions<br />
Exact case and lead configuration at supplier discretion within limits shown<br />
A Terminal #1 mark area<br />
A<br />
7.75 ±0.36<br />
Copyright ©1994-2009, Allegro MicroSystems, Inc.<br />
Allegro MicroSystems, Inc. reserves the right to make, from time to time, such de par tures from the detail spec i fi ca tions as may be required to permit<br />
improvements in the per for mance, reliability, or manufacturability of its products. Before placing an order, the user is cautioned to verify that the<br />
information being relied upon is current.<br />
Allegro’s products are not to be used in life support devices or systems, if a failure of an Allegro product can reasonably be expected to cause the<br />
failure of that life support device or system, or to affect the safety or effectiveness of that device or system.<br />
The in for ma tion in clud ed herein is believed to be ac cu rate and reliable. How ev er, Allegro MicroSystems, Inc. assumes no re spon si bil i ty for its use;<br />
nor for any in fringe ment of patents or other rights of third parties which may result from its use.<br />
4.57 MAX<br />
SEATING<br />
PLANE<br />
For the latest version of this document, visit our website:<br />
www.allegromicro.com<br />
1.27<br />
C<br />
0.51<br />
7.75 ±0.36<br />
7.75 ±0.36<br />
Allegro MicroSystems, Inc.<br />
115 Northeast Cutoff, Box 15036<br />
Worcester, Massachusetts 01615-0036 (508) 853-<br />
5000<br />
www.allegromicro.com<br />
9
1 23<br />
TSC<br />
TS7800<br />
3-Terminal Fixed Positive Voltage Regulators<br />
TO-220 ITO-220 D-PAK<br />
Features<br />
1 23<br />
Pin: 1. Input 2. Ground 3. Output<br />
(Heatsink surface connected to Pin 2.)<br />
Output Current up to 1.5 Ampere<br />
No External Components Required<br />
Internal Thermal Overload Protection<br />
Internal Short-Circuit Current Limiting<br />
Output Transistor Safe-Area<br />
Compensation<br />
Output Voltage Offered in 2%<br />
Tolerance<br />
Absolute Maximum Ratings (Ta=25°C)<br />
Ratings Symbol TS7800 Series Unit<br />
Input Voltage Vin * 35 V<br />
Input Voltage Vin ** 40 V<br />
Power Dissipation TO-220 Without heatsink 2<br />
TO-220 Pt *** 15 °C/W<br />
TO-220F With 10<br />
TO-252 heatsink 10<br />
Operating Ambient Temperature Topr -20 to +85 °C<br />
Operating Junction Temperature Tj 0 to +125 °C<br />
Storage Temperature Tstg -25 to +150 °C<br />
Note: * TS7805 to TS7818 ** TS7824 *** Follow the derating curve<br />
Standard Application<br />
A common ground is<br />
required between the input<br />
and the output voltages.<br />
The input voltage must<br />
remain typically 2.0V above<br />
the output voltage even<br />
during the low point on the<br />
Input ripple voltage.<br />
1<br />
3<br />
2<br />
Voltage Range<br />
5 to 24 Volts<br />
Current<br />
1,5 Ampere<br />
Ordering Informations<br />
Device Operating Temperature Package<br />
(Ambient)<br />
TS78xxCZ TO-220<br />
TS78xxCI -20°C to +85°C TO-220F<br />
TS78xxCP TO-252<br />
Input Output<br />
78XX<br />
Cin*<br />
0,33μF<br />
XX = these two digits of the type number<br />
indicate voltage.<br />
- 1 -<br />
Co**<br />
0,1μF<br />
* = Cin is required if<br />
regulator is located<br />
an appreciable<br />
distance from<br />
power supply filter.<br />
** = Co is not needed<br />
for stability;<br />
however, it does<br />
improve transient<br />
response.<br />
Rev. 1 02/2003
TS7805 Electrical Characteristics<br />
(Vin=10V, Iout=500mA, 0°CTj125°C, Cin=0.33μF, Cout=0.1μF; unless otherwise specified.)<br />
Characteristics Symbol Test Conditions Min. Typ. Max. Unit<br />
Output Voltage Vout Tj=25°C 4.90 5 5.10 V<br />
7VVin20V, 5mAIout1.5A,<br />
PD15W<br />
4.85 -- 5.15 V<br />
Line Regulation REGline Tj=25°C 7.5VVin25V -- 3 100 mV<br />
8VVin12V -- 1 50 mV<br />
Load Regulation REGload Tj=25°C 5mAIout1.5A -- 15 100 mV<br />
250mAIout750mA -- 5 50 mV<br />
Quiescent Current Iq Iout=0, Tj=25°C -- 4.2 8 mA<br />
Quiescent Current Change Iq 7VVin25V -- -- 1.3 mA<br />
5mAIout1.5A -- -- 0.5 mA<br />
Output Noise Voltage Vn 10Hzf100KHz, Tj=25°C -- 40 -- μV<br />
Ripple Rejection Ratio RR f=120Hz, 8VVin18V 62 78 -- dB<br />
Voltage Drop Vdrop Iout=1.0A, Tj=25°C -- 2 -- V<br />
Output Resistance Rout f=1KHz -- 17 -- m<br />
Output Short Circuit Current Ios Tj=25°C -- 750 -- mA<br />
Peak Output Current lo peak Tj=25°C -- 2.2 -- A<br />
Temperature Coefficient<br />
Output Voltage<br />
Vout/Tj Iout=5mA, 0°CTj125°C -- -0.6 -- mV/°C<br />
TS7806 Electrical Characteristics<br />
(Vin=11V, Iout=500mA, 0°CTj125°C, Cin=0.33μF, Cout=0.1μF; unless otherwise specified.)<br />
Characteristics Symbol Test Conditions Min. Typ. Max. Unit<br />
Output Voltage Vout Tj=25°C 5.88 6 6.12 V<br />
8VVin21V, 5mAIout1.5A,<br />
PD15W<br />
5.82 -- 6.18 V<br />
Line Regulation REGline Tj=25°C 8VVin25V -- 5 120 mV<br />
9VVin13V -- 1.5 60 mV<br />
Load Regulation REGload Tj=25°C 5mAIout1.5A -- 14 120 mV<br />
250mAIout750mA -- 4 60 mV<br />
Quiescent Current Iq Iout=0, Tj=25°C -- 4.3 8 mA<br />
Quiescent Current Change lq 8VVin25V -- -- 1.3 mA<br />
5mAIout1.5A -- -- 0.5 mA<br />
Output Noise Voltage Vn 10Hzf100KHz, Tj=25°C -- 45 -- μV<br />
Ripple Rejection Ratio RR f=120Hz, 9VVin19V 59 75 -- dB<br />
Voltage Drop Vdrop Iout=1.0A, Tj=25°C -- 2 -- V<br />
Output Resistance Rout f=1KHz -- 19 -- m<br />
Output Short Circuit Current Ios Tj=25°C -- 550 -- mA<br />
Peak Output Current Io peak Tj=25°C -- 2.2 -- A<br />
Temperature Coefficient of Vout/Tj<br />
Output Voltage<br />
Iout=5mA, 0°CTj125°C -- -0.7 -- mV/°C<br />
Pulse testing techniques are used to maintain the junction temperature as close to the<br />
ambient temperature as possible, and thermal effects must be taken into account separately.<br />
This specification applies only for DC power dissipation permitted by absolute maximum ratings.<br />
- 2 -<br />
TSC<br />
Rev. 1 02/2003
TSC<br />
TS7808 Electrical Characteristics<br />
(Vin=14V, Iout=500mA, 0°CTj125°C, Cin=0.33μF, Cout=0.1μF; unless otherwise specified.)<br />
Characteristics Symbol Test Conditions Min. Typ. Max. Unit<br />
Output Voltage Vout Tj=25°C 7.84 8 8.16 V<br />
10.5VVin23V, 5mAIout1.5A,<br />
PD 15W<br />
7.76 -- 8.24 V<br />
Line Regulation REGline 10.5VVin25V -- 6 160 mV<br />
Tj=25°C 11VVin17V -- 2 80 mV<br />
Load Regulation REGload 10mAIout1.5A -- 12 160 mV<br />
Tj=25°C 250mAIout750mA -- 4 80 mV<br />
Quiescent Current Iq Iout=0, Tj=25°C -- 4.3 8 mA<br />
Quiescent Current Change lq 10.5VVin25V -- -- 1 mA<br />
5mAIout1.5A -- -- 0.5 mA<br />
Output Noise Voltage Vn 10Hzf100KHz, Tj=25°C -- 52 -- μV<br />
Ripple Rejection Ratio RR f=120Hz, 11VVin21V 56 72 -- dB<br />
Voltage Drop Vdrop Iout=1.0A, Tj=25°C -- 2 -- V<br />
Output Resistance Rout f=1KHz -- 16 -- m<br />
Output Short Circuit Current Ios Tj=25°C -- 450 -- mA<br />
Peak Output Current Io peak Tj=25°C -- 2.2 -- A<br />
Temperature Coefficient of Vout/Tj<br />
Output Voltage<br />
Iout=5mA, 0°CTj125°C -- -0.8 -- mV/°C<br />
TS7809 Electrical Characteristics<br />
(Vin=15V, Iout=500mA, 0°CTj125°C, Cin=0.33μF, Cout=0.1μF; unless otherwise specified.)<br />
Characteristics Symbol Test Conditions Min. Typ. Max. Unit<br />
Output Voltage Vout Tj=25°C 8.82 9 9.18 V<br />
11.5VVin24V, 5mAIout1.5A,<br />
PD 15W<br />
8.73 -- 9.27 V<br />
Line Regulation REGline 11.5VVin26V -- 6 180 mV<br />
Tj=25°C 11.5VVin17V -- 2 90 mV<br />
Load Regulation REGload 5mAIout1.5A -- 12 180 mV<br />
Tj=25°C 250mAIout750mA -- 4 90 mV<br />
Quiescent Current Iq Iout=0, Tj=25°C -- 4.3 8 mA<br />
Quiescent Current Change lq 11.5VVin26V -- -- 1 mA<br />
5mAIout1.5A -- -- 0.5 mA<br />
Output Noise Voltage Vn 10Hzf100KHz, Tj=25°C -- 52 -- μV<br />
Ripple Rejection Ratio RR f=120Hz, 11.5VVin21.5V 55 72 -- dB<br />
Voltage Drop Vdrop Iout=1.0A, Tj=25°C -- 2 -- V<br />
Output Resistance Rout f=1KHz -- 16 -- m<br />
Output Short Circuit Current Ios Tj=25°C -- 450 -- mA<br />
Peak Output Current Io peak Tj=25°C -- 2.2 -- A<br />
Temperature Coefficient of Vout/Tj<br />
Output Voltage<br />
Iout=5mA, 0°CTj125°C -- -1 -- mV/°C<br />
Pulse testing techniques are used to maintain the junction temperature as close to the<br />
ambient temperature as possible, and thermal effects must be taken into account separately.<br />
This specification applies only for DC power dissipation permitted by absolute maximum ratings.<br />
Rev. 1 02/2003<br />
- 3 -
TS7810 Electrical Characteristics<br />
(Vin=16V, Iout=500mA, 0°CTj125°C, Cin=0.33μF, Cout=0.1μF; unless otherwise specified.)<br />
Characteristics Symbol Test Conditions Min. Typ. Max. Unit<br />
Output Voltage Vout Tj=25°C 9.8 10 10.2 V<br />
12.5VVin25V, 5mAIout1.5A,<br />
PD 15W<br />
9.7 -- 10.3 V<br />
Line Regulation REGline 12.5VVin28V -- 7 200 mV<br />
- 4 -<br />
TSC<br />
Tj=25°C 13VVin17V -- 2 100 mV<br />
Load Regulation REGload 10mAIout1.5A -- 12 200 mV<br />
Tj=25°C 250mAIout750mA -- 4 100 mV<br />
Quiescent Current Iq Iout=0, Tj=25°C -- 4.3 8 mA<br />
Quiescent Current Change lq 12.5VVin28V -- -- 1 mA<br />
5mAIout1.5A -- -- 0.5 mA<br />
Output Noise Voltage Vn 10Hzf100KHz, Tj=25°C -- 70 -- μV<br />
Ripple Rejection Ratio RR f=120Hz, 13VVin23V 55 71 -- dB<br />
Voltage Drop Vdrop Iout=1.0A, Tj=25°C -- 2 -- V<br />
Output Resistance Rout f=1KHz -- 18 -- m<br />
Output Short Circuit Current Ios Tj=25°C -- 400 -- mA<br />
Peak Output Current Io peak Tj=25°C -- 2.2 -- A<br />
Temperature Coefficient of Vout/Tj<br />
Output Voltage<br />
Iout=5mA, 0°CTj125°C -- -1 -- mV/°C<br />
TS7812 Electrical Characteristics<br />
(Vin=19V, Iout=500mA, 0°CTj125°C, Cin=0.33μF, Cout=0.1μF; unless otherwise specified.)<br />
Characteristics Symbol Test Conditions Min. Typ. Max. Unit<br />
Output Voltage Vout Tj=25°C 11.76 12.0 12.24 V<br />
14.5VVin27V, 5mAIout1.5A,<br />
PD 15W<br />
11.64 -- 12.36 V<br />
Line Regulation REGline 14VVin30V -- 10 240 mV<br />
Tj=25°C 15VVin19V -- 3 120 mV<br />
Load Regulation REGload 10mAIout1.5A -- 12 240 mV<br />
Tj=25°C 250mAIout750mA -- 4 120 mV<br />
Quiescent Current Iq Tj=25°C, Iout=0 -- 4.3 8 mA<br />
Quiescent Current Change lq 14.5VVin30V -- -- 1 mA<br />
5mAIout1.5A -- -- 0.5 mA<br />
Output Noise Voltage Vn 10Hzf100KHz, Tj=25°C -- 75 -- μV<br />
Ripple Rejection Ratio RR f=120Hz, 15VVin25V 55 71 -- dB<br />
Voltage Drop Vdrop Iout=1.0A, Tj=25°C -- 20 -- V<br />
Output Resistance Rout f=1KHz -- 18 -- m<br />
Output Short Circuit Current Ios Tj=25°C -- 350 -- mA<br />
Peak Output Current Io peak Tj=25°C -- 2.2 -- A<br />
Temperature Coefficient of Vout/Tj<br />
Output Voltage<br />
Iout=5mA, 0°CTj125°C -- -1 -- mV/°C<br />
Pulse testing techniques are used to maintain the junction temperature as close to the<br />
ambient temperature as possible, and thermal effects must be taken into account separately.<br />
This specification applies only for DC power dissipation permitted by absolute maximum ratings.<br />
Rev. 1 02/2003
TSC<br />
TS7815 Electrical Characteristics<br />
(Vin=23V, Iout=500mA, 0°CTj125°C, Cin=0.33μF, Cout=0.1μF; unless otherwise specified.)<br />
Characteristics Symbol Test Conditions Min. Typ. Max. Unit<br />
Output Voltage Vout Tj=25°C 14.7 15 15.3 V<br />
17.5VVin30V, 5mAIout1.5A,<br />
PD 15W<br />
14.55 -- 15.45 V<br />
Line Regulation REGline 17.5VVin30V -- 12 300 mV<br />
Tj=25°C 18VVin22V -- 3 150 mV<br />
Load Regulation REGload 10mAIout1.5A -- 12 300 mV<br />
Tj=25°C 250mAIout750mA -- 4 150 mV<br />
Quiescent Current Iq Tj=25°C, Iout=0 -- 4.3 8 mA<br />
Quiescent Current Change lq 17.5VVin30V -- -- 1 mA<br />
5mAIout1.5A -- -- 0.5 mA<br />
Output Noise Voltage Vn 10Hzf100KHz, Tj=25°C -- 90 -- μV<br />
Ripple Rejection Ratio RR f=120Hz, 18VVin28V 54 70 -- dB<br />
Voltage Drop Vdrop Iout=1.0A, Tj=25°C -- 2 -- V<br />
Output Resistance Rout f=1KHz -- 19 -- m<br />
Output Short Circuit Current Ios Tj=25°C -- 230 -- mA<br />
Peak Output Current Io peak Tj=25°C -- 2.1 -- A<br />
Temperature Coefficient of Vout/Tj<br />
Output Voltage<br />
Iout=5mA, 0°CTj125°C -- -1 -- mV/°C<br />
TS7818 Electrical Characteristics<br />
(Vin=27V, Iout=500mA, 0°CTj125°C, Cin=0.33μF, Cout=0.1μF; unless otherwise specified.)<br />
Characteristics Symbol Test Conditions Min. Typ. Max. Unit<br />
Output Voltage Vout Tj=25°C 17.64 18 18.36 V<br />
21VVin33V, 5mAIout1.5A,<br />
PD 15W<br />
17.46 -- 18.54 V<br />
Line Regulation REGline 21VVin33V -- 15 360 mV<br />
Tj=25°C 22VVin26V -- 5 180 mV<br />
Load Regulation REGload 10mAIout1.5A -- 12 360 mV<br />
Tj=25°C 250mAIout750mA -- 4 180 mV<br />
Quiescent Current Iq Tj=25°C, Iout=0 -- 4.5 8 mA<br />
Quiescent Current Change lq 21VVin33V -- -- 1 mA<br />
5mAIout1.5A -- -- 0.5 mA<br />
Output Noise Voltage Vn 10Hzf100KHz, Tj=25°C -- 110 -- μV<br />
Ripple Rejection Ratio RR f=120Hz, 21VVin31V 54 70 -- dB<br />
Voltage Drop Vdrop Iout=1.0A, Tj=25°C -- 2 -- V<br />
Output Resistance Rout f=1KHz -- 22 -- m<br />
Output Short Circuit Current Ios Tj=25°C -- 200 -- mA<br />
Peak Output Current Io peak Tj=25°C -- 2.1 -- A<br />
Temperature Coefficient of Vout/Tj<br />
Output Voltage<br />
Iout=5mA, 0°CTj125°C -- -1 -- mV/°C<br />
Pulse testing techniques are used to maintain the junction temperature as close to the<br />
ambient temperature as possible, and thermal effects must be taken into account separately.<br />
This specification applies only for DC power dissipation permitted by absolute maximum ratings.<br />
- 5 -<br />
Rev. 1 02/2003
TS7824 Electrical Characteristics<br />
(Vin=33V, Iout=500mA, 0°CTj125°C, Cin=0.33μF, Cout=0.1μF; unless otherwise specified.)<br />
Characteristics Symbol Test Conditions Min. Typ. Max. Unit<br />
Output Voltage Vout Tj=25°C 23.52 24 24.48 V<br />
26VVin38V, 5mAIout1.5A,<br />
PD 15W<br />
23.28 -- 24.72 V<br />
Line Regulation REGline 26VVin38V -- 18 480 mV<br />
- 6 -<br />
TSC<br />
Tj=25°C 27VVin32V -- 6 240 mV<br />
Load Regulation REGload 10mAIout1.5A -- 12 480 mV<br />
Tj=25°C 250mAIout750mA -- 4 240 mV<br />
Quiescent Current Iq Iout=0, Tj=25°C -- 4.6 8 mA<br />
Quiescent Current Change lq 26VVin38V -- -- 1 mA<br />
5mAIout1.5A -- -- 0.5 mA<br />
Output Noise Voltage Vn 10Hzf100KHz, Tj=25°C -- 170 -- μV<br />
Ripple Rejection Ratio RR f=120Hz, 26VVin36V 54 70 -- dB<br />
Voltage Drop Vdrop Iout=1.0A, Tj=25°C -- 2 -- V<br />
Output Resistance Rout f=1KHz -- 28 -- m<br />
Output Short Circuit Current Ios Tj=25°C -- 150 -- mA<br />
Peak Output Current Io peak Tj=25°C -- 2.1 -- A<br />
Temperature Coefficient of Vout/Tj<br />
Output Voltage<br />
Iout=5mA, 0°CTj125°C -- -1.5 -- mV/°C<br />
Pulse testing techniques are used to maintain the junction temperature as close to the ambient temperature as<br />
possible, and thermal effects must be taken into account separately.<br />
This specification applies only for DC power dissipation permitted by absolute maximum ratings.<br />
FIG. 1 - WORST CASE POWER DISSIPATION<br />
versus AMBIENT TEMPERATURE<br />
FIG. 2 - PEAK OUTPUT CURRENT AS A FUNCTION OF<br />
INPUT-OUTPUT DIFFERENTIAL VOLTAGE<br />
Rev. 1 02/2003
TSC<br />
FIG. 3 - QUIESCENT CURRENT AS A FUNCTION<br />
OF TEMPERATURE<br />
FIG. 5 - OUTPUT VOLTAGE AS A FUNCTION<br />
OF JUNCTION TEMPERATURE<br />
FIG. 7 - RIPPLE REJECTION AS A FUNCTION<br />
OF OUTPUT VOLTAGE<br />
- 7 -<br />
FIG. 4 - INPUT OUTPUT DIFFERENTIAL AS A FUNCTION<br />
OF JUNCTION TEMPERATURE<br />
FIG. 6 - OUTPUT IMPEDANCE AS A FUNCTION<br />
OF OUTPUT VOLTAGE<br />
FIG. 8 - RIPPLE REJECTION AS A FUNCTION OF<br />
FREQUENCY<br />
Rev. 1 02/2003
TO-220 Mechanical drawing<br />
1. Top View 2. Side View<br />
TO-220F Mechanical drawing<br />
1. Top View 2. Side View<br />
TO-252 Mechanical drawing<br />
1. Top View 2. Side View<br />
- 8 -<br />
TSC<br />
TO-220 DIMENSION<br />
DIM MILLIMETERS INCHES<br />
MIN MAX MIN MAX<br />
A 10.00 10.50 0.394 0.413<br />
B 3.24 4.44 0.128 0.175<br />
C 2.44 2.94 0.096 0.116<br />
D 3.565 4.315 0.140 0.170<br />
E 0.68 0.92 0.027 0.036<br />
F 1.115 1.485 0.044 0.058<br />
G 2.345 2.715 0.092 0.107<br />
H 13.49 14.31 0.531 0.563<br />
I 4.475 5.225 0.176 0.206<br />
J 1.15 1.39 0.045 0.055<br />
K 27.78 29.62 1.094 1.166<br />
L 2.175 2.925 0.086 0.115<br />
M 0.297 0.477 0.012 0.019<br />
N 8.28 8.80 0.326 0.346<br />
O 14.29 15.31 0.563 0.603<br />
P 6.01 6.51 0.237 0.256<br />
TO-220F DIMENSION<br />
DIM MILLIMETERS INCHES<br />
MIN MAX MIN MAX<br />
A 9.9 10.1 0.390 0.398<br />
B 6.2 6.2 0.244 0.244<br />
C 2.2 2.2 0.087 0.087<br />
D 1.4 1.4 0.055 0.055<br />
E 15.0 15.2 0.591 0.598<br />
F 0.48 0.72 0.019 0.028<br />
G 2.355 2.725 0.093 0.107<br />
H 13.49 14.31 0.531 0.563<br />
I 1.115 1.485 0.044 0.058<br />
J 2.6 2.8 0.102 0.110<br />
K 4.4 4.6 0.173 0.181<br />
L 1.115 1.15 0.045 0.045<br />
M 2.95 3.15 0.116 0.124<br />
N 2.6 2.8 0.102 0.110<br />
O 6.55 6.65 0.258 0.262<br />
TO-252 DIMENSION<br />
DIM MILLIMETERS INCHES<br />
MIN MAX MIN MAX<br />
A 10.23 10.28 0.403 0.405<br />
B 9.92 9.96 0.391 0.392<br />
C 0.50 0.54 0.020 0.021<br />
D 1.83 1.96 0.072 0.077<br />
E 4.59 4.61 0.180 0.181<br />
F 0.49 0.51 0.019 0.020<br />
G 1.15 1.22 0.045 0.048<br />
H 0.43 0.47 0.017 0.019<br />
I 5.37 5.40 0.211 0.213<br />
J 1.33 1.39 0.052 0.055<br />
Rev. 1 02/2003
Technical data<br />
<br />
Dimensions<br />
<br />
<br />
[]<br />
<br />
<br />
[mH]<br />
<br />
<br />
[A]<br />
<br />
<br />
<br />
Hybrid stepper motors<br />
<br />
power<br />
<br />
6540-13-2-2 2 2.7 1.12 130 5<br />
6540-13-2-9 9 13 0.52 130 5<br />
6540-13-2-36 36 37 0.26 130 5<br />
6540-13-4-2 2 1.5 1.12 90 5<br />
6540-13-4-9 9 5.6 0.52 90 5<br />
6540-13-4-36 36 21 0.26 90 5<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Drawing not to scale. All dimensions in mm.<br />
h8<br />
0<br />
Ø 22 - 0.033<br />
h6<br />
0<br />
Ø 5 - 0.008<br />
6 ±0.5<br />
0<br />
2 - 0.25<br />
24 ±0.5<br />
32.5 ±0.5<br />
h6)<br />
0<br />
(Ø 5 -0.008<br />
9.5<br />
42<br />
31 ±0.25<br />
160 ±5<br />
4 ±1<br />
31 ±0.25<br />
42<br />
Cables AWG26 UL1007<br />
M3 (2x)<br />
Steps/rev. <br />
Step accuracy ± 5 %<br />
Rotor inertia <br />
Insulation class <br />
Protection <br />
<br />
Test voltage <br />
Detent torque
Dynamic characteristics<br />
<br />
Md [mNm]<br />
120<br />
100<br />
80<br />
60<br />
40<br />
20<br />
U = 24V<br />
U = 40V<br />
0<br />
0 2000 4000 6000 8000 10000<br />
<br />
Md [mNm]<br />
120<br />
100<br />
80<br />
60<br />
40<br />
20<br />
0<br />
0<br />
<br />
Md [mNm]<br />
120<br />
100<br />
80<br />
60<br />
40<br />
20<br />
Speed [pps]<br />
U = 24 V<br />
U = 40 V<br />
2000 4000 6000 8000 10000<br />
Speed [pps]<br />
0<br />
0 2000 4000 6000 8000 10000<br />
Speed [pps]<br />
SONCEBOZ SA<br />
2605 Sonceboz - Switzerland<br />
Tel. +41(0) 32 488 11 11<br />
Fax +41(0) 32 488 11 00<br />
E-mail : info@sonceboz.com<br />
Internet : www.sonceboz.com<br />
U = 24 V<br />
U = 40 V<br />
<br />
Md [mNm]<br />
120<br />
100<br />
80<br />
60<br />
40<br />
20<br />
0<br />
0 2000 4000 6000 8000 10000<br />
<br />
Md [mNm]<br />
120<br />
100<br />
80<br />
60<br />
40<br />
20<br />
Speed [pps]<br />
Speed [pps]<br />
U = 24 V<br />
U = 40 V<br />
U = 24 V<br />
U = 40 V<br />
0<br />
0 2000 4000 6000 8000 10000<br />
<br />
Md [mNm]<br />
120<br />
100<br />
80<br />
60<br />
40<br />
20<br />
[ Hybrid stepper motors 2/3 ]<br />
0<br />
0 2000 4000 6000 8000 10000<br />
Speed [pps]<br />
U = 24 V<br />
U = 40 V<br />
[pps] = pulses per second<br />
Special requirements upon customer specifications. Right to change reserved. < 1.0 >
MR [mNm]<br />
200<br />
180<br />
160<br />
140<br />
120<br />
100<br />
80<br />
60<br />
40<br />
20<br />
Static characteristics<br />
<br />
0<br />
0 20 40 60 80 100 120 140 160<br />
Iph [%]<br />
Electrical Interface<br />
<br />
green<br />
green-white<br />
U 1<br />
red<br />
M<br />
U 2<br />
red-white<br />
SONCEBOZ SA<br />
2605 Sonceboz - Switzerland<br />
Tel. +41(0) 32 488 11 11<br />
Fax +41(0) 32 488 11 00<br />
E-mail : info@sonceboz.com<br />
Internet : www.sonceboz.com<br />
MR [mNm]<br />
200<br />
180<br />
160<br />
140<br />
120<br />
100<br />
80<br />
60<br />
40<br />
20<br />
green<br />
0<br />
white<br />
green-white<br />
0 20 40 60 80<br />
Iph [%]<br />
100 120 140 160<br />
U 1<br />
U 2<br />
[ Hybrid stepper motors 3/3 ]<br />
M<br />
U3 U4 black<br />
red red-white<br />
Special requirements upon customer specifications. Right to change reserved. < 1.0 >
Bilaga M.<br />
Individuell rapport, LCD <strong>med</strong> touchpanel<br />
Av André Berglund
LCD <strong>med</strong> touchpanel<br />
Individuellt projekt inom FiM<br />
André Berglund<br />
MF108X<br />
<strong>KTH</strong> VT 2011
André Berglund<br />
FiM 2011<br />
Sammanfattning<br />
Detta arbete behandlar ämnena LCD och pekskärm och ger en inblick i hur de fungerar<br />
rent tekniskt. Det är två tekniker som syns alltmer i samhället bland konsumentprodukter,<br />
såsom mobiltelefoner, läsplattor och TV-apparater. Förutom en teoretisk beskrivning<br />
innehåller arbetet även en praktisk del där en prototyp ska konstrueras, baserad på dessa<br />
två tekniker och hur de integreras <strong>med</strong> en mikrokontroller. Komponenterna består i<br />
huvudsak av en grafisk display av modell DOGM128S-6 från Electronic Assembly <strong>med</strong><br />
tillhörande pekskärm TOUCH128-1 och mikrokontrollern ATMega644.<br />
Abstract<br />
This work addresses the topics of LCD and touchscreen and gives an insight into how they<br />
work from a technical point of view. These are two technologies that are growing rapidly in<br />
our society among consumer products, such as mobilephones, tablets and TVʼs. In<br />
addition to the theoretical description this work also includes a practical part where a<br />
prototype is built, based on these two technologies and how they are integrated with a<br />
microcontroller. The main components consist of a graphical display, DOGM128S-6 from<br />
Electronic Assembly aswell as a touchscreen TOUCH128-1 and a microcontroller<br />
ATMega644.<br />
2
André Berglund<br />
FiM 2011<br />
Innehåll<br />
Inledning! 4<br />
Teoretisk fördjupning! 5<br />
Omvärldsanalys! 5<br />
LCD! 5<br />
Bakgrund" 5<br />
Teknik" 5<br />
Touchscreen! 7<br />
Bakgrund" 7<br />
Resistiv! 8<br />
Kapacitiv! 9<br />
Praktisk fördjupning! 9<br />
Prototyp! 9<br />
Utvecklingshjälp<strong>med</strong>el! 9<br />
Hårdvara! 10<br />
Mjukvara! 12<br />
Diskussion! 13<br />
Slutsats! 13<br />
Referenser! 14<br />
Bilagor! 15<br />
3
André Berglund<br />
FiM 2011<br />
Inledning<br />
Antalet produkter <strong>med</strong> LCD- och pekskärmsteknologi, främst för konsumenter, har<br />
exploderat de senaste åren. De tjocka och tunga TV-apparaterna har blivit ersatta av<br />
tunna och lätta <strong>med</strong> hög upplösning. De senaste mobiltelefonerna har fått en mycket<br />
större skärm och saknar knappsats. Nu kan användaren peka direkt på skärmen för att<br />
navigera runt i gränssnittet, vilket har gjort telefonen lätthanterlig och mångsidig. Den<br />
teoretiska fördjupningen tar upp tekniken bakom LCD och pekskärmar samt hur och var de<br />
används.<br />
I den senare delen redogörs för hur en prototyp skapas för att demonstrera möjligheterna<br />
<strong>med</strong> dessa två teknologier. Prototypen baseras på en grafisk LCD om 128x64 pixlar från<br />
Electronic Assembly <strong>med</strong> tillhörande pekskärm. Mikrokontrollern ATMega644 är hjärnan i<br />
systemet och innehåller de instruktioner som styr enheterna.<br />
4
André Berglund<br />
FiM 2011<br />
Teoretisk fördjupning<br />
Omvärldsanalys<br />
Dagligen kommer man i kontakt <strong>med</strong> skärmar <strong>med</strong> LCD-teknik och eventuellt tillhörande<br />
pekskärm. Vanligaste produkttypen <strong>med</strong> båda dessa tekniker är de senaste modellerna av<br />
mobiltelefoner, där knappsatsen har blivit ersatt av en pekskärm. Enbart LCD finns främst<br />
hos TV- och datorskärmar, vilket har lett till att produkterna blivit väsentligt mycket tunnare<br />
och lättare samt strömsnålare.<br />
Tillsammans har de båda teknikerna gett utrymme till nya produktlösningar som till<br />
exempel så kallade läs- och surfplattor. Den låga strömförbrukningen har gjort att tekniken<br />
går att använda i mobila enheter <strong>med</strong> batteriförsörjning. Enkelheten att navigera runt i<br />
användargränssnittet <strong>med</strong> sitt eget finger direkt på skärmen är en av anledningarna till att<br />
denna lösning blivit så populär.<br />
LCD<br />
Bakgrund<br />
LCD är förkortning för Liquid Crystal Display och som namnet antyder är det flytande<br />
kristaller som möjliggör funktionen hos skärmen. Tekniken togs fram under 1960- och 70-<br />
talet och introducerades i klockor och miniräknare. Idag sträcker sig tekniken från<br />
monokrom visning av en siffra i en miniräknare till att visa högupplöst video på en skärm<br />
<strong>med</strong> en diagonal uppemot 100 tum.<br />
Teknik<br />
Principen bakom LCD är en flytande kristall mellan två plattor. Dessa plattor består av tre<br />
olika lager som utifrån och in är uppbyggda av ett polariserande filter, glasskiva och en<br />
tunn film av ett ledande ämne. De två polariserande filtren läggs vinkelrätt mot varandra,<br />
vilket innebär att inget ljus kan passera genom skärmen då endast ljus i samma<br />
polarisationsriktning tillåts passera genom ett filter. På andra sidan av glasskivan finns en<br />
tunn film av indiumtennoxid (ITO), ett ämne som har god elektronisk ledningsförmåga och<br />
optisk transparens. Detta ämne fungerar som elektrod och beroende på hur det är utlagt<br />
5
André Berglund<br />
FiM 2011<br />
kommer mönstret att avgöra vad som visas när LCD är påslagen. Oftast ges skärmen ett<br />
rutmönster och en ruta motsvarar då en pixel. Slutligen ligger flytande kristaller mellan de<br />
två plattorna som har skåror i inbördes olika riktningar. Kristallerna lägger sig i respektive<br />
skåror och skapar en skruvstruktur då de vrider sig från ena plattan till den andra. Ljuset<br />
som passerar det första polarisationsfiltret kommer att följa denna struktur och på så sätt<br />
passera ut genom det andra filtret.<br />
Kristallstrukturen ändras när en<br />
spänning läggs över ITO-filmerna och<br />
kristallerna ställer då in sig i en viss<br />
riktning enligt det elektriska fält som<br />
uppstår. Ljuset kan nu inte längre<br />
vrida sig på samma sätt som tidigare<br />
och därav inte heller passera genom<br />
båda polarisationsfilterna. En bild<br />
skapas på skärmen genom att<br />
bestämma var ljus ska släppas<br />
igenom, vilket regleras av spänningen<br />
över kristallerna.<br />
Det finns olika benämningar på LCD-<br />
skärmar beroende på hur kristallerna<br />
är vridna mellan plattorna. Twisted<br />
Nematic (TN) är den ursprungliga<br />
Figur 1. Principskiss för en TN-LCD utan spänning.<br />
Källa: Wiki<strong>med</strong>ia, M. Schadt<br />
typen där vridningsvinkel för kristallerna är 90 grader. En vidareutveckling av TN-displayen<br />
är Super Twisted Nematic (STN), vilken har en ännu större vridningsvinkel som är mellan<br />
180 och 270 grader. Detta kräver mindre spänningsändringar för att slå på och av en pixel.<br />
Den extra vridningen ger även förbättrad betraktningsvinkel och kontrast.<br />
6
André Berglund<br />
FiM 2011<br />
Förutom kristallernas struktur finns det andra egenskaper som skiljer LCD:er åt och det är<br />
bland annat vilken typ av ljuskälla som används. På reflektiva displayer sitter en spegelyta<br />
längst bak och reflekterar inkommande ljus. En sådan display går endast att läsa av om<br />
det finns omgivande ljus. En transmissiv display har en egen ljuskälla i form av<br />
bakgrundsbelysning, vilket ger bättre ljusstyrka och kontrast men samtidigt har den en<br />
högre strömförbrukning. Kombinationen av dessa två typer kallas för transflektiv display<br />
och kommer bäst till nytta då en display bör klara av både starka och svaga<br />
ljusförhållanden.<br />
Pekskärm<br />
Bakgrund<br />
Pekskärmen är en panel som reagerar på beröringar på dess yta. Panelen kan även<br />
avgöra var någonstans på panelens area som beröringen skedde. Vanliga appliceringar är<br />
datorskärmar, mobiltelefoner och automater. Teknologin blir allt mer vanlig då<br />
informationssamhället driver på utvecklingen och användningen.<br />
Tillämpningen av pekskärmar är stor. I stora drag finns det en väldig fördel <strong>med</strong> att<br />
använda en pekskärm istället för konventionella lösningar. Det är nämligen att en person<br />
kan interagera direkt <strong>med</strong> gränssnittet utan att använda sig av indirekta metoder såsom ett<br />
tangentbord. Med ett par enkla tryck på skärmen navigerar man sig fram och ett<br />
tangentbord blir <strong>med</strong> andra ord överflödigt.<br />
Den första tryckkänsliga panelen togs fram i början på 1970-talet av Dr. Sam Hurst i USA<br />
och fick namnet ”Elograph”. Förvisso skilde sig denna från dagens paneler då den inte<br />
vara transparent, men den har lett utvecklingen av modernare varianter och bara ett par år<br />
senare skapades transparenta paneler <strong>med</strong> resistiv teknologi, vilket idag är en av de två<br />
vanligaste typer av paneler som används.<br />
7
André Berglund<br />
FiM 2011<br />
Resistiv<br />
En resistiv pekskärm består i huvudsak av<br />
två lager. Överst finns en plastfilm vars<br />
undersida är täckt <strong>med</strong> en transparent<br />
hinna av en ledande metal, ITO, (översidan<br />
av denna plastfilm är den yta där<br />
beröringen sker). Sedan ett hårdare lager<br />
av glas eller plast, som också har en hinna<br />
av ledande metall, vilken är riktad mot den<br />
andra hinnan. Mellan dessa lager finns en<br />
ram längs kanterna som håller isär ytorna<br />
vid vila och innanför ramen ligger även små<br />
isolerande korn. Allra underst finns<br />
Figur 9%&!5,*4)!,-!$,4)($)!"7*:*7&3+!&($%!6(;&1!*4!(!3&1*&3!1&3*3),1!4&)0,1<br />
2. Elektroder i en resistiv touchscreen.<br />
ytterligare en ram som skiljer panelen från Källa: =3&&!>*?21&!@/ABC!(47!(!$,44&$)*4?!1&3*3),1!D&)0&&4!)%&!)0,!6(;&13<br />
Atmel<br />
:,6)(?&!()!)%*3!5,*4)!)%&!23&1!?&)3!*4-,1'()*,4!(D,2)!)%&!5,3*)*,4!,<br />
displayen. Längs motsatta kanter vid ,1)%,?,4(6!),!)%&!:,6)(?&!?1(7*&4)8!9,!?&)!(!$,'56&)&!3&)!,-!$,,17<br />
?1(7*&4)!'23)!D&!(556*&7!,4$&!*4!:&1)*$(6!(47!)%&4!*4!%,1*F,4)(6!7*1&<br />
metallhinnorna sitter elektroder, vilka är vinkelrätt vridna mellan de två lagren. Då ytan<br />
:,6)(?&!'23)!D&!(556*&7!),!,4&!6(;&1!(47!(!'&(321&'&4)!,-!)%&!<br />
vidrörs sker en förändring i spänningen som ,)%&1!6(;&1!*3!5&1-,1'&7C!4&H)!)%&!32556;!*3!*43)&(7!$,44&$)&7!),!<br />
går genom panelen då lagren kommer i<br />
)%&! ,55,3*)&! 6(;&1! :,6)(?&! *3! '&(321&78! I4! 3)(47/D;! ',7&! ,4<br />
kontakt <strong>med</strong> varandra, vilket gör att systemet $,44&$)&7!),!(!6&:&6!)1*??&1&7!*4)&1125)!*4!,17&1!),!7&)&$)!),2$%!($)*<br />
reagerar och kan beräkna var på ytan som<br />
9(D6&!@/K!-,1!$,44&$)*,43!0%*6&!'&(321*4?!)%&!$,,17*4()&38!<br />
beröringen inträffade. Detta görs genom att först lägga en spänning över ena axeln och<br />
Table 2-1. ./0*1&!),2$%!3$1&&43!3$(44*4?!<br />
låta en av elektroderna på andra axeln läsa av denna. Proceduren upprepas sedan för<br />
motsatt axel.<br />
Den enklaste och billigaste varianten kräver endast Y-Coordinate fyra kablar, M*/N! en till varje M*/N!O!QRS! elektrod längs L47!<br />
!<br />
<strong>med</strong> kanterna. Eftersom spänningen behöver läsas av på båda lagren, kommer panelen<br />
Q!T/0*1&!),2$%!3$1&&4!,46;!23&!)%&!),53%&&)!-,1!'&(321*4?8!J6&(3<br />
bli obrukbar om en skada skulle uppstå på ett -,1!$,44&$)*,43!0%*6&!'&(321*4?!)%&!$,,17*4()&3!,4!T/0*1&!),2$%!3<br />
av lagren. Dyrare varianter <strong>med</strong> fem kablar<br />
är inte lika känsliga för skador på det övre lagret Table då 2-2. större T/0*1&!),2$%!3$1&&43!3$(44*4?8!<br />
delen av elektroniken befinner<br />
sig på det undre lagret. I detta fall läggs en jämn spänning på topplagret och då kretsen<br />
sluts läses spänningen av i hörnen av panelen. Denna teknik lämpar sig bättre till större<br />
displayer än vad varianten <strong>med</strong> fyra kablar gör.<br />
!<br />
4 AVR341<br />
8<br />
Figure 2-3. "#$%&'()*$+!,-!(!./0*1&!),2$%!3$1&&4!0%&4!51&3321&!*3<br />
X+Excite X-Excite Y+Excite<br />
Standby L47! M*/N! M*/N!<br />
X-Coordinate L47! P$$! M*/N!<br />
ULExcite URExcite LLExcite LRExcite<br />
Standby L47! M*/N! M*/N! M*/N!<br />
X-Coordinate L47! P$$! L47! P$$!<br />
Y-Coordinate L47! L47! P$$! P$$!<br />
9,!?&)!(!$,'56&)&!3&)!,-!$,,17*4()&3C!)%&!:,6)(?&!?1(7*&4)!*3!(556*&<br />
6(;&1!,4$&!*4!%,1*F,4)(6!7*1&$)*,4!),!7&)&1'*4&!)%&!U!$,,17*4()&!(<br />
7*1&$)*,4!),!7&)&1'*4&!)%&!V!$,,17*4()&8!I4!D,)%!$(3&3!)%&!),53%&&)<br />
(! %*?%/*'5&7(4$&! '&(321&'&4)! (-)&1! )%&! 3&43*4?! :,6)(?&! %(3!
André Berglund<br />
FiM 2011<br />
Kapacitiv<br />
Denna typ av touchscreen är uppbyggd av en dielektrisk yta, såsom glas, som är täckt<br />
<strong>med</strong> ITO. En spänning läggs över hörnen vilket skapar ett jämnt elektriskt fält. Panelen<br />
reagerar då den vidrörs av exempelvis ett finger, eftersom fingrar leder ström, vilket skapar<br />
en förvrängning av det elektriska fältet. Till skillnad från en resistiv pekskärm går det inte<br />
att använda sig av tryck i form av beröring vid användandet. Denna teknik lämpar sig<br />
bättre till exempelvis mobiltelefoner och automater.<br />
Praktisk fördjupning<br />
Prototyp<br />
Denna praktiska fördjupning syftar till att integrera de båda teknikerna LCD och pekskärm<br />
till en prototyp. Målet är att få ett fristående och fungerande system som kan demonstrera<br />
vad dessa tekniker kan åstadkomma tillsammans. Den ursprungliga tanken var att skapa<br />
en fjärrkontroll <strong>med</strong> knappar illustrerade på displayen, men det övergick sedan till att göra<br />
en interaktiv pekskärm.<br />
Utvecklingshjälp<strong>med</strong>el<br />
Till förfogande har det funnits ett antal verktyg, utöver de komponenter som ingår i själva<br />
prototypen, som behövts för att genomföra detta projekt. Programmering har skett i AVR<br />
Studio 4 och för att överföra koden till mikrokontrollern har Atmels STK500-kort använts.<br />
Kopplingsschemat är baserat på manualer för display samt touchscreen och har ritats,<br />
<strong>med</strong> vissa tillägg, i NI Multisim. Kretskortlayout har skapats från ett komponentbibliotek<br />
tillhandahållet av Electronic Assembly och ritats i Eagle. De bildfiler som är tänkt att visas<br />
på displayen är ritade i Paint och har sedan konverterats till kod <strong>med</strong> Image2Code.<br />
9
André Berglund<br />
FiM 2011<br />
Hårdvara<br />
En av huvudkomponenterna i prototypen är en LCD av<br />
modell DOGM128-S från Electronic Assembly. Det är en<br />
grafisk display <strong>med</strong> en upplösning på 128x64 pixlar och<br />
är av typen FSTN transmissiv <strong>med</strong> negativ visning.<br />
Kommunikationen sker via styrkretsen ST7565R från<br />
Sitronix <strong>med</strong> ett SPI-interface. En transmissiv display<br />
behöver som bekant bakgrundsbelysning och det ges av<br />
tillhörande komponent för displayen, EA LED55x46-R.<br />
Pekpanelen är måttanpassad för displayen då även den<br />
kommer från Electronic Assembly, EA TOUCH128-1. Det är en analog resistiv panel <strong>med</strong><br />
fyra kablar och har ett självhäftande material på undersidan som fäster samman panelen<br />
<strong>med</strong> displayen. Anslutning sker <strong>med</strong> en ZIF-kontakt.<br />
Mikrokontrollern som användes var ursprungligen en ATMega16, men den har endast<br />
minne motsvarande en bild (128x64) på displayen. Därför byttes den ut mot en<br />
ATMega644, som i stort sett är lika förutom att den har större minne. I korta drag är det en<br />
8-bitars kontroller <strong>med</strong> fyra portar varav en är AD-omvandlare.<br />
Innan ett eget kretskort tillverkades så monterades displayen tillsammans <strong>med</strong> övriga<br />
komponenter på ett breadbord och kopplades in enligt kopplingsschemat (se Bilaga 2).<br />
För enkelhetens skull valdes att förse hela systemet <strong>med</strong> en spänning om 3,3V, vilket<br />
innebar att tre extra kondensatorer behövdes till displayen eftersom den då får köras på så<br />
kallad Single Supply och låta displayen använda den inbyggda förstärkaren. En<br />
spänningsregulator, LM2937ES, användes för att omvandla spänningskällan till 3,3V. Två<br />
kondensatorer sattes på vardera sida om spänningsregulatorn för att få en stabil spänning<br />
enligt databladet för typen ovan. Vidare var bakgrundsbelysningen tvungen att ha en egen<br />
spänning annars skulle lysdioderna brinna upp och därför kopplades den in via resistans<br />
och sedan löddes displayens nedre komponentben (två rader om tre ben vardera) ihop<br />
<strong>med</strong> bakgrundsbelysningen.<br />
10<br />
Figur 3. Pekskärmens uppbyggnad.<br />
Källa: Electronic Assembly
André Berglund<br />
FiM 2011<br />
Då systemet verkade fungerade på breadbord var det dags att tillverka ett eget enkelsidigt<br />
kretskort. Kretskortslayouten (se Bilaga 3) ritades i Eagle <strong>med</strong> kopplingsschemat som<br />
grund samt ett bibliotek innehållande bland annat en färdig modell av displayen. Tre kablar<br />
fick dras på ovansidan av kretskortet, då ledningarna annars skulle korsas. Ett speciellt<br />
kretskort designades även för att fästa ZIF-kontakten, då pinnarna på den låg väldigt tätt<br />
och att fästa kablar direkt på pinnarna ansågs för svårt.<br />
Figur 4. Egentillverkat<br />
kretskort <strong>med</strong> komponenter.<br />
Kommunikationen mellan enheterna sker genom mikrokontrollern. Till displayens drivkrets<br />
används SPI, Serial Peripheral Interface, <strong>med</strong> fyra olika pinnar. SPI <strong>med</strong> tillhörande<br />
preferenser måste först aktiveras i mikrokontrollens register innan det går att skicka data,<br />
vilket beskrivs i databladet. Displayen kan bara ta emot data och detta görs genom att<br />
skicka en byte i taget bitvis från mikrokontrollens MOSI-port (Master In Slave Out). För att<br />
data ska kunna läsas av så ser SCK-porten (Serial Clock) till att enheterna använder sig<br />
av samma frekvens och då endast data till displayen skickas över MOSI-pinnen behöver<br />
CS-pinnen (Chip Select) inte ändras, utan kan sättas till låg. Den sista pinnen, A0, talar om<br />
för drivkretsen om det är data eller kommando som skickas. Data är sådant som ska<br />
skrivas ut på displayen, <strong>med</strong>an ett kommando talar till exempel om var på displayen data<br />
ska visas. Det finns även en Reset-pinne mellan mikrokontrollen och drivkretsen, som<br />
sätts till hög, annars återställs alla inställningar.<br />
11
André Berglund<br />
FiM 2011<br />
Upplösningen på displayen är 128x64 pixlar där varje pixel<br />
motsvarar en bit, men data skickas <strong>med</strong> en byte i taget och MSB<br />
(Most Significant Bit) först. Då displayen är uppdelad i åtta sidor<br />
(Page 0-7) och 128 kolumner <strong>med</strong> åtta rader per sida (D0-D7),<br />
kommer MSB att hamna på raden längst ned på sidan (D7). Efter<br />
att man skickat en byte går displayen vidare till nästa kolumn. För<br />
ett sidbyte behöver man skicka ett kommando som talar om för<br />
displayen att skriva på nästa sida. Man inser snabbt att <strong>med</strong> en<br />
upplösning om 128x64 blir det 8192 bitar, vilket omräknat i bytes är<br />
Figur 4. Skärmuppdelning.<br />
DATA 1024 TRANSFER bytes (1kB). Detta är anledningen till att mikrokontrollen byttes Källa: Electronic Assembly<br />
Data transfer is unidirectional. That means that data can only be written; it cannot be read again. In contrast to other<br />
ut till ATMega644 <strong>med</strong> 4kB SRAM.<br />
displays, a busy query is not necessary with this display. The clock-pulse rate of the SCL line can be up to 20 MHz,<br />
depending on the supply voltage. You will find more detailed information on timing on pages 64 and 65 of the data sheet<br />
of the ST7565R controller, which you will find on our website at<br />
Mjukvara<br />
http://www.lcd-module.de/eng/pdf/zubehoer/st7565r.pdf<br />
Displayen behöver instruktioner för att kunna fungera och mikrokontrollen innehåller dessa<br />
i form av maskinkod som ursprungligen är skrivet i C. Koden är uppdelad i två olika filer,<br />
en <strong>med</strong> själva anropen och den andra <strong>med</strong> logiken bakom anropen. Den har byggts främst<br />
ur databladen för mikrokontrollen och displayen, men också från de<br />
programmeringsexempel som Electronic Assembly tillhandahåller på sin hemsida.<br />
Programvaran börjar <strong>med</strong> att aktivera SPI på mikrokontrollern genom funktionen init_spi(),<br />
där pinnarna som ska skicka data till displayen sätts som utgångar. Ett par ändringar görs<br />
även i SPI-kontrollregistret. Sedan skapas funktionen för att skicka data och kommandon<br />
via SPI, send_spi(), som behövs då displayen ska initieras <strong>med</strong> kommandon, vilket nästa<br />
funktion gör, init_lcd(). Den börjar <strong>med</strong> att använda reset och sedan skickas kommandon<br />
som beskriver för displayen bland annat att det är Single Supply som gäller, vilken kontrast<br />
skärmen ska ha osv. Funktionen avslutas <strong>med</strong> att rensa skärmen från eventuella tända<br />
pixlar som kan förekomma vid uppstart.<br />
12
André Berglund<br />
FiM 2011<br />
Diskussion<br />
Det har varit intressant att utforska dessa tekniker, främst praktiskt, men även få en<br />
förståelse för hur de är uppbyggda genom den teoretiska fördjupningen. Tyvärr har den<br />
praktiska delen kantats av en del problem då jag inte lyckats ta mig vidare och där<strong>med</strong><br />
fastnat på vissa plan. Jag har främst mig själv att skylla då jag försökt att lösa det själv<br />
utan att be om hjälp. Detta har resulterat i en prototyp som inte fungerar enligt önskan.<br />
Det som gick snett var att LCD:n aldrig lyckades att initiera sig. Spontant känns det som<br />
att felet ligger i programvaran och inte i hårdvaran. Jag misstänker att det kan vara något<br />
så enkelt som reset, men kan inte avgöra om det verkligen är det.<br />
En framtida prototyp skulle kunna ha ett par förbättringar som jag har upptäckt under<br />
projektets gång. Bland annat skulle kretskortslayouten designas om för att göra den<br />
kompaktare, dock var det lite struligt att göra layouten i Eagle eftersom programmet hade<br />
vissa begränsningar på hur man kunde placera komponenterna. Att kunna felsöka <strong>med</strong><br />
JTAG vore också önskvärt, vilket innebär att nya ledningar behöver dras till Port C på<br />
mikrokontrollen. Annars behövs mest tid läggas på att se över programvaran."<br />
Slutsats<br />
Två tekniker som är väldigt lämpade för varandra. Pekskärmar är mer eller mindre gjorda<br />
för att användas <strong>med</strong> LCD eller andra typer av skärmar, <strong>med</strong>an LCD har en egen marknad<br />
som fristående produkt. Dock är pekskärmar på frammarsch och integreras i allt fler<br />
produkter och erbjuder fantastisk användarvänlighet.<br />
Trots att prototypen inte kan demonstrera teknikerna, så har mycket lärdom tagits in under<br />
projektets gång, både vad gäller genomförande och integration av flera enheter, vilket jag<br />
tar <strong>med</strong> mig till nästa projekt.<br />
13
André Berglund<br />
FiM 2011<br />
Referenser<br />
Electronic Assembly. DOGM128-6,<br />
http://www.lcd-module.com/eng/pdf/grafik/dogm128e.pdf<br />
Atmel Corporation, AVR341: Four and five-wire Touch Screen Controller<br />
http://www.atmel.com/dyn/resources/prod_documents/doc8091.pdf<br />
David J. R. Cristaldi,Salvatore Pennisi, Francesco Pulvirenti, Liquid Crystal Display<br />
Drivers: Techniques and Circuits, Springer 2009, ISBN 978-90-481-2254-7<br />
Stefan Agamanolis, Liquid Crystal Displays: Past, Present, and Future,<br />
http://web.<strong>med</strong>ia.mit.edu/~stefean/liquid-crystals/<br />
http://www.touchscreenguide.com/touchscreen/res.html<br />
http://www.pcworld.idg.com.au/article/355922/<br />
capacitive_vs_resistive_touchscreens/<br />
14
André Berglund<br />
FiM 2011<br />
Bilagor<br />
Bilaga 1, komponentlista<br />
Artikel! ! ! ! ! Ca pris (kr/st)! !<br />
EA DOGM128S-6" " " " " 200<br />
EA TOUCH128-1" " " " " 130"<br />
EA LED55x46-R" " " " " 45"<br />
ATMega644" " " " " " 75<br />
1st spänningsregulator LM2937ES" " 20<br />
3st motstånd 56 ohm" " " " 0,25<br />
1st motstånd 10k ohm" " " " 0,25<br />
9st kondensator 1μF" " " " 2<br />
3st kondensator 0,1μF" " " " 2<br />
1st kondensator 10μF" " " " 5<br />
Bilaga 2, använda pinnar på mikrokontrollen<br />
Pinne!! ! Ansluten till<br />
PA0" " " Touch128, Bottom<br />
PA1" " " Touch128, Left<br />
PA2" " " Touch128, Top<br />
PA3" " " Touch128, Right<br />
PB0" " " DOGM128, RST<br />
PB3" " " DOGM128, A0<br />
PB4" " " DOGM128, CS1B<br />
PB5" " " DOGM128, SI<br />
PB7" " " DOGM128, SCL<br />
VCC " " " Power in<br />
GND" " " GND<br />
AVCC " " VCC<br />
AREF"" " VCC<br />
15
André Berglund<br />
FiM 2011<br />
Bilaga 2, kopplingsschema<br />
Bilaga 3, kretskortslayout<br />
16
André Berglund<br />
FiM 2011<br />
Bilaga 4, C-kod<br />
//************************************************************<br />
//! ! dogm128s.h<br />
//! ! Andre Berglund<br />
//! !<br />
//************************************************************<br />
//------------------------------------------------------------<br />
//! ! ST7565<br />
//------------------------------------------------------------<br />
#define DISP_START_LINE 0x40! ! // display start line = 0<br />
#define ADC_SET! ! ! 0xA1! // ADC reverse, 6o'clock viewing angle<br />
#define COM_OUT_MODE! 0xC0! ! // normal<br />
#define DISP_NORM! ! 0xA6!! // normal, no mirror<br />
#define LCD_BIAS ! 0xA2!! // bias 1/9 (duty 1/65)<br />
#define PWR_CTRL ! 0x2F! ! // booster, regulator and follower on<br />
#define BOOST1! ! ! 0xF8!! // internal booster x4<br />
#define BOOST2! ! ! 0x00! ! // internal booster x4<br />
#define CONTRAST1! ! 0x27!! // constrast set<br />
#define CONTRAST2! ! 0x81! ! // constrast set<br />
#define CONTRAST3! ! 0x16!! // constrast set<br />
#define INDICATOR1! ! 0xAC!! // no indicator<br />
#define INDICATOR2! ! 0x00! ! // no indicator<br />
#define! DISP_ON! ! 0xAF! ! // display on<br />
//------------------------------------------------------------<br />
//! ! ATMega portdef<br />
//------------------------------------------------------------<br />
#define MOSI PB5<br />
#define SCK PB7<br />
#define CS PB4<br />
#define A0 PB3<br />
#define RES PB0<br />
#define BOTTOM PA0<br />
#define LEFT PA1<br />
#define TOP PA2<br />
#define RIGHT PA3<br />
#define DATA (PORTB |= (1
André Berglund<br />
FiM 2011<br />
//************************************************************<br />
//! ! dogm128s.c<br />
//! ! André Berglund<br />
//! !<br />
//************************************************************<br />
#include <br />
#include !<br />
#include <br />
#include <br />
#include "dogm128s.h"<br />
void init_spi(void){<br />
!<br />
! DDRB = (1
André Berglund<br />
FiM 2011<br />
void init_disp(void){<br />
! RESET;!! ! ! ! ! ! // reset low -> high<br />
!<br />
! _delay_ms(200);<br />
! ENABLE;! ! ! ! ! ! // CS low, enable display<br />
!<br />
! _delay_ms(200);!<br />
! COMMAND;! ! ! ! ! ! // A0 low, command data<br />
! _delay_ms(200);<br />
! send_spi(DISP_START_LINE);<br />
! send_spi(ADC_SET);<br />
! send_spi(COM_OUT_MODE);<br />
! send_spi(DISP_NORM);<br />
! send_spi(LCD_BIAS);<br />
! send_spi(PWR_CTRL);<br />
! send_spi(BOOST1);<br />
! send_spi(BOOST2);<br />
! _delay_ms(200);<br />
! send_spi(CONTRAST1);<br />
! send_spi(CONTRAST2);<br />
! send_spi(CONTRAST3);<br />
! send_spi(INDICATOR1);<br />
! send_spi(INDICATOR2);<br />
! //send_spi(INDICATOR3);<br />
! send_spi(DISP_ON);<br />
!<br />
! DISABLE;! ! ! ! ! ! // CS high, disable display<br />
! ! ! ! ! !<br />
}<br />
!<br />
19
André Berglund<br />
FiM 2011<br />
void clear_disp(){<br />
! ENABLE;<br />
!<br />
! uint8_t page;<br />
! for (page = 0; page < 8; page++){<br />
! !<br />
! ! COMMAND;<br />
! ! send_spi(0xB0 + page);<br />
! ! send_spi(0x10);! ! ! // column adress of 4 MSB<br />
! ! send_spi(0x00);! ! ! // column adress of 4 LSB<br />
! !<br />
! ! uint8_t column;<br />
! ! for (column = 0; column < 128; column++){<br />
! ! ! DATA;<br />
! ! ! send_spi(0x00);<br />
! ! }<br />
! }<br />
!<br />
! DISABLE;<br />
}<br />
void goto_xy(char xcol, char ypage)<br />
{<br />
! char set[] = {0xB0, 0x10, 0x00};<br />
! set[0] = set[0] + ypage;<br />
! set[2] = set[2] + (xcol & 0x0F);<br />
! set[1] = set[1] + (xcol >> 4);<br />
!<br />
! COMMAND;<br />
!<br />
! send_spi(set[0]);<br />
! send_spi(set[2]);<br />
! send_spi(set[1]);<br />
}<br />
20
André Berglund<br />
FiM 2011<br />
//------------------------------------------------------------<br />
//! ! ! ! ADC<br />
//------------------------------------------------------------<br />
volatile unsigned char xpos(){<br />
!<br />
! DDRA = 0x00;! ! ! ! // "reset"<br />
! PORTA = 0x00;<br />
! _delay_ms(20);<br />
!<br />
! DDRA = (1
André Berglund<br />
FiM 2011<br />
!<br />
!<br />
! ! !<br />
! PORTA = (1