07.12.2009 Technika Mikroprocesorowa II Wtorek, godzina 14.00 Zespół w składzie: Kalita Kamil Kempiński Bartosz Pociecha Michał Linefollower robot śledzący linię I. Cel Celem projektu było stworzenie w pełni autonomicznego robota, którego zadaniem jest przejechanie toru wyznaczonego przez czarną linię o szerokości 1,5-2 cm znajdującą się na białej powierzchni. II. Plan prac 1. Stworzenie schematu ideowego robota. 2. Projektowanie płytek PCB głównej płytki oraz płytki z czujnikami. 3. Tworzenie podwozia z układem napędowym. 4. Łączenie robota w całość. 5. Programowanie robota. III. Wstęp Układ robota wykorzystuje ośmiobitowy mikrokontroler AVR ATtiny 2313. Trasa zostaje wykryta za pomocą czujników odbiciowych, które znajdują się na osobnej płytce i są połączone przewodami z główną płytką PCB. Zastosowaliśmy 6 transoptorów SG2BC ustawionych następująco: a) 2 czujniki z przodu, odpowiednio 7 mm po prawej i po lewej od środka płytki (biorąc pod uwagę jej długość) b) 4 czujniki cofnięte o 2 cm w stosunku do przednich, rozmieszczone symetrycznie względem środka, odległe od siebie (parami) po 4 i nieco ponad 8cm Rozmieszczenie czujników (tu celowo pokolorowanych na niebiesko) Ilustracja 1: Rozmieszczenie czujników (tu celowo pokolorowanych na niebiesko)
Sygnał z czujników przekazywany jest do mikrokontrolera za pośrednictwem dwóch wzmacniaczy operacyjnych LM324. Za pomocą potencjometru ustala się odpowiednie napięcie odniesienia pozwalające określić, kiedy czujnik napotkał linię, a kiedy nie. Na podstawie danych z czujników procesor steruje dwoma silnikami DC. Sterowanie odbywa się za pomocą układu mostkującego L298 połączonego z mikrokontrolerem i silnikami, które są niezależne od siebie, a różnica w prędkości ich obrotów powoduje skręt robota. Ustalanie szybkości obrotów silnika polega na modulacji szerokości impulsu podawanego na wejścia enable mostka (PWM). Robot został wyposażony w złącze programatora ISP. Korzystamy również ze stabilizatora napięcia 7805, dzięki czemu korzystamy tylko z jednego źródła zasilania dla silników (11,1 V) oraz reszty podzespołów (5 V). Do programowania procesora użyto: język C, środowisko programowania WinAVR z kompilatorem GCC. Do wgrania pliku w formacie IntelHEX korzystamy z programatora USB i programu AVRDude. IV. Przebieg prac Do zaprojektowania obu płytek PCB wykorzystaliśmy program Eagle. Najpierw stworzyliśmy schematy, a następnie na ich podstawie wykonaliśmy projekty płytek. W trakcie projektowania na bieżąco uczyliśmy się obsługi Eagle a. Ponadto proces tworzenia wiązał się z koniecznością odszukania i pobrania odpowiednich bibliotek, a w przypadku zastosowanych przez nas transoptorów SG2BC musieliśmy również stworzyć własną bibliotekę w oparciu o datasheet. Po stworzeniu schematu kupiliśmy części potrzebne do wykonania płytek PCB. Dopiero w tym momencie można było poprawić schemat i zaprojektować płytki rozmieścić elementy i połączyć je ścieżkami, gdyż konieczne było uwzględnienie wymiarów tych konkretnych, posiadanych przez nas części, odległości między ich nóżkami etc. Kolejnym etapem było wytrawienie płytek i wlutowanie elementów. Schematy wydrukowaliśmy laserową drukarką na kredowym papierze. Następnie przy użyciu głównie żelazka i wody przenieśliśmy je na przycięte do odpowiednich rozmiarów kawałki laminatu. Warto zauważyć, że rozmiar płytki z czujnikami był podyktowany między innymi ograniczeniami, które są związane z używaniem darmowej wersji Eagle a. Samo wytrawienie płytek sprawiło nam nieco problemów, gdyż skorzystaliśmy z pożyczonego, wielokrotnie używanego uprzednio przez właściciela środka. Mimo początkowego podgrzania i mieszania roztworu, proces wytrawiania trwał bardzo długo. W pewnym momencie zaczęły nawet odpadać kawałki toneru. Na szczęście udało się uratować sytuację przy pomocy flamastra. Po wytrawieniu wywiercono otwory, przylutowano elementy i ocynowano ścieżki. Szkielet robota stworzyliśmy w oparciu o klocki lego, gdyż jest to budulec umożliwiający łatwe przeróbki. Do napędzania robota używamy silników z napędów CD wraz z odpowiednimi przekładniami. Silniki te w pierwotnych planach miały posłużyć tylko do testów, zanim nie otrzymamy zamówionych, lepszych silników. Ostatecznie jednak silniki te do nas nie dotarły, a te, które już mieliśmy, okazały się sprawdzać na tyle przyzwoicie, że zarzuciliśmy myśl, by je wymieniać. Do zasilania robota zastosowano pakiet litowopolimerowy o napięciu 11,1 V.
Fotografia 1: Brute Force Do zasilania robota zastosowano pakiet litowo-polimerowy o napięciu 11,1 V. Wcześniej empirycznie dobieraliśmy optymalne parametry zasilania dla stosowanych silników i uznaliśmy, że napięcie 10-12V zapewni nam dobrą, dostosowaną do czułości transoptorów szybkość, jak również wystarczy do zasilania układu obliczeniowego. Wybraliśmy pakiet litowo-polimerowy, jako że jest to względnie tanie i nowoczesne rozwiązanie, popularne zwłaszcza wśród modelarzy. Akumulatory tego typu posiadają tylko jedną wadę: specyficzne zależności dotyczące ich ładowania i rozładowywania. Nie wolno dopuścić do spadku pojemności poniżej pewnego poziomu; także niewielkie przeładowanie może doprowadzić do uszkodzenia takiego akumulatora. Stąd wyjścia do balancera, który jest nieodzownym (oprócz, oczywiście, ładowarki) narzędziem do ładowania układu zasilającego. Konstrukcja robota wielokrotnie ulegała modyfikacjom. Było kilka wariantów przymocowania płytki z czujnikami. Ostatecznie zdecydowaliśmy się na wariant widoczny na zdjęciu powyżej. Płytka ślizga się na płozach wykonanych z elementów, które uprzednio służyły nam do przymocowania głównej płytki. Płozy te, poza odpowiednio niskim tarciem przy skręcaniu, zapewniają również odpowiednią odległość czujników od podłoża. Trzy klamerki nie tylko zapewniają groźny wygląd zgodny z przyjętą przez nas nazwą robota (Brute Force), ale również dociążają przód płytki z czujnikami nie dopuszczając do jej podnoszenia się, a tym samym do możliwości przeoczenia linii przez przednie czujniki. Reszta konstrukcji również parokrotnie ulegała przeobrażeniom, ponieważ szukaliśmy optymalnych ustawień. Rozmieszczenie kół zostało starannie dobrane tak, aby obciążenie przodu było jak najmniejsze (a tym samym były jak najmniejsze opory w czasie skręcania), jak również aby robot był stabilny i nie przechylał się do tyłu, co wiązałoby się z unoszeniem płytki z czujnikami. Aby poprawić działanie czujników, zrobiliśmy przesłonę z czarnej taśmy izolacyjnej. Również kod, który napisaliśmy dla robota ulegał modyfikacjom. W pewnym momencie, nabrawszy nieco doświadczenia, całkowicie zmieniliśmy założenia co do programu. Wiązało się to z koniecznością zmodyfikowania głównej płytki PCB. A mianowicie trzeba było dołączyć wyjścia z Timera 1 procesora na wejścia enable układu
mostkującego. Takiego połączenia nie uwzględnialiśmy w pierwszej koncepcji. Co więcej, wyjścia z Timera były podłączone na inne wejścia mostka, a wejścia enable mostka były połączone jeszcze z innymi pinami procesora. Operacja polegająca na zamianie miejsc docelowych dwóch par sygnałów z procesora powiodła się. W tym celu dolutowano kolejne zworki. Przewody te widać na zdjęciu pomiędzy procesorem a układem mostkującym. V. Opis schematów płytek PCB Ze względu na rozmiary schematu głównej płytki, w trosce o czytelność, podzielimy schemat na części i opiszemy je po kolei. Schemat 1 Na schemacie nr 1 widoczna jest część głównej płytki zawierająca procesor, diody LED, kwarc oraz gniazdo do programatora. Przycisk S1 służy do resetowania procesora. Natomiast przycisk S2 umieściliśmy tu z myślą o startowaniu robota. SV1 to gniazdo do programatora. Jego goldpiny zostały połączone z odpowiednimi nóżkami procesora służącymi właśnie do programowania. LED1 to zielona, a LED2 to czerwona dioda. Obiema możemy sterować za pomocą procesora. Pierwsza świeci się, gdy przednie czujniki widzą linię, a druga, gdy tylnimi wykryto kąt prosty. Q1 to kwarc, którym początkowo taktowaliśmy procesor. Kwarc, jak widać na schemacie, musi być połączony z pinami XTAL1 i XTAL2 procesora. Obecnie kwarc jest nieużywany, gdyż procesor taktujemy wewnętrznym zegarem o częstotliwości 8 MHz. Wyższa częstotliwość jest bardziej przez nas pożądana. Zegar wewnętrzny cechuje się dużą niedokładnością oraz wrażliwością na temperaturę. W naszym projekcie nie jest potrzebny dokładny zegar. Aby skonfigurować mikrokontroler do pracy z zegarem wewnętrznym konieczne było zaprogramowanie Fuse- Bitów. Ustawiliśmy Fuse-Bity w sposób podany w dokumentacji: CKSEL3..0 0100. Należało pozostawić Fuse-Bit CKDIV8 niezaprogramowany, jego zaprogramowanie powodowało dzielenie częstotliwości wewnętrznego zegara przez 8.
Schemat 2 Piny procesora PB0 PB5 są połączone z wejściami układu mostkującego L298 i za ich pomocą steruje się dwoma silnikami prądu stałego. Powyższy schemat nie uwzględnia przeróbek opisanych we wcześniejszym rozdziale dokumentacji. Silniki podłącza się do goldpinów znajdujących się po prawej stronie schematu. Na wejście VS mostka podaje się napięcie zasilające silniki. Diody po prawej od mostka zabezpieczają go przed spaleniem i są podłączone wg opisu z dokumentacji tego układu. Schemat 3
SV2 to listwa goldpinowa. Jej piny nr 8 i 7 to odpowiednio VCC i uziemienie. Na pozostałe przekazywane są sygnały z transoptorów znajdujących się na osobnej płytce. Sygnały te docierają do odpowiednich pinów portu D procesora po przejściu przez dwa układy LM324. Każdy LM324 to zespół czterech wzmacniaczy operacyjnych. Na schemacie znalazło się ich sześć, a nie osiem, ponieważ dwa są nieużywane. Do określenia, jaki poziom sygnału odpowiada linii, a który oznacza jej brak, wykorzystuje się potencjometr R3. IC4 to stabilizator obniżający napięcie na 5V, natomiast JP1 to dwa goldpiny, do których podpina się akumulator. Schemat 4 Schemat nr 4 to schemat płytki z czujnikami. Transoptory na podstawie tego, co widzą, generują sygnały, które następnie poprzez przewody podłączone do listwy goldpinowej SV1 zostają przekazane do głównej płytki robota. VI. Opis programu Program, który został napisany na platformę Brute Force, przechodził wiele zmian w celu ulepszenia działania robota. Ta część dokumentacji zawiera opis zmian, które zachodziły w programie oraz opis wszystkich funkcji i makrodefinicji użytych w końcowej wersji programu. 1. Makra. Podczas pracy nad projektem zestaw makr nie zmieniał się. tu zostaną opisane wszystkie makra które zostały użyte w programie. Makra wykorzystują trzy rejestry:
DDRX - rejestr który służy do inicjalizowania danego portu jako wejście i wyjście. Wpisanie 1 oznacza inicjalizację wyjścia, 0 wejścia. Przykładowa inicjalizacja 8 bitowego rejestru X: DDRX = 0xF0 Pierwsza połowa portu X - wyjście. Druga połowa portu X - wejście. PINX - rejestr z którego można odczytać wartość danego portu. Wyprowadzenie portu X musi być zainicjalizowane jako wejście. PORTX - rejestr służący do ustawiania wartości wyprowadzeń danego portu. Wyprowadzenie portu X musi być zainicjalizowane jako wyjście. Nazwy symboliczne rejestrów zawarte są w bibliotece avr/io.h. Wygląd używanych makr z pliku makra.h #define PORT(x) XPORT(x) #define XPORT(x) (PORT##x) Operator podwójnego znaku ## pozwala na zastępowanie części ##x przez dowolny argument wywołania. Podwójna konstrukcja makra pozwala na używanie predefiniowanych stałych różnych od nazw portów. Przykład: PORT(SW_PORT) zostaje rozwinięte w PORTB co pozwala na ustawianie wartości portu B. Gdyby użyć jedynie definicji: #define PORT(x) (PORT##x) wówczas poprzednie rozwinięcie było by błędne : PORTSW_PORT. 2. Opis synchronicznego sposobu sterowania ruchem robota. W pierwszej wizji projektu sterowanie robotem przewidziane zostało w wersji synchronicznej. Program działał z wykorzystaniem przerwania sprzętowego następującego przy przepełnieniu ośmiobitowego licznika Timer/Counter0. W głównej pętli programu analizowany był odczyt z portu czujników. Wynikiem analizy było ustawienie zmiennej sterującej pracą programu. Podejście to miało poważną wadę której rezultatem było zmienienie architektury programu. Przepełnienie licznika wymagało przerwania analizy odczytów z portu czujników, następował przeskok do kodu sterującego pracą silników. Problem polegał na tym, że niemożliwe było jednoczesne przeglądanie drogi i sterowanie pracą silników. Ta wada przekładała się na efektywność pracy robota. Poniżej znajdują się komentarze do pierwszego kodu programu. volatile uint8_t tryb = 0xff; Jest to bajt służący do sterowania ruchem robota. Modyfikator volatile zapewnia, że zmienna nie będzie optymalizowana w czasie działania programu. Jej odczyt będzie następował zawsze z pamięci, nie z rejestru w którym może być przechowywana. Volatile oznacza że zmienna może zmieniać się w każdej chwili działania programu, nawet w niewidoczny dla niego sposób. Wszystkie zmienne globalne używane w programie i będące w użyciu w przerwaniu procesora powinny posiadać ten modyfikator.
TCCR0B = 1<<CS01 1<<CS00; Rejestr sterujący TCCR0B odpowiada za pracę licznika 0. Ten ciąg instrukcji odpowiada za ustawienie preskalera na wartość 64. TIMSK = 1<<TOIE0; Rejestr TIMSK odpowiada za konfigurację przerwań procesora. Ustawienie bitu TOIE0 powoduje włączenie przerwań powstałych po przepełnieniu licznika Timer/Counter0. sei(); Jest funkcją z biblioteki avr\signal.h. sei() powoduje globalne włączenie przerwań procesora. Na listingu 1 znajduje się wycinek głównej pętli programu. W każdej iteracji pobierany jest obraz trasy z portu czujników. W zależności od pobranej wartości ustawiana jest zmienna tryb. Tu widać kolejną wadę rozwiązania. Mianowicie instrukcja switch pozwala porównywać jedynie odczyt z całego portu. W późniejszej wersji programu instrukcję switch zastąpiono instrukcją if() porównującą poszczególne bity portu czujników. Należy zauważyć, że odczyt z czujnika który aktualnie znajduje się nad trasą jest logicznym zerem. while(1){ switch(pin(sensor_port)){ case 47: tryb = 0x00; break;... } } listing 1 void obsluzprzycisk(uint8_t maska, void(*proc)(void) ); Jest to funkcja która powoduje uruchomienie procedury przy odpowiednim warunku. Ta funkcja przeznaczona jest dla obsługi przycisku. Po naciśnięciu przycisku następuje wyjście z pętli i przejście do dalszej części programu. Ta procedura pozwala na startowanie robota po naciśnięciu przycisku. Procedura ta również korzysta z przerwania systemowego aby eliminować drgania styków przycisku. Na listingu 2 znajduje się wycinek kodu przerwania systemowego. Stała SIG_OVERFLOW0 podana jako argument funkcji SIGNAL oznacza, ze podczas przepełnienia się licznika Timer/Counter0 zostanie wykonany przeskok z bieżącego miejsca programu do początku procedury SIGNAL(SIG_OVERFLOW0). Zmienna st jest ustawiana przez procedurę start() wywoływaną przez naciśnięcie przycisku. Podczas przerwania porównywana jest stała tryb z odpowiednimi wartościami. Na listingu podany jest kod który powoduje taktowanie sygnału na lewym silniku. Tryb 0x00 powoduje skręcanie robota w lewo. Należy zwrócić uwagę, że sterowanie silnikiem odbywa się poprzez sterowanie sygnałem podawanym na wyprowadzenie silnika(poprzez układ mostkujący). W kolejnym rozwiązaniu sterowanie pracą silnika odbywa się w inny sposób.
SIGNAL(SIG_OVERFLOW0){ if(st == 0){ if(tryb == 0x00){ if(i){ PORT(MOTOR_PORT) &= ~(1<<LEFT_MOTOR_1); } else PORT(MOTOR_PORT) = 1<<LEFT_MOTOR_1; PORT(MOTOR_PORT) = 1<<RIGHT_MOTOR_1; }... } listing 2 3. Opis asynchronicznego sposobu sterowania ruchem robota. W tej części dokumentacji opisany jest sposób starowania robotem w sposób asynchroniczny. W przeciwieństwie do poprzedniego rozwiązania obciążającego niepotrzebnie procesor w tym rozwiązaniu zastosowano bardziej efektywną metodą sterowania pracą silników. Sterowanie pracą silników odbywa się za pomocą kanału PWM sprzężonego z szesnastobitowym licznikiem Timer/Counter1. Kanał PWM taktuje tym razem sygnał ENABLE danego silnika. Enable jest to wyprowadzenie mostka H. Umieszczeniu na wyjściu enable logicznej jedynki powoduje uruchomienie silnika. Dwa pozostałe wyprowadzenia input służą do polaryzacji silnika. Odpowiednie ustawienie wejść input mostka powoduje obroty w przód lub w tył. Opis działania PWM. We wcześniejszej wersji przez pewien czas procesor nie wykonywał czytania z portu czujników ponieważ zajęty był działaniem w kodzie przerwania. W tym rozwiązaniu przerwania systemowe są niepotrzebne. W programie inicjalizowany jest tryb działania PWM, który taktuje sygnał enable układu mostka, włączając i wyłączając silnik. Taktowanie sygnały PWM powoduje zmniejszenie prędkości silnika. Tryb pracy PWM został wybrany według dokumentacji mikrokontrolera. Tryb Phase and Frequency Correct jest przeznaczony specjalnie do sterowania silnikami dlatego też ten tryb został wybrany do programu. Inicjalizacja pracy PWM zostaje wykonana za pomocą odpowiednich rejestrów sterujących. TCCR1A=0xA0; TCCR1B=0x12; listing 3 Listing 3 ilustruje ustawienie rejestrów TCCR1A i B które inicjalizuje PWM w tryb PaFC, przy nieodwróconej logice wyjść. W trybie PaFC który został ustawiony licznik Timer/Counter1 zlicza w górę dopóki nie dotrze do wartości definiowanej jako TOP. W tej inicjalizacji wykorzystany został rejestr ICR1 do zdefiniowania TOP. Gdy Licznik zliczy odpowiednią ilość impulsów i dotrze do stałej TOP zmienia kierunek liczenia. Zmiana stanu wyprowadzenia mikrokontrolera następuje gdy licznik posiada wartość zgodną z wartością wpisaną do rejestru OCR1X. Działanie zainicjalizowanego PWM ilustruje rysunek 1.
Rys 1 Kanały PWM wykorzystywane do obsługi silników wyprowadzone są na port B mikrokontrolera. Kanał A PB3, kanał B PB4. Rejestry OCR1A i B pozwalają na kontrolę częstotliwości i fazy(w tym znaczeniu stosunku stanu wysokiego do niskiego) zmiany stanów wspomnianych stanów wyprowadzeń mikrokontrolera. Rys 2 Na rysunku 2 zaznaczone są wyprowadzenia mikrokontrolera, które są kanałami PWM dla licznika Timer/Counter1. Opis głównej pętli programu. Część głównej pętli programu zawarta jest na listingu 4. Tym razem zmienna tryb służy jedynie do przechowywania odczytu z portu z czujnikami. Zmienna jest negowana, ponieważ pozwala to na łatwiejszą obsługę analizy odczytu. W przeciwieństwie do poprzedniego rozwiązania synchronicznego, instrukcja switch została zastąpiona szeregiem wykluczających się instrukcji if - else. Pozwoliło to na eliminację szumów z czujników. Poprzednio błędy odczytów z czujników powodowały ominięcie całej instrukcji switch. W podanym niżej kodzie sprawdzane są odpowiednio kolejne bity. Największy priorytet mają bity, które odpowiadają dwu przednim czujnikom. Następnie
parami są sprawdzane tylne czujniki, co pozwala w skuteczny sposób wykrywać fragmenty trasy tworzące kąty proste. W takim przypadku jeden z silników obraca się do przodu, a drugi do tyłu, dzięki czemu robot obraca się w miejscu nie wypadając z toru. W przypadku przednich czujników w jednym przypadku jeden z silników obraca się do przodu, a drugi stoi, a w drugim jest na odwrót. while(1) { } tryb = PIN(SENSOR_PORT); tryb = ~tryb; wdt_reset(); if (tryb & (1<<FL)){ PORTD = (1<<LED_R); PORTB &= ~(1<<LED_G); lewystop(); prawyprzod(9500); } else{... listing 4 Robot porusza się w prosty, jednak bardzo skuteczny sposób. Jego budowa i ułożenie czujników powodują, że obecny, prosty algorytm pozwala na dokładne trzymanie się nawet skomplikowanej trasy. W ostatniej wersji przeznaczonej na konkurs (o czym będzie w następnym punkcie dokumentacji) włączony jest również system watchdog i wyłączone zostało oczekiwanie na przycisk przed startem. System watchdog pozwala na wymuszenie programowo restartu mikrokontrolera, jeżeli licznik watchdog nie zostanie odpowiednio szybko zresetowany. Pozwala to na uniknięcie błędów procesora. Jeżeli podczas drogi procesor ulegnie zawieszeniu, system watchdog zresetuje mikrokontroler po upływie zainicjalizowanej wartości. Robot wtedy nie zatrzyma się podczas jazdy. Inicjalizacja przedstawiona jest na listingu 5. W programie resetowanie odbywało się w głównej pętli programu. wdt_enable(wdto_500ms); wdt_reset(); //inicjalizacja watchdog //reset licznika watchdog listing 5 VII. Test robota w warunkach bojowych konkurs Robotic Arena 2009 we Wrocławiu 28 listopada 2009 roku odbyły się we Wrocławiu zawody robotów Robotic Arena. Jest to obecnie największa tego typu impreza w Polsce. Wśród czterech konkursowych kategorii znalazła się również kategoria robotów śledzących linię. Postanowiliśmy sprawdzić, jak Brute Force prezentuje się na tle innych tego typu robotów z kraju i zagranicy. Na konkursie przede wszystkim trzeba było ponownie dostroić czujniki i poprawić przesłonę, gdyż, ze względu na inne oświetlenie niż podczas testów w Krakowie, początkowo robot nie widział linii. Dodatkowo góra płytki została zaklejona czarną taśma izolacyjną, aby nie przepuszczała
światła. Brute Force przejechał całą trasę w każdym z dwóch przejazdów eliminacyjnych. W pierwszym przejeździe uzyskał czas 18,08 s, natomiast w drugim, kiedy w programie nieco zwiększyliśmy mu szybkość, zgubił linię na łączeniu płyt i wykonał dwa obroty w miejscu, zanim ruszył dalej. Z tego powodu pokonanie toru zajęło mu ok. 19 sekund. Trasa była stworzona z płyt o rozmiarze metr na metr. Co prawda szpary miedzy płytami zostały zaklejone białą taśmą, jednak nie wyeliminowało to wszystkich nierówności i różnic w wysokości płyt. Stąd te obroty. Niektóre roboty wręcz zaczepiały się czujnikami o łączenia płyt. Uzyskany czas nie pozwolił zbliżyć się do osiągnięć najlepszej szóstki, która przeszła do finału rozgrywanego wieczorem w auli. Mimo to uważamy zajęcie piętnastego miejsca wśród 58 linefollowerów (bo na takim miejscu został sklasyfikowany Brute Force) za bardzo przyzwoity wynik jak na pierwszą naszą konstrukcję i pierwszy start w tego typu zawodach. Fotografia 2: Zawody. Filmy z konkursowych przejazdów oraz z przejazdu na naszej testowej, znacznie trudniejszej trasie zostały dołączone do sprawozdania. Dołączyliśmy również projekt z Eagle a oraz kody źródłowe zarówno nowej, jak i starej wersji programu. VIII. Rozważane zmiany i ulepszenia projektu. W przypadku gdybyśmy zaczynali projekt od początku i mielibyśmy trzymać się ustalonych przez nas założeń, przede wszystkim od razu pomyślelibyśmy o asynchronicznym sterowaniu silnikami. A zatem już na etapie projektowania TimerCounter1 procesora połączylibyśmy z wejściami enable układu mostkującego. Przy napięciu 11,1 V stabilizator napięcia bardzo się przegrzewa. Dlatego też zdecydowalibyśmy się na dwa źródła zasilania 5 lub 7,4 V na układ logiczny i 11,1 V na silniki. Rozważany jest też układ pasywnego chłodzenia. Oczywiście wykorzystanie drugiego akumulatorka wiąże się ze wzrostem wagi robota, czyli potrzebne byłyby może wolniejsze, ale mocniejsze silniki. Moc ta zapewne przełożyłaby się na większą odporność na wszelkiego rodzaju niedoskonałości trasy jak nierówności czy niedoklejona taśma. Skoro korzystamy z wewnętrznego zegara procesora, to
nie jest nam potrzebny zewnętrzny kwarc. Warto byłoby natomiast zwiększyć ilość czujników z przodu płytki z czujnikami. Przy wolniejszych, ale mocniejszych silnikach można by jeździć na dwóch silnikach jednocześnie i stopniowo zwiększać szybkość na prostych. Na pewno nie zrezygnowalibyśmy z tylnych czujników, bowiem bardzo dobrze sprawdzają się przy kątach prostych, a takie właśnie stawialiśmy im wymagania. IX. Literatura i źródła dokumentacji. Kurs programowania mikrokontrolerów rodziny AVR w języku C. http://www.kursc.dioda.com.pl/index.php?user=go%b6%e6 Kurs programowania w języku C mikrokontrolerów, opis konfiguracji środowiska programowania. http://www.edw.com.pl/index.php? module=contentexpress&func=display&btitle=ce&mid=&ceid=101 Źródło dokumentacji użytych układów elektronicznych. http://www.alldatasheet.com/ Źródła przydatne w wyborze zasilania robota. http://www.dioda.com.pl/forum/topics20/zasilanie-robotow-czyli-jak-i-czymkarmic-robota-vt2147.htm http://pl.wikipedia.org/wiki/akumulator_litowo-polimerowy http://pl.wikipedia.org/wiki/akumulator_niklowo-metalowo-wodorowy Pogląd na konstrukcję innych robotów i wygląd trasy. http://www.konar.pwr.wroc.pl/