#include <Wire.h>
#include <RTClib.h>
// --- TEST SETTINGS ---
#define TEST_MODE false // Set to false to use actual RTC time
float simSpeed = 30.0; // 1.0 = real time. 60.0 = 1 minute passes every second.
int fakeHour = 23; // Starting test hour
int fakeMinute = 59; // Starting test minute
float fakeSecond = 0; // Internal counter for simulation
// --- PINS ---
#define DIR_PIN 15
#define M_STEP_PIN 2
#define MM_STEP_PIN 0
#define H_STEP_PIN 4
#define HH_STEP_PIN 16
const int Button_pin = 14;
const int STEPS_PER_UNIT = 20;
int ResetButton = 33;
int Reset_Button_value;
int power_fail_pin = 14;
//THIS VALUES MUST BE TESTED!!
int b1value = 100;
int b2value = 200;
int b3value = 300;
int b4value = 400;
// State Tracking
int Saved_M = 0, Saved_MM = 0, Saved_H = 0, Saved_HH = 0;
unsigned long lastUpdateMicros = 0;
RTC_DS1307 rtc;
void stepMotor(int pin, int steps) {
for (int i = 0; i < steps; i++) {
digitalWrite(pin, HIGH);
delayMicroseconds(500);
digitalWrite(pin, LOW);
delayMicroseconds(500);
}
}
void setup() {
Serial.begin(115200);
int outputPins[] = {M_STEP_PIN, MM_STEP_PIN, H_STEP_PIN, HH_STEP_PIN, DIR_PIN};
for(int pin : outputPins) pinMode(pin, OUTPUT);
pinMode(Button_pin, INPUT);
pinMode(power_fail_pin, INPUT);
digitalWrite(DIR_PIN, HIGH);
Wire.begin();
if (!rtc.begin()) Serial.println("RTC not found");
lastUpdateMicros = micros();
}
void loop() {
int currH, currM;
Reset_Button_value = analogRead(33);
if (Reset_Button_value > b1value - 20 && Reset_Button_value < b1value +20){
stepMotor(HH_STEP_PIN, 20);
delay(1000);
}
if (Reset_Button_value > b2value - 20 && Reset_Button_value < b2value +20){
stepMotor(H_STEP_PIN, 20);
delay(1000);
}
if (Reset_Button_value > b3value - 20 && Reset_Button_value < b3value +20){
stepMotor(MM_STEP_PIN, 20);
delay(1000);
}
if (Reset_Button_value > b4value - 20 && Reset_Button_value < b4value +20){
stepMotor(M_STEP_PIN, 20);
delay(1000);
}
if (TEST_MODE) {
// --- VIRTUAL CLOCK LOGIC ---
unsigned long delta = micros() - lastUpdateMicros;
lastUpdateMicros = micros();
// Increment seconds based on simSpeed
fakeSecond += (delta / 1000000.0) * simSpeed;
if (fakeSecond >= 60.0) {
fakeSecond = 0;
fakeMinute++;
}
if (fakeMinute >= 60) {
fakeMinute = 0;
fakeHour++;
}
if (fakeHour >= 24) {
fakeHour = 0;
}
currH = fakeHour;
currM = fakeMinute;
} else {
DateTime now = rtc.now();
currH = now.hour();
currM = now.minute();
}
// Calculate Digits
int d_M = currM % 10;
int d_MM = currM / 10;
int d_H = currH % 10;
int d_HH = currH / 10;
// --- STEPPER EXECUTION ---
// Minutes Units
if (Saved_M != d_M) {
stepMotor(M_STEP_PIN, STEPS_PER_UNIT);
Saved_M = (Saved_M + 1) % 10;
}
// Minutes Tens
if (Saved_MM != d_MM) {
int steps = (Saved_MM == 5) ? (STEPS_PER_UNIT * 5) : STEPS_PER_UNIT;
stepMotor(MM_STEP_PIN, steps);
Saved_MM = (Saved_MM + 1) % 6;
}
// Hours Units (tracks 0-23)
if (Saved_H != currH) {
int steps = (Saved_H == 23) ? (STEPS_PER_UNIT * 7) : STEPS_PER_UNIT;
stepMotor(H_STEP_PIN, steps);
Saved_H = (Saved_H + 1) % 24;
}
// Hours Tens
if (Saved_HH != d_HH) {
int steps = (Saved_HH == 2) ? (STEPS_PER_UNIT * 8) : STEPS_PER_UNIT;
stepMotor(HH_STEP_PIN, steps);
Saved_HH = (Saved_HH + 1) % 3;
}
Serial.println(Reset_Button_value);
/*
// High-Speed Debugging Output
static unsigned long lastLog = 0;
if (millis() - lastLog > 500) {
Serial.printf("[%s] Time: %02d:%02d:%02.0f | Motors: %d%d:%d%d\n",
TEST_MODE ? "SIM" : "RTC", currH, currM, fakeSecond,
Saved_HH, Saved_H % 10, Saved_MM, Saved_M);
lastLog = millis();
}
*/
}1
4
0
5
2
3
6
7
8
9
1
4
0
5
2
3
6
7
8
9
1
4
0
5
2
3
6
7
8
9
1
4
0
5
2
3
6
7
8
9
WOKWI CANT SIMULATE THIS PART
YOU'LL NEED TO TEST VALUES IN REAL LIFE