Spisu treści:

Jak zrobić Robo-Bellhopa: 3 kroki
Jak zrobić Robo-Bellhopa: 3 kroki

Wideo: Jak zrobić Robo-Bellhopa: 3 kroki

Wideo: Jak zrobić Robo-Bellhopa: 3 kroki
Wideo: Как сделать перосъемную машину. 20 ответов по сборке 2024, Listopad
Anonim

By jeffreyfObserwuj Więcej autora:

Jak wziąć udział w minikonkursie iRobot Create Scholarship?
Jak wziąć udział w minikonkursie iRobot Create Scholarship?
Jak wziąć udział w minikonkursie iRobot Create Scholarship?
Jak wziąć udział w minikonkursie iRobot Create Scholarship?
Jak zrobić LOLCats, Meme cats, Cat macros lub zdjęcia kotów ze śmiesznymi napisami
Jak zrobić LOLCats, Meme cats, Cat macros lub zdjęcia kotów ze śmiesznymi napisami
Jak zrobić LOLCats, Meme cats, Cat macros lub zdjęcia kotów ze śmiesznymi napisami
Jak zrobić LOLCats, Meme cats, Cat macros lub zdjęcia kotów ze śmiesznymi napisami

O: Lubię rozbierać rzeczy na części i zastanawiać się, jak działają. Po tym generalnie tracę zainteresowanie. Więcej o Jeffreyfie »

Ta instrukcja pokazuje, jak używać iRobot Create, aby stworzyć ruchomego boya hotelowego. Zostało to całkowicie zniesione za zgodą z instrukcji carolTancer i umieściłem to jako przykładowy wpis do naszego konkursu. Robo-BellHop może być twoim osobistym asystentem do noszenia twoich toreb, artykułów spożywczych, prania itp., więc nie musisz do. Podstawowy model Create ma pojemnik przymocowany do góry i wykorzystuje dwa wbudowane detektory podczerwieni do śledzenia nadajnika podczerwieni właściciela. Za pomocą bardzo podstawowego kodu oprogramowania C użytkownik może zabezpieczyć ciężkie zakupy, duży ładunek prania lub torbę na noc na Robo-BellHop i pozwolić robotowi podążać za tobą ulicą, przez centrum handlowe, korytarzem lub lotniskiem - - wszędzie tam, gdzie użytkownik musi się udać. Podstawowa obsługa1) Naciśnij przycisk Reset, aby włączyć moduł poleceń i sprawdź, czy czujniki się włączają1a) Dioda odtwarzania powinna zapalić się, gdy zobaczy nadajnik IR, który podąża za tobą1b) Dioda Advance powinna zapalić się, gdy robot znajduje się bardzo blisko2) Naciśnij czarny miękki przycisk, aby uruchomić procedurę Robo-BellHop3) Przymocuj nadajnik podczerwieni do kostki i upewnij się, że jest włączony. Następnie załaduj kosz i idź!4) Logika Robo-BellHop jest następująca:4a) Gdy będziesz chodził, jeśli sygnał IR zostanie wykryty, robot będzie jechał z maksymalną prędkością4b) Jeśli sygnał IR zniknie (z powodu zbyt dużego lub zbyt ostrego kąta), robot przejedzie niewielką odległość z małą prędkością w przypadku ponownego odebrania sygnału4c) Jeśli sygnał podczerwieni nie zostanie wykryty, robot skręci w lewo i w prawo w spróbuj ponownie znaleźć sygnał4d) Jeśli sygnał IR zostanie wykryty, ale robot uderzy w przeszkodę, robot spróbuje ominąć przeszkodę4e) Jeśli robot zbliży się bardzo blisko sygnału IR, robot zatrzyma się, aby uniknąć uderzenia kostki właściciela Sprzęt1 wirtualna jednostka naścienna iRobot - 301 USD detektor podczerwieni z RadioShack - 31 USD męskie złącze DB-9 z Radio Shack - 44 USD 6-32 śruby z Home Depot - 2,502 USD 3V baterie, użyłem kosza na pranie D1 firmy Target - 51 USD dodatkowego koła na tył robota CreateTaśma elektryczna, drut i lut

Krok 1: Zakrycie czujnika podczerwieni

Przymocuj taśmę elektryczną, aby zakryć całą szczelinę czujnika podczerwieni z przodu robota Create. Zdemontuj wirtualną jednostkę ściany i wyjmij małą płytkę drukowaną z przodu urządzenia. Jest to trochę trudne, ponieważ jest wiele ukrytych śrub i plastikowych mocowań. Nadajnik podczerwieni znajduje się na płytce drukowanej. Przykryj nadajnik podczerwieni kawałkiem bibuły, aby uniknąć odbić podczerwieni. Przymocuj płytkę drukowaną do paska lub elastycznej opaski, którą można owinąć wokół kostki. Podłącz baterie do płytki drukowanej, aby mieć je w wygodnym miejscu (zrobiłem tak, abym mógł włożyć baterie do kieszeni).

Podłącz drugi detektor podczerwieni do złącza DB-9 i włóż go do styku 3 (sygnał) i 5 (masa) Cargo Bay ePort. Przymocuj drugi detektor IR do górnej części istniejącego czujnika IR w Create i przykryj go kilkoma warstwami bibuły, aż drugi detektor IR nie będzie widział emitera w odległości, którą chcesz, aby robot Create zatrzymał się, aby go utrzymać od uderzenia cię. Możesz to przetestować po naciśnięciu przycisku Reset i obserwowaniu, jak dioda LED Advance zapala się, gdy jesteś na odległości zatrzymania.

Krok 2: Zamocuj koszyk

Przymocuj koszyk za pomocą śrub 6-32. Właśnie zamontowałem kosz na górze robota Create. Wsuń również tylne koło, aby umieścić ciężarek z tyłu robota Create.

Uwagi: - Robot może udźwignąć spory ładunek, przynajmniej 30 funtów. - Niewielki rozmiar wydawał się najtrudniejszy do przewożenia jakiegokolwiek bagażu - IR jest bardzo temperamentny. Być może korzystanie z obrazowania jest lepsze, ale jest znacznie droższe

Krok 3: Pobierz kod źródłowy

Pobierz kod źródłowy
Pobierz kod źródłowy

Kod źródłowy następuje i jest dołączony w pliku tekstowym:

/************************************************** ******************** follow.c ** -------- ** działa na Create Command Module ** zakryj wszystko oprócz małego otworu z przodu czujnika IR ** Create będzie podążać za wirtualną ścianą (lub dowolnym IR wysyłającym ** sygnał pola siłowego) i miejmy nadzieję, że ominie przeszkody w tym procesie ***************** ************************************************** **/#include interrupt.h>#include io.h>#include#include "oi.h"#definiuj TRUE 1#definiuj FALSE 0#definiuj pełną prędkość 0x7FFF#definiuj wolną prędkość 0x0100#definiuj prędkość wyszukiwania 0x0100#definiuj ExtraAngle 10#definiuj SearchLeftAngle 125#definiuj SearchRightAngle (SearchLeftAngle - 1000)#define CoastDistance 150#define TraceDistance 250#Define TraceAngle 30#define BackDist 25#define IRDetected (~PINB i 0x01)//stany#Define Gotowe 0#define Śledzenie 1#Definicja Śledzenia 2 #define Wyszukiwanie po lewej 3#define Wyszukiwanie po prawej 4#define Śledzenie po lewej 5#define Śledzenie po prawej 6#define PodkładŚledź po lewej 7#define PodkładŚledź po prawej 8// Zmienne globalnev olatile uint16_t timer_cnt = 0;volatile uint8_t timer_on = 0;volatile uint8_t sensor_flag = 0;volatile uint8_t sensor_index = 0;volatile uint8_t sensor_in[Sen6Size];ulotny uint8_t sensory[Sen6 int_rozmiar = 0_16_ulotny]; volatile uint8_t inRange = 0;// Functionsvoid byteTx(uint8_t value);void delayMs(uint16_t time_ms);void delayAndCheckIR(uint16_t time_ms);void delayAndUpdateSensors (unsigned int time_ms);void inicjowanie (uint16_t);void power baud(uint8_t baud_code);void drive(int16_t prędkość, int16_t promień);uint16_t randomAngle(void);void defineSongs(void);int main (void){//stan zmiennauint8_t stan = Gotowy; znaleziony int = 0;int wait_counter = 0;// Skonfiguruj Create i moduleinitialize();LEDBothOff;powerOnRobot();byteTx(CmdStart);baud(Baud28800);byteTx(CmdControl);byteTx(CmdFull);// ustaw we/wy dla drugiego czujnika podczerwieniDDRB &= ~0x01; //ustaw pin 3 ePort w ładowni jako inputPORTB |= 0x01; //set cargo ePort pin3 pullup włączony// program loopwhile(TRUE){// Zatrzymaj jako precautiondrive(0, RadStraight);// set LEDsbyteTx(CmdLeds);byteTx(((sensors[SenVWall])?LEDPlay:0x00) | (inRange?LEDAdvance:0x00));byteTx(sensors[SenCharge1]);byteTx(64);IRDetected?LED2On:LED2Off;inRange?LED1On:LED1Off;//szukając przycisku użytkownika, sprawdzaj częstodelayAndUpdateSensors(10);delayAndCheckIR (10);if(UserButtonPressed) {delayAndUpdateSensors(1000);//active loopwhile(!(UserButtonPressed)&&(!sensors[SenCliffL])&&(!sensors[SenCliffFL])&&(!sensors[SenCliffFR])&&(! czujniki[SenCliffR])) {byteTx(CmdLeds);byteTx(((czujniki[SenVWall])?LEDPlay:0x00) | (inRange?LEDAdvance:0x00));byteTx(czujniki[SenCharge1]);byteTx(255);IRDetected ?LED2On:LED2Off;inRange?LED1On:LED1Off;switch(stan) {case Ready:if(sensors[SenVWall]) {//sprawdź bliskość lideraif(inRange) {drive(0, RadStraight);} else {// jedź prosto(SlowSpeed, RadStraight);stan = Follow;}} else {//szukaj kąta wiązki = 0;distance = 0;wait_counter = 0; znaleziono = FALSE;drive(SearchSpeed, RadCCW);state = SearchingLeft;}break;case Następujące:if(sensors[SenBumpDrop] & BumpRight) {distance = 0;angle = 0;drive(-SlowSpeed, RadStraight); state=BackingTraceLeft;} else if(sensors[SenBumpDrop] & BumpLeft) {distance = 0;angle = 0;drive(-SlowSpeed, RadStraight);state=BackingTraceRight;} else if(sensors[SenVWall]) {//sprawdź bliskość do lideraif(inRange) {drive(0, RadStraight);state = Ready;} else {//drive straightdrive(FullSpeed, RadStraight);state = Follow;}} else {//właśnie utraciłeś sygnał, jedź dalej powoli jeden cycledistance = 0;drive(SlowSpeed, RadStraight);state = WasFollowing;}break;case WasFollowing:if(sensors[SenBumpDrop] & BumpRight) {distance = 0;angle = 0;drive(-SlowSpeed, RadStraight);state=BackingTraceLeft;} else if(sensors[SenBumpDrop] & BumpLeft) {distance = 0;angle = 0;drive(-SlowSpeed, RadStraight);state=BackingTraceRight;} else if (sensors[SenVWall]) {//sprawdź bliskość do lidera (inRange) {drive(0, RadStraight);stan = R eady;} else {//drive straightdrive(FullSpeed, RadStraight);state = Follow;}} else if (odległość >= CoastDistance) {drive(0, RadStraight);state = Ready;} else {drive(SlowSpeed, RadStraight);}break;case SearchingLeft:if(found) {if (angle >= ExtraAngle) {drive(SlowSpeed, RadStraight);state = Follow;} else {drive(SearchSpeed, RadCCW);}} else if (czujniki[SenVWall]) {found = TRUE;angle = 0;if (inRange) {drive(0, RadStraight);state = Ready;} else {drive(SearchSpeed, RadCCW);}} else if (angle >= SearchLeftAngle) {drive(SearchSpeed, RadCW);wait_counter = 0;state = SearchingRight;} else {drive(SearchSpeed, RadCCW);}break;case SearchingRight:if(found) {if (-angle >= ExtraAngle) {drive(SlowSpeed, RadStraight);state = Follow;} else {drive(SearchSpeed, RadCW);}} else if (sensors[SenVWall]) {found = TRUE;angle = 0;if (inRange) {drive(0, RadStraight);state = Ready;} else {drive(SearchSpeed, RadCCW);}} else if(wait_counter > 0) {wait_counter -= 20;drive(0, RadStraight);} else if (kąt = Szukaj RightAngle) {drive(0, RadStraight);wait_counter = 5000;angle = 0;} else {drive(SearchSpeed, RadCW);}break;case TracingLeft:if(sensors[SenBumpDrop] & BumpRight) {distance = 0;angle = 0;drive(-SlowSpeed, RadStraight);state=BackingTraceLeft;} else if(sensors[SenBumpDrop] & BumpLeft) {drive(0, RadStraight);state=Ready;} else if (czujniki[SenVWall]) {//check bliskość do lideraif(inRange) {drive(0, RadStraight);state = Ready;} else {//drive straightdrive(SlowSpeed, RadStraight);state = Follow;}} else if (!(odległość >= TraceDistance)) { drive(SlowSpeed, RadStraight);} else if (!(-angle >= TraceAngle)) {drive(SearchSpeed, RadCW);} else {distance = 0;angle = 0;drive(SlowSpeed, RadStraight);state = Ready; }break;case TracingRight:if(sensors[SenBumpDrop] & BumpRight) {drive(0, RadStraight);state=Ready;} else if(sensors[SenBumpDrop] & BumpLeft) {distance = 0;angle = 0;drive(- SlowSpeed, RadStraight);state=BackingTraceRight;} else if (sensors[SenVWall]) {//sprawdź bliskość lideraif(inRang e) {drive(0, RadStraight);state = Ready;} else {//drive straightdrive(SlowSpeed, RadStraight);state = Follow;}} else if (!(distance >= TraceDistance)) {drive(SlowSpeed, RadStraight);} else if (!(angle >= TraceAngle)) {drive(SearchSpeed, RadCCW);} else {distance = 0;angle = 0;drive(SlowSpeed, RadStraight);state = Ready;}break;case BackingTraceLeft: if (sensors[SenVWall] && inRange) {drive(0, RadStraight);state = Ready;} else if (angle >=TraceAngle) {distance = 0;angle = 0;drive(SlowSpeed, RadStraight);state = TracingLeft; } else if (-distance >= BackDistance) {drive (SearchSpeed, RadCCW);} else {drive(-SlowSpeed, RadStraight);}break;case BackingTraceRight:if (sensors[SenVWall] && inRange) {drive(0, RadStraight);state = Gotowe;} else if (-angle >=TraceAngle) {distance = 0;angle = 0;drive(SlowSpeed, RadStraight);state = TracingRight;} else if (-distance >= BackDistance) {drive (SearchSpeed, RadCW);} else {drive(-SlowSpeed, RadStraight);}break;default://stopdrive(0, RadStraight);stan = Re ady;break;}delayAndCheckIR(10);delayAndUpdateSensors(10);}//cliff lub userbutton wykryto, zezwól na ustabilizowanie się stanu (np. zwolnienie przycisku)drive(0, RadStraight);delayAndUpdateSensors(2000);}}} // Przerwanie odbioru szeregowego do przechowywania wartości czujnikówSIGNAL(SIG_USART_RECV){uint8_t temp;temp = UDR0;if(sensors_flag){sensors_in[sensors_index++] = temp;if(sensors_index >= Sen6Size)sensors_flag = 0;}}// Przerwanie timera 1 na opóźnienia czasowe w msSIGNAL(SIG_OUTPUT_COMPARE1A){if(timer_cnt)timer_cnt--;elsetimer_on = 0;}// Prześlij bajt przez port szeregowyvoid byteTx(uint8_t value){while(!(UCSR0A & _BV(UDRE0))); UDR0 = wartość;}// Opóźnienie o podany czas w ms bez aktualizacji wartości czujnikavoid delayMs(uint16_t time_ms){timer_on = 1;timer_cnt = time_ms;while(timer_on);}// Opóźnienie o podany czas w ms i sprawdź sekundę Detektor podczerwieni void AndCheckIR(uint16_t time_ms){uint8_t timer_val = 0;inRange = 0;timer_on = 1;timer_cnt = time_ms;while(timer_on) {if(!(timer_val == timer_cnt)) {inRange + = IRDetected;timer_val = timer_cnt;}}inRange = (inRange>=(time_ms>>1));}// Opóźnienie o określony czas w ms i aktualizacja wartości czujnikavoid delayAndUpdateSensors(uint16_t time_ms){uint8_t temp;timer_on = 1; timer_cnt = time_ms;while(timer_on){if(!sensors_flag){for(temp = 0; temp Sen6Rozmiar; temp++)sensors[temp] = sensor_in[temp];// Aktualizuj bieżące sumy odległości i odległości kątowej += (int)((sensors[SenDist1] 8) | sensors[SenDist0]);angle += (int)((sensors [SenAng1] 8) |sensory[SenAng0]);byteTx(CmdSensors);byteTx(6);sensors_index = 0;sensors_flag = 1;}}}// Zainicjuj mikrokontroler ATmega168 Mind Control 'initialize(void){cli(); // Ustaw piny we/wyDDRB = 0x10;PORTB = 0xCF;DDRC = 0x00;PORTC = 0xFF;DDRD = 0xE6;PORTD = 0x7D;// Ustaw timer 1, aby generował przerwanie co 1 msTCCR1A = 0x00;TCCR1B = (_BV (WGM12) | _BV(CS12));OCR1A = 71;TIMSK1 = _BV(OCIE1A);// Ustaw port szeregowy z przerwaniem rxUBRR0 = 19;UCSR0B = (_BV(RXCIE0) | _BV(TXEN0) | _BV(RXEN0));UCSR0C = (_BV(UCSZ00) | _BV(UCSZ01));// Włącz przerwaniessei();}void powerOnRobot(void){// Jeśli zasilanie Create jest wyłączone, włącz je włączif(!RobotIsOn){while(!RobotIsOn){RobotPwrToggleLow;delayMs(500); // Opóźnienie w tym stanieRobotPwrToggleHigh; // Przejście od niskiego do wysokiego do przełączenia powerdelayMs(100); // Opóźnienie w tym stanieRobotPwrToggleLow;}delayMs(3500); // Opóźnienie startu}}// Przełącz szybkość transmisji na Create i modulevoid baud(uint8_t baud_code){if(baud_code = 11){byteTx(CmdBaud);UCSR0A |= _BV(TXC0);byteTx(baud_code);/ / Poczekaj, aż transmisja zostanie zakończona while(!(UCSR0A & _BV(TXC0)));cli();// Przełącz rejestr szybkości transmisjiif(baud_code == Baud115200)UBRR0 = Ubrr115200;else if(baud_code == Baud57600)UBRR0 = Ubrr57600;else if(baud_code == Baud38400)UBRR0 = Ubrr38400;else if(baud_code == Baud28800)UBRR0 = Ubrr28800;else if(baud_code == Baud19200)UBRR0 = Ubrr19200;else if(baud_code == Baud14400)UBRR0;else if(baud_code == Baud9600)UBRR0 = Ubrr9600;else if(baud_code == Baud480)UBRR0 = Ubrr4800;else if(baud_code == Baud2400)UBRR0 = Ubrr2400;else if(baud_code == Baud1200)UBRR0 = Ubrr1200;else if(baud_code == Baud600)UBRR0 = Ubrr600;else if(baud_code == Baud300)UBRR0 = Ubrr300;sei();delayMs(100);}}// Wyślij Utwórz polecenia napędu pod względem prędkości i promieniavoid drive(int16_t velocity, int16_t promień){byteTx(CmdDrive);byteTx((uint 8_t)((prędkość >> 8) & 0x00FF));byteTx((uint8_t)(prędkość & 0x00FF));byteTx((uint8_t)((promień >> 8) & 0x00FF));byteTx((uint8_t)(promień & 0x00FF));}

Zalecana: