// Variabili globali
volatile unsigned long milliseconds = 0;
volatile unsigned long millisecond1 = 0;
volatile unsigned long millisecond2 = 0;
volatile bool flag1Sec = false;
volatile bool flag14Sec = false;
volatile bool flag18Sec = false;
float temperature = 0.0;
volatile uint16_t ntcVal = 0;
bool RONStato = false;
bool allarmeStato = false;
uint16_t PVntcVal = 1;
bool adc_ready = false;
uint8_t channel=0;
//-----------------------------------------------------
//Variabili del sistema che l'utente puo personalizzare
volatile unsigned int seconds = 0;
volatile unsigned int minutes = 0;
volatile unsigned int hours = 18;
volatile unsigned int daysOfWeek = 0;//0=lunedi
// Range e giorni per l'attivazione dell'allarme (HH:MM)
// Definizione degli array per l'ora di inizio e fine per ogni giorno (0 = Domenica, 6 = Sabato)
const uint8_t orarioInizioOreSettimana[7] = {8, 9, 9, 8, 7, 10, 12}; // Esempio di orari di inizio
const uint8_t orarioFineOreSettimana[7] = {17, 18, 17, 16, 15, 14, 13}; // Esempio di orari di fine
// Soglie di temperatura
int sogliaGiallaInferiore = 14;
int sogliaRossaInferiore = 0;
//-----------------------------------------------
//Modulo Setup
void setup() {
//Inizializzazione pin di output
DDRC |= (1 << DDC4) | (1 << DDC5) | (1 << DDC6) | (1 << DDC7);
DDRA = 0xFF;
// Inizializzazione Timer: gestione del conteggio temporale e interrupt
SREG &= ~(1 << 7); // Disabilita gli interrupt globali
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 15; // Imposta il valore di confronto per 1ms
TCCR1B |= (1 << WGM12) | (1 << CS12) | (1 << CS10); // Modalità CTC e prescaler a 1024
TIMSK1 |= (1 << OCIE1A); // Abilita l'interrupt
SREG |= (1 << 7); // Abilita gli interrupt globali
ADMUX = (1 << REFS0); // Seleziona AVcc come riferimento di tensione
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // Prescaler a 128
ADCSRA |= (1 << ADSC);
}
//Modulo Timer
ISR(TIMER1_COMPA_vect) {
milliseconds++;
millisecond1++;
millisecond2++;
if (milliseconds >= 1000) { // 1 secondo trascorso
milliseconds = 0;
seconds++;
flag1Sec = true; // Segnala che è trascorso 1 secondo
if (seconds >= 60) {
seconds = 0;
minutes++;
if (minutes >= 60) {
minutes = 0;
hours++;
if (hours >= 24) {
hours = 0;
daysOfWeek++;
if (daysOfWeek >= 7) {
daysOfWeek = 0;
}
}
}
}
}
if (millisecond1 >= 1400) { // 1.4 secondo trascorso
millisecond1 = 0;
flag14Sec = true; // Segnala che è trascorso 1.4 secondo
}
if (millisecond2 >= 1800) { // 1.8 secondo trascorso
millisecond2 = 0;
flag18Sec = true; // Segnala che è trascorso 1.8 secondo
}
}
// Funzione che controlla se l'ora attuale rientra nel range orario specifico per il giorno corrente
bool controlloRangeOrario(uint8_t giorno, uint8_t ore) {
// Controlla se l'ora corrente è dopo l'orario di inizio per il giorno corrente
bool dopoInizio = ore >= orarioInizioOreSettimana[giorno];
// Controlla se l'ora corrente è prima dell'orario di fine per il giorno corrente
bool primaFine = ore < orarioFineOreSettimana[giorno];
// L'ora corrente deve essere tra l'inizio e la fine per il giorno specifico
return dopoInizio && primaFine;
}
// Modulo Debug: stampa dei valori e del tempo
void debugPrint() {
Serial.print("Temperatura: ");
Serial.println(temperature);
Serial.print("Giorno della settimana: ");
Serial.print(daysOfWeek);
Serial.print(" | Ora: ");
Serial.print(hours);
Serial.print(":");
if (minutes < 10) Serial.print("0");
Serial.print(minutes);
Serial.print(":");
if (seconds < 10) Serial.print("0");
Serial.println(seconds);
}
void loop() {
if (flag1Sec) {
flag1Sec = false;
//Modulo ADC
// --- Inizio Lettura ADC ---
channel &= 0x07; // Assicura che il canale sia entro i limiti (0-7)
ADMUX = (ADMUX & 0xF8) | channel; // Seleziona il canale ADC
ADCSRA |= (1 << ADSC); // Avvia la conversione
while (ADCSRA & (1 << ADSC)); // Attende che la conversione sia completata
ntcVal = ADC; // Legge il valore ADC
// --- Fine Lettura ADC ---
}
if (flag14Sec) {
flag14Sec = false;
// Conversione del valore ADC in temperatura
const float BETA = 3950;
temperature = 1 / (log(1 / (1023.0 / ntcVal - 1)) / BETA + 1.0 / 298.16) - 273.15;
}
if (flag18Sec) {
flag18Sec = false;
//Modulo barra led
// --- Inizio Aggiornamento Barra LED ---
PORTA = 0x00; // Spegni tutti i LED sulla porta A (verdi e gialli)
PORTC &= ~((1 << PORTC7) | (1 << PORTC6)); // Spegni i LED rossi su PORTC6 e PORTC7
if (temperature >= sogliaGiallaInferiore) {
int ledVerdi = map(temperature, 80, sogliaGiallaInferiore, 1, 5);
PORTA = (1 << ledVerdi) - 1; // Accendi i LED verdi (0-4)
} else if (temperature >= sogliaRossaInferiore) {
int ledAccesi = map(temperature, sogliaGiallaInferiore, sogliaRossaInferiore, 6, 8);
PORTA = 0x1F; // Accendi i 5 LED verdi (0-4)
PORTA |= (1 << ledAccesi) - 1; // Accendi i LED gialli (5-7)
} else if (temperature < sogliaRossaInferiore) {
int ledAccesi = map(temperature, sogliaRossaInferiore, -24, 9, 10); // Mappa per i LED rossi
PORTA = 0xFF; // Accendi tutti i LED verdi e gialli (0-7)
if (ledAccesi == 9) {
PORTC |= (1 << PORTC7); // Accendi un LED rosso su PORTC7
} else if (ledAccesi == 10) {
PORTC |= ((1 << PORTC7) | (1 << PORTC6)); // Accendi entrambi i LED rossi
}
}
// --- Fine Aggiornamento Barra LED ---
//Modulo R-ON e Allarme
// --- Inizio Controllo R-ON e Allarme ---
if (temperature < sogliaGiallaInferiore) {
PORTC |= (1 << PORTC4); // Attiva R-ON
RONStato = true;
} else {
PORTC &= ~(1 << PORTC4); // Disattiva R-ON
RONStato = false;
}
// Controllo dell'intervallo orario per ogni giorno della settimana
bool dopoInizio = hours >= orarioInizioOreSettimana[daysOfWeek];
bool primaFine = hours < orarioFineOreSettimana[daysOfWeek];
if (temperature <= sogliaRossaInferiore && dopoInizio && primaFine) {
PORTC |= (1 << PORTC5); // Attiva allarme
allarmeStato = true;
} else {
PORTC &= ~(1 << PORTC5); // Disattiva allarme
allarmeStato = false;
}
// --- Fine Controllo R-ON e Allarme ---
}
}