//------------------------------------------------------------------------------------ // Magnetuhr Code (c) Martin Allemann 2022 // Read Real Time Clock DS3231 // After every Minute, move Stepper by 'steps' (1 Minute at work gear output) // Enable a4988 Stepper driver only if needed (avoid Stepper noise). The work gear // holds the torque // Set Clock at Startup (commented out in production code after initial clock setting) // Interupt 18/19: move clock 1m clockwise or 1m counterclockwise. Set Seccond to 0 at // 1m clockwise move //------------------------------------------------------------------------------------ // Include RTC and Serial/I2C Libraries #include #include // Stepper variables int stepCounter; // Count Steps moved int steps = 80; // number of steps to move every 1 minute int stepdelay = 1000; // delay between steps // Pins used as Interrupt pins connected to PCB-Switches const byte interruptPin18 = 18; // Step 15min const byte interruptPin19 = 19; // Step 1min int int18stat = 1; // Interrupt Pin Status (1:high, 0:low) int int19stat = 1; // Interrupt Pin Status (1:high, 0:low) bool int18on = false; // True if Interrupt was fired bool int19on = false; // True if Interrupt was fired // Real Time Clock variables byte LastMinute = 0; byte year; byte month; byte date; byte dOW; byte hour; byte minute; byte second; bool century = false; bool h12Flag; bool pmFlag; // Instantiate RTC Board DS3231 myRTC; void setup() { // Start the I2C interface Wire.begin(); // Set Clock and Start Serial Monitor. Comment out for production // SetClock(); //Serial.begin(9600); //Serial.println("Start"); // Set Stepper Output Pins pinMode(6, OUTPUT); // Enable pinMode(5, OUTPUT); // Step pinMode(4, OUTPUT); // Direction // Disable Motor at Startup digitalWrite(6, HIGH); // Disable Motor // define interrupt pins. Interrupts if button pressed // buttons between pin18/19 to GND, open if not pressed pinMode(interruptPin18, INPUT_PULLUP); pinMode(interruptPin19, INPUT_PULLUP); } void loop() { // Interrupt Handler Pin 18 and Pin 19 int18stat = digitalRead(interruptPin18); int19stat = digitalRead(interruptPin19); if (int18stat == 0) { int18on = true; int18(); } if (int19stat == 0) { int19on = true; int19(); } // Get Minute and Move Stepper every 1 Minute by 1 Minute minute = myRTC.getMinute(); if (minute != LastMinute) { Step1MinuteCW(); // Control output, comment out in production // Serial.print(myRTC.getHour(h12Flag, pmFlag), DEC); // Serial.print(" "); // Serial.print(minute); LastMinute = minute; } } void Step1MinuteCW() { // move stepper for 1 Minute clockwise digitalWrite(6, LOW); // Enable digitalWrite(4, LOW); // im Uhrzeigersinn for (stepCounter = 0; stepCounter < steps; stepCounter++) { digitalWrite(5, HIGH); delayMicroseconds(stepdelay); digitalWrite(5, LOW); delayMicroseconds(stepdelay); } digitalWrite(6, HIGH); // Disable } void Step1MinuteCCW() { // move stepper for 1 Minute counterclockwise digitalWrite(6, LOW); // Enable digitalWrite(4, HIGH); // im gegenUhrzeigersinn for (stepCounter = 0; stepCounter < steps; stepCounter++) { digitalWrite(5, HIGH); delayMicroseconds(stepdelay); digitalWrite(5, LOW); delayMicroseconds(stepdelay); } digitalWrite(6, HIGH); // Disable } void SetClock() { // Set Clock to exact time // Only once, after the time is set, the RTC keeps the time through battery power hour = 14; minute = 54; second = 0; myRTC.setClockMode(true); // set to 12h myRTC.setHour(hour); myRTC.setMinute(minute); myRTC.setSecond(second); } // Interrupt Handling to adjust Time void int18() { if (int18on) { // Let minute start at 0 Seconds myRTC.setSecond(0); Step1MinuteCW(); delay(1000); } int18on = false; } void int19() { if (int19on) { Step1MinuteCCW(); delay(1000); } int19on = false; }