Schema per Realizzare un Termostato per Ambiente con Visualizzazione LCD e Tasti di Controllo…
INTRO
Il seguente schema serve per realizzare un termostato che chiude il contatto di un relè quando la temperatura è minore di una certa soglia. La soglia viene variata grazie a due pulsanti e inoltre sia la soglia che la temperatura vengono mostrate un un display LCD. In questo caso il circuito è tarato per il range di temperature 10-30 gradi centigradi, ma variando una costante nel codice si può variare il range. Visto che si usa un LM35 come sensore di temperatura, la temperatura massima è 150 gradi centigradi. Il circuito utilizza un microcontrollore per la lettura del sensore e per la visualizzazione delle temperature.
CODICE
Il codice è il seguente:
sbit LCD_RS at RC0_bit; // Configurazione Pin I/O
sbit LCD_EN at RC1_bit; //Indico alla libreria
sbit LCD_D4 at RC2_bit; //come è connesso l'LCD
sbit LCD_D5 at RC3_bit;
sbit LCD_D6 at RC4_bit;
sbit LCD_D7 at RC5_bit;
sbit LCD_RS_Direction at TRISC0_bit; //Indico se ho ingressi o uscite
sbit LCD_EN_Direction at TRISC1_bit;
sbit LCD_D4_Direction at TRISC2_bit;
sbit LCD_D5_Direction at TRISC3_bit;
sbit LCD_D6_Direction at TRISC4_bit;
sbit LCD_D7_Direction at TRISC5_bit;
unsigned int short adcvalue; //Variabile valore uscita da ADC
unsigned short int Tem1, Set_Temp; //Variabile temperatura e settaggio
float Tem; //Valore convertito della temperatura
char Text[7]; //Stringa contenente la temperatura
bit flag;
void print_temp(char text){ //Sottoprogramma per la visualizzazione della temperatura
Lcd_Cmd(_LCD_SECOND_ROW); //invia cursore sulla seconda riga
Lcd_Out_Cp(text); //scrivi la parte intera della temperatura
Lcd_Chr_Cp(223); //codice per scrivere il simbolo di grado °
Lcd_Chr_Cp('C'); //scrivi C
}
void EXT_INT() iv 0x0008 ics ICS_AUTO { //0018h per bassa priorità, 0008h per alta priorità
if(PORTB.B0==1){ //Controllo tasto incremento
if(Set_Temp < 30) Set_Temp ++;
}
else { //Controllo tasto decremento
if(Set_Temp > 0) Set_Temp --;
}
EEPROM_Write(0x00, Set_Temp); //Salva valore su memoria
Delay_ms(50); //Ciclo antirimbalzo
INTCON.INT0IF = 0; //reset del flag int0
INTCON3.INT1IF = 0; //reset del flag int1
}
void main(){ //Programma principale
Lcd_Init(); // Initializza LCD
Lcd_Cmd(_LCD_CLEAR); // Pulisci LCD
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursore non visibile
ADC_Init(); // Initializza il modulo ADC con valori di default
TRISB.B0 = 1; //pin di ingresso per pulsante + set temp
TRISB.B1 = 1; //pin di ingresso per pulsante - set temp
TRISC.B7 = 0; //Uscita relè
RCON.IPEN = 0; //disabilito la priorità degli interrupt
INTCON.GIE = 1; //attivo gli interrupt
INTCON2.INTEDG0 = 1; //interrupt sul fronte di salita int0
INTCON.INT0IE = 1;
INTCON2.INTEDG1 = 1; //interrupt sul fronte di salita int1
INTCON3.INT1IE = 1;
Set_Temp = EEPROM_Read(0x00); //Leggi valore su memoria
while(1){ //Ciclo infinito
adcvalue = ADC_Get_Sample(0); //Lettura da ADC
Tem = 0.48828 * adcvalue; //Conversione da Byte a Decimale
Tem1 = Tem; //conversione in intero
if (Tem1 < Set_Temp) PORTC.F7 = 1; //chiusura e apertura relè
else PORTC.B7 = 0;
IntToStr( Tem1, Text ); //conversione in stringa
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_FIRST_ROW); //invia cursore sulla PRIMA riga
Lcd_Out_Cp("TEMPERATURA:");
print_temp(text); //Invia i valori da visualizzare al sottoprogramma
delay_ms(600); //Ritardo visualizzazione temperatura
IntToStr(Set_Temp, Text ); //conversione in stringa
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_FIRST_ROW); //invia cursore sulla PRIMA riga
Lcd_Out_Cp("SET TEMPERATURA:");
print_temp(text); //Invia i valori da visualizzare al sottoprogramma
delay_ms(1000);
}
}
Prima di tutto nel codice bisogna inizializzare l’LCD e le variabili necessarie per il programma. Poi si crea una sotto porzione di codice per pilotare l’LCD, questa sotto funzione (print_temp) riceve una stringa che contiene il dato di temperatura e vi aggiunge “°C”.
Dopo di che vi è una routine di interrupt che controlla quale tasto è stato premuto e modifica la soglia del termostato, inoltre la memorizza nella memoria permanente per evitare che in caso di reset la soglia cambi.
Nel programma principale si inizializza LCD, ingressi e uscite, ADC e Interrupt e si legge dalla memoria un eventuale soglia salvata. Nel programma principale vi è un ciclo infinito che legge il valore del sensore, lo converte e in base ad esso accende o spegne il relè. Inoltre si converte il valore della temperatura in stringa e si visualizza sul display LCD prima la stringa della temperatura e poi quella della soglia.
SCHEMA
Lo schema è il seguente:
Il sensore LM35 è alimentato con una tensione di 5V e l’uscita del sensore è connesso al PIN2 che è il primo canale dell’ADC. Il PIN1 bisogna portare un livello logico alto per evitare che il PIC18F252 si resetti, questo viene fatto con una resistenza di pull-up da 10KΩ. Il circuito di oscillazione è composto dal risuonatore al quarzo X1 e dai condensatori C1 e C2.
La resistenza variabile RV1 serve per la regolazione del contrasto dell’LCD che viene alimentato anch’esso a 5V. Nello schema manca l’alimentazione della retroilluminazione dell’LCD che viene fatta collegano il catodo a massa e l’anodo a VCC interponendo però una resistenza da 470Ω.
Il PIC18F252 viene alimentato a 5V collegando i PIN8 e PIN19 a massa e il PIN20 a VCC. I tasti hanno una resistenza di pull-up ciascuno e sono R3 e R2.
Infine il relè viene controllato grazie a R4, Q1 e il diodo 1N4001 che fungono da amplificatore di corrente per la bobina del relè.
DOWNLOAD
Potete scaricare la simulazione del circuito con PROTEUS al seguente LINK!!!
Salve, se devo dare un range di temperatura da -10° a 15° quale valore devo cambiare?
grazie.
Ciao,
più che cambiare qualche componente dovresti realizzare la lettura del sensore lm35 per temperature negative come nell’esempio di figura 18 del datasheet: http://www.ti.com/lit/ds/symlink/lm35.pdf
ora che mi hai dato l’idea spero al più presto di realizzare un tutorial su come utilizzare lm35 per tensioni negative