Salve a tutti, frequento questo forum da quando ho iniziato ad usare Arduino ma non riesco a risolvere un problema.
Sulla base di alcuni programmi trovati e di molte modifiche ho creato un termostato che mi indica temperatura, umidità,data e ora su un display lcd ma dopo un po' di tempo (sempre inferiore a 2 ore) mi cambiano tutte le scritte diventando tipo cinesi (senza un senso).
Credo che il problema sia per la memoria che usa il programma ma non saprei.
Sapete dirmi se avete qualche idea per sistemarlo?
Qui vi posto il codice:
#include <Arduino.h>
#include <Wire.h>
#include "DS1307.h"
#include "LiquidCrystal.h"
#include "idDHT11.h"
int relay = 4;
int pot_pin = 1;
int led_rosso = 5;
int led_blu = 3;
int led_verde =12;
int lcd_luce = 13;
float act_temp = 0.0;
float set_temp = 15.0;
int hum = 0;
int last_time = 0;
int hys = 1;
int temperatura_notturna = 18;
//serve a settare il tempo in cui il termostato rimane spento
int time_STOPinizio = 2;
int time_STOPfine = 6;
int prev_temp = 0;
int prev_time = 0;
int delay_set = 5;
byte degree[8] = {
B01000,
B10100,
B01000,
B00011,
B00100,
B00100,
B00011,
};
//inizializza
LiquidCrystal lcd(10, 11, 6, 7, 8, 9); //LCD inizializzazione
int idDHT11pin = 2;
//pin digitale per la comunicazione del DHT11
int idDHT11intNumber = 0;
//interrupt number (deve essere quello che utilizza il pin definito precedentemente (guarda la tabella) DHT11
void dht11_wrapper(); // deve essere dichiarata prima dell'inizializzazione della libreria
idDHT11 DHT11(idDHT11pin,idDHT11intNumber,dht11_wrapper);
DS1307 clock;
//definisce l'oggetto (DS1307)
void setup()
{
Serial.begin(9600);
pinMode(relay, OUTPUT);
pinMode(led_blu, OUTPUT);
pinMode(led_rosso, OUTPUT);
pinMode(led_verde, OUTPUT);
pinMode(lcd_luce, OUTPUT);
clock.begin();
lcd.createChar(0, degree);
/* **********serve ad impostare data e ora********* *\
clock.fillByYMD(2015,9,16); //16-9-2015 *
clock.fillByHMS(19,00,00); //19:00 00" *
clock.fillDayOfWeek(WED); //mercoledì *
clock.setTime();//scrivi ora e data sul ds1307 *
\* ************************************************ */
lcd.begin(16, 2); // inizializza LCD
lcd.setCursor(0,0); // mette il cursore a 0,0
}
void dht11_wrapper() //necessario per inizializzare la libreria idDHT11
{
DHT11.isrCallback();
}
void stop_pump() //spegne il relay e accende il LED rosso
{
digitalWrite(relay, 1);
digitalWrite(led_verde, 0);
digitalWrite(led_rosso, 1);
digitalWrite(led_blu, 0);
}
void start_pump() //spegne il relay e accende il led blu
{
digitalWrite(relay, 0);
digitalWrite(led_verde, 0);
digitalWrite(led_rosso, 0);
digitalWrite(led_blu, 1);
}
void stop_system() //spegne il relay e accende il led verde
{
digitalWrite(relay, 1);
digitalWrite(led_verde, 1);
digitalWrite(led_rosso, 0);
digitalWrite(led_blu, 0);
}
void print_LCD() //scrive lo stato sul display LCD (16x2)
{
//linea 0
lcd.setCursor(0,0);
lcd.print(act_temp, 0);
lcd.setCursor(2,0);
lcd.write(byte(0));
lcd.setCursor(4,0);
lcd.print("|");
lcd.setCursor(5,0);
if(clock.hour < 10) // scrivi 0 prima dell'ora se è minore di 10
{
lcd.print("0");
lcd.setCursor(6,0);
lcd.print(clock.hour, DEC);
}
else (lcd.print(clock.hour, DEC));
lcd.setCursor(7,0);
lcd.print(":");
lcd.setCursor(8,0);
if(clock.minute < 10) // scrivi 0 prima dei minuti se sono minori di 10
{
lcd.print("0");
lcd.setCursor(9,0);
lcd.print(clock.minute, DEC);
}
else (lcd.print(clock.minute, DEC));
lcd.setCursor(10,0);
lcd.print("|");
lcd.setCursor(12,0);
lcd.setCursor(12,1);
lcd.print(set_temp, 1);
//linea 1
lcd.setCursor(2,1);
lcd.print("%");
lcd.setCursor(0,1);
lcd.print(DHT11.getHumidity(), 0);
lcd.setCursor(4,1);
lcd.print("|");
lcd.setCursor(5,1);
if(clock.dayOfMonth < 10) // scrivi 0 del giorno se è minore di 10
{
lcd.print("0");
}
lcd.print(clock.dayOfMonth, DEC);
lcd.setCursor(7,1);
lcd.print("/");
lcd.setCursor(8,1);
if(clock.month < 10) // scrivi 0 del giorno se è minore di 10
{
lcd.print("0");
}
lcd.print(clock.month, DEC);
lcd.setCursor(10,1);
lcd.print("|");
lcd.setCursor(12,1);
lcd.print(set_temp, 1);
lcd.setCursor(4,0);
}
void DHT11_acquiring() // aquisisci le informazioni dal sensore DHT11
{
DHT11.acquire();
while (DHT11.acquiring());
int result = DHT11.getStatus();
switch (result) //segnala se è tutto ok o che errore si verifica
{
case IDDHTLIB_OK:
Serial.println("OK");
break;
case IDDHTLIB_ERROR_CHECKSUM:
Serial.println("Error\n\r\tChecksum error");
break;
case IDDHTLIB_ERROR_ISR_TIMEOUT:
Serial.println("Error\n\r\tISR Time out error");
break;
case IDDHTLIB_ERROR_RESPONSE_TIMEOUT:
Serial.println("Error\n\r\tResponse time out error");
break;
case IDDHTLIB_ERROR_DATA_TIMEOUT:
Serial.println("Error\n\r\tData time out error");
break;
case IDDHTLIB_ERROR_ACQUIRING:
Serial.println("Error\n\r\tAcquiring");
break;
case IDDHTLIB_ERROR_DELTA:
Serial.println("Error\n\r\tDelta time to small");
break;
case IDDHTLIB_ERROR_NOTSTARTED:
Serial.println("Error\n\r\tNot started");
break;
default:
Serial.println("Unknown error");
break;
}
}
int day_time() //imposta il tempo
{
int x = (clock.hour);
if(x > time_STOPinizio && x < time_STOPfine)
return 2; //se è notte setta 2
else
return 1; //se è giorno setta 1
}
int seconds_elapsed()
{
int elapsed_secs = 0;
if(prev_time > clock.second) //necessario per lavorare con un conto di base di 60
{
elapsed_secs = (60-prev_time)+clock.second;
}
else
{
elapsed_secs = clock.second - prev_time;
}
return elapsed_secs;
}
int minutes_elapsed()
{
int elapsed_mins = 0;
if(last_time > clock.minute) //necessario per lavorare con un conto di base di 60
{
elapsed_mins = (60-last_time)+clock.minute;
}
else
{
elapsed_mins = clock.minute - last_time;
}
return elapsed_mins;
}
void loop()
{
int x = 0;
bool change_temp = 0;
//ottieni temperatura, data e tempo
DHT11_acquiring();
act_temp = (DHT11.getCelsius());
clock.getTime();
//leggi il pot pin
x = analogRead(pot_pin);
x = map(x, 0, 1023, 15, 45);
//se la temperatura è al minimo disattiva i controlli, spegni la retroilluminazione e accendi il led verde
if (x == 15)
{
stop_system();
print_LCD();
lcd.setCursor(12,1);
set_temp = (((x+15)*10)/2)/10.00; //se non si inserisce la temp si blocca sull'ultimo ricalcolo
lcd.setCursor(11,0);
lcd.print("-OFF-");
if(seconds_elapsed() >= delay_set)
digitalWrite(lcd_luce, 0);
goto stop;
}
//5 secondi dopo l'ultimo cambiamento spegni la retroilluminazione del LCD
if(seconds_elapsed() >= delay_set)
digitalWrite(lcd_luce, 0);
//se il potenziometro cambia temperatura accendi la retroilluminazione del LCD
if(x != prev_temp)
{
digitalWrite(lcd_luce, 1);
prev_time = (clock.second);
change_temp = 1;
delay(100);
}
//se è giorno regola la temperatura con il potenziometro
if (day_time() == 1)
{
set_temp = (((x+15)*10)/2)/10.00; // cambia la temperatura con il potenzionetro di 0.5°C per volta
lcd.setCursor(11,0);
lcd.print(" set");
lcd.setCursor(15,0);
lcd.write(byte(0));
}
//se è notte imposta la temperatura notturna
else if (day_time() == 2)
{
set_temp = temperatura_notturna;
lcd.setCursor(11,0);
lcd.print("sleep");
}
//se il tempo di attesa è passato attiva i controlli
if (minutes_elapsed() >= delay_set || change_temp == 1)
{
if (act_temp < (set_temp - hys)) //se la stanza è fredda accendi il termosifone
{
start_pump();
last_time = (clock.minute);
}
else //altrimenti se la stanza è calda spegni il termosifone
{
stop_pump();
last_time = (clock.minute);
}
change_temp = 0;
}
// scrivi sul LCD,imposta il valore del prev_temp
print_LCD();
prev_temp = x;
delay(100);
stop:
delay(500);
}