What if we can see three hours at once, what if we perceive the day as a repetition of the quarter form instead of a circular form with two 12-hour or 24-hour pieces? At the end of the three-hour journey, the hour hand goes back to the beginning point of the journey and drags the quarter window down or up to repeat the three-hour journey. This timepiece doesn't have a minute hand, still, we can assume where we are at in a day. This piece rejects being a precise clock and shows our being in repetition. Fragments and Repetitions.


Three hours, a unit of time to focus on something.
If the time exists every three hours, to express it in a minimal way, I wanted to disappear the rest of the part except for the quarter area, but still how to solve the visible area of the motor.
Quater, a fragment of time. After a three-hour journey, to start a new three-hour journey, the hour hand returns to the starting point, then drags and rotates the window down.
code
/*
VID28-05 Motor Control
Controls two stepper motors at once, used to test a VID28-05
concentric shaft motor
Created 24 May 2018
modified 20 Jan 2020
by Tom Igoe
*/
#include <Stepper.h>
#include <RTCZero.h>
//const int stepsPerRevolution = 720; // VID28-05 is 720 steps per revolution
const int stepsPerCircle = 720;
const int stepsPerHalfCircle = 360;
// initialize the stepper library.
// Any 8 pins will do. These numbers were used for the MKR Zero form factor:
Stepper hourMotor(stepsPerCircle, 7, 8, 9, 10);
Stepper windowMotor(stepsPerCircle, 2, 3, 4, 5);
int hourSteps = 0;
int windowSteps = 0;
// motors will move in opposite directions:
int hourDir = 1;
int windowDir = -1;
RTCZero rtc;
void setup() {
// initialize the serial port:
Serial.begin(9600);
rtc.begin();
// Check if the RTC has lost power and if so, set the time
if (!rtc.isConfigured()) {
rtc.setTime(12, 0, 0); // Set the time to 12:00:00
}
rtc.setTime(2,59,45);
}
void loop() {
int currentWindow = rtc.getHours() % 12;
int currentHour = rtc.getHours() % 12;
int actualHour = currentHour;
int currentMinute = rtc.getMinutes();
int currentSecond = rtc.getSeconds();
// ** Desired Hour position
// 0:00:00 < 0:00:03 :9
// 0:00:03 < 3:00:00 :current Hour
// 3:00:00 < 3:00:03 :0
// 3:00:03 < 6:00:00 :current Hour
// 6:00:00 < 6:00:03 :3
// 6:00:03 < 9:00:00 :current Hour
// 9:00:00 < 9:00:03 :6
// 9:00:03 < 12:00:00 :current Hour
if ((currentHour == 0) && (currentMinute == 0) && (currentSecond < 3)) {
currentHour = 9;
// } else if (currentHour < 3) {
// // currentHour = currentHour;
} else if ((currentHour == 3) && (currentMinute == 0) && (currentSecond < 3)) {
currentHour = 0;
} else if ((currentHour == 6) && (currentMinute == 0) && (currentSecond < 3)) {
currentHour = 3;
} else if ((currentHour == 9) && (currentMinute == 0) && (currentSecond < 3)) {
currentHour = 6;
}
// ** Desired Window position
// 0:00:00 < 3:00:00 :0
// 3:00:00 < 6:00:00 :3
// 6:00:00 < 9:00:00 :6
// 9:00:03 < 12:00:00 :9
if (((currentHour >= 0) && (currentMinute >= 0) && (currentSecond >= 0)) && ((currentHour < 3) && (currentMinute <= 59) && (currentSecond <= 59))) {
currentWindow = 0;
// } else if (currentHour < 3) {
// // currentHour = currentHour;
} else if (((currentHour >= 3) && (currentMinute >= 0) && (currentSecond >= 0)) && ((currentHour < 6) && (currentMinute <= 59) && (currentSecond <= 59))) {
currentWindow = 3;
} else if (((currentHour >= 6) && (currentMinute >= 0) && (currentSecond >= 0)) && ((currentHour < 9) && (currentMinute <= 59) && (currentSecond <= 59))) {
currentWindow = 6;
} else if (((currentHour >= 9) && (currentMinute >= 0) && (currentSecond >= 0)) && ((currentHour < 12) && (currentMinute <= 59) && (currentSecond <= 59))) {
currentWindow = 9;
}
// Calculate the desired position for the minute motor based on the current minute
int desiredHourPosition = (currentHour+ currentMinute/60.0) * (stepsPerCircle / 12);
//int desiredMinutePosition = (currentMinute+ currentSecond/60.0) * (stepsPerMinute / 60);
int desiredWindowPosition = (currentWindow) * (stepsPerCircle/ 12);
if ((desiredWindowPosition==0)&&((windowSteps-desiredWindowPosition)>stepsPerHalfCircle)) {
desiredWindowPosition=stepsPerCircle;
}
if ((desiredHourPosition==0)&&((hourSteps-desiredHourPosition)>stepsPerHalfCircle)) {
desiredHourPosition=stepsPerCircle;
}
// Move the window motor to the desired position
while ((windowSteps != desiredWindowPosition) || (hourSteps != desiredHourPosition)) {
if (windowSteps != desiredWindowPosition) {
if (windowSteps < desiredWindowPosition) {
windowMotor.step(windowDir);
windowSteps++;
} else {
windowMotor.step(-windowDir);
windowSteps--;
}
}
if (hourSteps != desiredHourPosition) {
if (hourSteps < desiredHourPosition) {
hourMotor.step(hourDir);
hourSteps++;
} else {
hourMotor.step(-hourDir);
hourSteps--;
}
}
delayMicroseconds(5000); // Adjust for your desired speed
}
if (windowSteps>=stepsPerCircle) {
windowSteps-=stepsPerCircle;
}
if (hourSteps>=stepsPerCircle) {
hourSteps-=stepsPerCircle;
}
// [[for a test]] // Move the minute motor
// for (int i=0; i<stepsPerMinute; i++){
// //hypothesis - 720 steps per revolution
// // hourMotor.step(1);
// //minuteMotor.step(1);
// minuteMotor.step(minuteDir);
// delayMicroseconds(5000); //this value determines the speed - higher means more time between steps and therefore slower
// }
// Print the current minute and the minute motor's position to the serial monitor
char bufferOut[128];
sprintf(bufferOut,"Time: %d:%d Steps: %d Window: %d Steps: %d", currentHour,currentMinute,hourSteps,currentWindow,windowSteps);
/*
Serial.print("Current Hour: ");
Serial.println(currentHour);
Serial.print("Current Minute: ");
Serial.println(currentMinute);
Serial.print("Hour Motor Position: ");
Serial.println(hourSteps);
Serial.print("Minute Motor Position: ");
Serial.println(windowSteps);*/
Serial.println(bufferOut);
delay(1000);
}
