Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

LEGO Wall-E con Arduino

Componentes y suministros

LEGO Wall-E
Tuve que conseguir una segunda mano porque ya no los hacen
× 1
Arduino Nano R3
× 1
Motor de CC (genérico)
× 2
Controlador de motor dual L298N
× 1
LED bicolor
con 3 pines
× 1
Sensor de infrarrojos
× 1
Buzzer
Uno que puede reproducir diferentes tonos
× 1
batería de 9V
× 1
Resistencia de 330 ohmios
× 3
Cables de puente (genéricos)
× 20

Herramientas y máquinas necesarias

Soldador (genérico)

Aplicaciones y servicios en línea

Arduino IDE

Acerca de este proyecto

Todo el mundo conoce la película Wall-E (y si no, ¡ve y mírala ahora!) Y el héroe amarillo que está tratando de limpiar la tierra. En este proyecto, utilicé una versión de Lego de nuestro pequeño amigo y le enseñé a evitar obstáculos. Este fue mi primer proyecto y una gran experiencia de aprendizaje para descubrir los conceptos básicos de la electrónica.

Paso 1:el código

Como desarrollador de software de profesión, pensé en lo que quería que hiciera y comencé con el código.

  // Este programa es para controlar el robot Lego Wall-E. // Wall-E está conduciendo. Cuando ve un obstáculo, se detiene para mirar a su alrededor y elige otro camino .// Arduino Nano tiene 21 pines que se pueden usar para digitalRead y digitalWrite // Los pines 3, 5, 6, 9, 10, 11 de PWM se pueden usar para analogWrite // los pines 0 y 1 se pueden usar para TTL // los pines 2 y 3 se pueden usar para interrupciones externas // los pines 10, 11, 12, 13 admiten comunicación SPI // el pin 13 puede ser LED interno // pines 14 a 21 también son pines analógicos A0 a A7 y se pueden usar para lectura analógica # define INFRA_RED 9 // puede ser cualquier pin # define GREEN_LED 7 // puede ser cualquier pin pero necesita resistencia, tal vez 220 Ohm - o el pin de tierra obtiene 1 kOhm # define RED_LED 8 // puede ser cualquier pin pero necesita resistencia, tal vez 220 Ohm - o el pin de tierra obtiene 1 kOhm # define BUZZER 10 // necesita ser el pin PWM para establecer la frecuencia, necesita resistencia, tal vez 1 kOhm // MR es el motor derecho, ML es el motor izquierdo. pags en números en el escudo L289N # definir MR_ENABLE 5 // necesita ser un pin PWM para control de velocidad # definir ML_1 A3 // puede ser cualquier pin, así que hagámoslos corresponder a los números de pin en el escudo L289N # definir ML_2 A4 // puede ser cualquier pin, así que hagámoslos corresponder a los números de pin en el escudo L289N # define ML_ENABLE 6 // necesita ser un pin PWM para el control de velocidad // establecer su velocidad normal a la máxima constancia int NORMAL_SPEED =255; void setup () { // justo después de presionar el botón de reinicio, espere un poco para que podamos apagarlo sin dañar ningún componente a través del retraso de picos de voltaje (2000); // inicializar los LED y el zumbador pinMode (GREEN_LED, OUTPUT); pinMode (RED_LED, SALIDA); // pinMode (ZUMBADOR, SALIDA); // no es necesario // restablecer el LED a verde digitalWrite (RED_LED, LOW); digitalWrite (VERDE_LED, ALTO); // establece los pines del motor de CC pinMode (MR_ENABLE, OUTPUT); // motor pinMode derecho (MR_1, SALIDA); pinMode (MR_2, SALIDA); pinMode (ML_ENABLE, SALIDA); // motor pinMode izquierdo (ML_1, SALIDA); pinMode (ML_2, SALIDA); // inicializar pinMode infrarrojos (INFRA_RED, INPUT); // inicializar el generador de números aleatorios para turnos aleatorios randomSeed (analogRead (0)); // saluda playHello ();} void loop () {// operaciones normales driveForwards (NORMAL_SPEED); // establece el LED en verde digitalWrite (RED_LED, LOW); digitalWrite (VERDE_LED, ALTO); // verifica si hay obstáculos if (digitalRead (INFRA_RED) ==LOW) {// LOW significa obstáculo detectado // cambia el LED a rojo digitalWrite (GREEN_LED, LOW); digitalWrite (RED_LED, HIGH); // detener motores stopDriving (); // reproducir sonido uh-oh playUhOh (); // comprobar giro a la izquierdaLeft (500); obstáculoLeft booleano =falso; if (digitalRead (INFRA_RED) ==LOW) {obstacleLeft =true; } // volver al centro delay (100); girar a la derecha (500); // espera un poco, no queremos parecer apresurados delay (500); // comprobar giro a la derecha (500); obstáculo booleano derecho =falso; if (digitalRead (INFRA_RED) ==LOW) {obstacleRight =true; } // volver al centro delay (100); girar a la izquierda (500); // ahora compruebe cómo salir de aquí if (obstáculo izquierdo &&obstáculo derecho) {conducir hacia atrás (NORMAL_SPEED / 3); // bip mientras retrocede durante 5 segundos para (int i =0; i <5; i ++) {tone (BUZZER, 1000, 500); retraso (1000); } // para evitar quedarse atascado en algún lugar, girar aleatoriamente en una dirección antes de continuar el viaje randomTurn (800, 1600); } else if (obstáculo izquierdo) {giro a la derecha (1000); } else if (obstáculoDerecho) {giroIzquierdo (1000); } else {randomTurn (1000, 1800); }} // hacer cosas al azar para una mayor interacción int number =random (100); // crea un número aleatorio entre 0 y 99 if (número ==0) {randomTurn (200,2000); }} void driveForwards (int speed) {// configura los motores para que vayan en la misma dirección digitalWrite (MR_1, LOW); escritura digital (MR_2, ALTA); escritura digital (ML_1, ALTA); digitalWrite (ML_2, BAJO); setSpeed ​​(velocidad);} void driveBackwards (int speed) {// configura los motores para que vayan en la dirección opuesta digitalWrite (MR_1, HIGH); digitalWrite (MR_2, BAJO); digitalWrite (ML_1, BAJO); escritura digital (ML_2, ALTA); setSpeed ​​(velocidad);} void turnLeft (int duration) {// girar a la izquierda yendo hacia adelante con la rueda derecha y hacia atrás con la rueda izquierda digitalWrite (MR_1, HIGH); digitalWrite (MR_2, BAJO); escritura digital (ML_1, ALTA); digitalWrite (ML_2, BAJO); // reducir la velocidad para girar setSpeed ​​(NORMAL_SPEED / 2); retraso (duración); stopDriving ();} void turnRight (int duration) {// gira a la derecha yendo hacia atrás con la rueda derecha y hacia adelante con la rueda izquierda digitalWrite (MR_1, LOW); escritura digital (MR_2, ALTA); digitalWrite (ML_1, BAJO); escritura digital (ML_2, ALTA); // reducir la velocidad para girar setSpeed ​​(NORMAL_SPEED / 2); retraso (duración); stopDriving ();} void stopDriving () {// apaga todos los pines del motor digitalWrite (MR_1, LOW); digitalWrite (MR_2, BAJO); digitalWrite (ML_1, BAJO); digitalWrite (ML_2, BAJO); // No estoy seguro de qué hacer con los pines ENABLE, pero no está de más apagarlos también Supongo que digitalWrite (MR_ENABLE, LOW); digitalWrite (ML_ENABLE, LOW);} void setSpeed ​​(int speed) {// la velocidad debe estar entre 0 y 255 speed =restricin (velocidad, 0, 255); // establece la velocidad para encender los motores en analogWrite (MR_ENABLE, velocidad); analogWrite (ML_ENABLE, velocidad);} void randomTurn (int mínimo, int máximo) {unsigned long time =millis (); int duración =aleatorio (mínimo, máximo); if (tiempo% 2) {turnRight (duración); } else {turnLeft (duración); }} void playHello () {tono (ZUMBADOR, 262, 250); // reproduce C4 delay (300); tono (ZUMBADOR, 330, 250); // reproduce E4 delay (300); tono (ZUMBADOR, 392, 250); // reproduce G4 delay (300); tono (ZUMBADOR, 523, 500); // reproduce C5 delay (550);} void playUhOh () {tone (BUZZER, 523, 250); // reproduce C5 delay (300); tono (ZUMBADOR, 415, 500); // reproduce Gis4 delay (600);}  

Cuando desconecta un motor en funcionamiento, pueden ocurrir picos de voltaje y dañar sus componentes electrónicos. Por lo tanto, hago que Wall-E espere dos segundos antes de hacer algo. Eso significa que puedo simplemente presionar el botón Restablecer en el Arduino y desconectar rápidamente la batería sin dañar nada.

Toca una pequeña melodía cuando se despierta y luego comienza a conducir. Cuando ve un obstáculo, se detiene, emite un sonido de "Uh-oh" y mira a su alrededor para determinar la mejor manera. El tipo de sensor de infrarrojos que utilicé tiene un pequeño tornillo en la parte posterior que te permite determinar la distancia a la que crea una señal. Es por eso que no hay cálculos de distancia en el código. (Quería usar un sensor ultrasónico primero, pero no encaja con sus ojos).

Wall-E primero verifica si el lado izquierdo está despejado y luego si el lado derecho está despejado. Si ambos lados están bloqueados, retrocede mientras suena como maquinaria pesada en un sitio de construcción, luego gira en una dirección aleatoria y continúa. Si solo un lado está bloqueado, continúa hacia el otro lado. Si ambos lados están libres, elige uno al azar y continúa su camino.

Traté de hacer que hiciera giros aleatorios, pero esa parte aún no está completa. Estoy tratando de usar el temporizador Arduino incorporado. ¡Déjame saber en los comentarios si tienes una idea de cómo optimizarlo!

Paso 2:conectarlo

Lo primero fue incorporar el sensor de infrarrojos en el ojo para que no parezca demasiado obvio. Lo desmonté, pegué un alfiler de Lego al sensor (para que su ojo pudiera moverse hacia arriba y hacia abajo) y luego usé una tachuela azul para volver a colocar las piezas de Lego alrededor del sensor:

Lo más importante de los motores es que tienen suficiente torque, porque la configuración de las ruedas de Wall-E necesita bastante fuerza para moverse. Tuve que soldar cables a los motores y conectarlos de manera que se conectaran de forma segura al Lego. Así que desmonté sus ruedas, pedí una bolsa llena de alfileres de Lego Technic, envolví con cinta de yeso (¿así es como lo llamas? Es como una cinta suave que puede pegarse a tu piel) alrededor de los ejes del motor, y los pegué en dos alfileres. que se convirtió en el eje principal de cada rueda. Esto funcionó durante unos minutos, pero luego la fricción fue demasiado alta para que el pegamento de la cinta se sostuviera. Afortunadamente, los pines Technic tienen pequeñas ranuras en el costado, por lo que la cinta tenía un lugar al que agarrarse, lo que hicieron felizmente después de empaparse en superpegamento.

También le quité un poco de pecho para pasar el LED. Luego conecté todas las partes y el Arduino.

El escudo del motor solo encajar en su barriga:

El diagrama tampoco es muy claro, pero intenté codificar con colores los cables para tener una mejor descripción:

Según la convención, todos los cables rojos son positivos ("entregan" electricidad) y todos los cables negros son negativos ("reciben" electricidad). El cable amarillo en la parte superior derecha transmite la señal del sensor de infrarrojos; los cables naranja y verde son para el LED bicolor de tres clavijas, los cables violetas son para indicarle al blindaje del motor en qué dirección girar los motores, y los cables azules le indican al blindaje del motor qué tan rápido girarlos.

El protector del motor tenía un muy buen tutorial que facilitó la conexión y el uso. Desafortunadamente, la parte de Fritzing no tenía los dos pines para configurar la velocidad, por lo que los cables azules terminan al azar en el blindaje del motor en el diagrama.

Un problema más que enfrenté mientras lo unía todo fue la falta de pines de voltaje y tierra. Quería alimentar los motores directamente a través del escudo del motor para que pudieran obtener la mayor potencia posible, pero de alguna manera tuve que alimentar 5V al Arduino y también al sensor de infrarrojos. Así que hice lo que casi todos en la web dijeron que no debería hacer:conecté la salida de 5 V del protector del motor al pin de 5 V del Arduino como entrada. Ahora, con el escudo que estoy usando, puedo estar absolutamente seguro de que emite un 5V regulado sin picos desagradables que puedan dañar mi Arduino. Si conecta una fuente de alimentación no regulada a ese pin, probablemente freirá algo. Quería usar el pin Vin al principio, pero ese tiene un mecanismo incorporado que regula todo, por lo que mi 5V se habría convertido en 3.8V más o menos, lo cual no es suficiente para que el Arduino funcione correctamente. En cambio, usé el Vin gratis para alimentar (!) El sensor de infrarrojos con 5V, porque no tenía ningún divisor de cable, y sabía que también saldrían 5V de allí. Sí, comenzó a sentirse un poco como Frankenstein en este punto. ¡Pero funcionó!

Paso 3:Wall-E en acción

Aquí hay un par de videos que lo muestran en acción:

Y aquí probé lo que haría si estuviera atrapado en una esquina:

Así que este fue mi primer pequeño proyecto. Ahora estoy planeando optimizar las conexiones de los cables y tal vez agregar un servomotor para que pueda girar la cabeza. Incluso podría comprar divisores y un protector de motor y una placa más pequeños para poder colocar todo en su barriga.

Y entonces Wall-E vivido felizmente nunca después. El fin.

Código

  • Wall_e_control
Wall_e_control Arduino
Este es el archivo de control central de Wall-E. Es básico, pero todo lo que necesita en este momento.
 // Este programa es para controlar el robot Wall-E Lego.// Wall-E está conduciendo. Cuando ve un obstáculo, se detiene para mirar a su alrededor y elige otro camino .// Arduino Nano tiene 21 pines que se pueden usar para digitalRead y digitalWrite // Los pines 3, 5, 6, 9, 10, 11 de PWM se pueden usar para analogWrite // los pines 0 y 1 se pueden usar para TTL // los pines 2 y 3 se pueden usar para interrupciones externas // los pines 10, 11, 12, 13 admiten comunicación SPI // el pin 13 puede ser LED interno // pines 14 a 21 también son pines analógicos A0 a A7 y se pueden usar para lectura analógica # define INFRA_RED 9 // puede ser cualquier pin # define GREEN_LED 7 // puede ser cualquier pin pero necesita resistencia, tal vez 220 Ohm - o el pin de tierra obtiene 1 kOhm # define RED_LED 8 // puede ser cualquier pin pero necesita resistencia, tal vez 220 Ohm - o el pin de tierra obtiene 1 kOhm # define BUZZER 10 // necesita ser el pin PWM para establecer la frecuencia, necesita resistencia, tal vez 1 kOhm // MR es el motor derecho, ML es el motor izquierdo. pags en números en el escudo L289N # definir MR_ENABLE 5 // necesita ser un pin PWM para control de velocidad # definir ML_1 A3 // puede ser cualquier pin, así que hagámoslos corresponder a los números de pin en el escudo L289N # definir ML_2 A4 // puede ser cualquier pin, así que hagámoslos corresponder a los números de pin en el escudo L289N # define ML_ENABLE 6 // necesita ser un pin PWM para el control de velocidad // establecer su velocidad normal a la máxima constancia int NORMAL_SPEED =255; void setup () { // justo después de presionar el botón de reinicio, espere un poco para que podamos apagarlo sin dañar ningún componente a través del retraso de picos de voltaje (2000); // inicializar los LED y el zumbador pinMode (GREEN_LED, OUTPUT); pinMode (RED_LED, SALIDA); // pinMode (ZUMBADOR, SALIDA); // no es necesario // restablecer el LED a verde digitalWrite (RED_LED, LOW); digitalWrite (VERDE_LED, ALTO); // establece los pines del motor de CC pinMode (MR_ENABLE, OUTPUT); // motor pinMode derecho (MR_1, SALIDA); pinMode (MR_2, SALIDA); pinMode (ML_ENABLE, SALIDA); // motor pinMode izquierdo (ML_1, SALIDA); pinMode (ML_2, SALIDA); // inicializar pinMode infrarrojos (INFRA_RED, INPUT); // inicializar el generador de números aleatorios para turnos aleatorios randomSeed (analogRead (0)); // saluda playHello ();} void loop () {// operaciones normales driveForwards (NORMAL_SPEED); // establece el LED en verde digitalWrite (RED_LED, LOW); digitalWrite (VERDE_LED, ALTO); // verifica si hay obstáculos if (digitalRead (INFRA_RED) ==LOW) {// LOW significa obstáculo detectado // cambia el LED a rojo digitalWrite (GREEN_LED, LOW); digitalWrite (RED_LED, HIGH); // detener motores stopDriving (); // reproducir sonido uh-oh playUhOh (); // comprobar giro a la izquierdaLeft (500); obstáculoLeft booleano =falso; if (digitalRead (INFRA_RED) ==LOW) {obstacleLeft =true; } // volver al centro delay (100); girar a la derecha (500); // espera un poco, no queremos parecer apresurados delay (500); // comprobar giro a la derecha (500); obstáculo booleano derecho =falso; if (digitalRead (INFRA_RED) ==LOW) {obstacleRight =true; } // volver al centro delay (100); girar a la izquierda (500); // ahora compruebe cómo salir de aquí if (obstáculo izquierdo &&obstáculo derecho) {conducir hacia atrás (NORMAL_SPEED / 3); // bip mientras retrocede durante 5 segundos para (int i =0; i <5; i ++) {tone (BUZZER, 1000, 500); retraso (1000); } // para evitar quedarse atascado en algún lugar, girar aleatoriamente en una dirección antes de continuar el viaje randomTurn (800, 1600); } else if (obstáculo izquierdo) {giro a la derecha (1000); } else if (obstáculoDerecho) {giroIzquierdo (1000); } else {randomTurn (1000, 1800); }} // hacer cosas al azar para una mayor interacción int number =random (100); // crea un número aleatorio entre 0 y 99 if (número ==0) {randomTurn (200,2000); }} void driveForwards (int speed) {// configura los motores para que vayan en la misma dirección digitalWrite (MR_1, LOW); escritura digital (MR_2, ALTA); escritura digital (ML_1, ALTA); digitalWrite (ML_2, BAJO); setSpeed ​​(velocidad);} void driveBackwards (int speed) {// configura los motores para que vayan en la dirección opuesta digitalWrite (MR_1, HIGH); digitalWrite (MR_2, BAJO); digitalWrite (ML_1, BAJO); escritura digital (ML_2, ALTA); setSpeed ​​(velocidad);} void turnLeft (int duration) {// girar a la izquierda yendo hacia adelante con la rueda derecha y hacia atrás con la rueda izquierda digitalWrite (MR_1, HIGH); digitalWrite (MR_2, BAJO); escritura digital (ML_1, ALTA); digitalWrite (ML_2, BAJO); // reducir la velocidad para girar setSpeed ​​(NORMAL_SPEED / 2); retraso (duración); stopDriving ();} void turnRight (int duration) {// gira a la derecha yendo hacia atrás con la rueda derecha y hacia adelante con la rueda izquierda digitalWrite (MR_1, LOW); escritura digital (MR_2, ALTA); digitalWrite (ML_1, BAJO); escritura digital (ML_2, ALTA); // reducir la velocidad para girar setSpeed ​​(NORMAL_SPEED / 2); retraso (duración); stopDriving ();} void stopDriving () {// apaga todos los pines del motor digitalWrite (MR_1, LOW); digitalWrite (MR_2, BAJO); digitalWrite (ML_1, BAJO); digitalWrite (ML_2, BAJO); // No estoy seguro de qué hacer con los pines ENABLE, pero no está de más apagarlos también Supongo que digitalWrite (MR_ENABLE, LOW); digitalWrite (ML_ENABLE, LOW);} void setSpeed ​​(int speed) {// la velocidad debe estar entre 0 y 255 speed =restricin (velocidad, 0, 255); // establece la velocidad para encender los motores en analogWrite (MR_ENABLE, velocidad); analogWrite (ML_ENABLE, velocidad);} void randomTurn (int mínimo, int máximo) {unsigned long time =millis (); int duración =aleatorio (mínimo, máximo); if (tiempo% 2) {turnRight (duración); } else {turnLeft (duración); }} void playHello () {tono (ZUMBADOR, 262, 250); // reproduce C4 delay (300); tono (ZUMBADOR, 330, 250); // reproduce E4 delay (300); tono (ZUMBADOR, 392, 250); // reproduce G4 delay (300); tono (ZUMBADOR, 523, 500); // reproduce C5 delay (550);} void playUhOh () {tone (BUZZER, 523, 250); // reproduce C5 delay (300); tono (ZUMBADOR, 415, 500); // reproduce Gis4 delay (600);} 

Esquemas

Significado de los colores de los cables:
rojo =voltaje (positivo)
negro =suelo (negativo)
amarillo =señal para sensor de infrarrojos
naranja y verde =conexiones para entrada LED rojo y verde
violeta =control de dirección del motor
azul =control de velocidad del motor (desafortunadamente, la parte Fritzing no tenía los dos pines que tenía mi puente del motor para estas conexiones, por lo que parece que hay cables sueltos en este momento) wall-e2_3P6X71BCnP.fzz

Proceso de manufactura

  1. Monitoreo de CO2 con sensor K30
  2. Comunicación para personas sordociegas con 1Sheeld / Arduino
  3. Controlar el aceptador de monedas con Arduino
  4. Tirador de Lego automatizado
  5. Obstáculos que evitan el robot con servomotor
  6. ¡Arduino con Bluetooth para controlar un LED!
  7. Sensor capacitivo de huellas dactilares con Arduino o ESP8266
  8. Robot seguidor de línea
  9. Jugando con Nextion Display
  10. Brazo robótico controlado por Nunchuk (con Arduino)
  11. Control del servomotor con Arduino y MPU6050