// Avvolgitrice bobine Marco
// Versione 0_2 del 26-03-2023
// Aggiunti movimenti motore in manuale
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
LiquidCrystal_I2C lcd(0x27,16,2);
// Valori per le velocità motori in manuale////////////
// variando questi valori si variano le velocità
const int V_MAN_A = 300; //Aumentando il valore diminuisce la velocità
const int V_MAN_M = 300;
/////////////////////////////////////////////////////
//Costante per la funzione antirimbalzo--------------
const int debounceDelay = 30;
//Testi per lcd
const String T_0 = " ";
const String T_1 = " Ciao";
const String T_2 = "Seleziona modo";
const String T_3 = "-Manuale";
const String T_4 = "2-3=Ma / 3-4=Av";
const String T_5 = "-Auto.";
const String T_6 = "2 = Marcia";
const String T_7 = "-Settaggio";
const String T_8 = "2=Menu / 3=+ 4=-";
const String T_9 = "Spire Tot.";
const String T_10 = "Spire Par.";
const String T_11 = "Dia. Filo";
const String T_12 = "Dia. Filo =";
const String T_13 = " ";
const String T_14 = "/";
const String T_15 = "Salva (Puls. 3)";
const String T_16 = "Fatto ";
const String T_17 = "Spi.P.Avv.=";
const String T_18 = "Fine";
// Assegnazione pin ai pulsanti
const int PUL_1 = 2;
const int PUL_2 = 3;
const int PUL_3 = 4;
const int PUL_4 = 5;
const int PUL_5 = 6; //piedino per la direzione di avvolgimento
// ------------------------------Costanti per indirizzi memoria
const int I_1 = 0; //Spire Totali
const int I_2 = 10; //SpireParziali
const int I_3 = 20; //diametroFilo
const int I_4 = 30; //Spire totali avvolte
const int I_5 = 40; //Spire parziali avvolte
//Costanti per movimento motori
const int DIR_MOT_A = 7;
const int STE_MOT_A = 8;
const int ENA_A = 9;
const int DIR_MOT_M = 10;
const int STE_MOT_M = 11;
const int ENA_M = 12;
// ------------------------------Semafori per non ripetere il loop-----------------
byte sem_0 = 0;
int sem_2 = 0;
int sem_3=0;
// Variabili globali
int stato = 0; // Controlla lo stato della macchina (0-1-2-3)
int vocMen=0 ; // Memorizza lo stato delle voci menù
int spireTotali = 0;
int spireParziali = 0;
int diametroFilo = 0;
int spiTotAvvolte =0;
int spiParAvvolte = 0;
// Variabili per movimento motore
long contatore = 0;
long contatore_1 = 0;
int manMotori =0;
int statoPulsanti;
// Variabili appoggio
int a=0; // serve nella funzione increment
int app_1 = 0; // serve per appoggiare il risultato della funzione debounce dei pulsanti
int app_2 = 0; // serve per appoggiare il risultato della funzione debounce dei pulsanti
int app_3 = 0; // serve per appoggiare il risultato della funzione debounce dei pulsanti
int app_4 = 0; // serve per appoggiare il risultato della funzione debounce dei pulsanti
void setup() {
//Imposta i pin pulsanti come input
pinMode(PUL_1, INPUT_PULLUP);
pinMode(PUL_2, INPUT_PULLUP);
pinMode(PUL_3, INPUT_PULLUP);
pinMode(PUL_4, INPUT_PULLUP);
pinMode(PUL_5, INPUT_PULLUP);
//Imposta le uscite
pinMode(DIR_MOT_A, OUTPUT);
pinMode(STE_MOT_A, OUTPUT);
pinMode(DIR_MOT_M, OUTPUT);
pinMode(STE_MOT_M, OUTPUT);
// legge i valori salvati in memoria
leggeMemoria();
// Scrive la prima schermata
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0,0);
lcd.print(T_1);
lcd.setCursor(0,1);
lcd.print(T_2);
//Disabilita i motori
digitalWrite(ENA_A, HIGH);
digitalWrite(ENA_M, HIGH);
}
void loop() {
selettore(PUL_1); // Richiama il selettore dei modi
//stato=1;
switch (stato) {
case 2: //Automatico
break;
case 1: //manuale
//Motore avanzamento-----------------------------
if (digitalRead(PUL_2) == LOW) {
digitalWrite(ENA_A, LOW);
digitalWrite(DIR_MOT_A, HIGH);
digitalWrite(STE_MOT_A, HIGH);
delayMicroseconds(V_MAN_A);
digitalWrite(STE_MOT_A, LOW);
}
else{
digitalWrite(ENA_A, HIGH);
}
if (digitalRead(PUL_3) == LOW) {
digitalWrite(ENA_A, LOW);
digitalWrite(DIR_MOT_A,LOW);
digitalWrite(STE_MOT_A, HIGH);
delayMicroseconds(V_MAN_A);
digitalWrite(STE_MOT_A, LOW);
}
else{
digitalWrite(ENA_A, HIGH);
}
// Motore mandrino-----------------------
if (digitalRead(PUL_4) == LOW) {
digitalWrite(ENA_M, LOW);
digitalWrite(DIR_MOT_M, HIGH);
digitalWrite(STE_MOT_M, HIGH);
delayMicroseconds(V_MAN_M);
digitalWrite(STE_MOT_M, LOW);
}
else{
digitalWrite(ENA_M, LOW);
}
if (digitalRead(PUL_5) == LOW) {
digitalWrite(ENA_M, LOW);
digitalWrite(DIR_MOT_M, LOW);
digitalWrite(STE_MOT_M, HIGH);
delayMicroseconds(V_MAN_M);
digitalWrite(STE_MOT_M, LOW);
}
else{
digitalWrite(ENA_M, LOW);
}
break;
case 3: // Setting
menuSetting(); // richiama la funzione voci menù
app_1 = debounce(PUL_3);
if (app_1==LOW) {
if (vocMen ==4){ // Se in Salva in memoria scrive i dati in memoria con il pulsante 3
scriveMemoria();
lcd.setCursor(6, 1); lcd.print(T_16);// scrive il risultato
leggeMemoria(); // rilegge la memria per sicurezza
}
else { // Se in incremento valori incrementa con il pulsante 3
impostaValori(1);
}
}
app_2 = debounce(PUL_4);
if (app_2==LOW) {// decrementai i valori con il pulsante 4
impostaValori(-1);
}
if(app_1==HIGH && app_2 ==HIGH){a=0;} // resetta la variabile a al rilascio dei pulsanti
break;
}
}
//-- Esegue la selezione voci menu
void menuSetting(){
int app;
app = !debounce(PUL_2);
if (app == HIGH) {
if (sem_3 == LOW) { // Impedisce la ripetizione continua del comando
sem_3 = HIGH;
vocMen=vocMen+1;
lcd.setCursor(0, 1); lcd.print(T_0);// Cancella la seconda riga del display
if (vocMen > 4) {vocMen = 1;} // cicla sempre tra stato 1 e stato 4
}
switch (vocMen) { // Scrive i vari messaggi
case 0: // intestazione
lcd.setCursor(0, 1); lcd.print(T_8);
//lcd.setCursor(0, 1); lcd.print(T_2);
break;
case 1: // Spire totali
lcd.setCursor(0, 1); lcd.print(T_9);
lcd.setCursor(12, 1); lcd.print(spireTotali);
break;
case 2: // Spire parziali
lcd.setCursor(0, 1);lcd.print(T_10);
lcd.setCursor(12, 1); lcd.print(spireParziali);
break;
case 3: // Diametro filo
lcd.setCursor(0, 1); lcd.print(T_11);
lcd.setCursor(12, 1); lcd.print(diametroFilo);
break;
case 4: // Salva in memoria
lcd.setCursor(0, 1); lcd.print(T_15);
//lcd.setCursor(12, 1); lcd.print(diametroFilo);
break;
}
}
else{
sem_3 = LOW;// resetta il semaforo
}
}
// Seleziona le varie modalità con il pulsante 1
void selettore(int pin) {
int app;
//app = digitalRead(pin);
app = !debounce(pin);
if (app == HIGH) {
if (sem_2 == LOW) { // Impedisce la ripetizione continua del comando
sem_2 = HIGH;
stato = stato + 1;// imposta la variabile stato della macchina
if (stato > 3) {stato = 0;} // cicla sempre tra stato 0 e stato 3
lcd.clear();// cancella lo schermo
switch (stato) { // Scrive i vari messaggi
case 0: // intestazione
lcd.setCursor(0, 0); lcd.print(T_1);
lcd.setCursor(0, 1); lcd.print(T_2);
break;
case 1: // Manuale
lcd.setCursor(0, 0); lcd.print(stato);lcd.print(T_3);
lcd.setCursor(0, 1); lcd.print(T_4);
break;
case 2: // Automatico
lcd.setCursor(0, 0); lcd.print(stato);lcd.print(T_5);
lcd.setCursor(9, 0); lcd.print(spireParziali);
lcd.print(T_14);lcd.print(spireTotali);
lcd.setCursor(0, 1); lcd.print(T_6);
break;
case 3: // Settaggio
lcd.setCursor(0, 0); lcd.print(stato);lcd.print(T_7);
lcd.setCursor(0, 1); lcd.print(T_8);
break;
}
}
}
else {
sem_2 = LOW;
}
}
//---- Incrementa o decrementa il valore delle variabili di funzionamento
void impostaValori(int inc_dec){ //inc_dec = 1 incrementa , -1 decrementa Variabile = valore da cambiare
int b;
a=a+1;
switch (vocMen) {
case 1:
if (a<10){b=1;} else if ((a>=10) && (a <=20)){b=10;}else{b=100;}
spireTotali = spireTotali + b*inc_dec;
if(spireTotali<=1){spireTotali =1;}
lcd.setCursor(11,1);lcd.print(T_13);
lcd.setCursor(12,1);lcd.print(spireTotali);//schermo.print(T_20);
break;
case 2:
if (a<=10){b=1;}else{b=10;}
spireParziali = spireParziali + b*inc_dec;
if(spireParziali<=1){spireParziali =1;}
lcd.setCursor(11,1);lcd.print(T_13);
lcd.setCursor(12,1);lcd.print(spireParziali);//schermo.print(T_20);
break;
case 3:
diametroFilo = diametroFilo + 1*inc_dec;
if(diametroFilo <=1){diametroFilo =1;}
lcd.setCursor(11,1);lcd.print(T_13);
lcd.setCursor(12,1);lcd.print(diametroFilo);//lcd.print(T_20);
break;
}
delay(400);
}
//Funzione antirimbalzo per i pulsanti
boolean debounce(int pin) {
boolean state;
boolean previousState;
previousState = digitalRead(pin);
for (int counter = 0; counter < debounceDelay; counter++) {
delayMicroseconds(10);
state = digitalRead(pin);
if ( state != previousState) {
counter = 0;
previousState = state;
}
}
return state;
}
void leggeMemoria(){ // legge i dati nella memoria
EEPROM.get(I_1, spireTotali); // Numero Spire Totali
EEPROM.get(I_2, spireParziali); // Numero Spire parziali
EEPROM.get(I_3, diametroFilo ); // Diametro del filo
EEPROM.get(I_4, spiTotAvvolte ); // Spire totali avvolte
EEPROM.get(I_5, spiParAvvolte ); // Spire parziali avvolte
}
void scriveMemoria(){ // scrive i dati nella memoria
EEPROM.put(I_1, spireTotali); // Diametro del filo usato
EEPROM.put(I_2, spireParziali ); // Numero di spire totali dell'avvolgimento
EEPROM.put(I_3, diametroFilo ); // Numeri di spire da avvolgere per ogni strato
EEPROM.put(I_4, spiTotAvvolte ); // Spire totali avvolte
EEPROM.put(I_5, spiParAvvolte ); // Spire parziali avvolte
}