Linefollower robot śledzący linię



Podobne dokumenty
Poradnik programowania procesorów AVR na przykładzie ATMEGA8

Podstawowe urządzenia peryferyjne mikrokontrolera ATmega8 Spis treści

Raport z budowy robota typu Linefollower Mały. Marcin Węgrzyn

Linefollower Torpeda. Magdalena Kaczorowska

MCAR Robot mobilny z procesorem AVR Atmega32

Cwiczenie nr 1 Pierwszy program w języku C na mikrokontroler AVR

Podstawowe urządzenia peryferyjne mikrokontrolera ATmega8 Spis treści

LABORATORIUM - ELEKTRONIKA Układy mikroprocesorowe cz.2

Język C. Wykład 9: Mikrokontrolery cz.2. Łukasz Gaweł Chemia C pokój 307

dokument DOK wersja 1.0

Instrukcja obsługi. PROGRAMATOR dualavr. redflu Tarnów

Uproszczony schemat blokowy zespołu 8-bitowego timera przedstawiono na rys.1

Edukacyjny sterownik silnika krokowego z mikrokontrolerem AT90S1200 na płycie E100. Zestaw do samodzielnego montażu.

LOW ENERGY TIMER, BURTC

Inż. Kamil Kujawski Inż. Krzysztof Krefta. Wykład w ramach zajęć Akademia ETI

Instrukcja obsługi programatora AVR Prog USB v2

Instrukcja obsługi programatora AVR Prog USB v2

Instrukcja obsługi programatora AVR Prog USB v2

AVR DRAGON. INSTRUKCJA OBSŁUGI (wersja 1.0)

Politechnika Gdańska Wydział Elektrotechniki i Automatyki Katedra Inżynierii Systemów Sterowania

Układy czasowo-licznikowe w systemach mikroprocesorowych

MozhePoyedzye. Robot klasy MiniSumo. Konrad Bednarek Michał Rataj

Mikroprocesory i Mikrosterowniki Liczniki Timer Counter T/C0, T/C1, T/C2

Instrukcja obsługi programatora AVR Prog USB v2

Zestaw Startowy EvB. Więcej informacji na stronie:

Instytut Teleinformatyki

1.1 Co to jest USBasp? Parametry techniczne Obsługiwane procesory Zawartość zestawu... 4

Autonomiczny robot mobilny w kategorii linefollower MORPROF

Uniwersalny sterownik silnika krokowego z portem szeregowym RS232 z procesorem AT90S2313 na płycie E200. Zestaw do samodzielnego montażu.

Immobilizer samochodowy otwierający dostęp poprzez kod czteroznakowy.

Autonomiczny robot mobilny LF3 klasy linefollower. Jacek Jankowski

Mikrokontroler ATmega32. System przerwań Porty wejścia-wyjścia Układy czasowo-licznikowe

Raport z budowy robota Krzysio

SML3 październik

1. Wprowadzenie Programowanie mikrokontrolerów Sprzęt i oprogramowanie... 33

Systemy wbudowane. Uniwersytet Łódzki Wydział Fizyki i Informatyki Stosowanej. Witold Kozłowski

Wprowadzenie do podstaw programowania AVR (na przykładzie mikrokontrolera ATmega 16 / 32)

Ćwiczenie 5 Zegar czasu rzeczywistego na mikrokontrolerze AT90S8515

LITEcompLPC1114. Zestaw ewaluacyjny z mikrokontrolerem LPC1114 (Cortex-M0) Sponsorzy:

Wizualizacja stanu czujników robota mobilnego. Sprawozdanie z wykonania projektu.

Instytut Teleinformatyki

Politechnika Gdańska Wydział Elektrotechniki i Automatyki Katedra Inżynierii Systemów Sterowania

ISP ADAPTER. Instrukcja obsługi rev.1.1. Copyright 2009 SIBIT

Niektóre piny mogą pełnić różne role, zależnie od aktualnej wartości sygnałów sterujących.

Wydział Elektryczny. Katedra Telekomunikacji i Aparatury Elektronicznej. Konstrukcje i Technologie w Aparaturze Elektronicznej.

KAmodQTR8A. Moduł QTR8A z ośmioma czujnikami odbiciowymi

SYSTEM PRZERWAŃ ATmega 32

Wyniki (prawie)końcowe - Elektroniczne warcaby

Systemy wbudowane. Uniwersytet Łódzki Wydział Fizyki i Informatyki Stosowanej. Witold Kozłowski

Hardware mikrokontrolera X51

Politechnika Białostocka

Instrukcja dla: Icomsat v1.0 SIM900 GSM/GPRS shield for Arduino oraz dla GPRS Shield produkcji Seeedstudio.

MOBOT RoboSnake. Moduł wieloczłonowego robota

Zegar Cieni Instrukcja montażu

2.1 Porównanie procesorów

Programowanie mikrokontrolerów AVR

SigmaDSP - zestaw uruchomieniowy dla procesora ADAU1701. SigmaDSP - zestaw uruchomieniowy dla procesora ADAU1701.

Firma DAGON Leszno ul. Jackowskiego 24 tel Produkt serii DAGON Lighting

Podstawowe urządzenia peryferyjne mikrokontrolera ATmega8 Spis treści

Analogowy sterownik silnika krokowego oparty na układzie avt 1314

2. Architektura mikrokontrolerów PIC16F8x... 13

DWUKIERUNKOWY REGULATOR SILNIKA DC VDC 20A

E-TRONIX Sterownik Uniwersalny SU 1.2

Płytka uruchomieniowa XM64

ZL8AVR. Płyta bazowa dla modułów dipavr

Instrukcja sterowania T4Power. Sterowanie T4Power. Instrukcja uruchomienia i obsługi.

Kod produktu: MP01611

Programowanie mikrokontrolerów AVR z rodziny ATmega.

PX342. Driver PWM 1x10A INSTRUKCJA OBSŁUGI

REGULATOR ŁADOWANIA 12V / 24V / 36V / 48V DC DO INSTALACJI ELEKTROWNI WIATROWEJ

Szkolenia specjalistyczne

INSTRUKCJA OBSŁUGI IMMOBILIZERA TRANSPONDEROWEGO

Wbudowane układy peryferyjne cz. 2 Wykład 8

Centrala alarmowa ALOCK-1

Programator AVR MKII. Instrukcja obsługi. Copyright by Barion

SERIA D STABILIZATOR PRĄDU DEDYKOWANY DO UKŁADÓW LED

Elastyczne systemy wytwarzania

Obługa czujników do robota śledzącego linie. Michał Wendland czerwca 2011

Spis treści. Projekt współfinansowany ze środków Unii Europejskiej w ramach Europejskiego Funduszu Społecznego

Zestaw uruchomieniowy z mikrokontrolerem LPC1114 i wbudowanym programatorem ISP

Pętle. Dodał Administrator niedziela, 14 marzec :27

Technika Mikroprocesorowa Laboratorium 5 Obsługa klawiatury

. Polski. Dekoder rozjazdów GEODec C1O. DEKODER ROZJAZDÓW ROCO GeoLine. GEODec C1O. Instrukcja obsługi, programowania i budowy dekodera

Płytka uruchomieniowa XM32

Płytka uruchomieniowa AVR oparta o układ ATMega16/ATMega32. Instrukcja Obsługi. SKN Chip Kacper Cyrocki Page 1

Proste układy wykonawcze

Programator AVR USBasp

Podstawy budowy robotów

LABORATORIUM. TIMERY w mikrokontrolerach Atmega16-32

Politechnika Poznańska Wydział Budowy Maszyn i Zarządzania. Sterowniki Urządzeń Mechatronicznych laboratorium. Ćw. 3: Timer v1.0

PikoCNC Board E v1.0 Copyright 2015 PPHU ELCOSIMO 1. PikoCNC Board E v1.0 wersja 1.0

Kod produktu: MP01611-ZK

Organizacja pamięci VRAM monitora znakowego. 1. Tryb pracy automatycznej

Konfiguracja i programowanie PLC Siemens SIMATIC S7 i panelu tekstowego w układzie sterowania napędami elektrycznymi. Przebieg ćwiczenia

ODBIORNIK ZDALNEGO STEROWANIA REMC1 DO MARKIZ I ROLET MODEL INSTRUKCJA

Programowanie mikrokontrolerów AVR z rodziny ATmega.

W semestrze letnim studenci kierunku Aplikacje Internetu Rzeczy podczas ćwiczeń z programowania CAD/CAM

Projekt i wykonanie robota klasy Micromouse

Programator ZL2PRG jest uniwersalnym programatorem ISP dla mikrokontrolerów, o budowie zbliżonej do STK200/300 (produkowany przez firmę Kanda).

Mikrokontroler ATmega32. Język symboliczny

Transkrypt:

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/