#include <AccelStepper.h>
//#include <RTClib.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DS3231.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
AccelStepper stepper2(1, 11, 12); //min (Typeof driver: with 2 pins, STEP, DIR) 1/8 passo MS1 on - MS2 on - MS3 -off
AccelStepper stepper1(1, 9, 10); //ore
long posizioneore, posizionemin;
long second, secondsToday, secondsTodayA, secondsTodayB;
int presecond;
long int initial_homingore=-1;
long int initial_homingmin=-1;
int buttonPressCount = 0; // Conteggio dei press del pulsante
bool varser=false;
bool century = false;
bool h12;
bool PM;
bool homing=false;
byte year, month, day, DoW, hour, minute, seconds;
byte Year, Month, Data, DOW, Hour ,Minute, Second ;
byte Imposta=0; //Variabile ausiliaria per impostare data e ora manuale
byte Comando = 0; //variabile gestione pulsanti menu
char Messaggio [20] = "";
//RTC_DS3231 rtc;
DS3231 Clock;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
Serial.begin(9600);
Wire.begin();
lcd.init();
lcd.backlight();
pinMode(5, INPUT_PULLUP); //int ore
pinMode(3, INPUT_PULLUP); //int min
pinMode(4, INPUT_PULLUP); //aux min
pinMode(8, INPUT_PULLUP); //ROSSO
pinMode(7, INPUT_PULLUP); //VERDE
pinMode(6, INPUT_PULLUP); //FN4
pinMode(16, INPUT_PULLUP); //FN3
pinMode(15, INPUT_PULLUP); //FN2
pinMode(14, INPUT_PULLUP); //FN1
pinMode(13, INPUT_PULLUP); //RANDOM
Serial.write("O");
homemin();
homeore(); //homing
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////7///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////7///////////////////////////////////////////////////////////////////////////
void loop() {
cout:
ReadDS3231();
ORALEGALE();
if ((digitalRead(14) == LOW)) {Comando =1; lcd.backlight(); }// pulsante fn1+fn2
if (Comando == 1) {
if (digitalRead(14) == LOW) {SetOra (0); goto cout;}// pulsante FN1
if (digitalRead(15) == LOW) {SetOra (1); goto cout;}// pulsante FN2
if (digitalRead(16) == LOW) {SetOra (2); goto cout;}// pulsante FN3
if (digitalRead(6) == LOW) {SetOra (3); goto cout;}// pulsante FN4
if (digitalRead(7) == LOW) {SetOra (4); goto cout;}// pulsante verde
if (digitalRead(8) == LOW) {SetOra (5); goto cout;}// pulsante rosso
goto cout;
}
//------------------------------------
if ((digitalRead(15) == LOW)||(digitalRead(16) == LOW)||(digitalRead(6) == LOW)||(digitalRead(7) == LOW)||(digitalRead(8) == LOW) ) {
lcd.init();
lcd.backlight();
fxprint( " Che c'è? "," ...pigi i bottoni "," a caso???? ", " ");
sprintf(Messaggio, "%02d/%02d/%d-%01d- %02d:%02d:%02d", day, month, year, DoW, hour, minute, second);
lcd.setCursor(0, 0);
lcd.print(Messaggio);
delay(1500);
fxprint( " se vuoi regolare "," ora e data devi ", " pigiare il ", " pulsante 1 ");
delay(1500);
fxprint( " ciao "," testina!! ", " ", " ");
goto cout;
}
//----------------------------------------------random
if (digitalRead(13) == HIGH) {
Serial.write("N");
CICLORANDOM();
} //homing
//----------------------------------------------dopo random homing
if (varser==true) {varser=false;
fxprint( " "," ", " ", " ");
homemin();
homeore();
}
//----------------------------------------------qui ciclo regolare
stepper1.run();
stepper2.run();
//----------------------------------------------una volta al minuto
if (second==0){lcd.noBacklight();}
//------------------------------------------- //se orario prossimo al finecorsa li inibisce
if (secondsTodayA>20700 || secondsTodayA<22500){ //ore 6 o 18 +- 15 minuti
homing=true; goto usci;
}
else {homing=false;}
if (secondsTodayB>28620 || secondsTodayB<180){ //ore 0 o 8 o 16 +- 3 minuti
homing=true;
}
else {homing=false;}
usci:
//------------------------------------------- //passaggio dal finecorsa
if (digitalRead(3) == LOW && digitalRead(4) == LOW) {
if (homing == false) { //passa da finecorsa min fuori orario: homemin
homemin();
}}
if (digitalRead(5) == LOW) {
if (homing == false) { //passa da finecorsa ore fuori orario: home ore
homeore();
}}
//una volta al secondo-------------------------------------------------------
if (second !=presecond) {
presecond=second;
secondsToday = (hour * long(3600)+ minute * long(60) + second);
secondsTodayA = secondsToday % 43200; //ora
secondsTodayB = secondsToday % 28800; //min
//-------------------qui si azzerano i conteggi degli stepper sennò tornerebbero indietro
switch (secondsToday) {
case 28800://alle 8
stepper2.setCurrentPosition(0);
break;
case 57600://alle 16
stepper2.setCurrentPosition(0);
break;
case 0://alle 0
stepper2.setCurrentPosition(0);
stepper1.setCurrentPosition(0);
break;
case 43200://alle 12
stepper1.setCurrentPosition(0);
break;
}
//-------------------------------------------qui si rallenta accelerazione per avanzamento ordinario
if (abs((stepper2.currentPosition() - ((secondsTodayB/3)*8)))<100){stepper2.setAcceleration(100); }
else {stepper2.setAcceleration(500); }
if (abs((stepper1.currentPosition() - ((secondsTodayA/27)*8)))<100){stepper1.setAcceleration(100); }
else {stepper1.setAcceleration(500); }
stepper1.runToNewPosition((secondsTodayA/27)*8);
stepper2.runToNewPosition((secondsTodayB/3)*8);
sprintf(Messaggio, "%02d/%02d/%d-%01d- %02d:%02d:%02d", day, month, year, DoW, hour, minute, second);
lcd.setCursor(0, 0);
lcd.print(Messaggio);
fxprint( "","Sec_gg: "+ String(secondsToday),"Step_ore: "+String(int(secondsTodayA/27)*8),"Step_min: "+ String(long(secondsTodayB/3)*8));
//-----------------------------------------GESTIONE SUONI
if (hour<22 && hour>8){ //solo di giorno
if (day==24 && month==12 && minute ==0 && second ==0){Serial.write("k"); goto cout;} //ogni ora del comp
if (day==25 && month==12 && minute ==0 && second ==0){Serial.write("j"); goto cout;} //ogni ora di nat
if (day==31 && month==12 && minute ==0 && second ==0){Serial.write("w"); goto cout;} //ogni ora di ultimo
if (hour==12 && minute ==0 && second ==0){Serial.write("x"); goto cout;} //ogni mezzogiorno
if (minute ==0 && second ==0){Serial.write("y"); goto cout;} //ogni ora
}
//-----------------------------------------GESTIONE LUCI
if (digitalRead(3) == LOW && digitalRead(4) == LOW) {Serial.write("Q"); goto cout;} //MINUTI ALLINEATO
if (digitalRead(5) == LOW) {Serial.write("R"); goto cout;} //ORE ALLINEATO
if (day==24 && month==12){ Serial.write("A");} //comp
else if (day==25 && month==12){ Serial.write("C"); goto cout;} //nat
else if (day==31 && month==12){ Serial.write("D"); goto cout;} //ultimo
else if (DoW==1){ Serial.write("E"); goto cout;} //DOM
else if (DoW==2){ Serial.write("F"); goto cout;} //LUN
else if (DoW==3){ Serial.write("G"); goto cout;} //MAR
else if (DoW==4){ Serial.write("H"); goto cout;} //MER
else if (DoW==5){ Serial.write("I"); goto cout;} //GIO
else if (DoW==6){ Serial.write("L"); goto cout;} //VEN
else if (DoW==7){ Serial.write("M"); goto cout;} //SAB
}
}
///////////////////////////////////////////////7///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////7///////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////
void homemin() {
ReadDS3231();
fxprint( "Homing..............","Woodstock cerca poso", " ", " ");
initial_homingmin = -1;
stepper2.setMaxSpeed(-4000);
stepper2.setAcceleration(2000);
stepper2.setCurrentPosition(0);
stepper2.setSpeed(-4000);
homing=true;
while (!(digitalRead(3) == LOW && digitalRead(4) == LOW)) { // cerca home min
stepper2.moveTo(initial_homingmin);
stepper2.runSpeed();
initial_homingmin++;
}
posizionemin = stepper2.currentPosition();
while (stepper2.speed() != 0) { //rallenta min
stepper2.runToNewPosition(posizionemin);
}
stepper2.setCurrentPosition(0);
Serial.write("Q");
//stepper2.setMaxSpeed(5000);
//stepper2.setAcceleration(2000);
homing=false;
fxprint( "SOSTANZA "," SOSTANZA "," SOSTANZA ", " SOSTANZA");
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
void homeore() {
ReadDS3231();
stepper1.setMaxSpeed(4000); // Set maximum speed value for the stepper
stepper1.setAcceleration(4000); // Set acceleration value for the stepper
stepper1.setCurrentPosition(0); // Set the current position to 0 steps
stepper1.setSpeed(4000);
initial_homingore = -1;
homing=true;
while (!digitalRead(5) == LOW) { // cerca home ore
stepper1.moveTo(initial_homingore);
stepper1.runSpeed();
initial_homingore ++;
}
posizioneore = stepper1.currentPosition()+ 6400; //correzione da 6400 teorico
while (stepper1.speed() != 0) { //rallenta ore
stepper1.runToNewPosition (posizioneore);
}
stepper1.setCurrentPosition(0);
Serial.write("R");
//stepper1.setMaxSpeed(40000); // Set maximum speed value for the stepper
//stepper1.setAcceleration(16000); // Set acceleration value for the stepper
fxprint( " "," FESTINA LENTE ", " ", " ");
homing=false;
}
///////////////////////////////////////////////7///////////////////////////////////////////////////////////////////////////
void ORALEGALE(){
//ANALIZZA ORA LEGALE/SOLARE -------
/*
L'Ultima domenica di Marzo le lancette passano dalle 02:00 alle 03:00 (Ora Legale)
L'ultima domenica di Ottobre le lancette passano dalle 03:00 alle 02:00 (Ora Solare)
*/
if (month==3){
if (DoW==1 && (day+7)>31){ //E' l'ultima domenica di Marzo
if (hour==2) {
Clock.setHour(3); //Si passa all'ora legale 02:00 -> 03:00
}
}
} //FINE ORA LEGALE
if (month==10){
if (DoW==1 && (day+7)>31){ //E' l'ultima domenica di Ottobre
if (hour==3) {
Clock.setHour(2); //Si passa all'ora solare 03:00 -> 02:00
}
}
} //FINE ORA SOLARE
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void ReadDS3231() //Funzione di aggiornamento clock
{
second=Clock.getSecond();
minute=Clock.getMinute();
hour=Clock.getHour(h12, PM);
day=Clock.getDate();
month=Clock.getMonth(century);
year=Clock.getYear();
DoW=Clock.getDoW();
//intemp=Clock.getTemperature();
return;
} //FINE ReadDS3231() --------------------
///////////////////////////////////////////////////////////////////////////////////////////////////////
void SetOra(int num){ // imposta ora da tastiera
switch (Imposta) {
case 0:
void ReadDS3231();
Year = year ;
Month =month;
Data = day;
DOW = DoW;
Hour = hour;
Minute = minute;
Second = second;
fxprint( "DATA e ORA attuale: "," ", "Verde: Modifica ", "Rosso: Annulla ");
sprintf(Messaggio, "%02d/%02d/%d - %02d:%02d:%02d", day, month, year, hour, minute, second);
lcd.setCursor(0, 1); //seconda riga
lcd.print(Messaggio);
break;
case 1:
fxprint( "ANNO:? (00-99) ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(Year));
break;
case 2:
fxprint( "MESE:? (1-12) ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(Month));
break;
case 3:
fxprint( "GIORNO:? (1-31) ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(Data));
break;
case 4:
fxprint( "GIORNO: 1=DOM 7=SAB ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(DOW));
break;
case 5:
fxprint( "ORA:? (0-23) ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(Hour));
break;
case 6:
fxprint( "MINUTI:? (0-59) ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(Minute));
break;
case 7:
fxprint( "SECONDI:? (0-59) ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(Second));
break;
}
if (num == 0) {// FN1
}
if (num == 1) {// FN2
if (Imposta>1){
Imposta = Imposta - 1;
SetOra(10);}
}
if (num == 2) {// FN3
switch (Imposta) {
case 1:
if (Year ==0){Year = 99;}
else {Year = Year-1;}
fxprint( "ANNO:? (00-99) ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(Year));
break;
case 2:
if (Month ==1){Month = 12;}
else {Month = Month-1;}
fxprint( "MESE:? (1-12) ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(Month));
break;
case 3:
if (Data ==1){Data = 31;}
else {Data = Data-1;}
fxprint( "GIORNO:? (1-31) ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(Data));
break;
case 4:
if (DOW ==1){DOW = 7;}
else {DOW = DOW-1;}
fxprint( "GIORNO: 1=DOM 7=SAB ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(DOW));
break;
case 5:
if (Hour ==0){Hour = 23;}
else {Hour = Hour-1;}
fxprint( "ORA:? (0-23) ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(Hour));
break;
case 6:
if (Minute ==0){Minute = 59;}
else {Minute = Minute-1;}
fxprint( "MINUTI:? (0-59) ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(Minute));
break;
case 7:
if (Second ==0){Second = 59;}
else {Second = Second-1;}
fxprint( "SECONDI:? (0-59) ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(Second));
break;}
}
if (num == 3) {// FN4
switch (Imposta) {
case 1:
if (Year ==99){Year = 0;}
else {Year = Year+1;}
fxprint( "ANNO:? (0-99) ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(Year));
break;
case 2:
if (Month ==12){Month = 1;}
else {Month = Month+1;}
fxprint( "MESE:? (1-12) ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(Month));
break;
case 3:
if (Data ==31){Data = 1;}
else {Data = Data+1;}
fxprint( "GIORNO:? (1-31) ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(Data));
break;
case 4:
if (DOW ==7){DOW = 1;}
else {DOW = DOW+1;}
fxprint( "GIORNO: 1=DOM 7=SAB ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(DOW));
break;
case 5:
if (Hour ==23){Hour = 0;}
else {Hour = Hour+1;}
fxprint( "ORA:? (0-23) ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(Hour));
break;
case 6:
if (Minute ==59){Minute = 0;}
else {Minute = Minute+1;}
fxprint( "MINUTI:? (0-59) ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(Minute));
break;
case 7:
if (Second ==59){Second = 0;}
else {Second = Second+1;}
fxprint( "SECONDI:? (0-59) ","FN3:(-) FN4:(+) ", "Verde:Ok FN2:Indiet.", String(Second));
break;
}
}
if (num == 4) {// verde
switch (Imposta) {
case 0:
Imposta = 1;
SetOra(10);
break;
case 1:
Imposta = 2;
SetOra(10);
break;
case 2:
Imposta = 3;
SetOra(10);
break;
case 3:
Imposta = 4;
SetOra(10);
break;
case 4:
Imposta = 5;
SetOra(10);
break;
case 5:
Imposta = 6;
SetOra(10);
break;
case 6:
Imposta = 7;
SetOra(10);
break;
case 7:
Clock.setSecond(Second);//Set the second
Clock.setMinute(Minute);//Set the minute
Clock.setHour(Hour); //Set the hour
Clock.setDoW (DOW); //Set the day of the week
Clock.setDate(Data); //Set the date of the month
Clock.setMonth(Month); //Set the month of the year
Clock.setYear(Year);
fxprint( "DATA e ORA impostata"," ", " ", " ");
ReadDS3231();
delay (800);
Imposta = 0;
Comando = 0;
homemin();
homeore();
lcd.noBacklight();
break;
}
}
if (num == 5) {// rosso
fxprint( "Nessuna modifica... "," ", " ", " ");
delay(800);
Imposta = 0;
Comando = 0;
lcd.noBacklight();
}
}
//OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
void fxprint(String smessage1, String smessage2, String smessage3, String smessage4)
{
if (smessage1 != ""){
lcd.setCursor(0, 0); //prima riga
lcd.print(" ");
lcd.setCursor(0, 0); //prima riga
lcd.print(smessage1);}
if (smessage2 != ""){
lcd.setCursor(0, 1); //seconda riga
lcd.print(" ");
lcd.setCursor(0, 1); //seconda riga
lcd.print(smessage2);}
if (smessage3 != ""){
lcd.setCursor(0, 2); //terza riga
lcd.print(" ");
lcd.setCursor(0, 2); //terza riga
lcd.print(smessage3);}
if (smessage4 != ""){
lcd.setCursor(0, 3); //quarta riga
lcd.print(" ");
lcd.setCursor(0, 3); //quarta riga
lcd.print(smessage4);}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
void CICLORANDOM() {
varser=true;
homing=true;
stepper1.setMaxSpeed(10000); // Set maximum speed value for the stepper
stepper2.setMaxSpeed(10000);
stepper2.setSpeed(10000);
stepper2.setSpeed(10000);
stepper1.setCurrentPosition(0);
stepper2.setCurrentPosition(0);
while(digitalRead(13) == HIGH){ //giri casuali
if (stepper1.distanceToGo() == 0) {
stepper1.moveTo(rand() % 15000);
stepper1.setAcceleration((rand() % 2000 + 1000));
}
if (stepper2.distanceToGo() == 0){
stepper2.moveTo(rand() % 25000);
stepper2.setAcceleration((rand() % 1000 + 1000));
}
stepper1.run();
stepper2.run();
}
while (stepper1.speed() != 0 || stepper2.speed() != 0) {//rallentamento fino a zero
if (stepper1.speed() != 0) {stepper1.run(); }
else {stepper1.stop();}
if (stepper2.speed() != 0) {stepper2.run(); }
else {stepper2.stop();}
}
homing=false;
}