Índice:

Como fazer um Robo-Bellhop: 3 etapas
Como fazer um Robo-Bellhop: 3 etapas

Vídeo: Como fazer um Robo-Bellhop: 3 etapas

Vídeo: Como fazer um Robo-Bellhop: 3 etapas
Vídeo: Como Resolver Rapidamente um Cubo de Rubik 3x3 | O Tutorial Mais Fácil 2024, Novembro
Anonim

Por jeffreyfFollow Mais do autor:

Como participar do mini-concurso iRobot Create Scholarship
Como participar do mini-concurso iRobot Create Scholarship
Como participar do mini-concurso iRobot Create Scholarship
Como participar do mini-concurso iRobot Create Scholarship
Como fazer LOLCats, Meme cats, Cat macros ou fotos de gatos com legendas engraçadas
Como fazer LOLCats, Meme cats, Cat macros ou fotos de gatos com legendas engraçadas
Como fazer LOLCats, Meme cats, Cat macros ou fotos de gatos com legendas engraçadas
Como fazer LOLCats, Meme cats, Cat macros ou fotos de gatos com legendas engraçadas

Sobre: Gosto de desmontar coisas e descobrir como funcionam. Eu geralmente perco o interesse depois disso. Mais sobre jeffreyf »

Este Instructable mostra como usar o iRobot Create para fazer um carregador móvel. Isso foi retirado inteiramente com a permissão das instruções do carolDancer, e eu coloquei como um exemplo de entrada para nosso concurso. Rob-BellHop pode ser seu próprio assistente pessoal para carregar suas malas, mantimentos, lavanderia, etc., para que você não tenha para. O Create básico tem um compartimento conectado à parte superior e usa dois detectores de infravermelho integrados para seguir o transmissor de infravermelho de seu proprietário. Com um código de software C muito básico, o usuário pode guardar mantimentos pesados, uma grande carga de roupa ou sua bolsa de viagem no Robo-BellHop e fazer com que o robô o siga pela rua, pelo shopping, pelo corredor ou pelo aeroporto - - onde quer que o usuário precise ir. Operação básica1) Aperte o botão Reset para ligar o módulo de comando e verificar se os sensores estão ativados1a) o LED Play deve acender quando vê que o transmissor IR segue você1b) o LED Advance deve acender quando o o robô está em um alcance muito próximo2) Pressione o botão soft preto para executar a rotina Robo-BellHop3) Conecte o transmissor IR ao tornozelo e certifique-se de que esteja ligado. Em seguida, carregue a cesta e vá! 4) A lógica do Robo-BellHop é a seguinte: 4a) Conforme você anda, se o sinal IR estiver sendo detectado, o robô irá dirigir na velocidade máxima 4b) Se o sinal IR sair de alcance (por estar muito longe ou em um ângulo muito agudo), o robô percorrerá uma distância curta em velocidade lenta no caso de o sinal ser captado novamente 4c) Se o sinal IR não estiver sendo detectado, o robô irá virar à esquerda e à direita em um tentar encontrar o sinal novamente4d) Se o sinal IR estiver sendo detectado, mas o robô bater em um obstáculo, o robô tentará contornar o obstáculo4e) Se o robô chegar muito perto do sinal IR, o robô irá parar para evitar atingir o anklesHardware1 unidade de parede virtual iRobot do proprietário - $ 301 detector IR da RadioShack - $ 31 DB-9 conector macho da Radio Shack - $ 44 parafusos 6-32 da Home Depot - $ 2,502 baterias 3V, usei cesto de roupa suja D1 da Target - $ 51 roda extra para o verso do robô Criar fita elétrica, fio e solda

Etapa 1: Cobrindo o Sensor IR

Prenda fita isolante para cobrir tudo, exceto uma pequena fenda do sensor IR na frente do robô Create. Desmonte a unidade de parede virtual e extraia a pequena placa de circuito na frente da unidade. Isso é um pouco complicado porque existem muitos parafusos ocultos e montagens de plástico. O transmissor IR está na placa de circuito. Cubra o transmissor de IV com um pedaço de papel absorvente para evitar reflexos de IV. Prenda a placa de circuito a uma tira ou faixa elástica que pode envolver seu tornozelo. Ligue as baterias à placa de circuito para que você possa colocá-las em um lugar confortável (eu fiz para que pudesse colocar as baterias no meu bolso).

Ligue o segundo detector de IV ao conector DB-9 e insira no Cargo Bay ePort pino 3 (sinal) e pino 5 (terra). Anexe o segundo detector de IV ao topo do sensor de IV existente em Create e cubra-o com algumas camadas de papel de seda até que o segundo detector de IV não veja o emissor a uma distância que você deseja que o robô Create pare para manter de bater em você. Você pode testar isso depois de apertar o botão Reset e observar o LED Advance acender quando você estiver na distância de parada.

Etapa 2: Anexe a cesta

Prenda a cesta usando os parafusos 6-32. Acabei de montar a cesta no topo do robô Criar. Também deslize a roda traseira para colocar o peso na parte traseira do robô Criar.

Notas: - O robô pode carregar um pouco de carga, pelo menos 30 libras. - O tamanho pequeno parecia ser a parte mais difícil de transportar qualquer bagagem - O IR é muito temperamental. Talvez usar imagens seja melhor, mas é muito mais caro

Etapa 3: Baixe o código-fonte

Baixe o código-fonte
Baixe o código-fonte

O código-fonte segue e é anexado em um arquivo de texto:

/ *************************************************** ********************* follow.c ** -------- ** é executado em Criar Módulo de Comando ** cobre tudo, exceto uma pequena abertura na frente do sensor de IR ** Create seguirá uma parede virtual (ou qualquer IR enviando o ** sinal de campo de força) e, com sorte, evitará obstáculos no 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) // estados # define Ready 0 # define Seguindo 1 # define WasFollowing 2 #define SearchingLeft 3 # define SearchingRight 4 # define TracingLeft 5 # define TracingRight 6 # define BackingTraceLeft 7 # define BackingTraceRight 8 // Variáveis globaisv olatile uint16_t timer_cnt = 0; volátil uint8_t timer_on = 0; voláteis uint8_t sensores_flag = 0; volátil uint8_t sensores_index = 0; voláteis uint8_t sensores_in [Sen6Size]; voláteis uint8_t sensores [Sen6Size]; volátil uint8_t inRange = 0; // Functionsvoid byteTx (valor uint8_t); void delayMs (uint16_t time_ms); void delayAndCheckIR (uint16_t time_ms); void delayAndUpdateSensors (unsigned int time_ms); void inicial void (voidOid); void inicial void (voidOid); void inicial void (voidOid); baud (uint8_t baud_code); void drive (int16_t velocity, int16_t radius); uint16_t randomAngle (void); void defineSongs (void); int main (void) {// state variableuint8_t state = Ready; int found = 0; int wait_counter = 0; // Configurar Criar e moduleinitialize (); LEDBothOff; powerOnRobot (); byteTx (CmdStart); baud (Baud28800); byteTx (CmdControl); byteTx (CmdFull); // definir i / o para o segundo sensor IRDDRB & = ~ 0x01; // define o pino 3 do ePort do compartimento de carga como um inputPORTB | = 0x01; // definir carregamento ePort pin3 pullup habilitado // program loopwhile (TRUE) {// Parar apenas como uma unidade de precaução (0, RadStraight); // definir LEDsbyteTx (CmdLeds); byteTx (((sensores [SenVWall])? LEDPlay: 0x00) | (inRange? LEDAdvance: 0x00)); byteTx (sensores [SenCharge1]); byteTx (64); IRDetected? LED2On: LED2Off; inRange? LED1On: LED1Off; // procurando o botão do usuário, verifique oftendelayAndCheckIrSensors (10); delayAndCheck (10); if (UserButtonPressed) {delayAndUpdateSensors (1000); // loop while (! (UserButtonPressed) && (! Sensores [SenCliffL]) && (! Sensores [SenCliffFL]) && (! Sensores [SenCliffFR]) && (! sensores [SenCliffR])) {byteTx (CmdLeds); byteTx (((sensores [SenVWall])? LEDPlay: 0x00) | (inRange? LEDAdvance: 0x00)); byteTx (sensores [SenCharge1]); byteTx (255); IRDetected ? LED2On: LED2Off; inRange? LED1On: LED1Off; switch (estado) {case Ready: if (sensores [SenVWall]) {// verifique a proximidade de leaderif (inRange) {drive (0, RadStraight);} else {// drive straightdrive (SlowSpeed, RadStraight); estado = Seguindo;}} else {// pesquise o beamangle = 0; distância = 0; wait_counter = 0; encontrado = FALSO; unidade (SearchSpeed, RadCCW); estado = SearchingLeft;} quebra; caso a seguir: if (sensores [SenBumpDrop] & BumpRight) {distância = 0; ângulo = 0; unidade (-SlowSpeed, RadStraight); estado = BackingTraceLeft;} else if (sensores [SenBumpDrop] & BumpLeft) {distance = 0; angle = 0; drive (-SlowSpeed, RadStraight); state = BackingTraceRight;} else if (sensores [SenVWall]) {// verificar proximidade ao leaderif (inRange) {drive (0, RadStraight); state = Ready;} else {// drive straightdrive (FullSpeed, RadStraight); state = Seguindo;}} else {// acabou de perder o sinal, continue devagar um cicledistância = 0; direção (SlowSpeed, RadStraight); estado = WasFollowing;} pausa; caso WasFollowing: if (sensores [SenBumpDrop] & BumpRight) {distância = 0; ângulo = 0; direção (-SlowSpeed, RadStraight); estado = BackingTraceLeft;} else if (sensores [SenBumpDrop] & BumpLeft) {distance = 0; angle = 0; drive (-SlowSpeed, RadStraight); state = BackingTraceRight;} else if (sensores [SenVWall]) {// verificar a proximidade do leaderif (inRange) {unidade (0, RadStraight); estado = R eady;} else {// drive straightdrive (FullSpeed, RadStraight); state = Seguindo;}} else if (distance> = CoastDistance) {drive (0, RadStraight); state = Ready;} else {drive (SlowSpeed, RadStraight);} break; case SearchingLeft: if (found) {if (angle> = ExtraAngle) {drive (SlowSpeed, RadStraight); state = Seguindo;} else {drive (SearchSpeed, RadCCW);}} else if (sensores [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); estado = Seguindo;} else {drive (SearchSpeed, RadCW);}} else if (sensores [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 (ângulo = Search RightAngle) {drive (0, RadStraight); wait_counter = 5000; ângulo = 0;} else {drive (SearchSpeed, RadCW);} break; case TracingLeft: if (sensores [SenBumpDrop] & BumpRight) {distance = 0; ângulo = 0; drive (-SlowSpeed, RadStraight); state = BackingTraceLeft;} else if (sensores [SenBumpDrop] & BumpLeft) {drive (0, RadStraight); state = Ready;} else if (sensores [SenVWall]) {// verificar para proximidade com o líderif (inRange) {unidade (0, RadStraight); estado = Pronto;} else {// unidade direta (SlowSpeed, RadStraight); estado = Seguindo;}} else if (! (distância> = TraceDistance)) { drive (SlowSpeed, RadStraight);} else if (! (- ângulo> = TraceAngle)) {drive (SearchSpeed, RadCW);} else {distance = 0; ângulo = 0; drive (SlowSpeed, RadStraight); estado = Pronto; } break; case TracingRight: if (sensores [SenBumpDrop] & BumpRight) {drive (0, RadStraight); state = Ready;} else if (sensores [SenBumpDrop] & BumpLeft) {distance = 0; ângulo = 0; drive (- SlowSpeed, RadStraight); state = BackingTraceRight;} else if (sensores [SenVWall]) {// verificar a proximidade de leaderif (inRang e) {unidade (0, RadStraight); estado = Pronto;} else {// unidade direta (SlowSpeed, RadStraight); estado = Seguindo;}} else if (! (distância> = TraceDistance)) {unidade (SlowSpeed, RadStraight);} else if (! (ângulo> = TraceAngle)) {drive (SearchSpeed, RadCCW);} else {distance = 0; angle = 0; drive (SlowSpeed, RadStraight); state = Ready;} break; case BackingTraceLeft: if (sensores [SenVWall] && inRange) {unidade (0, RadStraight); estado = Pronto;} else if (ângulo> = TraceAngle) {distância = 0; ângulo = 0; unidade (SlowSpeed, RadStraight); estado = TracingLeft; } else if (-distance> = BackDistance) {drive (SearchSpeed, RadCCW);} else {drive (-SlowSpeed, RadStraight);} break; case BackingTraceRight: if (sensores [SenVWall] && inRange) {drive (0, RadStraight); estado = Pronto;} 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; padrão: // stopdrive (0, RadStraight); state = Re ady; break;} delayAndCheckIR (10); delayAndUpdateSensors (10);} // precipício ou botão do usuário detectado, permite que a condição se estabilize (por exemplo, botão a ser liberado) drive (0, RadStraight); delayAndUpdateSensors (2000);}}} // Interrupção de recepção serial para armazenar os valores do sensorSIGNAL (SIG_USART_RECV) {uint8_t temp; temp = UDR0; if (sensores_flag) {sensores_in [sensores_index ++] = temp; if (sensores_index> = Sen6Size) sensores_flag = 0;}} // Interrupção do temporizador 1 para atrasos em msSIGNAL (SIG_OUTPUT_COMPARE1A) {if (timer_cnt) timer_cnt -; elsetimer_on = 0;} // Transmite um byte sobre o portvoid serial byteTx (valor uint8_t) {while (! (UCSR0A & _BV (UDRE0))); UDR0 = valor;} // Atraso para o tempo especificado em ms sem atualizar os valores do sensor evite atrasosMs (uint16_t time_ms) {timer_on = 1; timer_cnt = time_ms; while (timer_on);} // Atraso para o tempo especificado em ms e verifique os segundos Detector de IV evita 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));} // Atraso para o tempo especificado em ms e atualizar os valores do sensor evita delayAndUpdateSensors (uint16_t time_ms) {uint8_t temp; timer_on = 1; timer_cnt = time_ms; while (timer_on) {if (! sensores_flag) {for (temp = 0; temp Sen6Size; temp ++) sensores [temp] = sensores_in [temp]; // Atualizar totais de distância e ângulo + = (int) ((sensores [SenDist1] 8) | sensores [SenDist0]); ângulo + = (int) ((sensores [SenAng1] 8) | sensores [SenAng0]); byteTx (CmdSensors); byteTx (6); sensores_index = 0; sensores_flag = 1;}}} // Inicializar o microcontrolador Mind Control & aposs ATmega168 inicializar (void) {cli (); // Configure I / O pinsDDRB = 0x10; PORTB = 0xCF; DDRC = 0x00; PORTC = 0xFF; DDRD = 0xE6; PORTD = 0x7D; // Configure o temporizador 1 para gerar uma interrupção a cada 1 msTCCR1A = 0x00; TCCR1B = (_BV (WGM12) | _BV (CS12)); OCR1A = 71; TIMSK1 = _BV (OCIE1A); // Configurar a porta serial com interrupção rxUBRR0 = 19; UCSR0B = (_BV (RXCIE0) | _BV (TXEN0) | _BV (RXEN0)); UCSR0C = (_BV (UCSZ00) | _BV (UCSZ01)); // Ativar interruptssei ();} void powerOnRobot (void) {// Se a alimentação de Create & aposs estiver desligada, ative-aif (! RobotIsOn) {while (! RobotIsOn) {RobotPwrToggleLow; delayMs (500); // Atraso neste estadoRobotPwrToggleHigh; // Transição de baixo para alto para alternar powerdelayMs (100); // Atraso neste estadoRobotPwrToggleLow;} delayMs (3500); // Atraso para inicialização}} // Alternar a taxa de bauds em ambos Criar e baud do modulevoid (uint8_t baud_code) {if (baud_code = 11) {byteTx (CmdBaud); UCSR0A | = _BV (TXC0); byteTx (baud_code); / / Aguarde até que a transmissão seja concluída enquanto (! (UCSR0A & _BV (TXC0))); cli (); // Muda o registrador da taxa de baudif (baud_code == Baud115200) UBRR0 = Ubrr115200; senão se (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 == Baud28800) UBRR0 = Ubrr28800; else if (baud_code == Baud19200) UBRR0 = Ubrr19200; if (baud_code == Baud9600) UBRR0 = Ubrr2400; else if (baud_code == Baud4800) UBRR0 = Ubrr4800; else if (baud_code == Baud2400) UBRR0 = Ubrr2400; else if (baud_code == Baud1200) UBRR0; baud_code == Baud600) UBRR0 = Ubrr600; else if (baud_code == Baud300) UBRR0 = Ubrr300; sei (); delayMs (100);}} // Enviar Criar comandos de acionamento em termos de velocidade e raio-vazio (int16_t velocity, int16_t raio) {byteTx (CmdDrive); byteTx ((uint 8_t) ((velocidade >> 8) & 0x00FF)); byteTx ((uint8_t) (velocidade & 0x00FF)); byteTx ((uint8_t) ((raio >> 8) & 0x00FF)); byteTx ((uint8_t) (raio & 0x00FF));}

Recomendado: