#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
#include <AccelStepper.h>
// RTC
RTC_DS1307 rtc;
// LCD: I2C address 0x27, 20x4
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Stepper motors
AccelStepper stepperH(AccelStepper::DRIVER, 2, 3); // Horizontal motor (step, dir)
AccelStepper stepperV(AccelStepper::DRIVER, 5, 6); // Vertical motor (step, dir)
int lastHourDeg = -1;
int lastMinuteDeg = -1;
void setup() {
Wire.begin();
lcd.begin(20, 4);
lcd.backlight();
rtc.begin();
if (!rtc.isrunning()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Set RTC to compile time
}
stepperH.setMaxSpeed(1000);
stepperH.setAcceleration(500);
stepperV.setMaxSpeed(1000);
stepperV.setAcceleration(500);
lcd.setCursor(0, 0);
lcd.print("Solar Compass Mode");
}
void loop() {
DateTime now = rtc.now();
int hourDeg = map(now.hour(), 0, 23, 0, 360);
int minuteDeg = map(now.minute(), 0, 59, 0, 180);
// Only update motor if degree changes
if (hourDeg != lastHourDeg || minuteDeg != lastMinuteDeg) {
int stepsH = degreeToSteps(hourDeg);
int stepsV = degreeToSteps(minuteDeg);
stepperH.moveTo(stepsH);
stepperV.moveTo(stepsV);
lastHourDeg = hourDeg;
lastMinuteDeg = minuteDeg;
}
// Display time
lcd.setCursor(0, 1);
lcd.print("Time: ");
if (now.hour() < 10) lcd.print("0");
lcd.print(now.hour());
lcd.print(":");
if (now.minute() < 10) lcd.print("0");
lcd.print(now.minute());
lcd.print(":");
if (now.second() < 10) lcd.print("0");
lcd.print(now.second());
lcd.print(" ");
// Display date
lcd.setCursor(0, 2);
lcd.print("Date: ");
if (now.day() < 10) lcd.print("0");
lcd.print(now.day());
lcd.print("/");
if (now.month() < 10) lcd.print("0");
lcd.print(now.month());
lcd.print("/");
lcd.print(now.year());
// Display degrees
lcd.setCursor(0, 3);
lcd.print("H: ");
lcd.print(hourDeg);
lcd.print((char)223); // Degree symbol
lcd.print(" V: ");
lcd.print(minuteDeg);
lcd.print((char)223);
lcd.print(" ");
stepperH.run();
stepperV.run();
delay(10);
}
int degreeToSteps(int deg) {
// Example: 200 steps/rev × 16 microstepping = 3200 steps for 360 degrees
return map(deg, 0, 360, 0, 3200);
}
X - AXIS
(HORIZONTAL)
Y - AXIS
(VERTICAL)