INSTYTUT CYBERNETYKI TECHNICZNEJ POLITECHNIKA …kreczmer/wds/projekty/SPR/...8 DB1 H/L DATA BIT1 9...

18
INSTYTUT CYBERNETYKI TECHNICZNEJ POLITECHNIKA WROCAWSKA Wizualizacja danych sensorycznych Tarcza dla wskanika laserowego IRb-1400 Prowadzcy: dr in.. Bogdan Kreczmer Wykonali: Mariusz Zalewski Krzysztof Klempa

Transcript of INSTYTUT CYBERNETYKI TECHNICZNEJ POLITECHNIKA …kreczmer/wds/projekty/SPR/...8 DB1 H/L DATA BIT1 9...

  • INSTYTUT CYBERNETYKI TECHNICZNEJ POLITECHNIKA WROCŁAWSKA

    Wizualizacja danych sensorycznych

    Tarcza dla wskaźnika laserowego IRb-1400

    Prowadzący: dr inż. Bogdan Kreczmer Wykonali: Mariusz Zalewski Krzysztof Klempa

  • Założenia projektu Tarcza dla IRb-1400 ma być pomocą naukową dla laboratorium z Wprowadzenia do automatyki i robotyki. Dzięki niej studenci będą mieli możliwość kontroli ruchu w/w manipulatora. Tarcza składa się z 16 fotodiod. Dzięki zainstalowanemu na manipulatorze wskaźniku laserowemu możemy oddziaływać na fotodiody umieszczone na tarczy. Możemy zatem powiedzieć, że jeżeli robot wskaże na odpowiedni punkt na tarczy, to będziemy o tym wiedzieli. Sprawdzając odczyty ze wszystkich fotodiod w kolejnych odstępach czasu będziemy wiedzieli jak zachowuje się IRb-1400, a zatem będziemy mogli powiedzieć czy zrealizował on zaplanowaną trasę. Zadaniem studentów będzie takie zaprogramowanie IRb-1400 aby realizował on ruch po pożądanej trasie. Okiem użytkownika Podstawowym elementem tarczy jest 16 fotodiod. Odpowiadają kontrole położenia efektora robota. Przy każdej fotodiodzie umieszczone są dwie diody świecące LED. Jedna zielona, druga czerwona. Sygnalizują one poprawność wskazania na fotodiodę (tj. jeżeli wskaźnik pokaże na odpowiednią diodę dostaniemy sygnał zielony; jeżeli na nieprawidłową - czerwony). Ponadto wyniki są na bieżąco wyświetlane na wyświetlacze LCD 2x16. Użytkownik obsługuje tarcze przy pomocy czterech klawiszy. Odpowiednio od lewej: yes, no, lewo, prawo. Dodatkowo tarcza może komunikować się z komputerem przez złącze RS232. Układ zasilany jest napięciem stałym +18V. Budowa tarczy Jednostka centralna – 8-bitowy mikrokontroler Atmel AVR ATMega16. Procesor ten został wybrany do projektu ze względu na sporą (w stosunku da ATMega8) liczbę wyjść, niską cenę oraz dostępność na rynku. W urządzeniu wykorzystywane są 24 wyjścia/wejścia mikrokontrolera. Procesor taktowany jest wewnętrznym rezonatorem o częstotliwości 1MHz, lecz istnieje także możliwość uruchomienia zewnętrznego kwarcu 8MHz, w który to układ jest wyposażony. Mikrokontroler oprogramowany został z języku C w środowisku WinAVR poprzez złącze ISP. Układ zasilający – zastosowany mikroprocesor wymaga napięcia zasilania Vcc = +5V. Z tego względu zastosowano regulator napięcia L7805T. Ponieważ maksymalny pobór prądu urządzenia nie powinien przekroczyć jednego ampera, a właściwie nie powinien nawet zbliżyć się do tej granicy, a napięcie zasilanie waha się w okolicach +20V zastosowaliśmy rezystor mocy w celu zmniejszenia napięcia wejściowego na L7805. Na rezystancji 22ohm o mocy 5W odkłada się około 3.5-4V, dzięki czemu stabilizator przetwarza mniejsze napięcie zachowując stałe napięcie wyjścia na poziomie 5V. Wszelkie układy scalone jak i mikroprocesor zasilane są tym źródłem energii. Bezpośrednio na wejście mikroprocesora wpięto kondensator ceramiczny o wartości 100nF mający na celu odfiltrować ewentualne skoki napięć (szpilki).

  • Odczyt z fotodiod – odczyt informacji z tablicy odpowiedzialne są dwa wyjścia cyfrowe mikrokontrolera (PA6, PA7). Sygnał z 16 fotodiod jest na nie sekwencyjnie multipleksowany dwoma układami 74151N. Domyślna wartością na wejściu 74151 jest stan wysoki. Jeżeli podpiąć go poprzez diodę do masy, a następnie reagować na diodę światłem jesteśmy w stanie odczytać czy wskaźnik pokazuje na badaną diodę. Przy pomocy wyjść (PB0, PB1, PB2) wybieramy wejścia multipleksera i badamy kolejno stany na każdym wejściu. Jeden multiplekser odpowiada za odczyt z 8 diod. Sygnalizacja diodami LED – jak wspomniano wcześniej poprawność trafień jest sygnalizowana zapaleniem diody czerwonej bądź zielonej. Mamy zatem dla każdej fotodiody dwie diody świecące wykonujące w/w czynność. Do sterowanie tablicą wykorzystano cztery linie zasilająca (PD2, PD3, PD4, PD5) oraz podciąganie do masy poprzez demultiplekser 74138N sterowany wyjściami PB3, PB4, PB5. Prąd zasilający został ograniczony poprzez zastosowanie rezystorów 470 ohm. Zasilając odpowiednią linie i podciągając drugą do masy spowodujemy zapalenie pożądanej diody. Wyświetlacz LCD – w urządzeniu został zastosowany wyświetlacz LMC-S2M16 oparty o sterownik HD44780. Użyto 4-bitowego sterowanie wyświetlaczem (PA0, PA1, PA2, PA3). Używamy także wyjść PA4 i PA5 do sterowanie wejściami Enable i Register Select. Szczegółowy opis wyprowadzeń zamieszczam poniżej: 1 VDD - +5V 2 VSS - 0V 3 VO - CONTRAST 4 RS H/L REGISTER SELECT 5 R/W H/L READ/WRITE 6 E H.H->L ENABLE SIGNAL 7 DB0 H/L DATA BIT0 8 DB1 H/L DATA BIT1 9 DB2 H/L DATA BIT2 10 DB3 H/L DATA BIT3 11 DB4 H/L DATA BIT4 12 DB5 H/L DATA BIT5 13 DB6 H/L DATA BIT6 14 DB7 H/L DATA BIT7 Pin 5 został na stałe zwarty do masy, mamy więc możliwy tylko zapis na LCD. Ponieważ stosujemy 4-bitowy zapis danych piny 7-10 także zwarto do masy. Przy pomocy potencjometru podłączonego do pinu 3 lcd’ka możemy regulować kontrastem obrazu. Szczegółowe podłączenie układu przedstawiono na schemacie. Złącze RS232 – komunikacja z komputerem odbywa się szeregowo poprzez złącze RS232. Sterowanie zrealizowano na układzie max232. Układ wykorzystuje linie rxd i txd (PD0, PD1) oraz rejestr UART mikroprocesora. Ramka wysyłanych danych przedstawia się następująco: | Znacznik startu | rozkaz | argumenty funkcji | znacznik końca | Znacznik startu = 0x01, Znacznik końca = 0x0D, Dostępne są następujące rozkazy (funkcje):

    - zapal diodę – służąca do przesłania informacji o tym, która z diod jest zapalona. Funkcja jest dwuargumentowa: pierwszy przyjmuje wartości 1-16 i

  • określa numer diody, drugi przyjmuje wartości 0,1 i określa kolor (0 – czerwona, 1 - zielona).

    - Komunikat o liczbie błędów – jednoargumentowa funkcja służąca do przesyłania informacji o liczbie błędów w wykonywanej trajektorii. Argument przyjmuje wartości 0-10.

    Dane do PC przesyłane są przy okazji zapalenie którejkolwiek z diod (informacja o zapalonej diodzie), oraz po zakończeniu funkcji sprawdzania trasy (informacja o liczbie błędów). Klawiatura – aby możliwa była obsługa urządzenia niezbędne było zbudowanie klawiatury użytkownika. Zostały zaimplementowane klawisze: reset, ok, anuluj, , na wejściach mikroprocesora PB6, PB7, PD6, PD7. Każde wyjście jest wewnętrznie podciągane do plusa, natomiast załączenie przycisku powoduje zwarcie do masy. Aby układ pracował prawidłowo nie należy naciskać więcej niż jednego klawisza jednocześnie. Przytrzymanie klawisza przez pewien czas spowoduje wielokrotną akcje przypisaną temu klawiszowi. Reset – reset procesora odbywa się poprzez stan niski na linii resetu procesora. W celu uniknięcia samoczynnego resetowania się układu linię tę podciągnięto do plusa przez zewnętrzny rezystor 10k. Układ możemy zresetować zwierając go przyciskiem resetu do masy. Interfejs użytkownika – uruchamiając urządzenie użytkownika przywita tekst „Politechnika Wrocławska”, następnie „Tarcza dla IRb-1400”. Po chwili będziemy już w menu głównym, w którym to znajdziemy następujące opcje wyboru: - Wybór trajektorii – po wywołaniu funkcji przejdziemy do zakładki przeglądania

    zaprogramowanych w mikroprocesorze tras. Do wyboru będziemy mieli cztery odgórnie zapisane trajektorie. Po wybraniu jednej z nich na tarczy zostaną zapalone kolejne diody (zielone) wybranej trasy, zaś na wyświetlaczu otrzymamy opis kolejnych punktów i ich wartości. W trakcie prezentacji trajektorii nie mamy możliwości przerwania pracy. Należy więc odczekać, aż prezentacja minie by móc powrócić do menu.

    - Trajektoria własna – jeżeli brak jest jakichkolwiek trajektorii zaprogramowanych samodzielnie program automatycznie przechodzi do funkcji dodawania nowej trasy. Poruszając się klawiszami prawo, lewo wybieramy kolejny punkt trasy, zaś klawiszem ok akceptujemy punkt. Proceder ten trwa, aż do zapisania kolejnych 10 punktów trasy. W każdej chwili możemy usunąć poprzedni punkt za pomocą klawisza anuluj. Nie mamy możliwości przerwania dodawanie trajektorii. Aby zakończyć funkcje dodawania nowej trajektorii niezbędne jest wprowadzenie wszystkich 10 punktów. Dopuszczalne jest aby kolejne punkty trasy miały tę samą wartość. Możemy dodać maksymalnie cztery trajektorie własne. Jeżeli mamy już przynajmniej jedną trajektorię własną wchodzimy do menu wyboru pomiędzy przeglądem trajektorii własnych (funkcja analogiczna do przeglądu trajektorii zaprogramowanych odgórnie), a dodaniem kolejnej. Ponieważ nie ma możliwości usunięcia ani edycji trajektorii jedyną drogą by dodać kolejną trajektorię jest zresetowanie układu w celu wyczyszczenia pamięci.

    - Test diodowy – uaktywniamy test diod. Jeżeli zadziałamy światłem na jedną z diod zapali się zielona dioda znajdująca się obok. Przy pomocy tej funkcji możemy łatwo sprawdzić czy wszystkie fotodiody działają poprawnie. Jeżeli

  • „zapalimy” więcej niż jedną fotodiodę zapali się tylko jedna dioda LED, ta o wyższym indeksie.

    - Wlacz tarcze – czyli główna część programu, przechodzimy do menu wyboru trajektorii. Pierwsze 4 trajektorie to zdefiniowane domyślnie w programie. Każdą kolejną mogliśmy dodać w zakładce Trajektoria własna. Po wyborze trajektorii rozpoczyna się sekwencja startowa i program oczekuje na wskazanie którejkolwiek z diod wskaźnikiem laserowym. Jeżeli wskazanie jest poprawne zapalana jest zielona dioda i program przechodzi do kolejnej zadanej w trajektorii diody. Jeżeli wskazanie będzie błędne zapalamy czerwoną diodą, oraz naliczamy punkty karne. W przypadku błędnego zapalenie urządzenie nie oczekuje na poprawkę, lecz przechodzi do kolejnego punktu trajektorii. Na wyświetlaczu lcd otrzymujemy na bieżąco informacje o położeniu oczekiwanym kolejnego punktu. Po zakończeniu realizacji trasy otrzymamy informacje o liczbie popełnionych pomyłek. Jeżeli wskaźnik laserowy przejdzie po trajektorii omijającej diody tarcza nie będzie miała o tym żadnych informacji. W takiej sytuacji możemy wyjść z funkcji oczekiwania na trafienie naciskając klawisz anuluj. Zbyt długie zatrzymanie wskaźnika na fotodiodzie spowoduje dwukrotne policzenie tego samego punktu, co może być efektem niepożądanym.

    - Tworcy – zostaje wyświetlona informacja o autorach projektu.

  • Widok czołowy na tarcze

    Kolejne diody ponumerowane są od 1 do 16 jak pokazano powyżej. Użytkownik obsługuje tarczę przy użyciu klawiszy: Reset, Ok., Anuluj, < i >. Wszelkie niezbędne informacje wyświetlane są poprzez matryce LCD.

    Reset

    Ok Anuluj

    <

    >

    Matryca LCD

    1

    1

    2 3 4

    5

    9

    6 7 8

    10 11 12

    13 14 15 16

  • Wejścia i wyjścia

    Widok ogólny na płytkę

    Zasilanie +12V

    Programator ISP RS 232 do komunikacji z PC

    uP ATMega16

    Układ zasilacza

    Wyjście LCD

    LCD-kontrast

    Układ obsługi RS232

  • Przykładowe wywołanie programu • Politechnika Wroclawska • Tarcza dla IRb-1400 • Witaj Nacisnij-> //akcja > • Wybor trajektorii //akcja yes • Wyswietl trajektorie: 1 //akcja < • Wyswietl trajektorie: 4 //akcja yes • Punkt:1 Wartosc:5 //wyświetlane kolejne punkty na lcd • Punkt:2 Wartosc:6 //jak i na diodach LED • Punkt:3 Wartosc:7 • Punkt:4 Wartosc:8 • Punkt:5 Wartosc:12 • Punkt:6 Wartosc:11 • Punkt:7 Wartosc:15 • Punkt:8 Wartosc:14 • Punkt:9 Wartosc:10 • Punkt:10 Wartosc:9 • Wyswietl trajektorie: 4 //akcja no • Wybor trajektorii //akcja > • Trajektoria wlasna //akcja > • Test diodowy //akcja > • Wlacz tarcze //akcja yes • Wyswietl trajektorie: 4 //akcja yes • Przygotuj się! • 3 • 2 • 1 • START • Punkt: 1 Oczekiwany: 1 //program oczekuje na wskazanie diody • Punkt: 2 Oczekiwany: 2 //jeżeli poprawne zapala zielona diodę, • Punkt: 3 Oczekiwany: 3 //inaczej czerwona i nalicza punkty

    karne • ... • Punkt: 10 Oczekiwany: 10 • L. bledow: 4 Nacisnij klawisz //załóżmy, że tyle błędów popełniono • Wybierz trajektorie: 1 //akcja no • Wlacz tarcze //akcja > • Tworcy //akcja yes • Mariusz Zalewski • Krzysztof Klempa

  • Schemat układu tarczy

  • Oprogramowanie mikrokontrolera Main.cpp #include #include "lcd_tools.h" #include "uart.h" #include char text[20]; int p1,p2,p3,p4; int t[4][12]= {{1,2,3,4,5,6,7,8,9,10}, {2,6,10,11,12,16,15,14,13,9}, {16,15,14,13,9,5,1,2,3,4}, {5,6,7,8,12,11,15,14,10,9}}; //trajektorie zadane int tr[4][12],lr; //trajektorie zadane recznie, lr liczba zadanych trajektorii int diody[16]; //dioda zapalona - wartosc 0, zgaszona 1 int start(); int xl_wait(); int l_wait(); int s_wait(); int read_key(); int wyswietl_trajektorie(int n,int wybor); int zapal(int poz,int kolor); int wygas(); int dodawanie_trajektorii(int n); int read_input(); void main() { long i,j; int menu=0,menu1=1,menu2=1,menu3=1,menu4=1; int blad; cli(); lcd_ini(); //inicjalizacja wyswietlacza uart_ini(); lcd_gotopos(1,1); lcd_writetext(" Politechnika "); lcd_gotoline(2); lcd_writetext(" Wroclawska "); xl_wait(); lcd_gotopos(1,1); lcd_writetext(" Tarcza dla "); lcd_gotoline(2); lcd_writetext(" IRb-1400 "); xl_wait(); lcd_cls(); //wyczysc ekran DDRB |= 0b00000111; //wyjscia do obslugi multiplexerow DDRA &= ~_BV(PA6); //wejscia do odczytu diod DDRA &= ~_BV(PA7); PORTA &= ~_BV(PA6); //bez podciagania do plusa PORTA &= ~_BV(PA7); DDRB |= 0b00111000; //wyjscia do obslugi demultiplexerow DDRB &= 0b00111111; //wejscia do obslugi klawiatury (PD6, PD7) PORTB |= 0b11000000; //wejscia do klawiatury z wewnetrznym podciaganiem DDRD |= 0b00111100; //wyjscia zasilania LED'ek DDRD &= 0b00111111; //wejscia obslugi klawiatury (PC6, PC7) PORTD |= 0b11000000; //wejscia do klawiatury z wewnetrznym podciaganiem DDRD |= _BV(PD0); //RXD jako wejscie DDRD &= ~_BV(PD1); //TXD jako wyjscie while(1) { switch (menu) //glowne menu wyboru { case 0: lcd_gotopos(1,1); lcd_writetext(" Witaj :-) "); lcd_gotopos(2,1); lcd_writetext(" Nacisnij -> ");

  • break; case 1: lcd_gotopos(1,1); lcd_writetext(" Wybor "); lcd_gotopos(2,1); lcd_writetext(" trajektorii "); break; case 2: lcd_gotopos(1,1); lcd_writetext(" Trajektroria "); lcd_gotopos(2,1); lcd_writetext(" wlasna "); break; case 3: lcd_gotopos(1,1); lcd_writetext(" Test "); lcd_gotopos(2,1); lcd_writetext(" diodowy "); break; case 4: lcd_gotopos(1,1); lcd_writetext(" Wlacz "); lcd_gotopos(2,1); lcd_writetext(" tarcze "); break; case 5: lcd_gotopos(1,1); lcd_writetext(" Tworcy "); lcd_gotopos(2,1); lcd_writetext(" "); break; s_wait(); } read_key(); //odczyt klawiatury if (p3) { menu--; if (menu5) menu=1; l_wait(); } if ((p1)&&(menu==1)) { menu1=1; lcd_gotopos(1,1); lcd_writetext(" Wyswietl "); lcd_gotopos(2,1); lcd_writetext("trajektrorie: "); while(1) { lcd_gotopos(2,15); itoa(menu1,text,10); lcd_writetext(text); s_wait(); read_key(); if (p3) { menu1--; if (menu14) menu1=1; l_wait(); } if (p2) break; if (p1) wyswietl_trajektorie(menu1,0); } } if ((p1)&&(menu==2)) { if (!lr) dodawanie_trajektorii(lr); else while (1) { switch (menu2) { case 1: lcd_gotopos(1,1); lcd_writetext(" Zobacz "); lcd_gotopos(2,1); lcd_writetext(" trajektorie "); break; case 2:

  • lcd_gotopos(1,1); lcd_writetext(" Dodaj "); lcd_gotopos(2,1); lcd_writetext(" trajektorie "); break; } s_wait(); read_key(); if (p3) { menu2--; if (menu22) menu2=1; l_wait(); } if (p2) break; if ((p1)&&(menu2==2)) dodawanie_trajektorii(lr); if ((p1)&&(menu2==1)) { menu3=1; lcd_gotopos(1,1); lcd_writetext(" Wyswietl "); lcd_gotopos(2,1); lcd_writetext("trajektrorie: "); while(1) { lcd_gotopos(2,15); itoa(menu3,text,10); lcd_writetext(text); s_wait(); read_key(); if (p3) { menu3--; if (menu3lr) menu3=1; l_wait(); } if (p2) break; if (p1) wyswietl_trajektorie(menu3,1); } } } } if ((p1)&&(menu==3)) while(1) { read_input(); for (i=0;i

  • lcd_writetext(text); lcd_writetext(" "); lcd_gotopos(2,1); lcd_writetext("Nacisnij klawisz"); sei(); uart_putc(0x01); //rozpoczecie nadawania uart_putc(0x1E); //rozkaz - blad uart_putc(blad); //przeslanie na RS liczby popelnionych bledow uart_putc(0x0D); //zakonczenie nadawania while (1) { read_key(); s_wait(); if ((p1)||(p2)||(p3)||(p4)) break; } } } if ((p1)&&(menu==5)) { lcd_gotopos(1,1); lcd_writetext("Mariusz "); lcd_gotopos(2,1); lcd_writetext("Zalewski "); xl_wait(); lcd_gotopos(1,1); lcd_writetext("Krzysztof "); lcd_gotopos(2,1); lcd_writetext("Klempa "); xl_wait(); } } } int read_key() //funkcja odczytujaca stan klawiatury //odczyt do zmiennych globalnych p1,p2,p3,p4 { p1=p2=p3=p4=0; if bit_is_clear(PINB,PB6) p1=1; if bit_is_clear(PINB,PB7) p2=1; if bit_is_clear(PIND,PD6) p3=1; if bit_is_clear(PIND,PD7) p4=1; return 0; } int wyswietl_trajektorie(int n,int wybor) { long j=0; int i=0; for (i=0;i

  • wygas(); //zgas wszystkie diody lcd_gotopos(1,1); lcd_writetext(" Wyswietl "); lcd_gotopos(2,1); lcd_writetext("trajektrorie: "); return 0; } int zapal(int poz,int kolor) { int linia,demux; //linia - zasilanie, demux - sciaganie do masy if (kolor) { linia=((poz-1)/4); //zasilenie odpowiedniej linii demux=((poz-1)%4)*2; //podciagniecie do masy odpwiedniej linii } if (!kolor) { linia=((poz-1)/4); demux=((poz-1)%4)*2+1; } PORTB &= 0b11000111; //zerowanie portow dla demultipleksera PORTB |= demux

  • { i--; l_wait(); if (i

  • lcd_writetext(text); lcd_writetext(" "); lcd_gotopos(2,1); lcd_writetext(" Oczekiwany: "); if (traj4); lcd_flash_e (); PORTA = dataBits | (data&0x0F); g lcd_flash_e (); delay(50); } // lcd clear

  • void lcd_cls () { lcd_write(0x02,0); delay(50); lcd_write(0x01,0); delay(50); } void lcd_writechar ( char zeichen) { lcd_write (zeichen, 1); } void lcd_writetext ( char *text) { uint8_t i = 0; while (text[i]!=0) { lcd_writechar(text[i]); i++; } } void lcd_gotoline (uint8_t zeile) { if (zeile == 1) lcd_write(0x80,0); if (zeile == 2) lcd_write(0xC0,0); } void lcd_gotopos (uint8_t zeile, uint8_t spalte) { if (zeile == 1) lcd_write(0x80+spalte-1,0); if (zeile == 2) lcd_write(0xC0+spalte-1,0); } void lcd_ini () { DDRA |= 0x3F; PORTA=0x00; delay(10000); lcd_write(0x03,0); //seria inicjalizacyjna lcd_write(0x03,0); lcd_write(0x03,0); lcd_write(0x02,0); //czyszczenie z powrotem na pocz linii delay(1000); lcd_write(0x28,0); lcd_write(0x08,0); lcd_cls(); lcd_write(0x0c,0); //bez kursora bez mrugania } uart.h #include #include #define UART_BAUD_RATE 2400 #define UART_BAUD_CALC(UART_BAUD_RATE,F_CPU) ((F_CPU)/((UART_BAUD_RATE)*16l)-1) #define RBUFFLEN 40 //Dlugosc bufora dla odbioru szeregowego volatile unsigned char rbuff[RBUFFLEN]; volatile uint8_t rbuffpos, rbuffcnt, udr_data; SIGNAL (SIG_UART_RECV) { udr_data= UDR; if(rbuffcnt < RBUFFLEN) rbuff[(rbuffpos+rbuffcnt++) % RBUFFLEN] = udr_data; } void uart_putc(unsigned char c) { while(!(UCSRA & (1

  • } void uart_puts (char *s) { while (*s) { // tak dlugo az *s != NULL uart_putc(*s); s++; } } void uart_ini () { sei(); // Uruchumienie obsługi przerwan UCSRB |= (1