monsterbacke
Published © GPL3+

LEGO Wall-E with Arduino

My first project combines everyone's favorite robot with everyone's favorite tinkering platform. Hope you like it!

IntermediateFull instructions provided15 hours39,441

Things used in this project

Hardware components

LEGO Wall-E
Had to get one 2nd hand because they don't make them anymore
×1
Arduino Nano R3
Arduino Nano R3
×1
DC motor (generic)
×2
L298N Dual Motor Controller
×1
Bi-colour LED
with 3 pins
×1
Infra-red sensor
×1
Buzzer
Buzzer
One that can play different tones
×1
9V battery
×1
Resistor 330 ohm
Resistor 330 ohm
×3
Jumper wires (generic)
Jumper wires (generic)
×20

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

Wall_e_wiring

Meaning of the cable colours:
red = voltage (positive)
black = ground (negative)
yellow = signal for infra-red sensor
orange and green = connections for red and green LED input
purple = motor direction control
blue = motor speed control (unfortunately, the Fritzing part did not have the two pins that my motor bridge had for these connections, so it looks like loose wires at the moment)

Code

Wall_e_control

Arduino
This is the central control file for Wall-E. It is basic, but all he needs at the moment.
// This program is to control the Wall-E Lego robot.
// Wall-E is driving around. When he sees an obstacle, he stops to look around and chooses another path.

// Arduino Nano has 21 pins that can be used for digitalRead and digitalWrite
// PWM pins 3, 5, 6, 9, 10, 11 can be used for analogWrite
// pins 0 and 1 can be used for TTL
// pins 2 and 3 can be used for external interrupts
// pins 10, 11, 12, 13 support SPI communication
// pin 13 can be internal LED
// pins 14 to 21 are also analog pins A0 to A7 and can be used for analogRead


#define INFRA_RED 9   // can be any pin
#define GREEN_LED 7   // can be any pin but needs resistor, maybe 220 Ohm - or the ground pin gets 1 kOhm
#define RED_LED 8     // can be any pin but needs resistor, maybe 220 Ohm - or the ground pin gets 1 kOhm
#define BUZZER 10     // needs to be PWM pin to set frequency, needs resistor, maybe 1 kOhm

// MR is the right motor, ML is the left motor
#define MR_1 A1       // can be any pin, so let's make them correspond to the pin numbers on the L289N shield
#define MR_2 A2       // can be any pin, so let's make them correspond to the pin numbers on the L289N shield
#define MR_ENABLE 5   // needs to be PWM pin for speed control
#define ML_1 A3       // can be any pin, so let's make them correspond to the pin numbers on the L289N shield
#define ML_2 A4       // can be any pin, so let's make them correspond to the pin numbers on the L289N shield
#define ML_ENABLE 6   // needs to be PWM pin for speed control

// set his normal speed to maximum
const int NORMAL_SPEED = 255;

void setup() {

  // right after pressing the reset button, wait for a bit so we can turn him off without damaging any components through voltage spikes
  delay(2000);
  
  // initialise LEDs and buzzer
  pinMode(GREEN_LED, OUTPUT);
  pinMode(RED_LED, OUTPUT);
//  pinMode(BUZZER, OUTPUT);  // not necessary

  // reset LED to green  
  digitalWrite(RED_LED, LOW);
  digitalWrite(GREEN_LED, HIGH);
  
  // set DC motor pins
  pinMode(MR_ENABLE, OUTPUT);  // motor right
  pinMode(MR_1, OUTPUT);
  pinMode(MR_2, OUTPUT);
  pinMode(ML_ENABLE, OUTPUT);  // motor left
  pinMode(ML_1, OUTPUT);
  pinMode(ML_2, OUTPUT);

  // initialise infra red
  pinMode(INFRA_RED, INPUT);
  
  // initialise random number generator for random turns
  randomSeed(analogRead(0));

  // say hello
  playHello();

}

void loop() {
  // normal operations
  driveForwards(NORMAL_SPEED);

  // set LED to green
  digitalWrite(RED_LED, LOW);
  digitalWrite(GREEN_LED, HIGH);

  // check for obstacles
  if (digitalRead(INFRA_RED) == LOW) {  //LOW means obstacle detected
    // change LED to red
    digitalWrite(GREEN_LED, LOW);
    digitalWrite(RED_LED, HIGH);

    // stop motors
    stopDriving();

    // play uh-oh sound
    playUhOh();

    // check left
    turnLeft(500);
    boolean obstacleLeft = false;
    if (digitalRead(INFRA_RED) == LOW) {
      obstacleLeft = true;
    }
    // turn back to centre
    delay(100);
    turnRight(500);

    // wait a little, we don't want to seem rushed
    delay(500);

    // check right
    turnRight(500);
    boolean obstacleRight = false;
    if (digitalRead(INFRA_RED) == LOW) {
      obstacleRight = true;
    }
    // turn back to centre
    delay(100);
    turnLeft(500);
    
    // now check how to get out of here
    if (obstacleLeft && obstacleRight) {
      driveBackwards(NORMAL_SPEED / 3);
      // beep while going backwards for 5 seconds
      for (int i = 0; i < 5; i++) {
        tone(BUZZER, 1000, 500);
        delay(1000);
      }
      // to avoid getting stuck somewhere, randomly turn into a direction before continuing journey
      randomTurn(800, 1600);

    } else if (obstacleLeft) {
      turnRight(1000);
      
    } else if (obstacleRight) {
      turnLeft(1000);
      
    } else {
      randomTurn(1000, 1800);
    }
  }

  // do random stuff for more interaction
  int number = random(100);  // creates a random number between 0 and 99
  if (number == 0) {
    randomTurn(200,2000);
  }
  
}

void driveForwards(int speed) {
  // set the motors to go in the same direction
  digitalWrite(MR_1, LOW);
  digitalWrite(MR_2, HIGH);
  digitalWrite(ML_1, HIGH);
  digitalWrite(ML_2, LOW);

  setSpeed(speed);
}

void driveBackwards(int speed) {
  // set the motors to go in the opposite direction
  digitalWrite(MR_1, HIGH);
  digitalWrite(MR_2, LOW);
  digitalWrite(ML_1, LOW);
  digitalWrite(ML_2, HIGH);

  setSpeed(speed);
}

void turnLeft(int duration) {
  // turn left by going forwards with the right wheel and backwards with the left wheel
  digitalWrite(MR_1, HIGH);
  digitalWrite(MR_2, LOW);
  digitalWrite(ML_1, HIGH);
  digitalWrite(ML_2, LOW);

  // slow down to turn
  setSpeed(NORMAL_SPEED / 2);

  delay(duration);
  stopDriving();
}

void turnRight(int duration) {
  // turn right by going backwards with the right wheel and forwards with the left wheel
  digitalWrite(MR_1, LOW);
  digitalWrite(MR_2, HIGH);
  digitalWrite(ML_1, LOW);
  digitalWrite(ML_2, HIGH);

  // slow down to turn
  setSpeed(NORMAL_SPEED / 2);

  delay(duration);
  stopDriving();
}

void stopDriving() {
  // turn off all the motor pins
  digitalWrite(MR_1, LOW);
  digitalWrite(MR_2, LOW);
  digitalWrite(ML_1, LOW);
  digitalWrite(ML_2, LOW);

  // not sure what to do with the ENABLE pins, but doesn't hurt to turn them off as well I guess
  digitalWrite(MR_ENABLE, LOW);
  digitalWrite(ML_ENABLE, LOW);
}

void setSpeed(int speed) {
  // speed must be between 0 and 255
  speed = constrain(speed, 0, 255);

  // set the speed to turn the motors on
  analogWrite(MR_ENABLE, speed);
  analogWrite(ML_ENABLE, speed);
}

void randomTurn(int minimum, int maximum) {
  unsigned long time = millis();
  int duration = random(minimum, maximum);
  if (time % 2) {
    turnRight(duration);
  } else {
    turnLeft(duration);
  }
}

void playHello() {
  tone(BUZZER, 262, 250); // plays C4
  delay(300);
  tone(BUZZER, 330, 250); // plays E4
  delay(300);
  tone(BUZZER, 392, 250); // plays G4
  delay(300);
  tone(BUZZER, 523, 500); // plays C5
  delay(550);
}

void playUhOh() {
  tone(BUZZER, 523, 250); // plays C5
  delay(300);
  tone(BUZZER, 415, 500); // plays Gis4
  delay(600);
}

Credits

monsterbacke

monsterbacke

1 project • 25 followers

Comments