Sommario:
- Passaggio 1: copertura del sensore IR
- Passaggio 2: collegare il cestino
- Passaggio 3: scarica il codice sorgente
Video: Come fare un Robo-Bellhop: 3 passaggi
2024 Autore: John Day | [email protected]. Ultima modifica: 2024-01-30 10:05
Di jeffreyfFollow Altro dell'autore:
A proposito: mi piace smontare le cose e capire come funzionano. In genere perdo interesse dopo. Maggiori informazioni su Jeffreyf »
Questo Instructable mostra come utilizzare iRobot Create per creare un fattorino in movimento. Questo è stato completamente rimosso con il permesso delle istruzioni di carolDancer, e l'ho inserito come un campione per il nostro concorso. Robo-BellHop può essere il tuo assistente personale per portare le tue borse, la spesa, il bucato, ecc., Quindi non hai a. Il Create di base ha un cestino attaccato alla parte superiore e utilizza due rilevatori IR di bordo per seguire il trasmettitore IR del suo proprietario. Con un codice software C molto semplice, l'utente può proteggere generi alimentari pesanti, un grande carico di biancheria o la borsa per la notte su Robo-BellHop e fare in modo che il robot ti segua per la strada, attraverso il centro commerciale, lungo il corridoio o attraverso l'aeroporto. - ovunque l'utente debba andare. Operazioni di base1) Premi il pulsante Reset per accendere il modulo di comando e verificare che i sensori siano impegnati1a) il LED Play dovrebbe accendersi quando vede il trasmettitore IR che ti segue1b) il LED Advance dovrebbe accendersi quando il il robot è a distanza molto ravvicinata2) Premi il pulsante morbido nero per eseguire la routine Robo-BellHop3) Collega il trasmettitore IR alla caviglia e assicurati che sia acceso. Quindi carica il cestino e vai!4) La logica di Robo-BellHop è la seguente:4a) Mentre cammini, se viene rilevato il segnale IR, il robot guiderà alla massima velocità4b) Se il segnale IR si spegne raggio (da un angolo troppo lontano o troppo acuto), il robot percorrerà una breve distanza a bassa velocità nel caso in cui il segnale venga nuovamente rilevato4c) Se il segnale IR non viene rilevato, il robot girerà a sinistra e a destra in un tentare di ritrovare il segnale4d) Se il segnale IR viene rilevato ma il robot colpisce un ostacolo, il robot tenterà di aggirare l'ostacolo4e) Se il robot si avvicina molto al segnale IR, il robot si fermerà per evitare di colpire il caviglie del proprietarioHardware1 unità da parete virtuale iRobot - $ 301 rilevatore IR da RadioShack - $ 31 connettore maschio DB-9 da Radio Shack - $ 44 6-32 viti da Home Depot - $ 2,502 batterie 3V, ho usato il cesto della biancheria D1 da Target - $ 51 extra ruota sul retro del robot Crea nastro elettrico, filo e saldatura
Passaggio 1: copertura del sensore IR
Attacca del nastro isolante per coprire tutto tranne una piccola fessura del sensore IR sulla parte anteriore del robot Crea. Smontare il pensile virtuale ed estrarre il piccolo circuito stampato nella parte anteriore dell'unità. Questo è un po' complicato perché ci sono molte viti nascoste e supporti in plastica. Il trasmettitore IR è sulla scheda del circuito. Coprire il trasmettitore IR con un pezzo di carta velina per evitare riflessi IR. Attacca il circuito stampato a una cinghia o a un elastico che possa avvolgere la caviglia. Collega le batterie al circuito in modo da poterle tenere in un posto comodo (l'ho fatto in modo da poterle mettere in tasca).
Collegare il 2° rilevatore IR al connettore DB-9 e inserire nel Cargo Bay ePort il pin 3 (segnale) e il pin 5 (terra). Attacca il 2° rilevatore IR alla parte superiore del sensore IR esistente su Crea e coprilo con un paio di strati di carta velina finché il 2° rilevatore IR non vede l'emettitore a una distanza che vuoi che il robot Create si fermi per mantenere dal colpirti. Puoi testarlo dopo aver premuto il pulsante Reset e guardare il LED Advance accendersi quando sei alla distanza di arresto.
Passaggio 2: collegare il cestino
Fissare il cestello utilizzando le viti 6-32. Ho appena montato il cestello sulla parte superiore del robot Create. Fai scorrere anche la ruota posteriore in modo da posizionare il peso sul retro del robot Create.
Note: - Il robot può trasportare un bel po' di carico, almeno 30 libbre. - Le dimensioni ridotte sembravano essere la parte più difficile per trasportare qualsiasi bagaglio - IR è molto capriccioso. Forse usare l'imaging è meglio ma è molto più costoso
Passaggio 3: scarica il codice sorgente
Il codice sorgente segue, ed è allegato in un file di testo:
/************************************************** ******************** follow.c ** -------- ** funziona su Crea modulo di comando ** copre tutto tranne una piccola apertura sul davanti del sensore IR ** Create seguirà un muro virtuale (o qualsiasi IR che invia il ** segnale del campo di forza) e, si spera, eviterà ostacoli nel processo *************** ************************************************** **/#include interrupt.h>#include io.h>#include#include "oi.h"#define TRUE 1#define FALSE 0#define FullSpeed 0x7FFF#define SlowSpeed 0x0100#define SearchSpeed 0x0100#define ExtraAngle 10#define SearchLeftAngle 125#define SearchRightAngle (SearchLeftAngle - 1000)#define CoastDistance 150#define TraceDistance 250#define TraceAngle 30#define BackDistance 25#define IRDetected (~PINB & 0x01)//states#define Ready 0#define Following 1#define WasFollowing 2 #define SearchingLeft 3#define SearchingRight 4#define TracingLeft 5#define TracingRight 6#define BackingTraceLeft 7#define BackingTraceRight 8// Variabili globaliv olatile uint16_t timer_cnt = 0;volatile uint8_t timer_on = 0;volatile uint8_t sensori_flag = 0;volatile uint8_t sensor_index = 0;volatile uint8_t sensori_in[Sen6Size];volatile uint8_t sensori[Sen6Size];angolo volatile = 0;volatile int16_ 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 initialize(void);void powerOnRobot(void); baud(uint8_t baud_code);void drive(int16_t velocità, int16_t raggio);uint16_t randomAngle(void);void defineSongs(void);int main (void){//state variableuint8_t state = Ready;int found = 0;int wait_counter = 0;// Configura Crea e moduleinitialize();LEDBothOff;powerOnRobot();byteTx(CmdStart);baud(Baud28800);byteTx(CmdControl);byteTx(CmdFull);// imposta i/o per il secondo sensore IRDDRB &= ~0x01; //imposta il pin 3 ePort della stiva di carico come inputPORTB |= 0x01; //set cargo ePort pin3 pullup abilitato// program loopwhile(TRUE){// Stop solo come precauzionedrive(0, RadStraight);// set LEDsbyteTx(CmdLeds);byteTx(((sensors[SenVWall])?LEDPlay:0x00) | (inRange?LEDAdvance:0x00));byteTx(sensors[SenCharge1]);byteTx(64);IRDetected?LED2On:LED2Off;inRange?LED1On:LED1Off;//cercando il pulsante utente, controlla spessodelayAndUpdateSensors(10);delayAndCheckIR (10);if(UserButtonPressed) {delayAndUpdateSensors(1000);//active loopwhile(!(UserButtonPressed)&&(!sensors[SenCliffL])&&(!sensors[SenCliffFL])&&(!sensors[SenCliffFR])&&(! sensori[SenCliffR])) {byteTx(CmdLeds);byteTx(((sensors[SenVWall])?LEDPlay:0x00) | (inRange?LEDAdvance:0x00));byteTx(sensors[SenCharge1]);byteTx(255);IRDetected ?LED2On:LED2Off;inRange?LED1On:LED1Off;switch(state) {case Ready:if(sensors[SenVWall]) {//verifica la vicinanza a leaderif(inRange) {drive(0, RadStraight);} else {// drive straightdrive(SlowSpeed, RadStraight);state = Following;}} else {//cerca l'angolo del fascio = 0;distanza = 0;wait_counter = 0;trovato = FALSE;drive(SearchSpeed, RadCCW);state = SearchingLeft;}break;case Following:if(sensors[SenBumpDrop] & BumpRight) {distanza = 0;angolo = 0;drive(-SlowSpeed, RadStraight); state=BackingTraceLeft;} else if(sensors[SenBumpDrop] & BumpLeft) {distanza = 0;angolo = 0;drive(-SlowSpeed, RadStraight);state=BackingTraceRight;} else if(sensors[SenVWall]) {//check for prossimità a leaderif(inRange) {drive(0, RadStraight);state = Pronto;} else {//drive straightdrive(FullSpeed, RadStraight);state = Following;}} else {//ho appena perso il segnale, prosegui lentamente uno cycledistance = 0;drive(SlowSpeed, RadStraight);state = WasFollowing;}break;case WasFollowing:if(sensors[SenBumpDrop] & BumpRight) {distanza = 0;angle = 0;drive(-SlowSpeed, RadStraight);state=BackingTraceLeft;} else if(sensors[SenBumpDrop] & BumpLeft) {distanza = 0;angle = 0;drive(-SlowSpeed, RadStraight);state=BackingTraceRight;} else if (sensors[SenVWall]) {//controlla la vicinanza al leaderif (inRange) {drive(0, RadStraight);state = R eady;} else {//drive straightdrive(FullSpeed, RadStraight);state = Following;}} else if (distanza >= CoastDistance) {drive(0, RadStraight);state = Ready;} else {drive(SlowSpeed, RadStraight);}break;case SearchingLeft:if(found) {if (angle >= ExtraAngle) {drive(SlowSpeed, RadStraight);state = Following;} else {drive(SearchSpeed, RadCCW);}} else if (sensors[SenVWall]) {trovato = 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(trovato) {if (-angle >= ExtraAngle) {drive(SlowSpeed, RadStraight);state = Following;} 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 (angolo = Cerca RightAngle) {drive(0, RadStraight);wait_counter = 5000;angle = 0;} else {drive(SearchSpeed, RadCW);}break;case TracingLeft:if(sensors[SenBumpDrop] & BumpRight) {distanza = 0;angolo = 0;drive(-SlowSpeed, RadStraight);state=BackingTraceLeft;} else if(sensors[SenBumpDrop] & BumpLeft) {drive(0, RadStraight);state=Ready;} else if (sensors[SenVWall]) {//check per prossimità a leaderif(inRange) {drive(0, RadStraight);state = Ready;} else {//drive straightdrive(SlowSpeed, RadStraight);state = Following;}} else if (!(distanza >= TraceDistance)) { drive(SlowSpeed, RadStraight);} else if (!(-angle >= TraceAngle)) {drive(SearchSpeed, RadCW);} else {distanza = 0;angolo = 0;drive(SlowSpeed, RadStraight);state = Ready; }break;case TracingRight:if(sensors[SenBumpDrop] & BumpRight) {drive(0, RadStraight);state=Ready;} else if(sensors[SenBumpDrop] & BumpLeft) {distanza = 0;angolo = 0;drive(- SlowSpeed, RadStraight);state=BackingTraceRight;} else if (sensors[SenVWall]) {//controlla la vicinanza a leaderif(inRang e) {drive(0, RadStraight);state = Ready;} else {//drive straightdrive(SlowSpeed, RadStraight);state = Following;}} else if (!(distanza >= TraceDistance)) {drive(SlowSpeed, RadStraight);} else if (!(angle >= TraceAngle)) {drive(SearchSpeed, RadCCW);} else {distanza = 0;angolo = 0;drive(SlowSpeed, RadStraight);state = Ready;}break;case BackingTraceLeft: if (sensors[SenVWall] && inRange) {drive(0, RadStraight);state = Ready;} else if (angle >=TraceAngle) {distanza = 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 = Ready;} else if (-angle >=TraceAngle) {distanza = 0;angle = 0;drive(SlowSpeed, RadStraight);state = TracingRight;} else if (-distance >= BackDistance) {drive (SearchSpeed, RadCW);} else {drive(-SlowSpeed, RadStraight);}break;default://stopdrive(0, RadStraight);state = Re ady;break;}delayAndCheckIR(10);delayAndUpdateSensors(10);}//cliff o userbutton rilevato, consente la stabilizzazione della condizione (ad esempio, il rilascio del pulsante)drive(0, RadStraight);delayAndUpdateSensors(2000);}}} // Interrupt di ricezione seriale per memorizzare i valori del sensoreSIGNAL(SIG_USART_RECV){uint8_t temp;temp = UDR0;if(sensors_flag){sensors_in[sensors_index++] = temp;if(sensors_index >= Sen6Size)sensors_flag = 0;}}// Timer 1 interrupt ai ritardi temporali in msSIGNAL(SIG_OUTPUT_COMPARE1A){if(timer_cnt)timer_cnt--;elsetimer_on = 0;}// Trasmette un byte sulla porta serialevoid byteTx(uint8_t value){while(!(UCSR0A & _BV(UDRE0))); UDR0 = valore;}// Ritardo per il tempo specificato in ms senza aggiornare i valori del sensorevoid delayMs(uint16_t time_ms){timer_on = 1;timer_cnt = time_ms;while(timer_on);}// Ritardo per il tempo specificato in ms e controllo secondo IR detectorvoid delayAndCheckIR(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));}// Ritardo per il tempo specificato in ms e aggiorna i valori del sensorevoid 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 Sen6Size; temp++)sensors[temp] = sensor_in[temp];// Aggiorna i totali correnti di distanza e angledistance += (int)((sensors[SenDist1] 8) | sensor[SenDist0]);angle += (int)((sensors [SenAng1] 8) | sensori[SenAng0]);byteTx(CmdSensors);byteTx(6);sensors_index = 0;sensors_flag = 1;}}}// Inizializza il microcontrollore ATmega168 di Mind Control&void initialize(void){cli(); // Imposta i pin I/ODDRB = 0x10;PORTB = 0xCF;DDRC = 0x00;PORTC = 0xFF;DDRD = 0xE6;PORTD = 0x7D;// Imposta il timer 1 per generare un interrupt ogni 1 msTCCR1A = 0x00;TCCR1B = (_BV (WGM12) | _BV(CS12));OCR1A = 71;TIMSK1 = _BV(OCIE1A);// Configura la porta seriale con rx interruptUBRR0 = 19;UCSR0B = (_BV(RXCIE0) | _BV(TXEN0) | _BV(RXEN0));UCSR0C = (_BV(UCSZ00) | _BV(UCSZ01));// Attiva interruptssei();}void powerOnRobot(void){// Se l'alimentazione di Create&aposs è disattivata, attivalaif(!RobotIsOn){while(!RobotIsOn){RobotPwrToggleLow;delayMs(500); // Ritardo in questo statoRobotPwrToggleHigh; // Transizione da basso ad alto per attivare/disattivare powerdelayMs(100); // Ritardo in questo statoRobotPwrToggleLow;}delayMs(3500); // Ritardo all'avvio}}// Commuta la velocità di trasmissione sia su Create che su modulevoid baud(uint8_t baud_code){if(baud_code = 11){byteTx(CmdBaud);UCSR0A |= _BV(TXC0);byteTx(baud_code);/ / Attendi il completamento della trasmissionewhile(!(UCSR0A & _BV(TXC0)));cli();// Cambia baud rate registerif(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 = U if(baud_code == Baud9600)UBRR0 = Ubrr9600;else if(baud_code == Baud4800)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);}}// Send Crea comandi di azionamento in termini di velocità e raggiovoid drive(int16_t velocità, int16_t raggio){byteTx(CmdDrive);byteTx((uint 8_t)((velocità >> 8) & 0x00FF));byteTx((uint8_t)(velocità & 0x00FF));byteTx((uint8_t)((raggio >> 8) & 0x00FF));byteTx((uint8_t)(raggio & 0x00FF));}
Consigliato:
Fai da te Come visualizzare l'ora su M5StickC ESP32 usando Visuino - Facile da fare: 9 passaggi
Fai da te Come visualizzare l'ora su M5StickC ESP32 usando Visuino - Facile da fare: in questo tutorial impareremo come programmare ESP32 M5Stack StickC con Arduino IDE e Visuino per visualizzare l'ora sul display LCD
Fai da te Come creare un orologio dall'aspetto accattivante - StickC - Facile da fare: 8 passaggi
Fai da te Come realizzare un orologio dall'aspetto accattivante - StickC - Facile da fare: in questo tutorial impareremo come programmare ESP32 M5Stack StickC con Arduino IDE e Visuino per visualizzare un'ora sul display LCD e anche impostare l'ora utilizzando i pulsanti StickC
Come fare l'analizzatore di spettro musicale con audio LED a 32 bande fai-da-te usando Arduino Nano a casa #arduinoproject: 8 passaggi
Come fare un analizzatore di spettro musicale audio a 32 bande LED fai-da-te usando Arduino Nano a casa #arduinoproject: oggi realizzeremo un analizzatore di spettro musicale audio a 32 bande LED a casa usando Arduino, può mostrare lo spettro di frequenza e riprodurre musica allo stesso tempo. va collegato davanti alla resistenza da 100k, altrimenti il rumore della spea
COME FARE ARDUINO NANO/MINI - Come masterizzare Bootloader: 5 passaggi
COME FARE ARDUINO NANO/MINI | Come masterizzare Bootloader: in questo Instructables ti mostrerò come creare un Arduino MINI da zero. La procedura scritta in questo instructables può essere utilizzata per creare qualsiasi scheda Arduino per i requisiti del tuo progetto personalizzato. Guarda il video per una migliore comprensione Il
Come fare un calendario dei nonni & Scrapbook (anche se non sai come scrapbook): 8 passaggi (con immagini)
Come fare un calendario dei nonni & Scrapbook (anche se non sai come scrapbook): questo è un regalo di festa molto economico (e molto apprezzato!) per i nonni. Ho realizzato 5 calendari quest'anno per meno di $ 7 ciascuno. Materiali: 12 fantastiche foto di tuo figlio, bambini, nipoti, cani, gatti o altri parenti 12 pezzi diversi