#include <IRremote.h>
#include <Stepper.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);
#define PIN_RECEIVER 0 // Signal Pin of IR receiver
IRrecv receiver(PIN_RECEIVER);
const int StepsPerRevolution = 360;
Stepper myStepper1(StepsPerRevolution, 2, 3, 4, 5);
Stepper myStepper2(StepsPerRevolution, 6, 7, 8, 9);
int activeMotor = 1;
int stepCount1 = 0;
int stepCount2 = 0;
void setup() {
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Motor 1 Active");
lcd.setCursor(0, 1);
lcd.print("Steps: ");
lcd.print(activeMotor == 1 ? stepCount1 : stepCount2);
receiver.enableIRIn();
myStepper1.setSpeed(60);
myStepper2.setSpeed(60);
Serial.begin(9600);
}
void loop() {
if (receiver.decode()) {
translateIR();
receiver.resume();
}
}
void activateMotor(int motorNumber) {
activeMotor = motorNumber;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Motor ");
lcd.print(activeMotor);
lcd.print(" Active");
lcd.setCursor(0, 1);
lcd.print("Steps: ");
lcd.print(activeMotor == 1 ? stepCount1 : stepCount2);
}
void moveMotor(int steps) {
if (activeMotor == 1) {
stepCount1 = constrain(stepCount1 + steps, 0, StepsPerRevolution);
} else if (activeMotor == 2) {
stepCount2 = constrain(stepCount2 + steps, 0, StepsPerRevolution);
}
lcd.setCursor(7, 1);
lcd.print(" "); // Clear the previous steps display
lcd.setCursor(7, 1);
lcd.print(activeMotor == 1 ? stepCount1 : stepCount2);
if (activeMotor == 1) {
myStepper1.step(steps);
} else if (activeMotor == 2) {
myStepper2.step(steps);
}
}
void resetMotors() {
stepCount1 = 0;
stepCount2 = 0;
lcd.setCursor(7, 1);
lcd.print(" "); // Clear the previous steps display
lcd.setCursor(7, 1);
lcd.print(activeMotor == 1 ? stepCount1 : stepCount2);
}
void translateIR() {
switch (receiver.decodedIRData.command) {
case 162: //power
resetMotors();
break;
case 2: //plus
drawTriangle();
break;
case 224: //prev.
moveMotor(-10);
break;
case 144: //next
moveMotor(10);
break;
case 176: //key: c
drawCircle();
break;
case 48: //num 1
activateMotor(1);
break;
case 24: //num 2
activateMotor(2);
break;
}
}
void drawCircle() {
int stepsPerRevolution = StepsPerRevolution; // Adjust this value if needed
float angleRad;
float radius = 5.0; // Adjust the radius of the circle
for (int i = 0; i < 360; i++) {
angleRad = i * PI / 180.0; // Convert degrees to radians
float x = radius * cos(angleRad); // Calculate x position
float y = radius * sin(angleRad); // Calculate y position
myStepper1.step(x); // Move the first stepper to the calculated x position
myStepper2.step(y); // Move the second stepper to the calculated y position
delay(10); // Adjust the delay for the speed of the circle
}
}
void drawTriangle() {
int stepsPerSide = StepsPerRevolution / 3; // Divide a full revolution into 3 steps for a triangle
float sideLength = 15.0; // Adjust the side length of the equilateral triangle
float angleIncrement = 2 * PI / 3.0; // Angle increment for each vertex
for (int step = 0; step < stepsPerSide; step++) {
float angleRad = step * angleIncrement / stepsPerSide; // Calculate angle in radians for each step
int x = round(sideLength * cos(angleRad)); // Calculate x position
int y = round(sideLength * sin(angleRad)); // Calculate y position
x = constrain(x, -200, 200); // Limit x to prevent overshooting or exceeding motor limits
y = constrain(y, -200, 200); // Limit y to prevent overshooting or exceeding motor limits
myStepper1.step(x); // Move the first stepper to the calculated x position
myStepper2.step(y); // Move the second stepper to the calculated y position
delay(10); // Adjust the delay for the speed of the drawing
}
}