EFA:The Little EFA Robot

This week we are going to go through some basics of the Arduino platform and while we do that, we are going to implement the things we learn into building a little robot. Meet EFA, the little robot that could:

Parts List

  • 1 x Aluminium Robot Chassis
  • 1 x Custom Extension Plate (laser cut acrylic)
  • 2 x TT Motors (3-6VDC)
  • 2 x Wheels
  • 1 x Caster Wheel
  • 1 x Arduino Uno
  • 1 x Breadboard
  • 1 x L293D H-Bridge (motor driver)
  • 1 x Ultrasonic Sensor (HC-SR04)
  • 1 x Light Dependent Resistor (LDR, light sensor)
  • 1 x 10 kΩ resistor
  • 1 x Battery Pack (5xAA) + one small screw for attaching the battery pack to the chassis
  • 3 x M3x25 Spacers
  • 4 x M3x25 Screws (for the TT motors)
  • 4 x M3 Nuts (for the TT motors)
  • 8 x M3x6 Screws

How To Build It?

  1. Attach the TT motors to the chassis using M3x25 machine screws and nuts
  2. Attach the caster wheel to the bottom of the frame (frontside of the chassis) using two M3x6 screws.
  3. Attach the battery pack to the chassis
  4. Attach the black plate to the chassis
  5. Attach the Arduino and the breadboard to the chassis
  6. Hook up the ultrasonic sensor to the Arduino using the breadboard
  7. Connect the motors to the L293D H-Bridge
  8. Wire up the light sensor to pin A0 of the Arduino using a voltage divider together with the 10kΩ resistor.
  9. Upload the code below to the Arduino

Detailed Instructions

Code

The Little EFA Robot does not like it when there is too much light. If the light sensor sees too much light, it will try to find a darker area.

The code below works like this:

  • It reads the reading from the ultrasonic sensor and saves the distance to a variable called distance
  • It reads the light level and stores the value to a variable called light
  • The robot moves only when the light level is above the lightThreshold value
  • The robot goes forward if the distance sensor gives a value more than 30 (there are no obstacles in front of the sensors).
  • If the distance value is less than or equal to 30, the robot turns left to avoid the obstacle.

Feel free to edit the code to make the robot behave in a different way. This is just the starting point.


#define MR_EN 5
#define MR_C1 6
#define MR_C2 7

#define ML_EN 9
#define ML_C1 10
#define ML_C2 11

#define TRIG_PIN 3
#define ECHO_PIN 2

long duration;
int distance;

int light;
int lightThreshold = 800;

void setup() {
  Serial.begin(9600);
  
  pinMode(MR_EN, OUTPUT);
  pinMode(MR_C1, OUTPUT);
  pinMode(MR_C2, OUTPUT);

  pinMode(ML_EN, OUTPUT);
  pinMode(ML_C1, OUTPUT);
  pinMode(ML_C2, OUTPUT);

  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);

  leftSpeed(255);
  rightSpeed(255);
}

void loop() {
  // read the sensors
  readUltrasonic(true,400);
  readLight();

  // only move if the light level is high enough
  if(light > lightThreshold){
    // turn left if there is something in the way
    if(distance > 30){
        goForward();
      }else{
        goLeft();  
      }
  }else{
    stopAll();
  }
  
}

void goForward(){
  leftMotorForward();
  rightMotorForward();
}

void goBackward(){
  leftMotorBackward();
  rightMotorBackward();
}

void goLeft(){
  rightMotorForward();
  leftMotorBackward();
}

void goRight(){
  leftMotorForward();
  rightMotorBackward();
}

void stopAll(){
  leftMotorStop();
  rightMotorStop();
}

void leftMotorForward(){
  digitalWrite(ML_C1, HIGH);
  digitalWrite(ML_C2, LOW);
}

void leftMotorBackward(){
  digitalWrite(ML_C1, LOW);
  digitalWrite(ML_C2, HIGH);
}

void leftMotorStop(){
  digitalWrite(ML_C1, LOW);
  digitalWrite(ML_C2, LOW);
}

void rightMotorStop(){
  digitalWrite(MR_C1, LOW);
  digitalWrite(MR_C2, LOW);
}

void rightMotorForward(){
  digitalWrite(MR_C1, HIGH);
  digitalWrite(MR_C2, LOW);
}


void rightMotorBackward(){
  digitalWrite(MR_C1, LOW);
  digitalWrite(MR_C2, HIGH);
}

void leftSpeed(int mSpeed){
 analogWrite(ML_EN, mSpeed);
}

void rightSpeed(int mSpeed){
 analogWrite(MR_EN, mSpeed);
}

void readUltrasonic(bool shouldPrint, int maxDistance) {
  // Clear the TRIG_PIN
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);

  // Set the TRIG_PIN HIGH for 10 microseconds
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  // Read the ECHO_PIN, returns the sound wave travel time in microseconds
  duration = pulseIn(ECHO_PIN, HIGH);

  // Calculate the distance
  // The calculation we use below is an approximation of the real formula:
  // duration * 0.034 / 2.0
  // (0.017 equals roughly to 1/58)
  // We do it this way to avoid having to use floating point numbers.
  int tempDistance = duration / 58;

  // sometimes the sensor gives strange values. This just ignores all values larger than the maxDistance.
  if (tempDistance < maxDistance) {
    distance = tempDistance;
  }

  if (shouldPrint) {
    // Prints the distance on the Serial Monitor (cm)
    Serial.print("Distance: ");
    Serial.print(distance);
    Serial.println("cm");
  }
}

void readLight(){
  light = analogRead(A0);
  Serial.print("light: ");
  Serial.println(light);
}