#include <TimerOne.h>
#include <Stepper.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "RTClib.h"
// LED's
#define LED_1 3
#define LED_2 5
#define LED_3 6
#define LED_4 9
// LED_1
// LED_4 LED_2
// LED_3
int led_timer_inteval = 1000;
int quadrant_interval = 1000000;
int led_max_value = 255;
enum led_quadrant {first, second, third, fourth};
led_quadrant current_quadrant = led_quadrant::first;
bool entry = true;
unsigned long delta_time;
// Stepper-Motor
#define Stepper_A_minus 8
#define Stepper_A_plus 7
#define Stepper_B_plus 4
#define Stepper_B_minus 2
const int stepsPerRevolution = 16;
Stepper hour_hand(stepsPerRevolution,Stepper_B_minus,Stepper_B_plus,Stepper_A_plus,Stepper_A_minus);
bool turn_hour_hand = false;
int hour = 0;
int max_hour = 12;
int correction_steps = 8;
// I2C Display
#define I2C_ADDR 0x27
#define LCD_COLUMNS 16
#define LCD_LINES 2
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
// RTC - Module
RTC_DS1307 rtc;
// general
enum general_state {show_time, set_clock, set_alarm_clock};
general_state current_input_state = general_state::set_clock;
void Timer_led_ISR()
{
// Timer loops every second
set_time_minutes();
show_time_display();
}
void turn_hour_hand_func(){
hour_hand.step(stepsPerRevolution);
hour++;
if(hour == max_hour){
hour = 0;
hour_hand.step(correction_steps);
}
}
void show_time_display(){
DateTime now = rtc.now();
char buffer[20];
snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
lcd.setCursor(0, 0);
lcd.print("Aktuelle Zeit:");
lcd.setCursor(0, 1);
lcd.print(buffer);
}
void setup() {
lcd.init();
lcd.backlight();
pinMode(LED_1, OUTPUT);
pinMode(LED_2, OUTPUT);
pinMode(LED_3, OUTPUT);
pinMode(LED_4, OUTPUT);
hour_hand.setSpeed(40);
if (!rtc.begin()) {
Serial.println("RTC nicht gefunden!");
while (1);
}
if (!rtc.isrunning()) {
Serial.println("RTC wird gestartet.");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
//Timer with 100ms
Timer1.initialize(led_timer_inteval);
Timer1.attachInterrupt(Timer_led_ISR);
}
void loop() {
if(turn_hour_hand){
turn_hour_hand = !turn_hour_hand;
turn_hour_hand_func();
}
// ## Too much traffic, wenn man es bei jedem loop macht
show_time_display();
}
void check_input(){
enum general_state {show_time, set_clock, set_alarm_clock};
switch (current_input_state){
case show_time:
}
}
void set_time_minutes(){
unsigned long current_time = millis();
switch (current_quadrant){
case first:
if(entry){
entry =false;
digitalWrite(LED_1, HIGH);
delta_time = current_time;
break;
}
if (current_time - delta_time < quadrant_interval ){
int dim = (current_time - delta_time) * led_max_value / quadrant_interval;
analogWrite(LED_1, led_max_value-dim);
analogWrite(LED_2, dim);
break;
}
if(!entry && (current_time - delta_time >= quadrant_interval))
{
current_quadrant = led_quadrant::second;
entry = true;
digitalWrite(LED_1, LOW);
digitalWrite(LED_2, LOW);
break;
}
case second:
if(entry){
entry =false;
digitalWrite(LED_2, HIGH);
delta_time = current_time;
break;
}
if (current_time - delta_time < quadrant_interval ){
int dim = (current_time - delta_time) * led_max_value / quadrant_interval;
analogWrite(LED_2, led_max_value-dim);
analogWrite(LED_3, dim);
break;
}
if(!entry && (current_time - delta_time >= quadrant_interval))
{
current_quadrant = led_quadrant::third;
entry = true;
digitalWrite(LED_2, LOW);
digitalWrite(LED_3, LOW);
break;
}
case third:
if(entry){
entry =false;
digitalWrite(LED_3, HIGH);
delta_time = current_time;
break;
}
if (current_time - delta_time < quadrant_interval ){
int dim = (current_time - delta_time) * led_max_value / quadrant_interval;
analogWrite(LED_3, led_max_value-dim);
analogWrite(LED_4, dim);
break;
}
if(!entry && (current_time - delta_time >= quadrant_interval))
{
current_quadrant = led_quadrant::fourth;
entry = true;
digitalWrite(LED_3, LOW);
digitalWrite(LED_4, LOW);
break;
}
case fourth:
if(entry){
entry =false;
digitalWrite(LED_4, HIGH);
delta_time = current_time;
break;
}
if (current_time - delta_time < quadrant_interval ){
int dim = (current_time - delta_time) * led_max_value / quadrant_interval;
analogWrite(LED_4, led_max_value-dim);
analogWrite(LED_1, dim);
break;
}
if(!entry && (current_time - delta_time >= quadrant_interval))
{
current_quadrant = led_quadrant::first;
entry = true;
digitalWrite(LED_4, LOW);
digitalWrite(LED_1, LOW);
turn_hour_hand = true;
break;
}
}
}