//--------LIBRERIE-------------------------
#include <LiquidCrystal_I2C.h> //lcd
#include <Keypad.h>
#include <EEPROM.h>
//-----------------------------------------
#define pompa 10
#define valvola 11
//----------------LCD----------------------
LiquidCrystal_I2C lcd(0x27,20,4);
//-----------------------------------------
//-----Tastierino------------
const uint8_t ROWS = 4;
const uint8_t COLS = 4;
char keys[ROWS][COLS] = {
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};
uint8_t colPins[COLS] = { 5, 4, 3, 2 }; // Pins connected to C1, C2, C3, C4
uint8_t rowPins[ROWS] = { 9, 8, 7, 6 }; // Pins connected to R1, R2, R3, R4
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
//------------TMP-------------
const float BETA = 3950;
int val = 0;
int sensore = A0;
int temp = 0;
//-----------------------------
int stato = 0;
bool x = 0; //carotti spa
bool i = 0; //stringa messaggio carotti spa
bool a = 0;
bool o = 0;
bool time = 0;
bool seconda_cifra = 0;
int margine = 0;
int temp_def = 0;
//--------------------------
int mem_EEPROM = 0;
int LCDRow = 0;
int unita = 0;
int decine = 0;
int num_temp = 0, num_temp2 = 0;
int filtro = 48;
int conferma = 0;
int c = 67;
bool pressione_decine = 0;
bool pressione_unita = 0;
int cifra_1 = 0;
int temp_impostata;
bool mod =0;
int posizione = 0;
//--------------------------
void setup()
{
//----------EEPROM------------
int v_val = EEPROM.read(0);
//----------------------------
//----------LCD---------------
lcd.init();
//----------------------------
//----------TMPSENS-----------
pinMode(sensore, INPUT);
Serial.begin(9600);
//----------------------------
pinMode(pompa, OUTPUT);
pinMode(valvola, OUTPUT);
}
//--------------------------
//--------------------------
int key = 0;
void loop(){ //SOTTO CI SONO LE SPIEGAZIONI PER OGNI VOID
Serial.print("stato");
Serial.println(stato);
switch(stato){
case 0: //case per mettere in evidenza la propria azienda, non e' altro che un array con una variabile di tipo
showSpalshScreen(); //stringa che ogni volta che si incrementa aggiunge una lettera al LCD cosi da creare quell effetto "scorrevole"
lcd.clear();
if(x == 1) stato = 1; // questa operazione la fa solo una volta appena si accende
break;
case 1:
leggo_temp(); //in questo case e' il case di lettura temperatura e di interazione tra uomo-macchina attraverso il display
LCD(); //e la configuarazione del menu
menu();
break;
case 10:
calc_marg(); //questo case calcola il margine che daremo in seconda occasione dopo aver impostato la temperatura.
break;
case 2:
lcd.clear(); //questo case e' di transizione tra il case 1 e il case 3 ( pulisce solamente LCD )
stato = 3;
break;
case 3:
writing(); //..questo case e' molto importante in pratica serve a trasformare i segnali dati dal keypad ad arduino attraverso un
break; //paglio di calcoli ( piu dettagliato SOTTO )
case 4:
error(); //..questo case e' il case di errore nel caso si volesse immettere una temperatura maggiore a quella prevista dal sensore
stato = 5; // cosa che si puo ovviare mettendo un sensore con soglia piu alta
break;
case 5:
clean(); //questo case serve per reimpostare tutti i valori del case 3 nel caso si sbagliasse a impostare la temperatura superiore
stato = 3; // a quella prevista, RESETTA SOLAMENTE TUTTI I VALORI RELATIVI ALLA SOVRASCRITTURA DELLA TEMPERATURA
o = 0;
break;
case 6:
Serial.print("temp impos"); // questo case e' il case di conferma per quanto riguarda la temperatura da impostare
Serial.println(temp_impostata); //visualizzi addizione dei due valori : temperatura impostata + margine e se si vuole confermare
confi(); //o rifiutare l impostazione
menu();
break;
case 7:
leggo_temp(); //questo case e' per l avvio degli attuatori
LCD();
menu();
attuatori();
if(stato == 7 )posizione = 1;
Serial.print(temp_impostata);
break;
case 8: //questo case serve nel caso dallo stato di configurazione della temperatura si voglia tornare indietro
clean(); //e resetta ogni informazione che e' stata data (insieme alla variabili stesse ) e disattivare eventuali attuatori
lcd.clear();
digitalWrite(pompa, LOW);
digitalWrite(valvola, LOW);
stato = 1;
break;
}
}
void attuatori(){ //..come dice il nome stesso questo void e' dedicato all' attivazione degli attuatori..
temp_def = margine + temp_impostata; //qui la temp_def = temperatura definita ( nome fittizzio per dire la somma della temp + il margine)
if( temp < temp_impostata ){
digitalWrite(pompa, HIGH);
digitalWrite(valvola, HIGH);
}
if(temp > temp_def){
digitalWrite(pompa, LOW);
digitalWrite(valvola, LOW);
}
}
void leggo_temp(){ // questo void molto importante serve per leggere la temperatura
val = analogRead(sensore);
temp = 1 / (log(1 / (1023. / val - 1)) / BETA + 1.0 / 298.15) - 273.15; //questa operazione non e' tutta farina del mio sacco anzi io non centro
if(temp >= -9 ){ //assolutamente niente (ringraziate quel genio che l ha fatta)
lcd.setCursor(14,0); //tutto quello che te posso di e' che nce stanno numeri con la virgola
lcd.print(" "); //scappano solo interi. basta solo questo.
}
if(temp < 9){
if(temp >= 0){
lcd.setCursor(13,0);
lcd.print(" ");
}
}
}
/*
void LCD_att(){
char key = keypad.getKey(); // nn fa caso era un prototipo e lo lascio qua perche me fara' comodo in futuro
if(key == 'A') {
stato = 8;
}
lcd.setCursor(0,0);
lcd.print("(A) MOD");
lcd.setCursor(0,1);
lcd.print("(B) Temperature");
if(key == 'B') {
lcd.setCursor(0,1);
lcd.print(" ");
stato = 5;
}
}*/
void LCD(){ //sto void te o dice e' per LCD interfaccia grafica
lcd.setCursor(0, 0);
lcd.print("Temperature:");
lcd.setCursor(12, 0);
lcd.print(temp);
lcd.setCursor(15, 0);
lcd.print("C");
lcd.setCursor(0,1);
lcd.print("Mod:");
lcd.setCursor(4,1);
if(mod == 0){
lcd.print("Inverno ");
}
else
{
lcd.print("Estate ");
lcd.setCursor(15, 1);
lcd.print(" ");
}
}
void menu(){ // sto void e' per la configurazione del menu in base a che pulsante clicchi te manda in menu differenti
int conf = 0;
char key = keypad.getKey();
if(key == 'A' && posizione == 0) stato = 2;
if(key == 'A' && posizione == 1) stato = 5;
if(key == 'D') conf = 2;
if(key == 'B') stato = 8;
if(key == 'C' && stato != 1) conf = 1;
if(conf == 1)stato = 7;
if(conf == 2)stato = 5;
if(key == '*'){
mod = !mod;
}
}
void showSpalshScreen() { //sto void e' per mettere i diritti d'autore in questo caso la propria compagnia.
lcd.setCursor(0,0);
lcd.print("Carotti Spa.");
lcd.setCursor(3, 1);
String message = "Loading...";
for (byte i = 0; i < message.length(); i++) {
lcd.print(message[i]);
delay(50);
}
delay(500);
x = 1;
}
void calc_marg(){ //questo santidio e' molto importante, cosa fa? e mo te o spiego. allora questo void e' per il calcolo
if(o == 0){ //e introduzione del margine
clean();
o = 1;
}
lcd.setCursor(0,0);
lcd.print("Impostare Marg:");
char key = keypad.getKey();
if(key == c)conferma = 1;
if(pressione_decine == 1 && pressione_unita == 0 && conferma == 1){
unita = (decine * 0.1);
decine = 0;
pressione_unita = pressione_decine;
}
if (key){ //da qui parte un filtro per non far visualizzare le lettere o caratteri speciali nel momento della
cifra_1++; //scelta della temperatura, tutti questi numeri corrispondono alla combinazione che danno se premuti
if(cifra_1 == 1){ //e con un filto ( sta botta da me creato ) riconosce che tasti vengono cliccati. Funzionamento?
num_temp = key; //clicchi il pulsante esempio l asterisco " * " questo carattere e' riconosciuto con il numero 35
if(num_temp != 35){ //passante per il primo if(cifra_1...) se ne trova davanti un altro che non glie lo permette e cosi via
if(num_temp != 42){ //per tutti gli altri, mo pero arrivano i numeri, come famo? semplice. Pure i numeri hanno un loro valore
if(num_temp != 65){ //tipo 1 equivale a 49, creando un filtro faccio una sottrazione " (numero da me scelto) - filtro "
if(num_temp != 66){ //questa operazione equivale a scrivere 49 - 48 che e' uguale a 1 e cosi pure per il 2 3 4..ecc.
if(num_temp != 67){ //dopo aver filtrato il tutto bisogna vedere se fara' parte delle decine o unita. cosi con una funzione
if(num_temp != 68){ //molto elementare faccio diventare quell 1 10 cosi: (numero filtrato) * 10 = x. e una variabile che ho
lcd.setCursor (LCDRow, 1); //chiamato pressione_decine diventera = 1 almeno dara conferma di avre cliccato per le decine.
lcd.print(key); //e soprattutto per ovviare a un problema molto comune in questi casi, metterne solo un numero per
decine=(num_temp-filtro)*10;//rappresentare le unita.
pressione_decine = 1;
lcd.setCursor (++LCDRow, 1);
seconda_cifra = 1;
}
}
}
}
}
}
}
if(cifra_1 == 2){ //
if(LCDRow == 1){
num_temp2 = key;
if(num_temp2 != 35){
if(num_temp2 != 42){
if(num_temp2 != 65){
if(num_temp2 != 66){
if(num_temp2 != 67){
if(num_temp2 != 68){
lcd.setCursor (LCDRow, 1);
lcd.print(key);
unita=(num_temp2-filtro);
pressione_unita = 1;
lcd.setCursor (LCDRow, 1);
}
}
}
}
}
}
}
}
}
if(key == 'D'){
num_temp = 0;
num_temp2 = 0;
unita = 0;
decine = 0;
pressione_unita = 0;
pressione_decine = 0;
cifra_1 = 0;
LCDRow = 0;
lcd.setCursor(0,1);
lcd.print(" ");
conferma = 0;
}
if(margine + temp_impostata > 80 && conferma == 1){
a = 1;
stato = 4;
}
if(pressione_decine == 1 && pressione_unita == 1){
margine = decine + unita;
if(temp_impostata + margine <= 80 && conferma == 1){
conferma = 0;
lcd.clear();
stato = 6; //stato = 6
}
}
}
void clean(){
cifra_1 = 0;
num_temp = 0;
num_temp2 = 0;
unita = 0;
pressione_unita = 0;
pressione_decine = 0;
decine = 0;
LCDRow = 0;
conferma = 0;
lcd.clear();
}
void writing (){
lcd.setCursor(0,0);
lcd.print("Impostare Temp:");
char key = keypad.getKey();
if(key == c)conferma = 1;
if(!pressione_unita && !pressione_decine && conferma == 1)conferma = !conferma;
if(pressione_decine == 1 && pressione_unita == 0 && conferma == 1){
unita = (decine * 0.1);
decine = 0;
pressione_unita = pressione_decine;
}
mem_EEPROM = temp_impostata;
if(pressione_decine == 1 && pressione_unita == 1){
temp_impostata = decine + unita;
if(temp_impostata > 80 && conferma == 1)stato = 4;
if(temp_impostata <= 80 && conferma == 1){
conferma = 0;
lcd.clear();
stato = 10; //stato = 6
}
}
if (key){
cifra_1++;
if(cifra_1 == 1){
num_temp = key;
if(num_temp != 35){
if(num_temp != 42){
if(num_temp != 65){
if(num_temp != 66){
if(num_temp != 67){
if(num_temp != 68){
lcd.setCursor (LCDRow, 1);
lcd.print(key);
decine=(num_temp-filtro)*10;
pressione_decine = 1;
lcd.setCursor (++LCDRow, 1);
seconda_cifra = 1;
}
}
}
}
}
}
}
if(cifra_1 == 2){
if(LCDRow == 1){
num_temp2 = key;
if(num_temp2 != 35){
if(num_temp2 != 42){
if(num_temp2 != 65){
if(num_temp2 != 66){
if(num_temp2 != 67){
if(num_temp2 != 68){
lcd.setCursor (LCDRow, 1);
lcd.print(key);
unita=(num_temp2-filtro);
pressione_unita = 1;
lcd.setCursor (LCDRow, 1);
}
}
}
}
}
}
}
}
if(key == 'A'){
stato = 8;
}
if(key == 'D'){
num_temp = 0;
num_temp2 = 0;
unita = 0;
decine = 0;
pressione_unita = 0;
pressione_decine = 0;
cifra_1 = 0;
LCDRow = 0;
lcd.setCursor(0,1);
lcd.print(" ");
conferma = 0;
}
}
}
void confi(){
lcd.setCursor(0,0);
lcd.print("CONFERMI:");
lcd.setCursor(9,0);
if(temp_impostata < 10 ){
lcd.print(margine + temp_impostata); //cambiare
lcd.setCursor(11,0);
lcd.print(" ");
}
else
{
lcd.print(margine + temp_impostata);
lcd.setCursor(11,0);
lcd.print(" ");
}
lcd.setCursor(0,1);
lcd.print("C SI");
lcd.setCursor(12,1);
lcd.print("D NO");
}
void error(){
if( a == 1){
lcd.clear();
lcd.setCursor(6,0);
lcd.print("ERROR");
lcd.setCursor(0,1);
lcd.print("Marg+Temp x> 80C");
delay(1000);
lcd.clear();
}
else
{
lcd.clear();
lcd.setCursor(6,0);
lcd.print("ERROR");
lcd.setCursor(0,1);
lcd.print("Max Temp 80C");
delay(1000);
lcd.clear();
}
}
Pulsante A = Settaggio Temperatura menu.
Pulsante C = Conferma
Pulsante D = Cancella/Delete.
Attuatore Pompa
Pulsante * = Cambio Estate/Inverno.
Attuatore Valvola