Every 1 day my arduino go offline and i need to reset hardware. I think i made a mystake. I don’t understand. I can Ping my arduino without problem. Help me and sorry for my bad English
Can you tell us more about the total hardware setup you use? Is it Wifi, ethernet, what sketch/code is used?
Yeap. Sketch would be nice.
A solution for this situations is watch dog but mega must be upgraded the bootloader…
Ethernet W5100
I try to upload my sketch
How i can do that? Is it difficult?
/* Allarme e controllo temperatura con display e collegamento ethernet, Arduino MEGA 2560
*/
#include <String.h>
#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h>
#include <MFRC522.h>
#include <ModbusRtu.h>
#include <SD.h>
#include <RTClib.h>
#include <EthernetUdp.h>
#include <Flash.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <Adafruit_FT6206.h>
#include <Wire.h>
#include <DHT22.h>
#include "EmonLib.h" // Include Emon Library
#include <BlynkSimpleEthernet.h> // Blynk library
#include <BlynkApiArduino.h>
#include <SimpleTimer.h>
// Enable serial print debug message
//#define DEBUG 1
//#define DEBUG_RFID 1
//#define DEBUG_MYSQL 1
//#define CRONO_DEBUG 1
//#define DEBUG_MODBUS 1
//#define DEBUG_EMONCMS 1
//#define BLYNK_PRINT Serial // Enables Serial Monitor
// definizione PIN
byte currentSensorPin = A2; // pin pinza amperometrica
byte PIN_TX = 3; // TX RS485
byte SD_CS = 4; // pin 4 is the SPI select pin for the SDcard
#define DHT22_PIN 7 // pin7 per input dati DHT22 locale
// 18 TX1 ModBus
// 19 RX1 ModBus
byte pin_RFID_ok = 23; // serve per abilitare RFID con W5100 (non toccare) e NON COLLEGARE
byte releCaldaia = 24; // Caldaia
byte releSirena = 25; // Sirena
byte pin_systemON = 26; // NON COLLEGARE --- SERVE SOLO PER PASSAGGIO DATI AL WEBSERVER TRAMITE LA VARIABILE "systemON"
#define RST_PIN 31 // RFID
byte TFT_CLK = 34;
byte TFT_MISO = 35;
byte TFT_MOSI = 36;
byte TFT_CS = 37;
byte TFT_DC = 38;
byte TFT_RST = 39; // non collegato
byte SD_non_toccare = 53; // serve per abilitare scheda SD nella EthernetShield (non toccare)
#define SS_PIN 53 // RFID
//Blynk definizione server
SimpleTimer timer_blynk;
char auth[] = "................."; // Blynk token - locale
IPAddress BlynkServer(192, 168, 1, 92);
// Create an Emon instance e configuration
EnergyMonitor emon1;
char emon_server[] = "emoncms.org"; // name address for emoncms.org
#define serverPort 80 //porta di connessione
String apikey = "................"; //api key per server remoto
int node = 0; //if 0, not used
const float ct_calibration = 26.6; // era 29 nuova_calibrazione = (lettura_corretta / lettura_arduino) * attuale_calibrazione
float power = 0;
int power_old = 10; // all'inizio devono essere diversi
const byte volt = 220;
// TFT TOUCH Adafruit. Collegare anche SDA e SCL !!!!!!!!!!!!!!!!!
#define PENRADIUS 3
#define TS_MAXX 240 // Imposto variabile massima ascissa X
#define TS_MINX 0 // Imposto variabile minima ascissa X
#define TS_MAXY 320 // Imposto variabile massima ascissa Y
#define TS_MINY 0 // Imposto variabile minima ascissa Y
#define MINPRESSURE 5 // Imposto il minimo della presssione
#define MAXPRESSURE 2000 // Imposto il massimo della pressione
#define BANDA_INF_X 0 // Imposto la coordinata X banda inferiore
#define BANDA_INF_Y 200 // Imposto la coordinata Y banda inferiore
#define BANDA_INF_LUNG 320 // lunghezza banda inferiore
#define BANDA_INF_LARG 40 // larghezza banda inferiore
#define BANDA_SUP_X 0 // Imposto banda superiore
#define BANDA_SUP_Y 0
#define BANDA_SUP_LUNG 320
#define BANDA_SUP_LARG 20
#define BANDA_IMPOSTA_X 5 // Banda per sottomenu imposta
#define BANDA_IMPOSTA_Y 25
#define BANDA_IMPOSTA_LUNG 310
#define BANDA_IMPOSTA_LARG 160
#define BANDA_IMPOSTA_RADIUS 1
#define SETTING_X 0 // posizione ingranaggi
#define SETTING_Y 120
#define SETTING_DIM_X 80
#define SETTING_DIM_Y 80
#define ALTRI_DATI_X 80
#define ALTRI_DATI_Y 120
#define ALTRI_DATI_X 80
#define ALTRI_DATI_Y 80
#define ALARM_ONOFF_X 160 // posizione simbolo allarme on/off
#define ALARM_ONOFF_Y 120
#define ALARM_ONOFF_DIM_X 80
#define ALARM_ONOFF_DIM_Y 80
#define SIRENA_X 240 // posizione sirena se suona
#define SIRENA_Y 120
#define SIRENA_DIM_X 80
#define SIRENA_DIM_Y 80
#define FIAMMA_X 150 // posizione simbolo fiamma
#define FIAMMA_Y 25
#define FIAMMA_DIM_X 50
#define FIAMMA_DIM_Y 54
#define CENTRO_CELSIUS_X 136 // Imposto posizione centro grado celsius
#define CENTRO_CELSIUS_Y 33
#define RAGGIO_CELSIUS 7
#define MANO_X 202 // Imposto posizione automatico/manuale
#define MANO_Y 25
#define MANO_DIM_X 50
#define MANO_DIM_Y 54
#define INV_EST_X 254 // Imposto posizione inverno/estate
#define INV_EST_Y 25
#define INV_EST_DIM_X 50
#define INV_EST_DIM_Y 54
#define Q_TEMP_X 5 // Imposto quadrato temperatura e umidita
#define Q_TEMP_Y 25
#define Q_TEMP_LUNG 140
#define Q_TEMP_LARG 65
#define Q_TEMP_RADIUS 1
#define Q_POWER_X 5 // Imposto quadrato Kw
#define Q_POWER_Y 90
#define Q_POWER_LUNG 140
#define Q_POWER_LARG 20
#define Q_POWER_RADIUS 1
#define BANDA_TEMPSOGLIA_X 150 // Imposto banda per indicazione temperatura di soglia impostata
#define BANDA_TEMPSOGLIA_Y 85
#define BANDA_TEMPSOGLIA_LUNG 165
#define BANDA_TEMPSOGLIA_LARG 20
#define BANDA_TEMPSOGLIA_RADIUS 1
#define TEXTSIZE_BANDE 2 // altezza font scrittura per Banda SUP e INF
#define TEXTSIZE_TEMP 4
#define TEXTSIZE_UMID 3
#define TEXTSIZE_KW 2
#define TEXTSIZE_IMPOSTA 3
#define TEXTSIZE_TEXT 1
boolean menu = true;
int submenu = 0;
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
// The FT6206 uses hardware I2C (SCL/SDA)
Adafruit_FT6206 ctp = Adafruit_FT6206();
// definizione variabili per Multitasking
unsigned long previousMillis_DateTime = 0; // registra il precedente cambio stato - update linea ora/data
unsigned long previousMillis_W = 0; // registra il precedente cambio stato - update W
unsigned long previousMillis_EmonCMS = 0; // registra il precedente cambio stato - update EMONCMS
unsigned long previousMillis_TempUmid = 0; // registra il precedente cambio stato - update Temperatura e umidita
unsigned long previousMillis_Fiamma = 0; //// registra il precedente cambio stato - update Fiamma
// setting DHT22 e definisce l'istruzione, il pin e' settato assieme ali altri
DHT22 myDHT22(DHT22_PIN); // setup DHT22
float temp_locale = 0;
float h_locale = 0;
int temp_int_locale;
int temp_float_locale;
int h_int_locale;
int h_float_locale;
// definizione variabili per temperatura e cronotermostato
String strURL = "";
float temp_remoto = 0;
float h_remoto = 0;
float temp_remoto_int;
float temp_remoto_float;
float h_remoto_int;
float h_remoto_float;
boolean CronotermostatoAutomatico = true;
boolean CronotermostatoAutomaticoHOLD = true;
boolean Caldaia = false;
float temp_soglia = 18;
float temp_sogliaHOLD = 0; // memorizza lo stato e serve per fare il confronto in caso di cambio stato, alla partenza sono diversi
float isteresi = 0.2;
char INV_EST = 'E'; // definizione stagione
char INV_EST_HOLD = 'I'; // memorizza stagione attuale per non ricaricare sempre immagine
byte actualTime_soglia = 0; // memorizza l'ora di soglia attuale per non ricaricare sempre il file
byte actualTime;
// definizione variabili per sistema allarme
boolean systemON = false;
boolean systemON_HOLD = true;
boolean ok_RFID = false;
//boolean SirenaON = false;
int eventoAllarme = 0;
int eventoAllarmeHOLD = 0;
//boolean ReleSirena = false;
//boolean ReleSirenaHOLD = true;
// NTP
unsigned int localPort = 8888; // local port to listen for UDP packets
IPAddress timeServer(193, 204, 114, 232); //INRiM (Istituto Nazionale di Ricerca Metereologica
//IPAddress timeServer(192, 43, 244, 18); // time.nist.gov NTP server
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte pb[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
const long timeZoneOffset = +3600L; // GMT+1 Italy
EthernetUDP Udp; // A UDP instance to let us send and receive packets over UDP
// RTC real time clock
RTC_DS1307 RTC;
int lastTime = -1; // ultimo Sync RTC
int day_of_the_week = 0; // numero giorno settimana
// RFID
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
long uno = 696; // rappresenta la somma delle 4 cifre
int due = 450;
int codiciAutorizzati[] = {
432, 763
}; // aggiungere la 763 contiene i codici autorizzati
/**
* Modbus object declaration
* u8id : node id = 0 for master, = 1..247 for slave
* u8serno : serial port (use 0 for Serial)
* u8txenpin : 0 for RS-232 and USB-FTDI
* or any pin number > 1 for RS-485
*/
uint16_t au16data[16]; //!< data array for modbus network sharing
uint16_t au16data_output[16];
uint8_t u8state_id; //!< machine state
uint8_t u8query_id; //!< pointer to message query
#define ID 0
#define SERIAL_PORT 1
#define SLAVE_SENSORI 1
Modbus master(ID, SERIAL_PORT, PIN_TX);
modbus_t telegram[2];
modbus_t telegram_output[2];
unsigned long u32wait;
// setting ethernet card
byte mac[] = { 0x98, 0x4F, 0xEE, 0x00, 0x77, 0xA2 };
byte ip[] = { 192, 168, 1, 20};
byte gateway[] = { 192, 168, 1, 1};
byte dns1[] = { 192, 168, 1, 1};
EthernetClient client;
boolean has_filesystem = true;
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;
boolean has_ip_address = false;
const char* ip_to_str(const uint8_t* ipAddr)
{
static char buf[16];
sprintf(buf, "%d.%d.%d.%d\0", ipAddr[0], ipAddr[1], ipAddr[2], ipAddr[3]);
return buf;
}
void send_power_blynk()
{
Blynk.virtualWrite(V1, power);
}
void send_temp_blynk()
{
Blynk.virtualWrite(V2, temp_locale);
Blynk.virtualWrite(V3, h_locale);
Blynk.virtualWrite(V4, temp_remoto);
Blynk.virtualWrite(V5, CronotermostatoAutomatico);
WidgetLED led1(V6);
if (Caldaia)
led1.on();
else
led1.off();
WidgetLED led2(V7);
if (systemON)
led2.on();
else
led2.off();
WidgetLED led3(V8);
if (digitalRead(releSirena))
led3.on();
else
led3.off();
}
bool isFirstConnect_blynk = true;
BLYNK_CONNECTED() {
if (isFirstConnect_blynk) {
Blynk.syncAll();
isFirstConnect_blynk = false;
}
}
BLYNK_WRITE(V5)
{
int i = param.asInt();
if (i == 1)
CronotermostatoAutomatico = true;
else
CronotermostatoAutomatico = false;
}
BLYNK_WRITE(V0)
{
int sliderValue = param.asInt();
temp_soglia = sliderValue/10;
}
void BlynkNotifyAllarme(boolean sirena, int sensore)
{
if (sirena)
Blynk.notify(String("Allarme! Sensore: ")+ sensore);
}
// !!!!!!!!!!!!! inizio programmi SETUP e LOOP !!!!!!!!!!!!!!!!!!!!!!
void setup()
{
Serial.begin(115200);
Serial << F("Free RAM: ") << FreeRam() << "\n";
pinMode(releSirena, OUTPUT);
pinMode(releCaldaia, OUTPUT);
digitalWrite(releCaldaia, HIGH); // inverso per normalmente aperto
digitalWrite(releSirena, LOW);
// serve per usare W5100 (ethernet) con RFID
pinMode(pin_RFID_ok, OUTPUT);
digitalWrite(pin_RFID_ok, HIGH);
// Inizializzazione Scheda SD
pinMode(SD_CS, OUTPUT);
digitalWrite(SD_CS, HIGH);
pinMode(SD_non_toccare, OUTPUT);
// inizializzo TFT
tft.begin();
#ifdef DEBUG
if (! ctp.begin(40)) { // pass in 'sensitivity' coefficient
Serial.println("Couldn't start FT6206 touchscreen controller");
while (1);
}
Serial.println("Capacitive touchscreen started");
#endif
reset_tft();
// Inizializzazione Ethernet e scrivo su LCD/Seriale indirizzo IP
#ifdef DEBUG
Serial << F("Setting up the Ethernet card...\n");
#endif
Ethernet.begin(mac, ip, dns1, gateway);
delay(1000);
Serial.print("My IP address: ");
Serial.println(Ethernet.localIP());
Udp.begin(localPort);
delay(500);
//RTC
Wire.begin();
RTC.begin();
if (! RTC.isrunning())
{
#ifdef DEBUG
Serial.println("RTC is NOT running!");
#endif
RTC.adjust(DateTime(__DATE__, __TIME__));
}
lastTime = ntp(lastTime); // aggiorno orario con NTP
#ifdef DEBUG
Serial << F("Setting up SD card...\n");
#endif
// Pass over the speed and Chip select for the SD card
if (!card.init(SPI_HALF_SPEED, SD_CS)) {
#ifdef DEBUG
Serial << F("card failed\n");
#endif
has_filesystem = false;
}
// initialize a FAT volume.
if (!volume.init(&card)) {
#ifdef DEBUG
Serial << F("vol.init failed!\n");
#endif
has_filesystem = false;
}
if (!root.openRoot(&volume)) {
#ifdef DEBUG
Serial << F("openRoot failed\n");
#endif
has_filesystem = false;
}
// RDFID
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
// Start the web server.
#ifdef DEBUG
Serial << F("Web server starting...\n");
#endif
web.begin();
#ifdef DEBUG
Serial << F("Ready to accept HTTP requests.\n\n");
#endif
/* ModBus Telegram
*
*
*/
// telegram 0: read registers
telegram[0].u8id = SLAVE_SENSORI; // slave address
telegram[0].u8fct = 3; // function code (this one is registers read)
telegram[0].u16RegAdd = 1; // start address in slave
telegram[0].u16CoilsNo = 7; // number of elements (coils or registers) to read
telegram[0].au16reg = au16data; // pointer to a memory array in the Arduino
// telegram 1: write a single register
telegram[1].u8id = SLAVE_SENSORI; // slave address
telegram[1].u8fct = 6; // function code (this one is write a single register)
telegram[1].u16RegAdd = 4; // start address in slave
telegram[1].u16CoilsNo = 1; // number of elements (coils or registers) to read
telegram[1].au16reg = au16data + 4; // pointer to a memory array in the Arduino
master.begin(57600); // baud-rate
master.setTimeOut(2500); // if there is no answer in 5000 ms, roll over
u32wait = millis() + 100;
u8state_id = u8query_id = 0;
// Emoncms
emon1.current(currentSensorPin, ct_calibration);
// inizializza lettore temperatura
myDHT22.readData();
delay(500);
// disegna tft
sfondo_tft();
// attiva Blynk
Blynk.begin(auth, BlynkServer);
#ifdef DEBUG
Serial.print(Blynk.connect());
#endif
Blynk.notify("Sistema attivo");
timer_blynk.setInterval(30000, send_temp_blynk);
timer_blynk.setInterval(15000, send_power_blynk);
timer_blynk.setInterval(60000L, BlynkNotifyAllarme);
}
void loop()
{
Blynk.run();
timer_blynk.run();
byte exit = 0;
lastTime = ntp(lastTime); // aggiornamento RCT via NTP
Controllo_TFT();
ok_RFID = controllo_accesso();
systemON = ins_dis_allarme(ok_RFID, systemON);
ioportsStatus[actualread] = digitalRead(ioports[actualread]);
actualread++;
if (actualread >= ioportsnum) {
actualread = 0;
}
do {
switch (u8state_id) {
case 0:
if (millis() > u32wait)
u8state_id++; // wait state
else
exit = 1;
break;
case 1:
master.query( telegram[u8query_id] ); // send query (only once)
u8state_id++;
u8query_id++;
if (u8query_id > 2) u8query_id = 0;
break;
case 2:
master.poll(); // check incoming messages
if (master.getState() == COM_IDLE) {
u8state_id = u8query_id = 0;
u32wait = millis() + 25;
eventoAllarme = au16data[0];
temp_remoto_int = au16data[1];
temp_remoto_float = au16data[2];
temp_remoto = temp_remoto_int + (temp_remoto_float / 100);
h_remoto_int = au16data[3];
h_remoto_float = au16data[4];
h_remoto = h_remoto_int + (h_remoto_float / 100);
exit = 1;
}
break;
}
} while (exit < 1);
Calcolo_WATT();
Dati_temp_locale();
Funzioni_visualizzazione();
UpdateTemp(); // invio dati server emoncms
Cronotermostato(temp_locale);
if (eventoAllarmeHOLD != eventoAllarme || systemON_HOLD != systemON ) {
tft_allarme(eventoAllarme);
GestioneAllarme(systemON, eventoAllarme); // gestione allarme
eventoAllarmeHOLD = eventoAllarme;
systemON_HOLD = systemON;
}
}
void Calcolo_WATT()
{
float Irms = 0;
Irms = emon1.calcIrms(1480);
power = Irms * volt;
#ifdef DEBUG_EMONCMS
Serial.print("Watt: ");
Serial.println(power);
Serial.print("Irms: ");
Serial.println(Irms);
#endif
}
void Dati_temp_locale()
{
myDHT22.readData();
delay(250);
temp_locale = myDHT22.getTemperatureC();
h_locale = myDHT22.getHumidityInt()/10;
}
void Funzioni_visualizzazione()
{
unsigned long interval_DateTime = 60000; // tempo update linea data/ora in millisecondi (60secondi)
unsigned long interval_W = 90000; // tempo update W in millisecondi (90secondi)
unsigned long interval_TempUmid = 60000; // tempo update Temperatura e Umidita in millisecondi (60secondi)
unsigned long currentMillis_DateTime = millis();
unsigned long currentMillis_W = millis();
unsigned long currentMillis_TempUmid = millis();
int power_temp = int(power / 250); // definisce intervallo visualizzazione W
// chiama la funzione di visualizzazione data e ora su tft ogni tempo intervallo (vedere definizione variabili)
if (currentMillis_DateTime - previousMillis_DateTime > interval_DateTime) {
DateTime now = RTC.now();
tft_data_ora(now);
previousMillis_DateTime = currentMillis_DateTime;
}
// funzione visualizzazione consumi W su tft ogni tempo intervallo (vedere definizioni variabili) o cambiamenti di potenza
if ((power_old != power_temp) || (currentMillis_W - previousMillis_W > interval_W)) {
tft_power();
power_old = power_temp;
previousMillis_W = currentMillis_W;
}
// chiama la funzione di visualizzazione temperatura su tft ogni tempo intervallo (vedere definizione variabili)
if (currentMillis_TempUmid - previousMillis_TempUmid > interval_TempUmid) {
tft_temp_umid();
previousMillis_TempUmid = currentMillis_TempUmid;
}
// cambia immagine inverno/estate se cambiato immagine
if (INV_EST_HOLD != INV_EST) {
if (INV_EST == 'E')
bmpDraw("sole.bmp", INV_EST_X, INV_EST_Y);
if (INV_EST == 'I')
bmpDraw("neve.bmp", INV_EST_X, INV_EST_Y);
INV_EST_HOLD = INV_EST;
}
if (temp_sogliaHOLD != temp_soglia) {
tft_manual_auto();
temp_sogliaHOLD = temp_soglia;
}
}
void Controllo_TFT()
{
if (ctp.touched()) {
TS_Point p = ctp.getPoint();
p.x = map(p.x, TS_MINX, TS_MAXX, 0, 240);
p.y = map(p.y, TS_MINY, TS_MAXY, 320, 0);
int coord_y = p.x;
int coord_x = p.y;
if (coord_x > SETTING_X && coord_x < (SETTING_X + SETTING_DIM_X) && coord_y > SETTING_Y && coord_y < (SETTING_Y + SETTING_DIM_Y)) {
imposta();
}
if (coord_x > MANO_X && coord_x < (MANO_X + MANO_DIM_X) && coord_y > MANO_Y && coord_y < (MANO_Y + MANO_DIM_Y)) {
if (CronotermostatoAutomatico) {
bmpDraw("mano_on.bmp", MANO_X, MANO_Y);
CronotermostatoAutomatico = false;
}
else {
bmpDraw("mano_off.bmp", MANO_X, MANO_Y);
CronotermostatoAutomatico = true;
}
}
}
}
void GestioneAllarme(boolean sistema_inserito, int evento)
{
tft.setTextSize(TEXTSIZE_BANDE);
switch (sistema_inserito) {
case 0:
tft.fillRect(SIRENA_X, SIRENA_Y, SIRENA_DIM_X, SIRENA_DIM_Y, ILI9341_BLACK);
tft.fillRect(BANDA_INF_X, BANDA_INF_Y, BANDA_INF_LUNG, BANDA_INF_LARG, ILI9341_BLACK);
digitalWrite(releSirena, LOW);
break;
case 1:
if (evento == 0) {
tft.fillRect(SIRENA_X, SIRENA_Y, SIRENA_DIM_X, SIRENA_DIM_Y, ILI9341_BLACK);
tft.fillRect(BANDA_INF_X, BANDA_INF_Y, BANDA_INF_LUNG, BANDA_INF_LARG, ILI9341_BLACK);
digitalWrite(releSirena, LOW);
}
else {
bmpDraw("sirena.bmp", SIRENA_X, SIRENA_Y);
tft.fillRect(BANDA_INF_X, BANDA_INF_Y, BANDA_INF_LUNG, BANDA_INF_LARG, ILI9341_BLACK);
tft.setCursor(BANDA_INF_X + 1, BANDA_INF_Y + 1);
tft.print("Allarme INSERITO");
tft.setCursor(BANDA_INF_X + 1, BANDA_INF_Y + 21);
tft.print("DISINSERIRE TOCCANDO ICONA");
sistema_inserito = waitfor_input_RFID(sistema_inserito);
if (sistema_inserito) {
digitalWrite(releSirena, HIGH);
BlynkNotifyAllarme(digitalRead(releSirena), evento);
}
else {
tft.fillRect(BANDA_INF_X, BANDA_INF_Y, BANDA_INF_LUNG, BANDA_INF_LARG, ILI9341_BLACK);
tft.fillRect(SIRENA_X, SIRENA_Y, SIRENA_DIM_X, SIRENA_DIM_Y, ILI9341_BLACK);
digitalWrite(releSirena, LOW);
}
}
break;
}
}
void UpdateTemp()
{
unsigned long interval_EmonCMS = 15000; // tempo update EmonCMS in millisecondi (15secondi)
unsigned long currentMillis_EmonCMS = millis();
if (currentMillis_EmonCMS - previousMillis_EmonCMS > interval_EmonCMS) {
if (client.connect(emon_server, serverPort)) {
Serial.println("Connecting...");
// send the HTTP GET request:
client.print("GET /api/post?apikey=");
client.print(apikey);
if (node > 0) {
client.print("&node=");
client.print(node);
}
client.print("&json={power");
client.print(":");
client.print(power);
client.print(",temp_locale:");
client.print(temp_locale);
client.print(",umid_locale:");
client.print(h_locale);
client.print(",temp_remoto:");
client.print(temp_remoto);
client.print(",umid_remoto:");
client.print(h_remoto);
client.print(",sens:");
client.print(eventoAllarme);
client.println("} HTTP/1.1");
client.println("Host:emoncms.org");
client.println("User-Agent: Arduino-ethernet");
client.println("Connection: close");
client.println();
previousMillis_EmonCMS = currentMillis_EmonCMS;
}
}
else {
// if you couldn't make a connection:
Serial.println("Connection failed");
Serial.println("Disconnecting...");
client.stop();
}
}
boolean controllo_accesso()
{
boolean ok_accesso = false;
#ifdef DEBUG_RFID
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Avvicinare");
lcd.setCursor(0, 1);
lcd.print("Tessera RFID");
#endif
/* Temporary loop counter */
if (mfrc522.PICC_IsNewCardPresent()) { // Se viene letta una tessera
byte i;
mfrc522.PICC_ReadCardSerial();
int codiceLetto = 0;
tft.setTextSize(TEXTSIZE_BANDE);
tft.fillRect(BANDA_INF_X, BANDA_INF_Y, BANDA_INF_LUNG, BANDA_INF_LARG, ILI9341_BLACK);
tft.setCursor(BANDA_INF_X + 1, BANDA_INF_Y + 1);
tft.print("Tessera: ");
// Viene caricato il codice della tessera, all'interno di una Stringa
for (i = 0; i <= 4; i++) {
codiceLetto += mfrc522.uid.uidByte[i];
}
#ifdef DEBUG_RFID
Serial.println(codiceLetto);
#endif
tft.print(codiceLetto);
if (verificaCodice(codiceLetto)) {
#ifdef DEBUG_RFID
Serial.println("Tessera autorizzata");
#endif
tft.print(" Autorizzato");
ok_accesso = true;
}
else {
#ifdef DEBUG_RFID
Serial.println("Tessera non autorizzata");
#endif
tft.print(" NON autorizzato");
ok_accesso = false;
}
delay(300);
}
return ok_accesso;
}
boolean verificaCodice(int codiceLetto) // Questa funzione verifica se il codice Letto è autorizzato
{
boolean autorizzato = false;
for (int i = 0; i < sizeof(codiciAutorizzati) ; i++) {
if (codiceLetto == codiciAutorizzati[i]) {
autorizzato = true;
}
}
return autorizzato;
}
boolean ins_dis_allarme(boolean ok_RFID, boolean systemON)
{
tft.setTextSize(TEXTSIZE_BANDE);
if (ok_RFID) {
tft.fillRect(BANDA_INF_X, BANDA_INF_Y, BANDA_INF_LUNG, BANDA_INF_LARG, ILI9341_BLACK);
tft.setCursor(BANDA_INF_X + 1, BANDA_INF_Y + 1);
if (systemON) {
tft.print("Allarme INSERITO");
tft.setCursor(BANDA_INF_X + 1, BANDA_INF_Y + 21);
tft.print("DISINSERIRE TOCCANDO ICONA");
systemON = waitfor_input_RFID(systemON);
tft.fillRect(BANDA_INF_X, BANDA_INF_Y, BANDA_INF_LUNG, BANDA_INF_LARG, ILI9341_BLACK);
}
else {
tft.print("Allarme DISINSERITO");
tft.setCursor(BANDA_INF_X + 1, BANDA_INF_Y + 21);
tft.print("INSERIRE TOCCANDO ICONA");
systemON = waitfor_input_RFID(systemON);
tft.fillRect(BANDA_INF_X, BANDA_INF_Y, BANDA_INF_LUNG, BANDA_INF_LARG, ILI9341_BLACK);
}
}
digitalWrite(pin_systemON, systemON);
return systemON;
}
boolean waitfor_input_RFID(boolean sistema_inserito)
{
unsigned long startingTime; //used to store the starting moment
boolean touch = false; //used to know if the user has touch the screen
const unsigned long timeout = 30000;
//loop
startingTime = millis();
do {
if (ctp.touched()) {
touch = true;
break;
}
} while ((!touch) && ((millis() - startingTime) < timeout));
if (touch) {
TS_Point p = ctp.getPoint();
p.x = map(p.x, TS_MINX, TS_MAXX, 0, 240);
p.y = map(p.y, TS_MINY, TS_MAXY, 320, 0);
int coord_y = p.x;
int coord_x = p.y;
if (coord_x > ALARM_ONOFF_X && coord_x < ALARM_ONOFF_X + ALARM_ONOFF_DIM_X && coord_y > ALARM_ONOFF_Y && coord_y < ALARM_ONOFF_Y + ALARM_ONOFF_DIM_Y) {
if (sistema_inserito) {
bmpDraw("alm_off.bmp", ALARM_ONOFF_X, ALARM_ONOFF_Y);
sistema_inserito = false;
}
else {
bmpDraw("alm_on.bmp", ALARM_ONOFF_X, ALARM_ONOFF_Y);
sistema_inserito = true;
}
}
}
//else {
// systemON = sistema_inserito; // lascia lo stato attuale
//}
return sistema_inserito;
}
void tft_allarme(int evento)
{
if (evento != 0) {
tft.fillRect(BANDA_INF_X, BANDA_INF_Y, BANDA_INF_LUNG, BANDA_INF_LARG, ILI9341_BLACK);
tft.setCursor(BANDA_INF_X + 1, BANDA_INF_Y + 1);
tft.setTextColor(ILI9341_RED);
tft.setTextSize(TEXTSIZE_BANDE);
tft.print("Apertura finestra/porta");
tft.setCursor(BANDA_INF_X + 1, BANDA_INF_Y + 21);
}
switch (evento) {
case 1: {
tft.print("MAGNETICO 1");
break;
}
case 2: {
tft.print("MAGNETICO 2");
break;
}
case 3: {
tft.print("MAGNETICO 3");
break;
}
case 4: {
tft.print("MAGNETICO 4");
break;
}
case 5: {
tft.print("MAGNETICO 5");
break;
}
case 6: {
tft.print("MAGNETICO 6");
break;
}
case 7: {
tft.print("MAGNETICO 7");
break;
}
case 20: {
tft.print("SENSORE PIR 1");
break;
}
case 21: {
tft.print("SENSORE PIR 2");
break;
}
}
}
Second part:
void tft_data_ora(DateTime now)
{
tft.setTextColor(ILI9341_WHITE); // risetta il colore standard delle scritte
tft.setTextSize(TEXTSIZE_BANDE); // risetta l'altezza del font
tft.fillRect(BANDA_SUP_X, BANDA_SUP_Y, BANDA_SUP_LUNG, BANDA_SUP_LARG, ILI9341_BLACK);
tft.setCursor(1, 1);
switch (day_of_the_week) {
case 0:
tft.print("Domenica ");
break;
case 1:
tft.print("Lunedi' ");
break;
case 2:
tft.print("Martedi' ");
break;
case 3:
tft.print("Mercoledi' ");
break;
case 4:
tft.print("Giovedi' ");
break;
case 5:
tft.print("Venerdi' ");
break;
case 6:
tft.print("Sabato ");
break;
}
tft.print(now.day(), DEC);
tft.print('/');
tft.print(now.month(), DEC);
tft.print('/');
tft.print(now.year(), DEC);
tft.print(' ');
tft.print(now.hour(), DEC);
tft.print(':');
tft.print(now.minute(), DEC);
}
void tft_temp_umid()
{
tft.setTextColor(ILI9341_WHITE); // risetta il colore standard delle scritte
tft.setTextSize(TEXTSIZE_BANDE); // risetta l'altezza del font
tft.fillRoundRect(Q_TEMP_X, Q_TEMP_Y, Q_TEMP_LUNG, Q_TEMP_LARG, Q_TEMP_RADIUS, ILI9341_BLACK); // Disegno il quadrato temperatura interna e umidita
tft.setCursor(Q_TEMP_X + 2, Q_TEMP_Y + 2);
tft.setTextSize(TEXTSIZE_TEMP);
tft.print(temp_locale);
tft.fillCircle(CENTRO_CELSIUS_X, CENTRO_CELSIUS_Y, RAGGIO_CELSIUS, ILI9341_WHITE);
tft.setTextSize(TEXTSIZE_UMID);
tft.setCursor(Q_TEMP_X + 2, Q_TEMP_Y + 38);
tft.print(int(h_locale));
tft.print("%RH");
}
void tft_power()
{
tft.setTextColor(ILI9341_WHITE); // risetta il colore standard delle scritte
tft.setTextSize(TEXTSIZE_KW); // risetta l'altezza del font
tft.fillRoundRect(Q_POWER_X, Q_POWER_Y, Q_POWER_LUNG, Q_POWER_LARG, Q_POWER_RADIUS, ILI9341_BLACK); // Disegno il quadrato temperatura interna e umidita
tft.setCursor(Q_POWER_X + 2, Q_POWER_Y + 2);
tft.print("Kw: ");
tft.print(power);
}
void tft_manual_auto()
{
tft.setTextColor(ILI9341_WHITE); // risetta il colore standard delle scritte
tft.setTextSize(TEXTSIZE_BANDE); // risetta l'altezza del font
tft.fillRoundRect(BANDA_TEMPSOGLIA_X, BANDA_TEMPSOGLIA_Y, BANDA_TEMPSOGLIA_LUNG, BANDA_TEMPSOGLIA_LARG, BANDA_TEMPSOGLIA_RADIUS, ILI9341_BLACK);
tft.setCursor(BANDA_TEMPSOGLIA_X + 2, BANDA_TEMPSOGLIA_Y + 2);
tft.print("Soglia: ");
tft.print(temp_soglia);
}
int ntp(int lastTime)
{
DateTime now = RTC.now();
int time = now.day();
#ifdef DEBUG
Serial.println(time);
Serial.println(lastTime);
#endif
if (abs(time - lastTime) > 1) {
sendNTPpacket(timeServer); // send an NTP packet to a time server
delay(1000); // wait to see if a reply is available
if (Udp.parsePacket());
{
Serial.println(Udp.read(pb, NTP_PACKET_SIZE)); // read the packet into the buffer
unsigned long t1, t2, t3, t4;
t1 = t2 = t3 = t4 = 0;
for (int i = 0; i < 4; i++) {
t1 = t1 << 8 | pb[16 + i];
t2 = t2 << 8 | pb[24 + i];
t3 = t3 << 8 | pb[32 + i];
t4 = t4 << 8 | pb[40 + i];
}
// part of the fractional part could be 4 bytes but this is more precise than the 1307 RTC
// which has a precision of ONE second in fact one byte is sufficient for 1307
float f1, f2, f3, f4;
f1 = ((long)pb[20] * 256 + pb[21]) / 65536.0;
f2 = ((long)pb[28] * 256 + pb[29]) / 65536.0;
f3 = ((long)pb[36] * 256 + pb[37]) / 65536.0;
f4 = ((long)pb[44] * 256 + pb[45]) / 65536.0;
// NOTE:
// one could use the fractional part to set the RTC more precise
// 1) at the right (calculated) moment to the NEXT second!
// t4++;
// delay(1000 - f4*1000);
// RTC.adjust(DateTime(t4));
// keep in mind that the time in the packet was the time at
// the NTP server at sending time so one should take into account
// the network latency (try ping!) and the processing of the data
// ==> delay (850 - f4*1000);
// 2) simply use it to round up the second
// f > 0.5 => add 1 to the second before adjusting the RTC
// (or lower threshold eg 0.4 if one keeps network latency etc in mind)
// 3) a SW RTC might be more precise, => ardomic clock :)
// convert NTP to UNIX time, differs seventy years = 2208988800 seconds
// NTP starts Jan 1, 1900 - Unix time starts on Jan 1 1970.
const unsigned long seventyYears = 2208988800UL;
t1 -= seventyYears;
t2 -= seventyYears;
t3 -= seventyYears;
t4 -= seventyYears;
#ifdef DEBUG
Serial.println("T1 .. T4 && fractional parts");
PrintDateTime(DateTime(t1)); Serial.println(f1, 4);
PrintDateTime(DateTime(t2)); Serial.println(f2, 4);
PrintDateTime(DateTime(t3)); Serial.println(f3, 4);
#endif
PrintDateTime(DateTime(t4));
// Adjust timezone and DST... in my case CET and DST?
if (IsDST(now.day(), now.month(), now.dayOfWeek()))
t4 += (2 * 3600L);
else
t4 += (1 * 3600L); // Notice the L for long calculations!!
t4 += 1; // adjust the delay(1000) at begin of loop!
if (f4 > 0.4) t4++; // adjust fractional part, see above
RTC.adjust(DateTime(t4));
long day = t4 / 86400L;
day_of_the_week = (day + 4) % 7;
#ifdef DEBUG
Serial.println("RTC synced");
Serial.print("Giorno della settimana: ");
Serial.println(day_of_the_week);
#endif
}
lastTime = time;
}
return lastTime;
}
unsigned long sendNTPpacket(IPAddress& address)
{
// set all bytes in the buffer to 0
memset(pb, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request (see URL above for details on the packets)
pb[0] = 0b11100011; // LI, Version, Mode
pb[1] = 0; // Stratum, or type of clock
pb[2] = 6; // Polling Interval
pb[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
pb[12] = 49;
pb[13] = 0x4E;
pb[14] = 49;
pb[15] = 52;
// all NTP fields have been given values, now you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(pb, NTP_PACKET_SIZE);
Udp.endPacket();
}
void PrintDateTime(DateTime t)
{
char datestr[24];
sprintf(datestr, "%04d-%02d-%02d %02d:%02d:%02d ", t.year(), t.month(), t.day(), t.hour(), t.minute(), t.second());
Serial.print(datestr);
}
boolean IsDST(int dayVal, int monthVal, int dow)
{
//January, february, and december are out.
if (monthVal < 3 || monthVal > 10) {
return false;
}
//April to October are in
if (monthVal > 3 && monthVal < 11) {
return true;
}
int previousSunday = dayVal - dow;
//In march, we are DST if our previous sunday was on or after the 8th.
if (monthVal == 3) {
return previousSunday >= 24; // era 8
}
//In november we must be before the first sunday to be dst.
//That means the previous sunday must be before the 1st.
return previousSunday <= 0;
}
void sfondo_tft() // Imposto lo sfondo del menu' principale
{
bmpDraw("cielo.bmp", 0, 0);
tft.fillRect(BANDA_SUP_X, BANDA_SUP_Y, BANDA_SUP_LUNG, BANDA_SUP_LARG, ILI9341_BLACK); // Disegno la banda nera superiore
tft.fillRoundRect(Q_TEMP_X, Q_TEMP_Y, Q_TEMP_LUNG, Q_TEMP_LARG, Q_TEMP_RADIUS, ILI9341_BLACK); // Disegno il quadrato temperatura interna e umidita
tft.fillRect(BANDA_INF_X, BANDA_INF_Y, BANDA_INF_LUNG, BANDA_INF_LARG, ILI9341_BLACK); // Disegno la banda nera inferiore
tft.fillRoundRect(Q_POWER_X, Q_POWER_Y, Q_POWER_LUNG, Q_POWER_LARG, Q_POWER_RADIUS, ILI9341_BLACK);
tft.fillRoundRect(BANDA_TEMPSOGLIA_X, BANDA_TEMPSOGLIA_Y, BANDA_TEMPSOGLIA_LUNG, BANDA_TEMPSOGLIA_LARG, BANDA_TEMPSOGLIA_RADIUS, ILI9341_BLACK);
bmpDraw("setting.bmp", SETTING_X, SETTING_Y);
bmpDraw("fire_off.bmp", FIAMMA_X, FIAMMA_Y);
if (CronotermostatoAutomatico)
bmpDraw("mano_off.bmp", MANO_X, MANO_Y);
else
bmpDraw("mano_on.bmp", MANO_X, MANO_Y);
if (INV_EST == 'E')
bmpDraw("sole.bmp", INV_EST_X, INV_EST_Y);
else
bmpDraw("neve.bmp", INV_EST_X, INV_EST_Y);
bmpDraw("alm_off.bmp", ALARM_ONOFF_X, ALARM_ONOFF_Y);
temp_sogliaHOLD = 0;
}
void bmpDraw(char *filename, uint8_t x, uint16_t y) {
File bmpFile;
int bmpWidth, bmpHeight; // W+H in pixels
uint8_t bmpDepth; // Bit depth (currently must be 24)
uint32_t bmpImageoffset; // Start of image data in file
uint32_t rowSize; // Not always = bmpWidth; may have padding
uint8_t sdbuffer[3 * 40]; // pixel buffer (R+G+B per pixel) originale 3*20
uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer
boolean goodBmp = false; // Set to true on valid header parse
boolean flip = true; // BMP is stored bottom-to-top
int w, h, row, col;
uint8_t r, g, b;
uint32_t pos = 0, startTime = millis();
if ((x >= tft.width()) || (y >= tft.height())) return;
Serial.println();
Serial.print(F("Loading image '"));
Serial.print(filename);
Serial.println('\'');
SD.begin(SD_CS);
// Open requested file on SD card
if ((bmpFile = SD.open(filename)) == NULL) {
Serial.print(F("File not found"));
return;
}
// Parse BMP header
if (read16(bmpFile) == 0x4D42) { // BMP signature
Serial.print(F("File size: ")); Serial.println(read32(bmpFile));
(void)read32(bmpFile); // Read & ignore creator bytes
bmpImageoffset = read32(bmpFile); // Start of image data
Serial.print(F("Image Offset: ")); Serial.println(bmpImageoffset, DEC);
// Read DIB header
Serial.print(F("Header size: ")); Serial.println(read32(bmpFile));
bmpWidth = read32(bmpFile);
bmpHeight = read32(bmpFile);
if (read16(bmpFile) == 1) { // # planes -- must be '1'
bmpDepth = read16(bmpFile); // bits per pixel
Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth);
if ((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed
goodBmp = true; // Supported BMP format -- proceed!
Serial.print(F("Image size: "));
Serial.print(bmpWidth);
Serial.print('x');
Serial.println(bmpHeight);
// BMP rows are padded (if needed) to 4-byte boundary
rowSize = (bmpWidth * 3 + 3) & ~3;
// If bmpHeight is negative, image is in top-down order.
// This is not canon but has been observed in the wild.
if (bmpHeight < 0) {
bmpHeight = -bmpHeight;
flip = false;
}
// Crop area to be loaded
w = bmpWidth;
h = bmpHeight;
if ((x + w - 1) >= tft.width()) w = tft.width() - x;
if ((y + h - 1) >= tft.height()) h = tft.height() - y;
// Set TFT address window to clipped image bounds
tft.setAddrWindow(x, y, x + w - 1, y + h - 1);
for (row = 0; row < h; row++) { // For each scanline...
// Seek to start of scan line. It might seem labor-
// intensive to be doing this on every line, but this
// method covers a lot of gritty details like cropping
// and scanline padding. Also, the seek only takes
// place if the file position actually needs to change
// (avoids a lot of cluster math in SD library).
if (flip) // Bitmap is stored bottom-to-top order (normal BMP)
pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
else // Bitmap is stored top-to-bottom
pos = bmpImageoffset + row * rowSize;
if (bmpFile.position() != pos) { // Need seek?
bmpFile.seek(pos);
buffidx = sizeof(sdbuffer); // Force buffer reload
}
for (col = 0; col < w; col++) { // For each pixel...
// Time to read more pixel data?
if (buffidx >= sizeof(sdbuffer)) { // Indeed
bmpFile.read(sdbuffer, sizeof(sdbuffer));
buffidx = 0; // Set index to beginning
}
// Convert pixel from BMP to TFT format, push to display
b = sdbuffer[buffidx++];
g = sdbuffer[buffidx++];
r = sdbuffer[buffidx++];
tft.pushColor(tft.color565(r, g, b));
} // end pixel
} // end scanline
Serial.print(F("Loaded in "));
Serial.print(millis() - startTime);
Serial.println(" ms");
} // end goodBmp
}
}
bmpFile.close();
if (!goodBmp) Serial.println(F("BMP format not recognized."));
bmpFile.close();
}
// These read 16- and 32-bit types from the SD card file.
// BMP data is stored little-endian, Arduino is little-endian too.
// May need to reverse subscript order if porting elsewhere.
uint16_t read16(File &f) {
uint16_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read(); // MSB
return result;
}
uint32_t read32(File &f) {
uint32_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read();
((uint8_t *)&result)[2] = f.read();
((uint8_t *)&result)[3] = f.read(); // MSB
return result;
}
void imposta()
{
menu = true;
submenu = 1;
reset_tft();
menu_imposta();
wait_for_input(submenu);
menu = false;
submenu = 0;
reset_tft();
sfondo_tft();
}
void menu_imposta()
{
tft.setTextSize(TEXTSIZE_IMPOSTA);
tft.fillRoundRect(BANDA_IMPOSTA_X, BANDA_IMPOSTA_Y, BANDA_IMPOSTA_LUNG, BANDA_IMPOSTA_LARG, BANDA_IMPOSTA_RADIUS, ILI9341_BLACK);
tft.setCursor(BANDA_IMPOSTA_X + 1, BANDA_IMPOSTA_Y + 1);
tft.setTextColor(ILI9341_WHITE);
tft.println("Programmazione");
tft.setCursor(BANDA_IMPOSTA_X + 1, BANDA_IMPOSTA_Y +50);
tft.setTextSize(TEXTSIZE_TEXT);
tft.print("Stagione?");
bmpDraw("sole.bmp", BANDA_IMPOSTA_X + 170, BANDA_IMPOSTA_Y + 35);
bmpDraw("neve.bmp", BANDA_IMPOSTA_X + 170 + 50, BANDA_IMPOSTA_Y + 35);
tft.setCursor(BANDA_IMPOSTA_X + 1, BANDA_IMPOSTA_Y + 105);
tft.print("Temperatura?");
bmpDraw("Up.bmp", BANDA_IMPOSTA_X + 100, BANDA_IMPOSTA_Y + 90);
tft.setTextSize(TEXTSIZE_IMPOSTA);
tft.setCursor(BANDA_IMPOSTA_X + 155, BANDA_IMPOSTA_Y + 115);
tft.print(temp_soglia);
bmpDraw("Down.bmp", BANDA_IMPOSTA_X + 100 + 50 + 100, BANDA_IMPOSTA_Y + 90);
}
void wait_for_input(int numero_menu)
{
const unsigned long timeout = 10000; //the timeout in milliseconds
unsigned long startingTime = millis(); //used to store the starting moment
do { //has the user pressed the tft??
if (ctp.touched()) {
TS_Point p = ctp.getPoint();
p.x = map(p.x, TS_MINX, TS_MAXX, 0, 240);
p.y = map(p.y, TS_MINY, TS_MAXY, 320, 0);
int coord_y = p.x;
int coord_x = p.y;
switch (numero_menu) {
case 1:
if (coord_x > BANDA_IMPOSTA_X + 170 && coord_x < BANDA_IMPOSTA_X + 170 + 50 && coord_y > BANDA_IMPOSTA_Y + 35 && coord_y < BANDA_IMPOSTA_Y + 35 +54) INV_EST = 'E';
if (coord_x > BANDA_IMPOSTA_X + 170 + 50 && coord_x < BANDA_IMPOSTA_X + 170 + 50 +50 && coord_y > BANDA_IMPOSTA_Y + 35 && coord_y < BANDA_IMPOSTA_Y + 35 +54) INV_EST = 'I';
if (coord_x > BANDA_IMPOSTA_X + 100 && coord_x < BANDA_IMPOSTA_X + 100 +50 && coord_y > BANDA_IMPOSTA_Y + 90 && coord_y < BANDA_IMPOSTA_Y + 90 +54) {
temp_soglia = temp_soglia + 0.1;
tft.setTextSize(TEXTSIZE_IMPOSTA);
tft.setCursor(BANDA_IMPOSTA_X + 155, BANDA_IMPOSTA_Y + 115);
tft.fillRect(BANDA_IMPOSTA_X + 155, BANDA_IMPOSTA_Y + 105, 75, 40, ILI9341_BLACK);
tft.print(temp_soglia);
}
if (coord_x > BANDA_IMPOSTA_X + 100 + 50 + 100 && coord_x < BANDA_IMPOSTA_X + 100 + 50 + 100 +50 && coord_y > BANDA_IMPOSTA_Y + 90 && coord_y < BANDA_IMPOSTA_Y + 90 +54) {
temp_soglia = temp_soglia - 0.1;
tft.setTextSize(TEXTSIZE_IMPOSTA);
tft.setCursor(BANDA_IMPOSTA_X + 155, BANDA_IMPOSTA_Y + 115);
tft.fillRect(BANDA_IMPOSTA_X + 155, BANDA_IMPOSTA_Y + 105, 75, 40, ILI9341_BLACK);
tft.print(temp_soglia);
}
break;
}
startingTime = millis(); //we reset the initial time
}
} while ((millis() - startingTime) < timeout);
//this loop will only end when the it goes in timeout
}
void Cronotermostato(float temp) // usare rele_caldaia
{
unsigned long interval_Fiamma = 15000; // tempo update Fiamma TFT in millisecondi (15secondi)
unsigned long currentMillis_Fiamma = millis();
boolean temporaneo_caldaia = true;
#ifdef CRONO_DEBUG
Serial.println(temp_soglia);
#endif
if (INV_EST == 'E' && INV_EST_HOLD == 'I') {
bmpDraw("clima.bmp", FIAMMA_X, FIAMMA_Y);
Caldaia = false;
temporaneo_caldaia = true;
digitalWrite(releCaldaia, temporaneo_caldaia);
}
if (CronotermostatoAutomaticoHOLD != CronotermostatoAutomatico && INV_EST == 'I') {
if (CronotermostatoAutomatico) {
bmpDraw("mano_off.bmp", MANO_X, MANO_Y);
bmpDraw("fire_off.bmp", FIAMMA_X, FIAMMA_Y);
Caldaia = false;
temporaneo_caldaia = true;
digitalWrite(releCaldaia, temporaneo_caldaia);
}
else {
bmpDraw("mano_on.bmp", MANO_X, MANO_Y);
Caldaia = false;
temporaneo_caldaia = true;
digitalWrite(releCaldaia, temporaneo_caldaia);
}
CronotermostatoAutomaticoHOLD = CronotermostatoAutomatico;
}
if (!CronotermostatoAutomatico && INV_EST == 'I') {
if (temp < temp_soglia - isteresi) {
Caldaia = true;
temporaneo_caldaia = false;
}
if (temp > temp_soglia + isteresi) {
Caldaia = false;
temporaneo_caldaia = true;
}
if (temp >= temp_soglia - isteresi && temp <= temp_soglia + isteresi) {
Caldaia = true;
temporaneo_caldaia = false;
}
digitalWrite(releCaldaia, temporaneo_caldaia);
//chiama la funzione di visualizzazione FIAMMA su tft ogni tempo intervallo (vedere definizione variabili)
if (currentMillis_Fiamma - previousMillis_Fiamma > interval_Fiamma) {
if (Caldaia)
bmpDraw("fire_on.bmp", FIAMMA_X, FIAMMA_Y);
else
bmpDraw("fire_off.bmp", FIAMMA_X, FIAMMA_Y);
previousMillis_Fiamma = currentMillis_Fiamma;
}
}
}
void reset_tft()
{
digitalWrite(TFT_RST, LOW);
digitalWrite(TFT_RST, HIGH);
tft.setRotation(1);
tft.setCursor(0, 0);
}
@icapelli a guy called Nick Gammon on the Arduino forum has some great stuff for changing to the required bootloader for WTD.
His github is at https://github.com/nickgammon/arduino_sketches and you need the section at Atmega_Board_Programmer
His write up about bootloader stuff is at http://www.gammon.com.au/forum/?id=11635
I bought 50 Nano clones and some had faulty bootloaders and I also needed the Optiboot to use WTD as it is faulty on some Arduinos. His sketches have helped me out on many occasions and just the other day I was trying in vain to upload a sketch to my Leonardo. I didn’t even check if his stuff works with the Leonardo but it was effectively dead so I tried it and it brought it back to life.
I do have one Mega but I haven’t used Nick’s stuff on this device but it looks like he has this covered.
For me as a Nano user there is one important thing to remember and that is after uploading the optiboot my Nano’s are Uno’s i.e. I have to select Uno when uploading sketches. Not sure if Mega stays as a Mega but I suspect it will as is is quite different to all the other Arduinos.
Some useful stuff by Big Dan the Blogging Man at https://bigdanzblog.wordpress.com/2014/10/23/installing-the-optiboot-loader-on-an-arudino-nano-to-fix-the-watch-dog-timer-wdt-issue/ but I needed to use Nick’s sketches for my fix.
I think you send too much data. I see you call all your functions in the loop() part. This is not the most efficient way to do things. I can imagine Blynk is not happy about that.
Have you tried removing the functions and instead calling them with a timer? I’ve made something similar over here: Home Domotics except it’s for lights instead of alarms, but I think the same principles apply. All you want in your main loop is:
void loop()
{
Blynk.run();
timer.run(); // For simple timer or other library you want
}
This should basically be your loop().
A comprehensive sketch and I see you are using an Ethernet shield for your Alarm and Thermostatic Controller.
Difficult for us to pinpoint why you might need to reset the Mega (with WDT or similar) every day.
Are there any patterns to when and why you need to reset?
Is the Mega losing the connection with Blynk or just generally crashing, I am guessing the former as you say you can ping the Mega?
I didn’t look very closely at the sketch as it contains a lot of Italian but yes the main loop should be VERY compact. I guess you wrote the sketch before you found Blynk. The sketch should be fine but the nature of what Blynk is means it needs reorganising as indicated by @Lichtsignaal.