#include <IRremote.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Motor pins
#define DIR1 2
#define STEP1 3
#define DIR2 4
#define STEP2 5
#define IR_RECEIVE_PIN 6
// Photodiodes
#define PD_TOP A0
#define PD_BOTTOM A1
#define PD_LEFT A2
#define PD_RIGHT A3
// LCD
LiquidCrystal_I2C lcd(0x27, 20, 4);
// IR
IRrecv irrecv(IR_RECEIVE_PIN);
decode_results results;
// Mode toggle
bool autoMode = false;
// Movement parameters
int steps = 200;
int tolerance = 100; // Light difference threshold
void setup() {
Serial.begin(9600);
IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);
pinMode(DIR1, OUTPUT);
pinMode(STEP1, OUTPUT);
pinMode(DIR2, OUTPUT);
pinMode(STEP2, OUTPUT);
// LCD init
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print(" Mode: MANUAL ");
lcd.setCursor(0, 1);
lcd.print("Waiting for input");
}
void loop() {
// IR remote input
if (IrReceiver.decode()) {
unsigned long key = IrReceiver.decodedIRData.command;
Serial.print("IR Code: ");
Serial.println(key, HEX);
if (key == 0x1C) { // OK button to toggle mode
autoMode = !autoMode;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(autoMode ? " Mode: AUTO " : " Mode: MANUAL ");
lcd.setCursor(0, 1);
lcd.print("Ready to track...");
}
if (!autoMode) {
switch (key) {
case 0x18: // UP
rotateMotor(DIR1, STEP1, true, "Motor 1", "Up (CW)");
break;
case 0x4A: // DOWN
rotateMotor(DIR1, STEP1, false, "Motor 1", "Down (CCW)");
break;
case 0x10: // LEFT
rotateMotor(DIR2, STEP2, true, "Motor 2", "Left (CW)");
break;
case 0x5A: // RIGHT
rotateMotor(DIR2, STEP2, false, "Motor 2", "Right (CCW)");
break;
default:
break;
}
}
IrReceiver.resume();
}
// Auto mode tracking
if (autoMode) {
int top = analogRead(PD_TOP);
int bottom = analogRead(PD_BOTTOM);
int left = analogRead(PD_LEFT);
int right = analogRead(PD_RIGHT);
// Vertical tracking (Motor 1)
if (abs(top - bottom) > tolerance) {
bool up = top > bottom;
rotateMotor(DIR1, STEP1, up, "Auto V", up ? "Up (CW)" : "Down (CCW)");
}
// Horizontal tracking (Motor 2)
if (abs(left - right) > tolerance) {
bool leftMove = left > right;
rotateMotor(DIR2, STEP2, leftMove, "Auto H", leftMove ? "Left (CW)" : "Right (CCW)");
}
}
}
void rotateMotor(int dirPin, int stepPin, bool clockwise, String motorLabel, String action) {
digitalWrite(dirPin, clockwise ? HIGH : LOW);
for (int i = 0; i < steps; i++) {
digitalWrite(stepPin, HIGH);
delayMicroseconds(800);
digitalWrite(stepPin, LOW);
delayMicroseconds(800);
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(autoMode ? "AUTO MODE" : "MANUAL MODE");
lcd.setCursor(0, 1);
lcd.print(motorLabel + ": " + action);
}
X - AXIS
(HORIZONTAL)
Y - AXIS
(VERTICAL)