#include <AccelStepper.h>

#include <Wire.h>

#include <LiquidCrystal_I2C.h>


LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display


const float STEPS_PER_REV = 800;

const float DEGREES_TO_MOVE_STEPPER1 = 6.8752;

const long STEPS_TO_MOVE_STEPPER1 = DEGREES_TO_MOVE_STEPPER1 * (STEPS_PER_REV / 360.0);

const float DEGREES_TO_MOVE_STEPPER2 = 90.0;

const long STEPS_TO_MOVE_STEPPER2 = DEGREES_TO_MOVE_STEPPER2 * (200 / 360.0);


#define X_STEP_PIN 2

#define X_DIR_PIN 5

#define Y_STEP_PIN 3

#define Y_DIR_PIN 6

#define IR_SENSOR_PIN A2

#define RELAY_PIN_1 A1

#define RELAY_PIN_2 9

#define L298N_ENABLE_PIN 10

#define L298N_IN1_PIN 11

#define L298N_IN2_PIN 12


AccelStepper stepper1(1, X_STEP_PIN, X_DIR_PIN);

AccelStepper stepper2(1, Y_STEP_PIN, Y_DIR_PIN);


unsigned long previousMoveTime = 0;

unsigned long delayDuration = 3000;

int potentiometerPin = A0;

int potValue = 0;


void setup() {
  Serial.begin(9600);

  lcd.init(); // initialize the lcd

  lcd.init();

  // Print a message to the LCD.

  lcd.backlight();

  lcd.setCursor(5, 0);

  lcd.print("Welcome");

  lcd.setCursor(1, 1);

  lcd.print("Processing...");

  pinMode(IR_SENSOR_PIN, INPUT);

  pinMode(RELAY_PIN_1, OUTPUT);

  pinMode(RELAY_PIN_2, OUTPUT);

  pinMode(L298N_ENABLE_PIN, OUTPUT);

  pinMode(L298N_IN1_PIN, OUTPUT);

  pinMode(L298N_IN2_PIN, OUTPUT);

  digitalWrite(RELAY_PIN_1, LOW);

  digitalWrite(RELAY_PIN_2, LOW);

  digitalWrite(L298N_ENABLE_PIN, HIGH);


  stepper1.setMaxSpeed(1000);

  stepper1.setAcceleration(500);

  stepper2.setMaxSpeed(1000);

  stepper2.setAcceleration(500);

  delay(2000);

}


void loop() {

  potValue = analogRead(potentiometerPin);

  // Map the analog value to the desired speed range (adjust minSpeed and maxSpeed as needed)

  int minSpeed = 100; // Minimum speed

  int maxSpeed = 1000; // Maximum speed

  int speed = map(potValue, 0, 1023, minSpeed, maxSpeed);

  stepper1.setMaxSpeed(speed);

  stepper2.setMaxSpeed(1000);

  speed = map(potValue, 0, 1023, 120, 255);

  analogWrite(L298N_ENABLE_PIN, speed);

  if (digitalRead(IR_SENSOR_PIN) == LOW) {

    // Object detected, stop the first stepper motor

    stepper1.stop();


    // Turn on the first relay for 4 seconds

    digitalWrite(RELAY_PIN_1, HIGH);

    lcd.clear();

    delay(100);

    lcd.print("Glue Gun ON");

    delay(3000); // 4 seconds delay

    digitalWrite(RELAY_PIN_1, LOW); // Turn off the first relay


    // Rotate the second stepper motor by 30 degrees clockwise

    stepper2.moveTo(-STEPS_TO_MOVE_STEPPER2); // Negative value for clockwise rotation

    stepper2.runToPosition(); // Wait for the second stepper to reach its target position

    lcd.clear();

    delay(100);

    lcd.print("Rotates");

    lcd.setCursor(0, 1);

    lcd.print("Extend & Suck");

    // Extend the actuator using L298N
    
    digitalWrite(RELAY_PIN_2, HIGH);
    
    digitalWrite(L298N_IN1_PIN, HIGH);

    digitalWrite(L298N_IN2_PIN, LOW);

    Serial.println("Extend and Vaccum ON");

    delay(5000); // Extend for 5 seconds

    digitalWrite(L298N_IN1_PIN, LOW);

    digitalWrite(L298N_IN2_PIN, LOW);

    delay(1000);
    lcd.clear();

    lcd.setCursor(0, 1);

    lcd.print("Retract");

    digitalWrite(L298N_IN1_PIN, LOW);

    digitalWrite(L298N_IN2_PIN, HIGH);


    delay(6000);

    digitalWrite(L298N_IN1_PIN, LOW);

    digitalWrite(L298N_IN2_PIN, LOW);

    Serial.println("Retracted");
    
    // Rotate the second stepper motor by 30 degrees counterclockwise
    lcd.clear();
    lcd.print("Rotates");
    Serial.println("ROTATES");
    stepper2.moveTo(STEPS_TO_MOVE_STEPPER2+stepper2.currentPosition()); // Positive value for counterclockwise rotation
    stepper2.runToPosition(); // Wait for the second stepper to reach its target position
    
    delay(1000);
    lcd.print("Extend & Suck");

    // Extend the actuator using L298N
    
    digitalWrite(L298N_IN1_PIN, HIGH);

    digitalWrite(L298N_IN2_PIN, LOW);

    Serial.println("Extend");

    delay(5000); // Extend for 5 seconds

    digitalWrite(L298N_IN1_PIN, LOW);
    digitalWrite(RELAY_PIN_2, LOW);
    Serial.println("Vaccum OFF");

    digitalWrite(L298N_IN2_PIN, LOW);

    delay(1000);
    lcd.clear();

    lcd.setCursor(0, 1);

    lcd.print("Retract");

    digitalWrite(L298N_IN1_PIN, LOW);

    digitalWrite(L298N_IN2_PIN, HIGH);
    


    delay(6000);

    digitalWrite(L298N_IN1_PIN, LOW);

    digitalWrite(L298N_IN2_PIN, LOW);


    lcd.clear();

    delay(100);

    lcd.print("Rotates disc");

    stepper1.moveTo(STEPS_TO_MOVE_STEPPER1 + stepper1.currentPosition());

    previousMoveTime = millis(); // Record the time when an object is detected

  } else if (millis() - previousMoveTime >= delayDuration) {

    lcd.clear();

    delay(100);

    lcd.print("Folding Stud");

    // After the delay duration, move the first stepper motor again

    stepper1.moveTo(STEPS_TO_MOVE_STEPPER1 + stepper1.currentPosition());

    previousMoveTime = millis();

  }


  stepper1.run();

}
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
A4988
drv1:ENABLE
drv1:MS1
drv1:MS2
drv1:MS3
drv1:RESET
drv1:SLEEP
drv1:STEP
drv1:DIR
drv1:GND.1
drv1:VDD
drv1:1B
drv1:1A
drv1:2A
drv1:2B
drv1:GND.2
drv1:VMOT
stepper1:A-
stepper1:A+
stepper1:B+
stepper1:B-
sw1:1
sw1:2
sw1:3
NOCOMNCVCCGNDINLED1PWRRelay Module
relay1:VCC
relay1:GND
relay1:IN
relay1:NC
relay1:COM
relay1:NO
A4988
drv2:ENABLE
drv2:MS1
drv2:MS2
drv2:MS3
drv2:RESET
drv2:SLEEP
drv2:STEP
drv2:DIR
drv2:GND.1
drv2:VDD
drv2:1B
drv2:1A
drv2:2A
drv2:2B
drv2:GND.2
drv2:VMOT
stepper2:A-
stepper2:A+
stepper2:B+
stepper2:B-
NOCOMNCVCCGNDINLED1PWRRelay Module
relay2:VCC
relay2:GND
relay2:IN
relay2:NC
relay2:COM
relay2:NO
pot1:GND
pot1:SIG
pot1:VCC
NOCOMNCVCCGNDINLED1PWRRelay Module
relay3:VCC
relay3:GND
relay3:IN
relay3:NC
relay3:COM
relay3:NO
NOCOMNCVCCGNDINLED1PWRRelay Module
relay4:VCC
relay4:GND
relay4:IN
relay4:NC
relay4:COM
relay4:NO
lcd1:GND
lcd1:VCC
lcd1:SDA
lcd1:SCL