#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display(128, 32, &Wire, -1);
#define pinA 1
#define pinB 0
#define SDA_PIN 2
#define SCL_PIN 3
#define hourPin 4
#define minPin 5
#define secPin 6
#define startPin 9
#define safePin 10
#define pwmPin 11
#define dirPin 12
#define outPin2 13
#define outPin1 14
#define vinPin 26
#define numRotation 10 // 10 motor rotation
#define speed 128 // 0-255
#define dir true // direction CW
int hh = 0, mm = 0, ss = 0;
bool start = false;
unsigned long timeNow = 0;
int count = 0;
int newCount = 0;
bool flag = false;
void setup() {
Serial.begin(115200);
analogReadResolution(12);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
while (true) {}
}
display.clearDisplay();
display.display();
display.setTextSize(2);
display.setTextColor(WHITE);
pinMode(pinA, INPUT_PULLUP);
pinMode(pinB, INPUT_PULLUP);
pinMode(hourPin, INPUT_PULLUP);
pinMode(minPin, INPUT_PULLUP);
pinMode(secPin, INPUT_PULLUP);
pinMode(startPin, INPUT_PULLUP);
pinMode(safePin, INPUT_PULLUP);
pinMode(dirPin, OUTPUT);
pinMode(pwmPin, OUTPUT);
pinMode(outPin1, OUTPUT);
pinMode(outPin2, OUTPUT);
pinMode(vinPin, INPUT);
digitalWrite(outPin1, 0);
digitalWrite(outPin2, 0);
analogWrite(pwmPin, 0);
}
void loop() {
if (!digitalRead(hourPin)) {
hh++;
if (hh >= 24) hh = 0;
delay(250);
}
if (!digitalRead(minPin)) {
mm++;
if (mm >= 60) mm = 0;
delay(250);
}
if (!digitalRead(secPin)) {
ss++;
if (ss >= 60) ss = 0;
delay(250);
}
if (!digitalRead(startPin)) {
start = true;
delay(250);
}
if (millis() % 1000 == 0) {
display.clearDisplay();
display.drawRect(0, 0, 128, 32, SSD1306_WHITE);
display.setCursor(16, 8);
// Manually format and display time (HH:MM:SS)
if (hh < 10) display.print("0");
display.print(hh);
display.print(":");
if (mm < 10) display.print("0");
display.print(mm);
display.print(":");
if (ss < 10) display.print("0");
display.print(ss);
display.display();
}
// when start button is pressed
while (start) {
// outputs to a 24v out
digitalWrite(outPin1, 1);
// A pre warn countdown from 10 seconds
for (int i = 10; i >= 0; i--) {
if (!safe()) break;
display.clearDisplay();
display.setCursor(16, 8);
display.print(i);
delay(1000);
}
// turn off output 1
digitalWrite(outPin1, 0);
while (ss != 0 && mm != 0 && hh != 0) {
if (!safe()) break;
else {
// other 24v output is made high
digitalWrite(outPin2, 1);
if (!digitalRead(pinA) && !flag) {
if (count < numRotation) count++;
flag = true;
} else
flag = false;
if (millis() - timeNow >= 1000) {
timeNow = millis();
if (count < numRotation) {
// Set motor direction and speed
digitalWrite(dirPin, dir);
analogWrite(pwmPin, speed);
} else {
// turn off motor
analogWrite(pwmPin, 0);
}
// Update the countdown timer
if (ss > 0) {
ss--;
} else if (mm > 0) {
mm--;
ss = 59;
} else if (hh > 0) {
hh--;
mm = 59;
ss = 59;
}
display.clearDisplay();
display.drawRect(0, 0, 128, 32, SSD1306_WHITE);
display.setCursor(16, 8);
// display time (HH:MM:SS)
if (hh < 10) display.print("0");
display.print(hh);
display.print(":");
if (mm < 10) display.print("0");
display.print(mm);
display.print(":");
if (ss < 10) display.print("0");
display.print(ss);
display.display();
}
}
}
// after countdown finished or stopped or safety reasons
// turn off output 2
digitalWrite(outPin2, 1);
// the motor returns ccw
while (newCount < count) {
if (!digitalRead(pinA) && !flag) {
newCount++;
flag = true;
} else
flag = false;
// Set motor opposite direction and speed
digitalWrite(dirPin, !dir);
analogWrite(pwmPin, speed);
}
// turn off motor
analogWrite(pwmPin, 0);
}
}
bool safe() {
if (digitalRead(safePin) || !digitalRead(startPin) || !digitalRead(vinPin)) {
start = false;
return false;
} else
return true;
}