sithum udayanga
Published © MIT

Automated Bottle Sorting Robot Using Arduino

Automated bottle sorter using Arduino, sensors and servos for efficient recycling. Detects and sorts metal and plastic bottles autonomously.

IntermediateFull instructions provided2 days671
Automated Bottle Sorting Robot Using Arduino

Things used in this project

Hardware components

SG90 Micro-servo motor
SG90 Micro-servo motor
×3
Ultrasonic Sensor - HC-SR04 (Generic)
Ultrasonic Sensor - HC-SR04 (Generic)
×4
Aldec 4 Sets TT Motor DC 3-6V Gearbox Motor
×1
BOJACK L298N Motor DC Dual H-Bridge Motor Driver Controller
×1
IR Infrared Obstacle Avoidance Sensor
×2
Arduino UNO
Arduino UNO
×2
Inductive Proximity Sensor, Stainless Steel
Inductive Proximity Sensor, Stainless Steel
×1
A23 23A 12V Battery
×3
Slot 3 Battery Holder
×1
Female/Female Jumper Wires
Female/Female Jumper Wires
×15
Male/Female Jumper Wires
Male/Female Jumper Wires
×15
Male/Male Jumper Wires
×15
Breadboard (generic)
Breadboard (generic)
×1
Toggle Switch, Toggle
Toggle Switch, Toggle
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Hot glue gun (generic)
Hot glue gun (generic)
Drill, Screwdriver
Drill, Screwdriver

Story

Read more

Schematics

Main Sorting Part

Diagram illustrating the connections of ultrasonic sensors, inductive sensor, LEDs, and servo motors used for detecting and sorting metal and plastic bottles in the recycling robot.

line following part

Circuit diagram depicting the connections of infrared (IR) sensors and motor control pins used for guiding the robot along a predefined path based on line detection.

Code

line following part

Arduino
Ensures robot navigation along a path using IR sensors, halting on approach detected by ultrasonic sensors.
// Motor control pins
const int ENA = 9;   // Enable pin for motor driver A
const int IN1 = 6;   // Control pin 1 for motor driver A
const int IN2 = 5;   // Control pin 2 for motor driver A
const int IN3 = 3;   // Control pin 1 for motor driver B
const int IN4 = 4;   // Control pin 2 for motor driver B
const int ENB = 10;  // Enable pin for motor driver B

// Ultrasonic sensor pins
const int trigPin = 8;
const int echoPin = 7;

// IR sensor pins
const int leftIRSensor = 2;
const int rightIRSensor = 4;

// Threshold distance in centimeters
const int thresholdDistance = 10;

// Kickstart parameters
const int KICK_START_SPEED = 100;  // Higher speed for kick start
const int NORMAL_SPEED = 50;       // Normal operating speed
const int KICK_START_DURATION = 200; // Kick start duration in milliseconds

void setup() {
  // Set motor control pins as outputs
  pinMode(ENA, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(ENB, OUTPUT);

  // Set ultrasonic sensor pins
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  // Set IR sensor pins
  pinMode(leftIRSensor, INPUT);
  pinMode(rightIRSensor, INPUT);

  // Initialize serial communication
  Serial.begin(9600);

  // Initially, stop all motors
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);

  // Enable motor driver A and B
  digitalWrite(ENA, HIGH);
  digitalWrite(ENB, HIGH);
}

void loop() {
  // Measure the distance
  int distance = measureDistance();

  // Read IR sensor values
  int leftIRValue = digitalRead(leftIRSensor);
  int rightIRValue = digitalRead(rightIRSensor);

  // Print the distance to the Serial Monitor
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");

  // Check the ultrasonic distance
  if (distance <= thresholdDistance) {
    // If the distance is less than or equal to the threshold, stop the motors
    stopMotors();
  } else {
    // Follow the line using IR sensors
    followLine(leftIRValue, rightIRValue);
  }

  // Add a short delay before the next loop
  delay(100);
}

void followLine(int leftIRValue, int rightIRValue) {
  if (leftIRValue == LOW && rightIRValue == LOW) {
    // Both sensors detect the line, move forward
    moveForward();
  } else if (leftIRValue == LOW && rightIRValue == HIGH) {
    // Left sensor detects the line, turn left
    turnLeft();
  } else if (leftIRValue == HIGH && rightIRValue == LOW) {
    // Right sensor detects the line, turn right
    turnRight();
  } else {
    // Both sensors detect white, stop
    stopMotors();
  }
}

void moveForward() {
  // Kick start to overcome initial inertia
  analogWrite(IN1, KICK_START_SPEED); // Motor A forward at kick start speed
  digitalWrite(IN2, LOW);
  analogWrite(IN3, KICK_START_SPEED); // Motor B forward at kick start speed
  digitalWrite(IN4, LOW);
  
  delay(KICK_START_DURATION); // Wait for kick start duration

  // Reduce to normal operating speed
  analogWrite(IN1, NORMAL_SPEED); // Motor A forward at normal speed
  digitalWrite(IN2, LOW);
  analogWrite(IN3, NORMAL_SPEED); // Motor B forward at normal speed
  digitalWrite(IN4, LOW);
}

void turnLeft() {
  analogWrite(IN1, 50);   // Motor A forward at speed 50/255
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW); // Motor B stop
  analogWrite(IN4, 50);   // Motor B backward at speed 50/255
}

void turnRight() {
  digitalWrite(IN1, LOW); // Motor A stop
  analogWrite(IN2, 50);   // Motor A backward at speed 50/255
  analogWrite(IN3, 50);   // Motor B forward at speed 50/255
  digitalWrite(IN4, LOW);
}

void stopMotors() {
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);
}

int measureDistance() {
  // Clear the trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

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

  // Read the echoPin and calculate the duration of the pulse
  long duration = pulseIn(echoPin, HIGH);

  // Calculate the distance based on the speed of sound
  int distance = duration * 0.0343 / 2;

  return distance;
}

Main Sorting Part

Arduino
Identifies metal bottles with an inductive sensor during countdown, sorts into separate bins with servo-operated doors. Monitors bin fill levels with ultrasonic sensors to prevent overflow.
#include <Servo.h>

// Define ultrasonic sensor pins for lid, metal, and plastic bins
#define LID_TRIG_PIN 9
#define LID_ECHO_PIN 8
#define METAL_TRIG_PIN 10
#define METAL_ECHO_PIN 11
#define PLASTIC_TRIG_PIN 13
#define PLASTIC_ECHO_PIN 12

// Define LED pins for indicating metal and plastic detection
#define METAL_LED A0
#define PLASTIC_LED A1

// Define servo motor pins for lid, metal bin, and plastic bin doors
#define SERVO_PIN 7
#define INDUCTIVE_SENSOR_PIN 5
#define METAL_SERVO_PIN 6 
#define PLASTIC_SERVO_PIN 4 

// Define distance thresholds for operations
#define THRESHOLD_DISTANCE 10  
#define LED_THRESHOLD_DISTANCE 20 

// Initialize servo objects
Servo myServo;
Servo metalServo;
Servo plasticServo;

void setup() {
  // Initialize serial communication
  Serial.begin(9600);
  
  // Configure pin modes for ultrasonic sensors
  pinMode(LID_TRIG_PIN, OUTPUT);
  pinMode(LID_ECHO_PIN, INPUT);
  pinMode(METAL_TRIG_PIN, OUTPUT);
  pinMode(METAL_ECHO_PIN, INPUT);
  pinMode(PLASTIC_TRIG_PIN, OUTPUT);
  pinMode(PLASTIC_ECHO_PIN, INPUT);
  
  // Configure pin modes for inductive sensor and LEDs
  pinMode(INDUCTIVE_SENSOR_PIN, INPUT);
  pinMode(METAL_LED, OUTPUT);
  pinMode(PLASTIC_LED, OUTPUT);
  
  // Attach servo motors to respective pins and set initial positions
  myServo.attach(SERVO_PIN); 
  metalServo.attach(METAL_SERVO_PIN); 
  plasticServo.attach(PLASTIC_SERVO_PIN);
  myServo.write(85); 
  metalServo.write(0); 
  plasticServo.write(0); 
}

// Function to read distance from ultrasonic sensor
long readUltrasonicDistance(int trigPin, int echoPin) {
  long duration, distance;
  
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  // Measure the duration of the echo pulse
  duration = pulseIn(echoPin, HIGH);
  
  // Calculate the distance based on the speed of sound
  distance = duration * 0.034 / 2;
  
  return distance;
}

void loop() {
  // Read distances from ultrasonic sensors
  long lidDistance = readUltrasonicDistance(LID_TRIG_PIN, LID_ECHO_PIN);
  long metalDistance = readUltrasonicDistance(METAL_TRIG_PIN, METAL_ECHO_PIN);
  long plasticDistance = readUltrasonicDistance(PLASTIC_TRIG_PIN, PLASTIC_ECHO_PIN);

  // Print distances to serial monitor
  Serial.print("Lid Distance: ");
  Serial.print(lidDistance);
  Serial.println(" cm");
  Serial.print("Metal Distance: ");
  Serial.print(metalDistance);
  Serial.println(" cm");
  Serial.print("Plastic Distance: ");
  Serial.print(plasticDistance);
  Serial.println(" cm");

  // Check if lid distance is within threshold for operation
  if (lidDistance <= THRESHOLD_DISTANCE) {
    openLid(); // Open the lid
    delay(3000);
    closeLid(); // Close the lid after 3 seconds

    bool metalDetected = false;
    unsigned long startTime = millis();
    // Perform metal detection process for up to 10 seconds
    while (millis() - startTime < 10000) {
      // Check if metal is detected by inductive sensor
      if (digitalRead(INDUCTIVE_SENSOR_PIN) == HIGH) {
        // If metal is detected and within LED threshold distance, indicate and sort metal
        if (metalDistance <= LED_THRESHOLD_DISTANCE) {
          indicateMetal();
          metalDetected = true;
          break;
        } else {
          sortMetal();
          metalDetected = true;
          break;
        }
      }
      delay(100);
    }

    // If no metal detected, check and sort plastic if within LED threshold distance
    if (!metalDetected) {
      if (plasticDistance <= LED_THRESHOLD_DISTANCE) {
        indicatePlastic();
      } else {
        sortPlastic();
      }
    }
  }

  // Update LEDs based on current distances
  updateLEDs(metalDistance, plasticDistance);

  // Delay before next loop iteration
  delay(1000);
}

// Function to open the lid
void openLid() {
  myServo.write(10);
}

// Function to close the lid
void closeLid() {
  myServo.write(85);
}

// Function to indicate detection of metal
void indicateMetal() {
  digitalWrite(METAL_LED, HIGH);
  delay(500);
  digitalWrite(METAL_LED, LOW);
  openLid();
  delay(3000);
  closeLid();
}

// Function to sort metal into the metal bin
void sortMetal() {
  metalServo.write(35);
  delay(1000);
  metalServo.write(0);
}

// Function to indicate detection of plastic
void indicatePlastic() {
  digitalWrite(PLASTIC_LED, HIGH);
  delay(500);
  digitalWrite(PLASTIC_LED, LOW);
  openLid();
  delay(3000);
  closeLid();
}

// Function to sort plastic into the plastic bin
void sortPlastic() {
  plasticServo.write(50);
  delay(1000);
  plasticServo.write(0);
}

// Function to update LEDs based on current distances
void updateLEDs(long metalDistance, long plasticDistance) {
  // Turn on metal LED if metal is detected within LED threshold distance
  if (metalDistance <= LED_THRESHOLD_DISTANCE && digitalRead(INDUCTIVE_SENSOR_PIN) == HIGH) {
    digitalWrite(METAL_LED, HIGH);
  } else {
    digitalWrite(METAL_LED, LOW);
  }

  // Turn on plastic LED if plastic is detected within LED threshold distance
  if (plasticDistance <= LED_THRESHOLD_DISTANCE) {
    digitalWrite(PLASTIC_LED, HIGH);
  } else {
    digitalWrite(PLASTIC_LED, LOW);
  }
}

Credits

sithum udayanga
1 project • 0 followers
Contact

Comments

Please log in or sign up to comment.