Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

LEGO Wall-E com Arduino

Componentes e suprimentos

LEGO Wall-E
Teve que conseguir uma segunda mão porque eles não os fabricam mais
× 1
Arduino Nano R3
× 1
Motor DC (genérico)
× 2
Controlador de motor duplo L298N
× 1
LED bicolor
com 3 pinos
× 1
Sensor infravermelho
× 1
Buzzer
Um que pode reproduzir tons diferentes
× 1
bateria de 9 V
× 1
Resistor 330 ohm
× 3
Fios de jumpers (genérico)
× 20

Ferramentas e máquinas necessárias

Ferro de soldar (genérico)

Aplicativos e serviços online

Arduino IDE

Sobre este projeto


Todo mundo conhece o filme Wall-E (e se você não conhece, vá assisti-lo agora!) E o herói amarelo que está tentando limpar a terra. Neste projeto, usei uma versão Lego do nosso amiguinho e ensinei-o a evitar obstáculos. Este foi meu primeiro projeto e uma grande experiência de aprendizado para entender o básico de eletrônica.





Etapa 1 - O código


Como desenvolvedor de software profissional, pensei no que queria que ele fizesse e comecei com o código.
  // Este programa é para controlar o robô Wall-E Lego.// Wall-E está circulando. Quando ele vê um obstáculo, ele para para olhar ao redor e escolhe outro caminho.// Arduino Nano tem 21 pinos que podem ser usados ​​para digitalRead e digitalWrite // PWM pinos 3, 5, 6, 9, 10, 11 podem ser usados ​​para analogWrite // os pinos 0 e 1 podem ser usados ​​para TTL // os pinos 2 e 3 podem ser usados ​​para interrupções externas // os pinos 10, 11, 12, 13 suportam comunicação SPI // o pino 13 pode ser LED interno // pinos 14 para 21 também são pinos analógicos A0 a A7 e podem ser usados ​​para analogRead # define INFRA_RED 9 // pode ser qualquer pino # define GREEN_LED 7 // pode ser qualquer pino, mas precisa de resistor, talvez 220 Ohm - ou o pino de aterramento obtém 1 kOhm # define RED_LED 8 // pode ser qualquer pino, mas precisa de resistor, talvez 220 Ohm - ou o pino de aterramento obtém 1 kOhm # define BUZZER 10 // precisa ser pino PWM para definir a frequência, precisa de resistor, talvez 1 kOhm // MR é o motor direito, ML é o motor esquerdo # define MR_1 A1 // pode ser qualquer pino, então vamos fazê-los corresponder aos números dos pinos na blindagem L289N # definir MR_2 A2 // pode ser qualquer pino, então vamos fazê-los corresponder ao p em números no escudo L289N # define MR_ENABLE 5 // precisa ser pino PWM para controle de velocidade # define ML_1 A3 // pode ser qualquer pino, então vamos fazê-los corresponder aos números dos pinos no escudo L289N # define ML_2 A4 // pode ser qualquer pino, então vamos fazê-los corresponder aos números dos pinos no escudo L289N # define ML_ENABLE 6 // precisa ser pino PWM para controle de velocidade // definir sua velocidade normal para máximaconst int NORMAL_SPEED =255; void setup () { // logo após pressionar o botão reset, espere um pouco para que possamos desligá-lo sem danificar nenhum componente através do retardo de picos de tensão (2000); // inicializa LEDs e buzzer pinMode (GREEN_LED, OUTPUT); pinMode (RED_LED, OUTPUT); // pinMode (BUZZER, OUTPUT); // não é necessário // redefinir o LED para verde digitalWrite (RED_LED, LOW); digitalWrite (GREEN_LED, HIGH); // define os pinos do motor DC pinMode (MR_ENABLE, OUTPUT); // pinMode direito do motor (MR_1, OUTPUT); pinMode (MR_2, SAÍDA); pinMode (ML_ENABLE, OUTPUT); // motor left pinMode (ML_1, OUTPUT); pinMode (ML_2, OUTPUT); // inicializa o pinMode infravermelho (INFRA_RED, INPUT); // inicializa o gerador de números aleatórios para voltas aleatórias randomSeed (analogRead (0)); // diga olá playHello ();} void loop () {// operações normais driveForwards (NORMAL_SPEED); // define LED para verde digitalWrite (RED_LED, LOW); digitalWrite (GREEN_LED, HIGH); // verifica se há obstáculos if (digitalRead (INFRA_RED) ==LOW) {// LOW significa obstáculo detectado // muda o LED para vermelho digitalWrite (GREEN_LED, LOW); digitalWrite (RED_LED, HIGH); // para os motores stopDriving (); // toca som uh-oh playUhOh (); // verifique left turnLeft (500); obstacleLeft booleano =false; if (digitalRead (INFRA_RED) ==LOW) {obstacleLeft =true; } // volta para o centro delay (100); turnRight (500); // espere um pouco, não queremos parecer apressado delay (500); // verificar turnRight à direita (500); boolean obstacleRight =false; if (digitalRead (INFRA_RED) ==LOW) {obstacleRight =true; } // volta para o centro delay (100); turnLeft (500); // agora verifique como sair daqui if (obstacleLeft &&obstacleRight) {driveBackwards (NORMAL_SPEED / 3); // beep enquanto retrocede por 5 segundos para (int i =0; i <5; i ++) {tone (BUZZER, 1000, 500); atraso (1000); } // para evitar ficar preso em algum lugar, vire aleatoriamente em uma direção antes de continuar a jornada randomTurn (800, 1600); } else if (obstacleLeft) {turnRight (1000); } else if (obstacleRight) {turnLeft (1000); } else {randomTurn (1000, 1800); }} // fazer coisas aleatórias para mais interação int number =random (100); // cria um número aleatório entre 0 e 99 if (number ==0) {randomTurn (200,2000); }} void driveForwards (int speed) {// define os motores para irem na mesma direção digitalWrite (MR_1, LOW); digitalWrite (MR_2, HIGH); digitalWrite (ML_1, HIGH); digitalWrite (ML_2, LOW); setSpeed ​​(speed);} void driveBackwards (int speed) {// define os motores para irem na direção oposta digitalWrite (MR_1, HIGH); digitalWrite (MR_2, LOW); digitalWrite (ML_1, LOW); digitalWrite (ML_2, HIGH); setSpeed ​​(speed);} void turnLeft (int duration) {// vire à esquerda indo para frente com a roda direita e para trás com a roda esquerda digitalWrite (MR_1, HIGH); digitalWrite (MR_2, LOW); digitalWrite (ML_1, HIGH); digitalWrite (ML_2, LOW); // desacelerar para girar setSpeed ​​(NORMAL_SPEED / 2); atraso (duração); stopDriving ();} void turnRight (int duration) {// vire à direita indo para trás com a roda direita e para frente com a roda esquerda digitalWrite (MR_1, LOW); digitalWrite (MR_2, HIGH); digitalWrite (ML_1, LOW); digitalWrite (ML_2, HIGH); // desacelerar para girar setSpeed ​​(NORMAL_SPEED / 2); atraso (duração); stopDriving ();} void stopDriving () {// desliga todos os pinos do motor digitalWrite (MR_1, LOW); digitalWrite (MR_2, LOW); digitalWrite (ML_1, LOW); digitalWrite (ML_2, LOW); // não tenho certeza do que fazer com os pinos ENABLE, mas não custa desligá-los também, acho digitalWrite (MR_ENABLE, LOW); digitalWrite (ML_ENABLE, LOW);} void setSpeed ​​(int speed) {// a velocidade deve estar entre 0 e 255 speed =constrain (speed, 0, 255); // define a velocidade para ligar os motores analogWrite (MR_ENABLE, velocidade); analogWrite (ML_ENABLE, velocidade);} void randomTurn (int mínimo, int máximo) {unsigned long time =millis (); duração interna =aleatório (mínimo, máximo); if (tempo% 2) {turnRight (duração); } else {turnLeft (duração); }} void playHello () {tone (BUZZER, 262, 250); // reproduz C4 delay (300); tom (BUZZER, 330, 250); // reproduz o atraso E4 (300); tom (BUZZER, 392, 250); // reproduz o atraso G4 (300); tom (BUZZER, 523, 500); // reproduz o atraso C5 (550);} void playUhOh () {tone (BUZZER, 523, 250); // reproduz C5 delay (300); tom (BUZZER, 415, 500); // reproduz atraso Gis4 (600);}  

Quando você desconecta um motor em funcionamento, picos de tensão podem ocorrer e danificar seus componentes eletrônicos. Portanto, faço Wall-E esperar dois segundos antes de fazer qualquer coisa. Isso significa que posso simplesmente pressionar o botão Reset no Arduino e desconectar rapidamente a bateria sem danificar nada.

Ele toca uma pequena melodia quando acorda e começa a dirigir. Ao ver um obstáculo, ele para, reproduz um som de "uh-oh" e olha ao redor para determinar o melhor caminho. O tipo de sensor infravermelho que usei tem um pequeno parafuso na parte traseira que permite determinar a distância em que ele cria um sinal. É por isso que não há cálculos de distância no código. (Eu queria usar um sensor ultrassônico primeiro, mas ele não se encaixa nos olhos dele).

Wall-E primeiro verifica se o lado esquerdo está livre e, em seguida, se o lado direito está livre. Se os dois lados estiverem bloqueados, ele vai para trás enquanto buzina como maquinário pesado em um canteiro de obras, e então vira para uma direção aleatória e continua. Se apenas um lado estiver bloqueado, ele continua para o outro lado. Se ambos os lados estiverem livres, ele escolhe um aleatoriamente e continua seu caminho.

Tentei fazê-lo girar aleatoriamente, mas essa parte ainda não foi concluída. Estou tentando usar o cronômetro embutido do Arduino. Deixe-me saber nos comentários se você tem alguma idéia de como otimizá-lo!





Etapa 2 - conectando-o


A primeira coisa foi instalar o sensor infravermelho no olho para que não parecesse muito óbvio. Eu o desmontei, colei um pino de Lego no sensor (para que seu olho possa se mover para cima e para baixo) e usei o marcador azul para colocar as peças de Lego de volta ao redor do sensor:

O mais importante sobre os motores é que eles têm torque suficiente, porque a configuração das rodas do Wall-E precisa de um pouco de força para se mover. Tive de soldar os fios aos motores e prendê-los de forma que se conectassem com segurança ao Lego. Então, desmontei as rodas dele, encomendei um saco cheio de pinos Lego Technic, embrulhei fita de gesso (é assim que você chama? É como uma fita macia que pode entrar na pele) ao redor dos eixos do motor e os prendi em dois pinos aquele se tornou o eixo principal de cada roda. Isso funcionou por alguns minutos, mas então o atrito era muito alto para a cola na fita segurar. Felizmente, os pinos Technic têm pequenas ranhuras nas laterais, então a fita tinha um lugar para se segurar, o que eles felizmente fizeram depois de serem embebidos em supercola.

Também tirei um pouco do peito dele para enfiar o LED. Aí conectei todas as peças e o Arduino.

A blindagem do motor apenas caber em sua barriga:

O diagrama também não é muito claro, mas tentei codificar os fios por cores para uma melhor visão geral:

De acordo com a convenção, todos os fios vermelhos são positivos ("distribuem" eletricidade) e todos os fios pretos são negativos ("recebem" eletricidade). O fio amarelo no canto superior direito carrega o sinal para o sensor infravermelho; os fios laranja e verde são para o LED bicolor de três pinos, os fios roxos são para informar a blindagem do motor em qual direção girar os motores e os cabos azuis indicam para a blindagem do motor a velocidade de girá-los.

O escudo do motor tinha um tutorial muito bom que o tornava fácil de conectar e usar. Infelizmente, a parte Fritzing não tinha os dois pinos para definir a velocidade, então os cabos azuis acabam aleatoriamente na blindagem do motor no diagrama.

Outro problema que enfrentei ao colar tudo junto foi a falta de pinos de tensão e aterramento. Eu queria alimentar os motores diretamente através do escudo do motor para que eles pudessem obter o máximo de potência possível, mas de alguma forma tive que alimentar 5 V para o Arduino e o sensor infravermelho também. Então eu fiz o que quase todo mundo na web disse que eu não deveria fazer:conectei a saída de 5 V da blindagem do motor ao pino de 5 V do Arduino como uma entrada. Agora, com o escudo que estou usando, posso ter certeza absoluta de que ele produz 5 V regulado sem quaisquer picos desagradáveis ​​que possam danificar meu Arduino. Se você conectar uma fonte de alimentação não regulamentada a esse pino, provavelmente irá fritar alguma coisa. Eu queria usar o pino Vin no início, mas aquele tem um mecanismo embutido que regula tudo, então meu 5V teria se transformado em 3,8V ou mais, o que não é suficiente para o Arduino funcionar corretamente. Em vez disso, usei o Vin grátis para alimentar (!) O sensor infravermelho com 5V, porque não tinha divisores de cabo e sabia que sairia 5V de lá também. Sim, começou a se sentir um pouco como Frankenstein neste momento. Mas funcionou!





Etapa 3 - Wall-E em ação


Aqui estão alguns vídeos que o mostram em ação:

E aqui eu testei o que ele faria se ficasse preso em um canto:

Portanto, este foi meu primeiro pequeno projeto. Agora estou planejando otimizar as conexões dos cabos e talvez adicionar um servo motor para que ele possa virar a cabeça. Posso até comprar divisores, um motor menor e uma placa para encaixar tudo em sua barriga.

E então Wall-E viveu felizmente sempre depois. O fim.

Código

  • Wall_e_control
Wall_e_control Arduino
Este é o arquivo de controle central do Wall-E. É básico, mas tudo o que ele precisa no momento.
 // Este programa é para controlar o robô Wall-E Lego.// Wall-E está dirigindo. Quando ele vê um obstáculo, ele para para olhar ao redor e escolhe outro caminho.// Arduino Nano tem 21 pinos que podem ser usados ​​para digitalRead e digitalWrite // PWM pinos 3, 5, 6, 9, 10, 11 podem ser usados ​​para analogWrite // os pinos 0 e 1 podem ser usados ​​para TTL // os pinos 2 e 3 podem ser usados ​​para interrupções externas // os pinos 10, 11, 12, 13 suportam comunicação SPI // o pino 13 pode ser LED interno // pinos 14 para 21 também são pinos analógicos A0 a A7 e podem ser usados ​​para analogRead # define INFRA_RED 9 // pode ser qualquer pino # define GREEN_LED 7 // pode ser qualquer pino, mas precisa de resistor, talvez 220 Ohm - ou o pino de aterramento obtém 1 kOhm # define RED_LED 8 // pode ser qualquer pino, mas precisa de resistor, talvez 220 Ohm - ou o pino de aterramento obtém 1 kOhm # define BUZZER 10 // precisa ser pino PWM para definir a frequência, precisa de resistor, talvez 1 kOhm // MR é o motor direito, ML é o motor esquerdo # define MR_1 A1 // pode ser qualquer pino, então vamos fazê-los corresponder aos números dos pinos na blindagem L289N # definir MR_2 A2 // pode ser qualquer pino, então vamos fazê-los corresponder ao p em números no escudo L289N # define MR_ENABLE 5 // precisa ser pino PWM para controle de velocidade # define ML_1 A3 // pode ser qualquer pino, então vamos fazê-los corresponder aos números dos pinos no escudo L289N # define ML_2 A4 // pode ser qualquer pino, então vamos fazê-los corresponder aos números dos pinos no escudo L289N # define ML_ENABLE 6 // precisa ser pino PWM para controle de velocidade // definir sua velocidade normal para máximaconst int NORMAL_SPEED =255; void setup () { // logo após pressionar o botão reset, espere um pouco para que possamos desligá-lo sem danificar nenhum componente através do retardo de picos de tensão (2000); // inicializa LEDs e buzzer pinMode (GREEN_LED, OUTPUT); pinMode (RED_LED, OUTPUT); // pinMode (BUZZER, OUTPUT); // não é necessário // redefinir o LED para verde digitalWrite (RED_LED, LOW); digitalWrite (GREEN_LED, HIGH); // define os pinos do motor DC pinMode (MR_ENABLE, OUTPUT); // pinMode direito do motor (MR_1, OUTPUT); pinMode (MR_2, SAÍDA); pinMode (ML_ENABLE, OUTPUT); // motor left pinMode (ML_1, OUTPUT); pinMode (ML_2, OUTPUT); // inicializa o pinMode infravermelho (INFRA_RED, INPUT); // inicializa o gerador de números aleatórios para voltas aleatórias randomSeed (analogRead (0)); // diga olá playHello ();} void loop () {// operações normais driveForwards (NORMAL_SPEED); // define LED para verde digitalWrite (RED_LED, LOW); digitalWrite (GREEN_LED, HIGH); // verifica se há obstáculos if (digitalRead (INFRA_RED) ==LOW) {// LOW significa obstáculo detectado // muda o LED para vermelho digitalWrite (GREEN_LED, LOW); digitalWrite (RED_LED, HIGH); // para os motores stopDriving (); // toca som uh-oh playUhOh (); // verifique left turnLeft (500); obstacleLeft booleano =false; if (digitalRead (INFRA_RED) ==LOW) {obstacleLeft =true; } // volta para o centro delay (100); turnRight (500); // espere um pouco, não queremos parecer apressado delay (500); // verificar turnRight à direita (500); boolean obstacleRight =false; if (digitalRead (INFRA_RED) ==LOW) {obstacleRight =true; } // volta para o centro delay (100); turnLeft (500); // agora verifique como sair daqui if (obstacleLeft &&obstacleRight) {driveBackwards (NORMAL_SPEED / 3); // beep enquanto retrocede por 5 segundos para (int i =0; i <5; i ++) {tone (BUZZER, 1000, 500); atraso (1000); } // para evitar ficar preso em algum lugar, vire aleatoriamente em uma direção antes de continuar a jornada randomTurn (800, 1600); } else if (obstacleLeft) {turnRight (1000); } else if (obstacleRight) {turnLeft (1000); } else {randomTurn (1000, 1800); }} // fazer coisas aleatórias para mais interação int number =random (100); // cria um número aleatório entre 0 e 99 if (number ==0) {randomTurn (200,2000); }} void driveForwards (int speed) {// define os motores para irem na mesma direção digitalWrite (MR_1, LOW); digitalWrite (MR_2, HIGH); digitalWrite (ML_1, HIGH); digitalWrite (ML_2, LOW); setSpeed ​​(speed);} void driveBackwards (int speed) {// define os motores para irem na direção oposta digitalWrite (MR_1, HIGH); digitalWrite (MR_2, LOW); digitalWrite (ML_1, LOW); digitalWrite (ML_2, HIGH); setSpeed ​​(speed);} void turnLeft (int duration) {// vire à esquerda indo para frente com a roda direita e para trás com a roda esquerda digitalWrite (MR_1, HIGH); digitalWrite (MR_2, LOW); digitalWrite (ML_1, HIGH); digitalWrite (ML_2, LOW); // desacelerar para girar setSpeed ​​(NORMAL_SPEED / 2); atraso (duração); stopDriving ();} void turnRight (int duration) {// vire à direita indo para trás com a roda direita e para frente com a roda esquerda digitalWrite (MR_1, LOW); digitalWrite (MR_2, HIGH); digitalWrite (ML_1, LOW); digitalWrite (ML_2, HIGH); // desacelerar para girar setSpeed ​​(NORMAL_SPEED / 2); atraso (duração); stopDriving ();} void stopDriving () {// desliga todos os pinos do motor digitalWrite (MR_1, LOW); digitalWrite (MR_2, LOW); digitalWrite (ML_1, LOW); digitalWrite (ML_2, LOW); // não tenho certeza do que fazer com os pinos ENABLE, mas não custa desligá-los também, acho digitalWrite (MR_ENABLE, LOW); digitalWrite (ML_ENABLE, LOW);} void setSpeed ​​(int speed) {// a velocidade deve estar entre 0 e 255 speed =constrain (speed, 0, 255); // define a velocidade para ligar os motores analogWrite (MR_ENABLE, velocidade); analogWrite (ML_ENABLE, velocidade);} void randomTurn (int mínimo, int máximo) {unsigned long time =millis (); duração interna =aleatório (mínimo, máximo); if (tempo% 2) {turnRight (duração); } else {turnLeft (duração); }} void playHello () {tone (BUZZER, 262, 250); // reproduz C4 delay (300); tom (BUZZER, 330, 250); // reproduz o atraso E4 (300); tom (BUZZER, 392, 250); // reproduz o atraso G4 (300); tom (BUZZER, 523, 500); // reproduz o atraso C5 (550);} void playUhOh () {tone (BUZZER, 523, 250); // reproduz C5 delay (300); tom (BUZZER, 415, 500); // reproduz atraso Gis4 (600);} 

Esquemas

Significado das cores do cabo:
vermelho =tensão (positivo)
preto =solo (negativo)
amarelo =sinal para sensor infravermelho
laranja e verde =conexões para entrada de LED vermelho e verde
roxo =controle de direção do motor
azul =controle de velocidade do motor (infelizmente, a peça Fritzing não tinha os dois pinos que minha ponte do motor tinha para essas conexões, então parece que há fios soltos no momento) wall-e2_3P6X71BCnP.fzz

Processo de manufatura

  1. Monitoramento de CO2 com Sensor K30
  2. Comunicação para surdos-cegos com 1Sheeld / Arduino
  3. Aceitar moeda de controle com Arduino
  4. Lego Shooter automatizado
  5. Obstáculos para evitar o robô com servo motor
  6. Arduino com Bluetooth para controlar um LED!
  7. Sensor capacitivo de impressão digital com um Arduino ou ESP8266
  8. Robô seguidor de linha
  9. Brincando com Nextion Display
  10. Braço robótico controlado por Nunchuk (com Arduino)