Full Arduino Code - Eco-Genie

Overview

This page provides the complete Arduino code for the Eco-Genie material sorting system, including an in-depth breakdown of its functionality.

Explanation & Technical Breakdown

This section provides an in-depth understanding of the functionality of the Eco-Genie system:

Full Arduino Code

#include "Wire.h"
#include "LiquidCrystal_I2C.h"
#include "Servo.h"

// Initialize the LCD with the I2C address 0x27 and dimensions 16x2
LiquidCrystal_I2C lcd(0x27, 16, 2);

// Pin assignments for sensors
const int trigPin = 26;
const int echoPin = 28;
const int capacitivePin = 24;
const int inductivePin = 22;
Servo tipperServo;
const int servoPin = 48;

// Stepper Motor Pins for CNC Shield
const int stepPinX = 2;    // Step pin for the X-axis stepper motor
const int dirPinX = 5;     // Direction pin for the X-axis stepper motor

// Variables to store sensor readings and counts
int capacitiveReadings = 0;
int inductiveReadings = 0;

// Detection thresholds
const int ultrasonicThreshold = 2; // Threshold in mm (7 cm)
const int detectionThreshold = 50;  // Number of readings for material detection
const int materialDelay = 10000;    // 10 seconds total delay for readings
const long stepsDistance = 244000;  // Updated steps for halfway tipping action
int stepDelay = 25;                 // Speed set to 50 microseconds delay (faster motor speed)

// Variables for servo operation
const int neutralPosition = 90;
const int tipPosition = 0; // Tipping position is 0 degrees

// Function to read ultrasonic distance
long getUltrasonicDistance() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  long duration = pulseIn(echoPin, HIGH);
  return duration * 0.034 / 2; // Convert duration to distance in cm
}

// Function to determine material based on sensor readings
String determineMaterial(int capacitiveCount, int inductiveCount) {
  if (capacitiveCount > 25 && inductiveCount > 25) {
    return "Aluminum Detected"; // Both sensors detect
  } else if (capacitiveCount > 25 && inductiveCount <= 25) {
    return "Glass Detected";    // Only capacitive detects
  } else if (capacitiveCount <= 25 && inductiveCount <= 25) {
    return "Plastic Detected";  // Neither sensor detects
  }
  return "No Material Detected";
}

// Function to move stepper motor
void moveStepper(long steps, bool direction) {
  digitalWrite(dirPinX, direction); // Set motor direction
  for (long i = 0; i < steps; i++) {
    digitalWrite(stepPinX, HIGH);
    delayMicroseconds(stepDelay);
    digitalWrite(stepPinX, LOW);
    delayMicroseconds(stepDelay);
  }
}

// Function to move the servo slowly to a target position
void slowMoveServo(int targetAngle) {
  int currentAngle = tipperServo.read(); // Get current position of the servo
  if (currentAngle < targetAngle) {
    for (int angle = currentAngle; angle <= targetAngle; angle++) {
      tipperServo.write(angle);
      delay(15); // Adjust delay for speed control
    }
  } else {
    for (int angle = currentAngle; angle >= targetAngle; angle--) {
      tipperServo.write(angle);
      delay(15); // Adjust delay for speed control
    }
  }
}

// Servo function to tip the container and return to the original position
void actuateServo() {
  // Move the servo slowly to the tipping position (0 degrees)
  slowMoveServo(tipPosition);
  delay(500); // Hold position for tipping

  // Move the servo back to the neutral position (90 degrees)
  slowMoveServo(neutralPosition);
}

// Setup function
void setup() {
  Serial.begin(9600);
  lcd.begin();
  lcd.backlight();
  
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(capacitivePin, INPUT);
  pinMode(inductivePin, INPUT);
  
  // Attach the servo
  tipperServo.attach(servoPin);
  tipperServo.write(neutralPosition); // Set servo to neutral position
  
  // Set stepper motor pins
  pinMode(stepPinX, OUTPUT);
  pinMode(dirPinX, OUTPUT);
  
  Serial.println("System Initialized");
  lcd.clear();
  lcd.print("System Ready");
  delay(2000);
  lcd.clear();
}

void loop() {
  // Step 1: Check if an object is detected by the ultrasonic sensor
  lcd.clear();
  lcd.print("Waiting for Obj...");
  long distance = getUltrasonicDistance();
  if (distance > ultrasonicThreshold) {
    delay(500);
    return; // No object detected, continue looping
  }

  // Step 2: Object detected, start material detection process
  lcd.clear();
  lcd.print("Object Detected");
  delay(1000);

  int capacitiveCount = 0;
  int inductiveCount = 0;

  // Take multiple readings to determine material
  for (int i = 0; i < detectionThreshold; i++) {
    int capacitiveReading = digitalRead(capacitivePin);
    int inductiveReading = digitalRead(inductivePin);

    if (capacitiveReading == LOW) capacitiveCount++;
    if (inductiveReading == LOW) inductiveCount++;

    delay(materialDelay / detectionThreshold);
  }

  // Step 3: Determine material type
  String material = determineMaterial(capacitiveCount, inductiveCount);
  Serial.println(material);
  lcd.clear();
  lcd.print(material);

  // Step 4: Actuate stepper motor and servo based on detected material
  if (material == "Plastic Detected") {
    moveStepper(stepsDistance, false);
    actuateServo();
    delay(1000);
    moveStepper(stepsDistance, true);
  } else if (material == "Aluminum Detected") {
    moveStepper(stepsDistance, true);
    actuateServo();
    delay(1000);
    moveStepper(stepsDistance, false);
  } else if (material == "Glass Detected") {
    actuateServo();
    delay(1000);
  }

  // Step 5: Reset display and prepare for next detection
  delay(5000);
  lcd.clear();
  lcd.print("Resetting...");
  delay(2000);
  lcd.clear();
}


            
⬅ Back to Home