TiDiGino il telecontrollo GSM basato su Arduino: il firmware di Felice Pascarelli


Dopo qualche mese dal lancio del concorso TiDiGino contest, possiamo ora presentare le soluzioni firmware e software arrivate in redazione.

Iniziamo mostrandovi la realizzazione di Felice Pascarelli.

Descrizione Generale

La scheda TiDiGino è una scheda multifunzionale utilizzabile per gestire impianti dicondizionamento temperatura, cancelli automatici, centraline antifurto, controlli domotici etc..
La scheda è dotata delle seguenti caratteristiche:
• Alimentazione 10/15 Vcc protetta da fusibile da Autoripristinabile;
• 2 uscite a relè: possibilità di configurazione funzionamento individuale comemonostabile o bistabile con possibilità di impostare il tempo di commutazione. Impostazione individuale della funzione di ripristino dello stato dei relè dopo un blackout;
• Uscite a relè assegnabili a: funzionalità termostato, apricancello e controllo tramiteDTMF;
• 2 ingressi optoisolati: possibilità di configurazione per rilevamento livello logico iningresso e generazione dei relativi allarmi (allarme livello logico alto, livello logicobasso, variazione di stato livello) o per gestione servo termostato(ingresso 1) e blocco caldaia (ingresso 2). Su ogni ingresso è possibile stabilire un tempo di inibizione tra unallarme e il successivo.
• Funzione termostato di termoregolazione ambiente.  Impostabile come:
o Automatico: impostazione della temperatura da mantenere (0/99°C) con isteresi selezionabile nel range ±1/99°C;
o Manuale: Caldaia controllabile con toni DTMF,
o servo termostato: asservito ad un termostato esterno
• Allarme superamento temperatura. Possibilità di stabilire due soglie nel range 0/99°C: una per superamento temperatura massima(in salita) ed una per superamento temperatura minima(in discesa). Tempo di inibizione tra un allarme ed il successivoimpostabile dal 1 a 99 minuti.
• Comandi impartibili con messaggi SMS o tramite PC connesso alla porta USB.  Nel casodi utilizzo del PC per configurare la scheda è possibile utilizzare Hyper Terminal ol’apposita applicazione “Configuratore TiDiGino V1.0”.
• Memorizzazione di 8 numeri master e 192 numeri apricancello.  Ad ogni numero masterè possibile associare il relativo sistema di notifica degli eventi di allarme: tramite chiamata, tramite SMS o entrambe.
• Possibilità di associare ad ogni SMS di allarme un testo personalizzato.
• Interrogazione tramite SMS dello stato degli ingressi e delle uscite;
• Interrogazione tramite SMS della temperatura ambiente rilevata dal sistema;
• Verifica tramite SMS delle principali impostazioni del sistema;
• Invio tramite SMS al numero master 1 della notifica di accensione del telecontrollo(disattivabile) con possibilità di personalizzazione del testo contenuto nel messaggio;
• Doppia Password personalizzabile: di gestione tramite PC e per invio comandi tramiteSMS;
• Diagnostica in tempo reale dello stato di attivazione dei relè e degli ingressi tramite applicazione “Configuratore TiDiGino V1.0”;
• Visualizzazione in tempo reale della temperatura rilevata dal sistema tramite applicazione “Configuratore TiDiGino V1.0”;
• Con l’applicazione “Configuratore TiDiGino V1.0” è possibile verificare la configurazionedella scheda e le informazioni sul modem GSM (IMEI, operatore SIM Card, versioneFirmware del modem etc.);
• Debug dei comandi inviati del PC al TiDiGIno e viceversa;
• Configurazione rapida del numero master 1 alla prima accensione o dopo il reset.
• Verifica del credito residuo sulla scheda tramite SMS

 

Invio comandi tramite SMS

L’invio dei comandi tramite sms avviene utilizzando i comandi elencati di seguito e solo rispettando la seguente sintassi: PPPP;CCCC:XXX oppure PPPP;RISPOSTA;CCCC:XXX  Dove PPPP è la password di gestione tramite SMS ed è composta da 0 a 4 cifre. Di default lapassword è 0000.
CCCC è il comando da impartire. Se il comando da impartire ha un sub comando questo deve essere posto dopo il comando preceduto dai due punti.Ad esempio per impostare la temperatura da mantenere a 35 °C, supponendo di aver impostato la password a 1234, il comando da utilizzare è:1234;TNOR:35 Nel caso si voglia la risposta dell’avvenuta ricezione del messaggio da parte del telecontrollo, il comando da utilizzare è: 1234;RISPOSTA;TNOR:35 È possibile inviare con un unico SMS più comandi. La sintassi da utilizzare in questo caso è la seguente: PPPP;Comando1:Subcomando1;Comando2:Subcomando2;Comando3:Subcomando3;etc. Ad esempio se si vuole impostare la temperatura da mantenere a 40 °C e l’isteresi a ±3°C ilcomando da inviare è: 1234;TNOR:35;TIST:3 Se un comando non ha un sub comando la sintassi è: PPPP;CCCC Ad esempio per la richiesta della temperatura ambiente rilevata il comando è: 1234;TEMPER

 

Invio comandi tramite PC

L’invio dei comandi tramite PC tramite Hyper Terminal avviene utilizzando i comandi della tabella sottoriportata e solo rispettando la seguente sintassi: #PPPP;CCCC:XXX! Dove “#” è il carattere iniziale (Header-Mark) e “!” e quello terminatore (End-Mark). Dove PPPP è la password di gestione tramite PC ed è composta da 0 a 4 cifre. Di default lapassword è 0000.CCCC è il comando da impartire. Se il comando da impartire ha un sub comando questo deve essere posto dopo il comandopreceduto dai due punti. Ad esempio per impostare la temperatura da mantenere a 35 °C, supponendo di averimpostato la password a 1234, il comando da utilizzare è:#1234;TNOR:35! Se un comando non ha un sub comando la sintassi è:#PPPP;CCCC! Ad esempio per la richiesta della temperatura ambiente rilevata il comando è:#1234;TEMPER! La porta seriale deve essere impostata con velocità di 9600bps, 8 bit di dati, 1 di stop enessuna parità (la classica 8N1).

 

Gestione con software “ConfiguratoreTiDiGino V1.0”


Una volta avviato il software, selezionare dal campo “Porta COM” la porta seriale assegnata dal PC al TiDiGino e premere il pulsante connetti. Una volta che la sincronizzazione è avvenutaverrà visualizzata una finestra di notifica. Premendo OK il TiDiGino invierà al PC tutti i settaggi memorizzati nella sua memoria. È possibile ricaricare i settaggi dal TiDiGino all’applicativo premendo anche il tasto “Leggi Parametri”. L’applicativo è strutturato in schede (TAB). Il primo TAB “Informazioni Generali “ mostra le informazioni relative alle versioni Hardware e Firmware del telecontrollo oltre al nome del gestore telefonico della SIM inserita. Il secondo TAB “Termostato e Ingressi 1 & 2” , permette di configurare il telecontrollo per il funzionamento come termostato, rilevazione degli allarmi di temperatura e gestione degli ingressi 1 e 2. Inoltre sono presenti tre LED “virtuali” che visualizzano lo stato degli ingressi 1 e 2 e del relè 1.

TAB “Termostato e Ingressi 1 & 2”. Il terzo TAB “Impostazione Uscite 1 & 2” permette di configurare le due uscite a relè. Inoltre sono presenti due LED “virtuali” che mostrano lo stato di attivazione dei due relè.

Il quarto TAB “Numeri” permette di memorizzare o visualizzare i numeri mastero i numeri per la funzione apricancello. Inoltre è presente la finestra nel quale sono visualizzati tutti i numeri memorizzati nel telecontrollo (Premere il pulsante “Lista Numeri” per caricarli).

Il quinto TAB “Testi SMS e Impostazioni Generali” permette di personalizzare i testi degli SMS di allarme, dell’SMS di accensione, di personalizzare le due password e di inserire il numero del centro servizi per la richiesta del messaggio di invio SMS del credito residuo.

Nell’applicativo sono state inserite due “Text Box” nelle quali vengono visualizzate a scopo di debug le comunicazioni tra TiDiGino e PC.

 

Configurazione rapida numero master 1

Alla prima accensione del TiDiGino o dopo un reset generale (tramite il pulsante P1 premuto durante la fase di accensione) i led LD3 ed LD4 lampeggeranno alternativamente per circa 60secondi. In questo frangente il primo numero che chiamerà il telecontrollo sarà memorizzato come numero master 1. Alla fine della procedura, per confermare l’avvenuta memorizzazione, il telecontrollo chiamerà il numero appena memorizzato.

 

Controllo relè 1 e 2 tramite DTMF

Chiamando il telecontrollo da uno degli otto numeri master è possibile comandare i relè 1 e 2 con i toni DTMF. Alla chiamata il telecontrollo risponderà e invierà in linea una serie di toni DTMF per confermare di essere pronto a ricevere comandi. Alla fine dei toni basterà premere sul telefono dal quale si sta chiamando il pulsante 1 per spegnere il relè 1, il 2 per accenderlo, il 3 per spegnere il relè 2 e 4 per accenderlo. Ad ogni comando il telecontrollo risponderà con due toni per confermare l’avvenuto riconoscimento del comando. È possibile comandare i relè in qualsiasi configurazione (bistabile o monostabile). Naturalmente se il relè 1 è assegnato al termostato (tranne se in manuale: FUNZ:M) non sarà possibile comandarlo con i toni DTMF. Infatti premendo i tasti 1 e 2 non si udiranno i toni diconferma.

 

Funzione apricancello

Abilitando il relè 1 al funzionamento monostabile (OUT1:ON) si attiverà la funzione apricancello. Chiamando quindi il telecontrollo da uno dei numeri inseriti nella lista apricancello il telecontrollo rifiuterà la chiamata e il relè 1 si attiverà per il tempo configurato col comando MON1:10 (esempio per 10 secondi). È possibile attivare l’apricancelo anche da un numero master ma in questo caso bisognerà pagare la telefonata poiché si utilizzerà la funzione DTMF (tasto 4).

 

Note sul funzionamento

Poiché le uscite IN 1 e IN 2 come pure i Relè 1 e 2 possono essere assegnate a funzioni differenti (ad esempio Relè1 a Termostato o DTMF, IN 1 a Servotermostato o rilevamento allarmi su presenza o assenza tensione etc.) si è previsto un sistema di auto esclusione della funzione incompatibile con l’ultima impostazione data. Ad esempio selezionando la funzione servo termostato (FUNZ:T) automaticamente verrà disabilitata la funzione di allarme sul rilevamento della presenza o assenza tensione sull’ingresso IN1. Così pure se viene impostato il relè 1 come monostabile (OUT1:ON) verrà disabilitata la funzione termostato. Oppure se è attivo il termostato con funzione automatico o servo termostato (FUNZ:A oFUNZ:T), non sarà possibile comandare il relè 1 con i toni DTMF.

 

Esempi di configurazione

Nelle seguenti  immagini sono mostrati gli schemi tipici di collegamento del TiDiGino con caldaia, condizionatore, elettroserratura (o ingresso diabilitazione apertura del cancello automatico) e servotermostato. Nel caso di collegamento con un termostato esterno bisogna eliminare dalla scheda TiDiGino l’opto isolatore U4 e montare le resistenze R31 ed R32 da 0 ohm (o fare un ponticello).

 

Messaggio da inviare per abilitare il funzionamento come Figura sotto riportata:
0000;OUT2:ON;MON2:5
(Impostazione del relè 2 come monostabile con tempo di attivazione di 5 secondi)

Messaggio da inviare per abilitare il funzionamento con condizionatore
0000;FUNZ:A;TNOR:25;TIST:2
(temperatura da mentenere 25°C con isteresi ±2°C).

 

Messaggio da inviare per abilitare il funzionamento con caldaia:
0000;FUNZ:A;TNOR:30;TIST:2;ACAL:ON
(temperatura da mentenere 30°C con isteresi ±2°C e allarme caldaia abilitato).

Messaggio da inviare per abilitare il funzionamento con caldaia e termostato:
0000;FUNZ:T
Per conoscere lo stato di funzionamento del sistema basta inviare il comando:
0000;INOUT;TEMPER
(verranno inviati due messaggi SMS di risposta al comando: uno con lo stato di attivazione deirelè e degli ingressi e uno con la temperatura ambiente rilevata dal sensore a bordo delTiDiGino).

 

 

Lo sketch

//************************************************************************
//*                                                                      *
//*        Firmware TiDiGino Ver. 1.1 del 27 ottobre 2011                *
//*                     By Felice Pascarelli - BARI                      *
//*                      		  	                         *
//*                                                                      *
//************************************************************************
#include <GSM.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <EEPROM.h>

GSM gsm;

// Set pin numbers:
const int powergsm =  77;
const int ctsgsm   =  39;
const int rtsgsm   =  29;
const int dcdgsm   =  27;
const int dtrgsm   =  28;
const int reset    =  35;
const int ring     =  34;
const int ld1      =  25;
const int ld2      =  26;
const int stato    =  76;
const int rele1    =  36;
const int rele2    =  37;
const int sda      =  20;
const int scl      =  21;
const int in1      =  84;
const int in2      =  83;
const int stddtmf  =  14;
const int q1dtmf   =  72;
const int q2dtmf   =  73;
const int q3dtmf   =  74;
const int q4dtmf   =  75;
const int puls     =  62;
const int sonda    =  63;

//************************************************************************
//*                                                                      *
//*                Dichiarazione Variabili e costanti                    *
//*                                                                      *
//************************************************************************

//************************** Costanti Progetto ***************************
const String tidigino = "Prototipo F.Pascarelli";
const String tidigifw = "V1.1";

//************************** Variabili comuni ****************************
byte rxrs232;
String ricezione = "";

//********************* Variabili parametri Modem e SIM*******************
String modello = "N.A.";
String firmware = "N.A.";
String imei = "N.A.";
String operatore = "N.A.";

int    response=0;
char   phone_num[20]; // array per numero di telefono
char   credit_num[20];
char   smsstring[160];
char   smsstring2[160];
int    tono=0;
int    buf = 0; // buffer rx seriale
int   chiamataattiva = 0;// flag chiamata attiva: 0 = no, 1 = si
char numeromaster1[20];
char numerochiamante[20]; 

//*******************************************************************************************
//*
//*                           				Variabili      		                            *
//*
//*******************************************************************************************
float tempC=0;// temperatura letta

int fun = 1; // modalità funzionamento termostato 0 = OFF, 1 = Auto, 2 = Man, 3 = Servo
int allth = 0; // allarme temperatura ALTA 0 = OFF, 1 = ON
int alltm = 0; // allarme temperatura BASSA 0 = OFF, 1 = ON
int liv1 = 0; // Allarme ingresso 1: 0 =OFF/Termostato, 1 = Alto, 2 = Basso, 3 = Variazione
int liv2 = 0; // Allarme ingresso 2: 0 =OFF, 1 = Alto, 2 = Basso, 3 = Variazione, 4 = Allarme Caldaia
int out1 = 0; // Relè 1 bistabile/monostabile 0 = bistabile, 1 = monostabile
int out2 = 0; // Relè 2 bistabile/monostabile 0 = bistabile, 1 = monostabile
int avv = 0; // messaggio accensione 0 = disattivato, 1 = attivato
int rip1 = 0; // ripristino relè 1 dopo blackout 1 = si, 0 = no
int rip2 = 0; // ripristino relè 2 dopo blackout 1 = si, 0 = no

int acccaldaia = 0; //Variabile per stato caldaia RELE1
int cancello = 0; //Variabile per stato CANCELLO RELE2
int statoin1 = 0; // Variabile per stato ingresso 1
int statoin2 = 0; // Variabile per stato ingresso 2

int statorele1 = 0; // variabile per stato relè 1 dopo blackout
int statorele2 = 0; // variabile per stato relè 2 dopo blackout

int nor = 25; //  temperatura XX = 0/99 °C
int ist = 1; // temperaturaisteresi XX = 0/99 °C
int allmax = 40; // temperatura massima allarme XX = 0/99 °C
int allmin = 5; // temperatura minima allarme XX = 0/99 °C
int tin =  5; // tempo inibizione allarmi temperatura XX = 0/99 minuti
int ini1 = 5; // tempo inibizione allarme ingresso 1 XX = 0/99 minuti
int ini2 = 5; // tempo inibizione allarme ingresso 2/allarme caldaia XX = 0/99 minuti
int mon1 = 5; // Tempo attivazione relè 1 monostabile XX = 1/99 secondi
int mon2 = 5; // Tempo attivazione relè 2 monostabile XX = 1/99 secondi

int rispostasms = 0;
int smscomando = 0;
int tipochiamata = 0;

int inoutaltobasso1 = 1;
int	inoutbassoalto1 = 1;
int inoutaltobasso2 = 1;
int	inoutbassoalto2 = 1;

int termostoff = 0;

String password2 = "0000"; //password 2
String password = "0000"; //password 1
char tsu[64] = "Telecontrollo TiDiGino by Felice Pascarelli Attivo"; // Messaggio Accensione
char tin1b[64]= "Mancanza alimentazione Ingresso 1"; // Messaggio in 1 basso
char tin1a[64] = "Presenza alimentazione Ingresso 1"; // Messaggio in 1 alto
char tin1v[64] = "Variazione Stato Ingresso 1"; // Messaggio in 1 variazione
char tin2b[64]= "Mancanza alimentazione Ingresso 2"; // Messaggio in 2 basso
char tin2a[64] = "Presenza alimentazione Ingresso 2"; // Messaggio in 2 alto
char tin2v[64] = "Variazione Stato Ingresso 2"; // Messaggio in 2 variazione
char thi[64] = "Allarme Temperatura Alta"; // messaggio temperatura alta
char tlo[64] = "Allarme Temperatura Bassa"; // messaggio temperatura Bassa
char tca[64] = "Allarme Blocco Caldaia"; // messaggio allarme caldaia

char sms[63]; // Appoggio per lettura testi sms

unsigned long inibitemp = 0;//Variabile TEMPO INIBIZIONE ALLARMI TEMPARATURA in ms (da 00 a 99 min.)
unsigned long inibitcald = 0;//Variabile TEMPO INIBIZIONE INGRESSO CALDAIA  in ms (da 00 a 99 min.)
unsigned long tinibin1 = 0;//Variabile TEMPO INIBIZIONE INGRESSO 1 in ms (da 00 a 99 min.)

//********************** variabili  per macchina a stati *****************
unsigned long time;
unsigned long rxseriale;
unsigned long sensori;
unsigned long termostato;
unsigned long ledstato;
unsigned long gestiscicall;
unsigned long gestiscisms;
unsigned long gestisciingressi;

//#define Debug
#define ONE_WIRE_BUS sonda
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress insideThermometer;
//************************************************************************
//*                                                                      *
//*                          Ciclo SetUp	    	                     *
//*                                                                      *
//************************************************************************
void setup()
{

  // setta le seguenti linee digitali come uscita:
	pinMode(powergsm, OUTPUT);
	pinMode(rtsgsm, OUTPUT);
	pinMode(dtrgsm, OUTPUT);
	pinMode(reset, OUTPUT);
	pinMode(ld1, OUTPUT);
	pinMode(ld2, OUTPUT);
	pinMode(rele1, OUTPUT);
	pinMode(rele2, OUTPUT);
	pinMode(sda, OUTPUT);
	pinMode(scl, OUTPUT); 

	// setta le seguenti linee digitali come ingresso:
	pinMode(ctsgsm, INPUT);
	pinMode(dcdgsm, INPUT);
	pinMode(ring, INPUT);
	pinMode(stato, INPUT);
	pinMode(in1, INPUT);
	pinMode(in2, INPUT);
	pinMode(stddtmf, INPUT);
	pinMode(q1dtmf, INPUT);
	pinMode(q2dtmf, INPUT);
	pinMode(q3dtmf, INPUT);
	pinMode(q4dtmf, INPUT);
	pinMode(puls, INPUT);
	pinMode(sonda, INPUT); 

//**** Inizializzazione variabili  per macchina a stati *****************
	time=millis();
	rxseriale=millis();
	sensori=millis();
	termostato=millis();
	ledstato=millis();
	gestiscicall=millis();
	gestiscisms=millis();
	gestisciingressi=millis();
	delay(500);
	Serial.begin(9600);  // Setta la velocità della porta seriale a 9600 bps:
	delay(500);

	if(digitalRead(puls) == 0)
	{
		Serial.println("Pulsante di Reset premuto");
		writeinte2prom();
	}
	int initeeprom = EEPROM.read(25);
	if(initeeprom != 1)
	{
	    Serial.println("Inizializzazione EEProm Interna");
		digitalWrite(ld2,1);
		delay(1000);
		writeinte2prom();
		digitalWrite(ld2,0);
	}
	digitalWrite(ld1,1);
	delay(5000);
	Serial.println("Caricamento impostazioni da EEProm Interna");
	readinte2prom();
	digitalWrite(ld1,0);
	delay(4000);

	//******************** Routine ripristino relè dopo blackout
	if(rip1 == 1)
	{
		Serial.println("Ripristino stato rele' 1");
		int statorel1 = EEPROM.read(26);
		if(statorel1 == 1)
		{
			digitalWrite(rele1,1);
			acccaldaia = 1;
			Serial.println("Rele 1 on");
		}
		else
		{
			digitalWrite(rele1,0);
			acccaldaia = 0;
			Serial.println("Rele 1 off");
		}
	}

	if(rip2 == 1)
	{
		Serial.println("Ripristino stato rele' 2");
		int statorel2 = EEPROM.read(27);
		if(statorel2 == 1)
		{
			digitalWrite(rele2,1);
			cancello = 1;
		}
		else
		{
			digitalWrite(rele2,0);
			cancello = 0;
		}
	}
	digitalWrite(ld1,1);

//********************* Routine inizializzazione periferiche
	// sensore temperatura
	Serial.println("Inizializzazione Sensore temperatura");
	sensors.begin();
	sensors.getAddress(insideThermometer, 0);
	sensors.setResolution(insideThermometer, 9);
	// gsm
	Serial.println("Inizializzazione Modulo GSM");
	gsm.TurnOn(115200); //accendi il modulo GSM
	gsm.InitParam(PARAM_SET_1);//Configura il modulo
	gsm.Echo(1);

	digitalWrite(ld1,0);
	delay(1500);

	digitalWrite(ld1,1);
	digitalWrite(ld2,0);
	Serial.flush();
	delay(1000);
	int z = 0;
	while (z < 30)
	{
	  digitalWrite(ld2,0);
	  delay (500);
	  digitalWrite(ld2,1);
	  delay (500);
	  z++;
	}
	Serial.print("~Attivo!");
	inviainfo();
	inviaimpost();

//********************* Registrazione numero master

	while(60000 > millis())
	//while(20000 > millis())
	{
		String confrapida = legginumeep("1");
		if(confrapida == "SMS,Posizione Vuota")
		{
			digitalWrite(ld1,0);
			digitalWrite(ld2,1);
			delay (200);
			digitalWrite(ld1,1);
			digitalWrite(ld2,0);

			switch (gsm.CallStatus())
			{
				case CALL_NONE:
				delay (500);
				break;

				case CALL_INCOM_VOICE:
				digitalWrite(ld1,0);
				digitalWrite(ld2,1);
				Serial.println("Chiamata in arrivo");
				delay (1000);
				gsm.CallStatusWithAuth(numerochiamante,0,0);
				Serial.println(" "); Serial.print("Numero Chiamante: "); Serial.println(numerochiamante);
				delay (2000);
				gsm.HangUp();
				Serial.println("Chiamata rifiutata.");
				Serial.println("Attesa chiamata a Master 1.....");
				delay (10000);
				gsm.Call(numerochiamante);
				Serial.println(" ");
				Serial.print("Chiamata in corso: ");
				Serial.println(numerochiamante);
				delay (20000);
				gsm.HangUp();
				///////////////////// salvataggio numero Master 1
				String nummastrapido = "1,SMS,";
				nummastrapido += numerochiamante;
				scrivinumeep(nummastrapido);
				Serial.print("Numero master 1 configurato: ");
				Serial.println(nummastrapido);

				digitalWrite(ld1,1);
				digitalWrite(ld2,0);
				break;
			}
		}
		else
		{
			int l = 0;
			while (l < 20)
			{
			  digitalWrite(ld2,0);
			  delay (50);
			  digitalWrite(ld2,1);
			  delay (50);
			  l++;
			}
			break;
		}
		digitalWrite(ld1,1);
		digitalWrite(ld2,0);
	}
		digitalWrite(ld1,1);
		digitalWrite(ld2,0);

//**************************** sms avvio
	if(avv == 1)
	{
		String smsavvio = legginumeep("1");
		if(smsavvio != "SMS,Posizione Vuota")
		{
			response=gsm.SendSMS(numeromaster1,tsu);
		}
	}
String lenucr = legginumecred();
}
//************************************************************************
//*                                                                      *
//*                      Ciclo Principale (main)			             *
//*                                                                      *
//************************************************************************
void loop()
{
  time=millis();
  gestisciin();
  gestiscisensori();
  gesttermostato();
  riceviseriale();
  gestiscivoce();
  gestisciled();
  controllasms();
}
//************************************************************************
//*                                                                      *
//*                      Classi macchina a stati			             *
//*                          				                             *
//************************************************************************
//********************* Gestione ingressi digitali
void gestisciin()
{
	if(time>gestisciingressi+500)
	{
		if (liv2 == 1)
		{
			if (time > (inibitcald+(ini2 * 60000)))
			{
				if (digitalRead(in2) == 0)
				{
				  Serial.println(" ");
				  Serial.println("Allarme Ingresso IN 2 Alto");
				  inibitcald = millis();
				  allarmein2();
				}
			}
		}
		if (liv2 == 2)
		{
			if (time > (inibitcald+(ini2 * 60000)))
			{
				if (digitalRead(in2) == 1)
				{
				  Serial.println(" ");
				  Serial.println("Allarme ingresso IN 2 Basso");
				  inibitcald = millis();
				  allarmein2();
				}
			}
		}

		if (liv2 == 3)
		{
			if (digitalRead(in2) == 1)
			{
				delay(200);
				if (digitalRead(in2) == 1)
				{
					if(inoutaltobasso2 == 1)
					{
						Serial.println(" ");
						Serial.println("Allarme Variazione ingresso IN 2 Basso");
						allarmein2();
						inoutaltobasso2 = 0;
						inoutaltobasso1 = 1;
					}

				}
			}
			if (digitalRead(in2) == 0)
			{
				delay(200);
				if (digitalRead(in2) == 0)
				{
					if(inoutaltobasso1 == 1)
					{
						Serial.println(" ");
						Serial.println("Allarme Variazione ingresso IN 2 Alto");
						allarmein2();
						inoutaltobasso2 = 1;
						inoutaltobasso1 = 0;
					}
				}
			}
		}
		//****************************Ingresso in1*****************************
		if (liv1 == 1)
		{
			if (time > (tinibin1+(ini1 * 60000)))
			{
				if (digitalRead(in1) == 0)
				{
				  Serial.println(" ");
				  Serial.println("Allarme Ingresso IN 1 Alto");
				  tinibin1 = millis();
				  allarmein1();
				}
			}
		}
		if (liv1 == 2)
		{
			if (time > (tinibin1+(ini1 * 60000)))
			{
				if (digitalRead(in1) == 1)
				{
				  Serial.println(" ");
				  Serial.println("Allarme Ingresso IN 1 Basso");
				  tinibin1 = millis();
				  allarmein1();
				}
			}
		}
		if (liv1 == 3)
		{
			if (digitalRead(in1) == 1)
			{
				delay(200);
				if (digitalRead(in1) == 1)
				{
					if(inoutbassoalto2 == 1)
					{
						Serial.println(" ");
						Serial.println("Allarme Variazione ingresso IN 1 Basso");
						allarmein1();
						inoutbassoalto2 = 0;
						inoutbassoalto1 = 1;
					}
				}
			}
			if (digitalRead(in1) == 0)
			{
				delay(200);
				if (digitalRead(in1) == 0)
				{
					if(inoutbassoalto1 == 1)
					{
						Serial.println(" ");
						Serial.println("Allarme Variazione ingresso IN 1 Alto");
						allarmein1();
						inoutbassoalto2 = 1;
						inoutbassoalto1 = 0;
					}
				}
			}
		}
		gestisciingressi = millis();
	}

}
//********************* Gestione Sensore di temperatura e ingressi digitali
void gestiscisensori()
{
	if(time>sensori+2000)
	{

		if(digitalRead(in2) == 1) statoin2 = 0;
		else statoin2 = 1;
		if(digitalRead(in1) == 1) statoin1 = 0;
		else statoin1 = 1;

		sensors.requestTemperatures();
		tempC = sensors.getTempC(insideThermometer);

		Serial.print("#"); Serial.print(tempC); Serial.print(",");

		if(acccaldaia == 0) Serial.print("0,");
		else Serial.print("1,");

		if(cancello == 0) Serial.print("0,");
		else Serial.print("1,");	

		if(statoin1 == 0) Serial.print("0,");
		else Serial.print("1,");	

		if(statoin2 == 0) Serial.print("0,");
		else Serial.print("1,");			

		Serial.print("!");

		sensori=millis();
	}
}
//********************* Gestione funzionamento termostato e allarmi temperatura
void gesttermostato()
{
	if(time>termostato+1500)
	{
		if(fun != 0)
		{
			termostoff = 0;
			if(fun  == 2)
			{
				Serial.println("Termostato Manuale ");
				Serial.println("Attivare Relè 1 con chiamata e toni DTMF: 1 = Off, 2 = On.");
			}
			if(liv1 == 0)
			{
				if(fun  == 3)
				{
					Serial.println("Termostato Servoassistito ");
					if (digitalRead(in1) == 0) caldaiaon();
					if (digitalRead(in1) == 1) caldaiaoff();
				}
			}
			if(fun == 1)
			{
				if (tempC <= (nor - ist) && acccaldaia == 0)
				{
					Serial.println("Termostato Automatico caldaia ON");
					caldaiaon();
					//isteresi= 1;
				}
				if (tempC >= (nor + ist) && acccaldaia == 1)
				{
					Serial.println("Termostato Automatico caldaia Off");
					caldaiaoff();
					//isteresi= 0;
				}
			}
		}
		// Termostato OFF
		/*if(fun == 0)
		{
			if(termostoff == 0)
			{
				if(statorele1 == 0) caldaiaoff();
				else caldaiaon();
				termostoff = 1;
			}
		}*/

		time=millis();
		// Allarme temperatura bassa
		if (alltm == 1)
		{
			if (time > (inibitemp+(tin * 60000)))
			{
				if (tempC <= allmin)
				{
				  Serial.println(" ");
				  Serial.println("Allarme T Min");
				  inibitemp = millis();
				  allarmetmin();
				}
			}
		}
		// Allarme temperatura alta
		if (allth == 1)
		{
			if (time > (inibitemp+(tin * 60000)))
			{
				if (tempC >= allmax)
				{
				  Serial.println(" ");
				  Serial.println("Allarme T Max");
				  inibitemp = millis();
				  allarmetmax();
				}
			}
		}
		// Allarme blocco caldaia in 2
		if (liv2 == 4)
		{
			if (time > (inibitcald+(ini2 * 60000)))
			{
				if (digitalRead(in2) == 0)
				{
				  Serial.println(" ");
				  Serial.println("Allarme Blocco Caldaia");
				  inibitcald = millis();
				  allarmein2();
				}
			}
		}

		termostato=millis();
	}
}
//********************* Gestione comunicazione seriale
void riceviseriale()
{
	if(time > rxseriale+500)
	{
		if(Serial.available() > 0)
		{
			rxrs232 = Serial.read();
			if(rxrs232 =='#')
			{
				while (rxrs232 != '!')
				{
					delay(10);
					rxrs232 = Serial.read();
					if (rxrs232 == '!') ricezione += (char)rxrs232;
					else ricezione += (char)rxrs232;
				}
				delay(30);
				comandors(ricezione);
			}
			ricezione = "";
		}
		rxseriale = millis();
	}

}

//********************* Gestione SMS
void controllasms()
{
	if(time>gestiscisms+4000)
	{  

		response=gsm.IsSMSPresent(SMS_UNREAD);
		if(response != 0)
		{
			Serial.println(" ");
			Serial.print("SMS non letti: ");
			Serial.println(response);
			if (response)
			{
				gsm.GetSMS(response, phone_num, smsstring, 160);
				Serial.print("Testo: ");
				Serial.println(smsstring);
			}
			delay (1000);
		} 

		response=gsm.IsSMSPresent(SMS_READ);
		if(response != 0)
		{
			Serial.print("SMS Arrivati: ");
			Serial.println(response);
			if (response)
			{
				gsm.GetSMS(response, phone_num, smsstring, 160);
				Serial.print("Posizione SMS: "); Serial.println(response );
				Serial.print("Numero Chiamante: "); Serial.println(phone_num );
				Serial.print("Testo: "); Serial.println(smsstring);
				smsricevuto(phone_num,smsstring);
				String smsdel = "";
				smsdel.toCharArray(phone_num, 20);
				smsdel.toCharArray(smsstring, 160);
				response=gsm.IsSMSPresent(SMS_READ);
				gsm.DeleteSMS(response);
				Serial.print("Cancello SMS ");
				Serial.println(response);
			}
			delay (200);
		}
		gestiscisms=millis();

	}
}

//********************* Gestione chiamate
void gestiscivoce()
{
	if(time>gestiscicall+300)
	{
		int numeroesist = 0;
		int numerocancel = 0;
		switch (gsm.CallStatus())
		{
			case CALL_NONE:
			chiamataattiva = 0;
			delay (500);
			break;

			case CALL_INCOM_VOICE:
			Serial.println("Chiamata in arrivo");
			delay (2000);
			gsm.CallStatusWithAuth(numerochiamante,0,0);
			Serial.print("Numero Chiamante: "); Serial.println(numerochiamante);

			numeroesist = verificanumeri(numerochiamante);
			if(numeroesist == 1)
			{
				gsm.PickUp();
				Serial.println("Risposto");
			}
			else
			{
				numerocancel = verificanumcanc(numerochiamante);
				if(numerocancel == 1)
				{

					Serial.print("Numero Apricancello: ");
					Serial.println(numerochiamante);
					apricancello();
				}
				gsm.HangUp();
			}
			break;

			case CALL_ACTIVE_VOICE:
			Serial.println("Chiamata attiva");
			for (int i=0;i<100;i++)
			{
				if(chiamataattiva == 0)
				{
					gsm.SendDTMFSignal(5);
					delay(1000);
					gsm.SendDTMFSignal(5);
					delay(1000);
					gsm.SendDTMFSignal(5);
					chiamataattiva = 1;
				}

				if (digitalRead(stddtmf)==1)
				{
					sprintf(smsstring,"DTMF %d - %d - %d - %d",digitalRead(q4dtmf),digitalRead(q3dtmf),digitalRead(q2dtmf),digitalRead(q1dtmf));
					Serial.println(smsstring);
					tono=0;
					bitWrite(tono, 0, digitalRead(q1dtmf));
					bitWrite(tono, 1, digitalRead(q2dtmf));
					bitWrite(tono, 2, digitalRead(q3dtmf));
					bitWrite(tono, 3, digitalRead(q4dtmf));
					Serial.print("tono = ");
					Serial.println(tono);
					if(fun == 0|| fun == 2)
					{
						if (tono == 1)
						{
							gsm.SendDTMFSignal(1);
							caldaiaoff();
						}
						if (tono == 2)
						{
							gsm.SendDTMFSignal(1);
							caldaiaon();
						}
					}
					if (tono == 3)
					{
						gsm.SendDTMFSignal(1);
						cancellooff();
					}
					if (tono == 4)
					{
						gsm.SendDTMFSignal(1);
						cancelloon();
					}
					while(digitalRead(stddtmf)==1)
					{
						delay (10);
					}
					i=0;

				}
				delay (10);
			}
			break;
		}
		gestiscicall=millis();
	}
}
//********************* Gestione LED di stato (LED 1)
void gestisciled()
{
	if(time>ledstato+500)
	{
		if(digitalRead(ld1) == 0) digitalWrite(ld1,1);
		else digitalWrite(ld1,0);
		ledstato = millis();
	}
}

//************************************************************************
//*                                                                      *
//*               			 Routine di supporto			          	 *
//*                                                                      *
//************************************************************************

//********************** Decodifica comandi in arrivo da seriale
void comandors(String rscomando)
{
	String passwordrx = "";
	String comando = "";
	String nome = "";
	String valore = "";
	char numer[20] = "1";

	int i = 0;
	while (rscomando.charAt(i) != ';')
	{
		passwordrx += rscomando.charAt(i);
		i++;
	}
	i++;
	if (passwordrx == password)
	{
		while (rscomando.charAt(i) != '!')
		{
			comando += rscomando.charAt(i);
			i++;
		}

		i = 0;
		//Serial.print("Comando: "); Serial.println(comando);
		if (comando.charAt(4) == ':')
		{
			comando += "!";
			while (comando.charAt(i) != ':')
			{
				nome += comando.charAt(i);
				i++;
			}
			i++;
			while (comando.charAt(i) != '!')
			{
				valore += comando.charAt(i);
				i++;
			}
			eseguicmd(numer,nome,valore);
		}
		else
		{
			nome = comando;
			eseguicmd(numer,nome,valore);
		}

	}
}
//********************** Esecuzione comandi
void eseguicmd(char numerosms[20], String nome, String valore)
{
	if(nome == "TEMPER")
	{
		Serial.println("Richiesta Temperatura");
		int tempCdec=tempC;
		int tempCuni=(tempC*100)-(tempCdec*100);
		sprintf(smsstring,"TiDiGino Felice Pascarelli: Temperatura rilevata %d.%d degC",tempCdec,tempCuni);
		Serial.print("Invio SMS. Testo: "); Serial.println(smsstring);
		Serial.print("Al numero: "); Serial.println(numerosms);
		response=gsm.SendSMS(numerosms,smsstring);

	}

	if(nome == "LISTNUM")
	{
		String invianum = "_";
		Serial.print(invianum);
		invianum = "";
		int posleggi = 1;
		while (posleggi != 9)
		{
			String posizione = posleggi;
			String numeromaster = legginumeep(posizione);
			invianum += posizione;
			invianum += ",";
			invianum += numeromaster;
			invianum += ",";
			Serial.print(invianum);
			invianum = "";
			delay(5);
			posleggi++;
		}
		while (posleggi != 201)
		{
			String posizione = posleggi;
			String numeromaster = legginumeepcanc(posizione);
			invianum += posizione;
			invianum += ",";
			invianum += numeromaster;
			invianum += ",";
			Serial.print(invianum);
			invianum = "";
			delay(5);
			posleggi++;
		}
		invianum = "!";
		Serial.print(invianum);
		Serial.println(" ");
	}

	if(nome == "RISPOSTA")
	{
		rispostasms = 1;
	}

	if (nome == "INOUT")
	{
		String rele1state ="";
		String rele2state ="";
		String in1state ="";
		String in2state ="";
		String inoutstate = "";
		if(digitalRead(in1) == 0)
		in1state = "Presenza tensione su Ingresso 1; ";
		else
		in1state = "Assenza tensione su Ingresso 1; ";

		if(digitalRead(in2) == 0)
		in2state = "Presenza tensione su Ingresso 2; ";
		else
		in2state = "Assenza tensione su Ingresso 2; ";

		if(digitalRead(rele1) == 0)
		rele1state = "Rele 1 Inattivo; ";
		else
		rele1state = "Rele 1 Attivo; ";

		if(digitalRead(rele2) == 0)
		rele2state = "Rele 2 inattivo; ";
		else
		rele2state = "Rele 2 Attivo; ";
		inoutstate += "Stato Ingressi e Uscite: ";
		inoutstate += in1state;
		inoutstate += in2state;
		inoutstate += rele1state;
		inoutstate += rele2state;

		inoutstate.toCharArray(smsstring, 160);
		Serial.println(smsstring);
		Serial.println(numerosms);
		response=gsm.SendSMS(numerosms,smsstring);
	}
	if (nome == "NUM?")
	{
		String numeroletto;
		numeroletto = legginumeep(valore);
		Serial.print("@"); Serial.print(numeroletto);Serial.print("!");
		Serial.print("Numero Letto da posizione ");
		Serial.print(valore);
		Serial.print(": ");
		Serial.println(numeroletto);
		if(smscomando == 1)
		{
			String invio = "Numero Letto da posizione ";
			invio += valore;
			invio += ": ";
			invio += numeroletto;
			invio.toCharArray(smsstring, 160);
			response=gsm.SendSMS(numerosms,smsstring);
			smscomando = 0;
		}
	}
	if (nome == "NUMM")
	{
		scrivinumeep(valore);
	}
	if (nome == "CREDITO")
	{
		Serial.print("Chiamata per credito: ");
		Serial.println(credit_num);
		gsm.Call(credit_num);

		Serial.println("");
		delay (10000);
		Serial.print("Fine Chiamata");
		Serial.println(credit_num);
		gsm.HangUp();
	}
	if (nome == "CRED")
	{
		if(valore == "?")
		{
			String credit = legginumecred();
		}
		else
		{
			salvacred(valore);
		}
	}
	if (nome == "CANC")
	{
		scrivinumcanc(valore);
	}
	if (nome == "CAN?")
	{
		String numeroletto;
		numeroletto = legginumeepcanc(valore);
		Serial.print("|"); Serial.print(numeroletto);Serial.print("!");
		Serial.print("Numero Letto da posizione ");
		Serial.print(valore);
		Serial.print(": ");
		Serial.println(numeroletto);
		if(smscomando == 1)
		{
			String invio = "Numero Letto da posizione ";
			invio += valore;
			invio += ": ";
			invio += numeroletto;
			invio.toCharArray(smsstring, 160);
			response=gsm.SendSMS(numerosms,smsstring);
			smscomando = 0;
		}
	}
	if (nome == "stato")
	{
		Serial.print("~Attivo!");
		inviainfo();
		inviaimpost();

	}
	if (nome == "IMPO")
	{
		inviaimpost();
	}
	if (nome == "FUNZ")
	{
		if (valore == "A")
		{
			EEPROM.write(0, 1);
			fun = 1;
			EEPROM.write(13, 0);
			out1 = 0;
		}
		if (valore == "M")
		{
			EEPROM.write(0, 2);
			fun = 2;
			EEPROM.write(13, 0);
			out1 = 0;
		}
		if (valore == "T")
		{
			EEPROM.write(0, 3);
			fun = 3;
			delay(5);
			EEPROM.write(11, 0);
			liv1 = 0; //in1 assegnato a termostato
			EEPROM.write(13, 0);
			out1 = 0;
		}
		if (valore == "OFF")
		{
			EEPROM.write(0, 0);
			fun = 0;
		}
		if(valore == "?")
		{
			String invio = "Impostazione Funzione termostato: ";
			if(fun == 1)
			invio += "Automatico";
			if(fun == 2)
			invio += "Manuale";
			if(fun == 3)
			invio += "Termostato";
			if(fun == 0)
			invio += "Disattivato";

			invio.toCharArray(smsstring, 160);
			response=gsm.SendSMS(numerosms,smsstring);
			smscomando = 0;
		}

	}
	if (nome == "TNOR")
	{
		if(valore != "?")
		{
			valore += "!";
			int valoretoint = 0;
			valoretoint = stringtoint(valore);
			EEPROM.write(1, valoretoint);
			nor  = valoretoint;
		}
		else
		{
			sprintf(smsstring,"Temperatura impostata %d degC",nor);
			response=gsm.SendSMS(numerosms,smsstring);
			smscomando = 0;
		}

	}
	if (nome == "TIST")
	{
		if(valore != "?")
		{
			valore += "!";
			int valoretoint = 0;
			valoretoint = stringtoint(valore);
			EEPROM.write(2, valoretoint);
			ist  = valoretoint;
		}
		else
		{
			sprintf(smsstring,"Temperatura isteresi %d degC",ist);
			response=gsm.SendSMS(numerosms,smsstring);
			smscomando = 0;
		}
	}
	if (nome == "AMAX")
	{
		if(valore != "?")
		{
			valore += "!";
			int valoretoint = 0;
			valoretoint = stringtoint(valore);
			EEPROM.write(3, valoretoint);
			allmax = valoretoint;
		}
		else
		{
			sprintf(smsstring,"Soglia temperatura alta:  %d degC",allmax);
			response=gsm.SendSMS(numerosms,smsstring);
			smscomando = 0;
		}

	}
	if (nome == "AMIN")
	{
		if(valore != "?")
		{
			valore += "!";
			int valoretoint = 0;
			valoretoint = stringtoint(valore);
			EEPROM.write(4, valoretoint);
			allmin = valoretoint;
		}
		else
		{
			sprintf(smsstring,"Soglia temperatura alta:  %d degC",allmin);
			response=gsm.SendSMS(numerosms,smsstring);
			smscomando = 0;
		}

	}
	if (nome == "TINI")
	{
		if(valore != "?")
		{
			valore += "!";
			int valoretoint = 0;
			valoretoint = stringtoint(valore);
			EEPROM.write(5, valoretoint);
			tin = valoretoint;
		}
		else
		{
			sprintf(smsstring,"Tempo inibizione allarme temperatura: %d minuti",tin);
			response=gsm.SendSMS(numerosms,smsstring);
			smscomando = 0;
		}
	}
	if (nome == "TRESH")
	{
		EEPROM.write(6, 0);
		allth = 0;
	}
	if (nome == "TABIH")
	{
		EEPROM.write(6, 1);
		allth = 1;
	}
	if (nome == "TRESL")
	{
		EEPROM.write(7, 0);
		alltm = 0;
	}
	if (nome == "TABIL")
	{
		EEPROM.write(7, 1);
		alltm = 1;
	}
	if (nome == "INI1")
	{
		if(valore != "?")
		{
			valore += "!";
			int valoretoint = 0;
			valoretoint = stringtoint(valore);
			EEPROM.write(8, valoretoint);
			ini1 = valoretoint;
		}
		else
		{
			sprintf(smsstring,"Tempo inibizione Allarme ingresso 1: %d minuti",ini1);
			response=gsm.SendSMS(numerosms,smsstring);
			smscomando = 0;
		}
	}
	if (nome == "INI2")
	{
		if(valore != "?")
		{
			valore += "!";
			int valoretoint = 0;
			valoretoint = stringtoint(valore);
			EEPROM.write(9, valoretoint);
			ini2 = valoretoint;
		}
		else
		{
			sprintf(smsstring,"Tempo inibizione Allarme ingresso 2: %d minuti",ini2);
			response=gsm.SendSMS(numerosms,smsstring);
			smscomando = 0;
		}
	}
	if (nome == "ACAL")
	{
		if(valore == "ON")
		{
			EEPROM.write(12, 4);//liv2
			liv2 = 4;
		}
		if(valore == "OFF")
		{
			EEPROM.write(12, 0);//liv2
			liv2 = 0;
		}
	}
	if (nome == "LIV1")
	{
		if(valore == "A")
		{
			EEPROM.write(11, 1);
			liv1 = 1;
		}
		if(valore == "B")
		{
			EEPROM.write(11, 2);
			liv1 = 2;
		}
		if(valore == "V")
		{
			EEPROM.write(11, 3);
			liv1 = 3;
		}
		if(valore == "T")
		{
			EEPROM.write(11, 0);
			liv1 = 0;
		}
	}
	if (nome == "LIV2")
	{
		if(valore == "A")
		{
			EEPROM.write(12, 1);
			liv2 = 1;
		}
		if(valore == "B")
		{
			EEPROM.write(12, 2);
			liv2 = 2;
		}
		if(valore == "V")
		{
			EEPROM.write(12, 3);
			liv2 = 3;
		}
		if(valore == "C")
		{
			EEPROM.write(12, 0);
			liv2 = 0;
		}
	}
	if (nome == "OUT1")
	{
		if(valore == "ON")
		{
			EEPROM.write(13, 1);
			out1 = 1;
			delay(5);
			EEPROM.write(0, 0);
			fun = 0;
		}
		if(valore == "OFF")
		{
			EEPROM.write(13, 0);
			out1 = 0;
		}
		if(valore == "?")
		{
			String invio = "Impostazione Relè 1: ";
			if(out1 == 1)
			invio += "Monostabile";
			if(out1 == 0)
			invio += "Bistabile";
			invio.toCharArray(smsstring, 160);
			response=gsm.SendSMS(numerosms,smsstring);
			smscomando = 0;
		}
	}
	if (nome == "MON1")
	{
		if(valore != "?")
		{
			valore += "!";
			int valoretoint = 0;
			valoretoint = stringtoint(valore);
			EEPROM.write(14, valoretoint);
			mon1 = valoretoint;
		}

		else
		{
			sprintf(smsstring,"Tempo attivazione relè 1 monostabile: %d secondi",mon1);
			response=gsm.SendSMS(numerosms,smsstring);
			smscomando = 0;
		}
	}
	if (nome == "OUT2")
	{
		if(valore == "ON")
		{
			EEPROM.write(15, 1);
			out2 = 1;
		}
		if(valore == "OFF")
		{
			EEPROM.write(15, 0);
			out2 = 0;
		}
		if(valore == "?")
		{
			String invio = "Impostazione Relè 2: ";
			if(out2 == 1)
			invio += "Monostabile";
			if(out2 == 0)
			invio += "Bistabile";
			invio.toCharArray(smsstring, 160);
			response=gsm.SendSMS(numerosms,smsstring);
			smscomando = 0;
		}
	}
	if (nome == "MON2")
	{
		if(valore != "?")
		{
			valore += "!";
			int valoretoint = 0;
			valoretoint = stringtoint(valore);
			EEPROM.write(16, valoretoint);
			mon2 = valoretoint;
		}

		else
		{
			sprintf(smsstring,"Tempo attivazione relè 2 monostabile: %d secondi",mon2);
			response=gsm.SendSMS(numerosms,smsstring);
			smscomando = 0;
		}
	}
	if (nome == "AVV1")
	{
		EEPROM.write(17, 1);
		avv = 1;
	}
	if (nome == "AVV0")
	{
		EEPROM.write(17, 0);
		avv = 0;
	}
	if (nome == "AVV?")
	{
		String invio = "Invio messaggio all'accensione: ";
		if(avv == 1)
		invio += "Abilitato";
		if(avv == 0)
		invio += "Disabilitato";
		invio.toCharArray(smsstring, 160);
		response=gsm.SendSMS(numerosms,smsstring);
		smscomando = 0;
	}
	if (nome == "RIP1")
	{
		if(valore == "ON")
		{
			EEPROM.write(18, 1);
			rip1 = 1;
		}
		if(valore == "OFF")
		{
			EEPROM.write(18, 0);
			rip1 = 0;
		}
		if(valore == "?")
		{
			String invio = "Ripristino Relè 1 dopo blakout: ";
			if(rip1 == 1)
			invio += "Attivato";
			if(rip1 == 0)
			invio += "Disattivato";
			invio.toCharArray(smsstring, 160);
			response=gsm.SendSMS(numerosms,smsstring);
			smscomando = 0;
		}
	}
	if (nome == "RIP2")
	{
		if(valore == "ON")
		{
			EEPROM.write(19, 1);
			rip2 = 1;
		}
		if(valore == "OFF")
		{
			EEPROM.write(19, 0);
			rip2 = 0;
		}
		if(valore == "?")
		{
			String invio = "Ripristino Relè 2 dopo blakout: ";
			if(rip2 == 1)
			invio += "Attivato";
			if(rip2 == 0)
			invio += "Disattivato";
			invio.toCharArray(smsstring, 160);
			response=gsm.SendSMS(numerosms,smsstring);
			smscomando = 0;
		}
	}
	if (nome == "PWD1")
	{
		password = valore;
		valore += "!";
		int i = 20;
		int b = 0;
		while (valore.charAt(b) != '!')
		{
			char pwdch = valore[b];
			EEPROM.write(i, pwdch);
			i++;
			b++;
		}
		EEPROM.write(i, '!');

		//String readpwd;
		password = "";
		i = 20;
		while(EEPROM.read(i) != '!')
		{
			password += EEPROM.read(i);
			i++;
		}
		Serial.print("passwordread: "); Serial.println(password);

	}
	if (nome == "PWD2")
	{
		password2 = valore;
		valore += "!";
		int i = 160;
		int b = 0;
		while (valore.charAt(b) != '!')
		{
			char pwdch = valore[b];
			EEPROM.write(i, pwdch);
			i++;
			b++;
		}
		EEPROM.write(i, '!');

		//String readpwd;
		password2 = "";
		i = 160;
		while(EEPROM.read(i) != '!')
		{
			password2 += EEPROM.read(i);
			i++;
		}
		Serial.print("passwordread: "); Serial.println(password2);

	}
	if (nome == "TSAC")
	{
		if(valore == "?")
		{
			readtsutext(176);
		}
		else
		{
			memsmstext(176,valore);
			readtsutext(176);
		}
	}
	if (nome == "TI1B")
	{
		if(valore == "?")
		{
			readtin1btext(240);
			Serial.print("/"); Serial.print(tin1b);Serial.print("!");
		}
		else
		{
			memsmstext(240,valore);
			readtin1btext(240);

		}
	}
	if (nome == "TI1A")
	{
		if(valore == "?")
		{
			readtin1atext(304);
			Serial.print("/"); Serial.print(tin1a);Serial.print("!");
		}
		else
		{
			memsmstext(304,valore);
			readtin1atext(304);
		}
	}
	if (nome == "TI1V")
	{
		if(valore == "?")
		{
			readtin1vtext(368);
			Serial.print("/"); Serial.print(tin1v);Serial.print("!");
		}
		else
		{
			memsmstext(368,valore);
			readtin1vtext(368);
		}
	}
	if (nome == "TI2B")
	{
		if(valore == "?")
		{
			readtin2btext(432);
			Serial.print("/"); Serial.print(tin2b);Serial.print("!");
		}
		else
		{
			memsmstext(432,valore);
			readtin2btext(432);
		}
	}
	if (nome == "TI2A")
	{
		if(valore == "?")
		{
			readtin2atext(496);
			Serial.print("/"); Serial.print(tin2a);Serial.print("!");
		}
		else
		{
			memsmstext(496,valore);
			readtin2atext(496);
		}
	}
	if (nome == "TI2V")
	{
		if(valore == "?")
		{
			readtin2vtext(560);
			Serial.print("/"); Serial.print(tin2v);Serial.print("!");
		}
		else
		{
			memsmstext(560,valore);
			readtin2vtext(560);
		}
	}
	if (nome == "TAHI")
	{
		if(valore == "?")
		{
			readthitext(688);
			Serial.print("/"); Serial.print(thi);Serial.print("!");
		}
		else
		{
			memsmstext(688,valore);
			readthitext(688);
		}
	}
	if (nome == "TALO")
	{
		if(valore == "?")
		{
			readtlotext(752);
			Serial.print("/"); Serial.print(tlo);Serial.print("!");
		}
		else
		{
			memsmstext(752,valore);
			readtlotext(752);
		}
	}
	if (nome == "TACA")
	{
		if(valore == "?")
		{
			readtcatext(624);
			Serial.print("/"); Serial.print(tca);Serial.print("!");
		}
		else
		{
			memsmstext(624,valore);
			readtcatext(624);
		}
	}

	Serial.print("nome: "); Serial.println(nome);
	Serial.print("valore: ");  Serial.println(valore);

	if(rispostasms == 1)
	{

		//response=gsm.SendSMS(numerosms,smsstring2);
	}
	smscomando = 0;
	inviaimpost();
}

//********************** Conversione stringa in numero
int stringtoint(String valore)
{
	char carattereapp;
	char * thisChar;
	int decimali;
	int i = 0;
	int intreturn = 0;

	carattereapp = valore.charAt(i);
	if (carattereapp == '!')
	{
		intreturn = 200;
	}
	else
	{
		thisChar = &carattereapp;
		intreturn = atoi(thisChar);
		i++;
		if(valore.charAt(i) != '!')
		{
			intreturn = intreturn * 10;
			carattereapp = valore.charAt(i);
			thisChar = &carattereapp;
			decimali = atoi(thisChar);
			intreturn = intreturn + decimali;
			i++;
		}
	}
	return (intreturn);
}

//********************** Caricamento impostazioni da EEprom interna
void readinte2prom()
{
	fun = EEPROM.read(0);
	nor = EEPROM.read(1);
	ist = EEPROM.read(2);
	allmax = EEPROM.read(3);
	allmin = EEPROM.read(4);
	tin = EEPROM.read(5);
	allth = EEPROM.read(6);
	alltm = EEPROM.read(7);
	ini1 = EEPROM.read(8);
	ini2 = EEPROM.read(9);
	//acal = EEPROM.read(10);
	liv1 = EEPROM.read(11);
	liv2 = EEPROM.read(12);
	out1 = EEPROM.read(13);
	mon1 = EEPROM.read(14);
	out2 = EEPROM.read(15);
	mon2 = EEPROM.read(16);
	avv = EEPROM.read(17);
	rip1 = EEPROM.read(18);
	rip2 = EEPROM.read(19);

	password = "";
	int i = 20;
	while(EEPROM.read(i) != '!')
	{
		password += EEPROM.read(i);
		i++;
	}

	readtsutext(176);
	readtin1btext(240);
	readtin1atext(304);
	readtin1vtext(368);
	readtin2btext(432);
	readtin2atext(496);
	readtin2vtext(560);
	readthitext(688);
	readtlotext(752);
	readtcatext(624);
}

//********************** Salvataggio impostazioni su EEprom interna
void writeinte2prom()
{
	EEPROM.write(0,fun);
	EEPROM.write(1,nor);
	EEPROM.write(2,ist);
	EEPROM.write(3,allmax);
	EEPROM.write(4,allmin);
	EEPROM.write(5,tin);
	EEPROM.write(6,allth);
	EEPROM.write(7,alltm);
	EEPROM.write(8,ini1);
	EEPROM.write(9,ini2);
	//acal = EEPROM.read(10);
	EEPROM.write(11,liv1);
	EEPROM.write(12,liv2);
	EEPROM.write(13,out1);
	EEPROM.write(14,mon1);
	EEPROM.write(15,out2);
	EEPROM.write(16,mon2);
	EEPROM.write(17,avv);
	EEPROM.write(18,rip1);
	EEPROM.write(19,rip2);
	EEPROM.write(25,1);
	String tsus = tsu;
	memsmstext(176,tsus);
	memsmstext(240,tin1b);
	memsmstext(304,tin1a);
	memsmstext(368,tin1v);
	memsmstext(432,tin2b);
	memsmstext(496,tin2a);
	memsmstext(560,tin2v);
	memsmstext(688,thi);
	memsmstext(752,tlo);
	memsmstext(624,tca);

	String pass = password;
	pass += "!";
	int i = 20;
	int b = 0;
	while (pass.charAt(b) != '!')
	{
		char pwdch = pass[b];
		EEPROM.write(i, pwdch);
		i++;
		b++;
	}
	EEPROM.write(i, '!');
}

//********************** Routine invio informazioni su modulo e GSM
void inviainfo()
{
	serialemodul();
	modellomodul();
	firmwmodul();
	opersim();

	Serial.print("*");
	Serial.print(modello + ",");
	Serial.print(firmware + ",");
	Serial.print(imei + ",");
	Serial.print(tidigino + ",");
	Serial.print(tidigifw + ",");
	Serial.print(operatore);
	Serial.print("!");
	delay(30);
}

//********************** Routine invio Impostazioni a PC
void inviaimpost()
{
	Serial.print("$");
	Serial.print(fun); Serial.print(",");
	Serial.print(nor); Serial.print(",");
	Serial.print(ist); Serial.print(",");
	Serial.print(allmax); Serial.print(",");
	Serial.print(allmin); Serial.print(",");
	Serial.print(tin); Serial.print(",");
	Serial.print(allth); Serial.print(",");
	Serial.print(alltm); Serial.print(",");
	Serial.print(ini1); Serial.print(",");
	Serial.print(ini2); Serial.print(",");
	Serial.print(liv1); Serial.print(",");
	Serial.print(liv2); Serial.print(",");
	Serial.print(out1); Serial.print(",");
	Serial.print(mon1); Serial.print(",");
	Serial.print(out2); Serial.print(",");
	Serial.print(mon2); Serial.print(",");
	Serial.print(avv); Serial.print(",");
	Serial.print(rip1); Serial.print(",");
	Serial.print(rip2); Serial.print(",");
	Serial.print(tsu); Serial.print(",");
	Serial.print(credit_num);Serial.print(",");
	Serial.print( "!");

}

//*****************************************************************
//*           Routine gestione rele 1 e 2                         *
//*****************************************************************

//******************* RELE 1
void caldaiaon()
{
	if(fun != 0)
	{
		digitalWrite(rele1,1);
		acccaldaia = 1;
		if(fun == 2)
		{
			if(rip1 == 1)
			{
				EEPROM.write(26,1);
			}
		}
	}
	else
	{
		if(out1 == 0)
		{
			digitalWrite(rele1,1);
			acccaldaia = 1;
			if(rip1 == 1)
			{
				EEPROM.write(26,1);
			}
		}
		else
		{
			digitalWrite(rele1,1);
			acccaldaia = 1;
			delay(mon1 * 1000);
			digitalWrite(rele1,0);
			acccaldaia = 0;
		}
	}
}
void caldaiaoff()
{
	if(fun != 0)
	{
		digitalWrite(rele1,0);
		acccaldaia = 0;
		if(fun == 2)
		{
			if(rip1 == 1)
			{
				EEPROM.write(26,0);
			}
		}
	}
	else
	{
		digitalWrite(rele1,0);
		acccaldaia = 0;
		if(rip1 == 1)
		{
			EEPROM.write(26,0);
		}
	}
}

//******************* RELE 2
void cancelloon()
{
	if(out2 == 0)
	{
	  digitalWrite(rele2,1);
	  cancello = 1;
	  if(rip2 == 1)
	  {
		EEPROM.write(27,1);
	  }
	}
	else
	{
		digitalWrite(rele2,1);
		cancello = 1;
		delay(mon2 * 1000);
		digitalWrite(rele2,0);
		cancello = 0;
	}
}

void apricancello()
{
	if(out2 == 1)
	{
		digitalWrite(rele2,1);
		cancello = 1;
		delay(mon2 * 1000);
		digitalWrite(rele2,0);
		cancello = 0;
	}
}
void cancellooff()
{
	digitalWrite(rele2,0);
	cancello = 0;
	if(rip2 == 1)
	{
		EEPROM.write(27,0);
	}
}

//*****************************************************************
//*           Routine Gestione allarmi                            *
//*****************************************************************
//*********************** Allarme temperatura massima
void allarmetmax()
{
	int posleggi = 1;
	while (posleggi != 9)
	{
		String posizione = posleggi;
		String numeromaster = legginumeep(posizione);

		if (numeromaster != "SMS,Posizione Vuota")
		{
			if(tipochiamata == 2 ||tipochiamata == 3 )
			{
				//numeromaster.toCharArray(numeromaster1, 20);
				gsm.Call(numeromaster1);
				Serial.print("Attesa risposta da: ");
				Serial.println(numeromaster1);
				Serial.println("");
				delay (30000);
				Serial.print("Fine Chiamata  Allarme Temperatura max: ");
				Serial.println(numeromaster1);
				gsm.HangUp();
			}
			if(tipochiamata == 1 ||tipochiamata == 3 )
			{

				//response=gsm.SendSMS(numeromaster1,thi);
				Serial.print("Invio SMS Allarme Temperatura max: ");
				Serial.println(numeromaster1);
			}
		}
		posleggi++;
	}
}

void allarmetmin()
{
	int posleggi = 1;
	while (posleggi != 9)
	{
		String posizione = posleggi;
		String numeromaster = legginumeep(posizione);

		if (numeromaster != "SMS,Posizione Vuota")
		{
			if(tipochiamata == 2 ||tipochiamata == 3 )
			{
				//numeromaster.toCharArray(numeromaster1, 20);
				gsm.Call(numeromaster1);
				Serial.print("Attesa risposta da: ");
				Serial.println(numeromaster1);
				Serial.println("");
				delay (30000);
				Serial.print("Fine Chiamata  Allarme Temperatura bassa: ");
				Serial.println(numeromaster1);
				gsm.HangUp();
			}
			if(tipochiamata == 1 ||tipochiamata == 3 )
			{

				//response=gsm.SendSMS(numeromaster1,tlo);
				Serial.print("Invio SMS Allarme Temperatura bassa: ");
				Serial.println(numeromaster1);
			}
		}
		posleggi++;
	}
}

void allarmein1()
{
	int posleggi = 1;
	while (posleggi != 9)
	{
		String posizione = posleggi;
		String numeromaster = legginumeep(posizione);

		if (numeromaster != "SMS,Posizione Vuota")
		{
			if(tipochiamata == 2 ||tipochiamata == 3 )
			{
				//numeromaster.toCharArray(numeromaster1, 20);
				gsm.Call(numeromaster1);
				Serial.print("Attesa risposta da: ");
				Serial.println(numeromaster1);
				Serial.println("");
				delay (30000);
				Serial.print("Fine Chiamata  Allarme IN 1: ");
				Serial.println(numeromaster1);
				gsm.HangUp();
			}
			if(tipochiamata == 1 ||tipochiamata == 3 )
			{
				if(liv1 == 1)
				{
					//response=gsm.SendSMS(numeromaster1,tin1a);
					Serial.print("Invio SMS Allarme IN 1 Alto: ");
					Serial.println(numeromaster1);
				}

				if(liv1 == 2)
				{
					//response=gsm.SendSMS(numeromaster1,tin1b);
					Serial.print("Invio SMS Allarme IN 1 Basso: ");
					Serial.println(numeromaster1);
				}

				if(liv1 == 3)
				{
					//response=gsm.SendSMS(numeromaster1,tin1v);
					Serial.print("Invio SMS Allarme IN 1 Variazione: ");
					Serial.println(numeromaster1);
				}
			}
		}
		posleggi++;
	}
}

void allarmein2()
{
	int posleggi = 1;
	while (posleggi != 9)
	{
		String posizione = posleggi;
		String numeromaster = legginumeep(posizione);

		if (numeromaster != "SMS,Posizione Vuota")
		{
			if(tipochiamata == 2 ||tipochiamata == 3 )
			{
				//numeromaster.toCharArray(numeromaster1, 20);
				gsm.Call(numeromaster1);
				Serial.print("Attesa risposta da: ");
				Serial.println(numeromaster1);
				Serial.println("");
				delay (30000);
				Serial.print("Fine Chiamata  Allarme Caldaia: ");
				Serial.println(numeromaster1);
				gsm.HangUp();
			}
			if(tipochiamata == 1 ||tipochiamata == 3 )
			{
				if(liv2 == 1)
				{
					//response=gsm.SendSMS(numeromaster1,tin2a);
					Serial.print("Invio SMS Allarme IN 2 Alto: ");
					Serial.println(numeromaster1);
				}

				if(liv2 == 2)
				{
					//response=gsm.SendSMS(numeromaster1,tin2b);
					Serial.print("Invio SMS Allarme IN 2 Basso: ");
					Serial.println(numeromaster1);
				}

				if(liv2 == 3)
				{
					//response=gsm.SendSMS(numeromaster1,tin2v);
					Serial.print("Invio SMS Allarme IN 2 Variazione: ");
					Serial.println(numeromaster1);
				}

				if(liv2 == 4)
				{
					//response=gsm.SendSMS(numeromaster1,tca);
					Serial.print("Invio SMS Allarme Caldaia: ");
					Serial.println(numeromaster1);
				}
			}
		}
		posleggi++;
	}
}
//*****************************************************************
//*           Routine Gestione Testi Messagggi                    *
//*****************************************************************
//*********************** Memorizzazione testi sms su memoria interna
void memsmstext(int startcella, String testo)
{
	testo += "!";
	int i = 0;
	int posizione = startcella;//Start cell
	int G = startcella + 64;//Stop cell
	int v = 0;
	delay(10);
	Serial.print("memsmstext: "); Serial.println(testo);
	while(posizione < G)
	{
		delay(10);
		if(testo.charAt(i) == '!')
		i++;
		EEPROM.write(posizione, testo.charAt(i));
		i++;
		v++;
		posizione++;
	}
}

//*****************************************************************
//*           Routine Gestione Messagggi                          *
//*****************************************************************
//*********************** Lettura messeggi
void smsricevuto(char numerosms[20], char testosms[160])
{
	String messaggio = "";
	int numeroesist = 0;
	int lunghezzasms = 0;
	String pswsms = "";
	numeroesist = verificanumeri(numerosms);
	String cred1 = numerosms;
	String cred2 = credit_num;
	String cred3 = "";
	if(cred1 == cred2)
	{
		String smsforcred = legginumeep("1");
		response=gsm.SendSMS(numeromaster1,testosms);
		cred3.toCharArray(numeromaster1, 20);
		cred3.toCharArray(testosms, 160);
		cred1 = cred3;
	}
	if(numeroesist == 1)
	{
		//Serial.print("Messaggio da numero master: ");Serial.println(numerosms);
		messaggio = testosms;
		lunghezzasms = messaggio.length();
		//Serial.print("Messaggio: "); Serial.println(messaggio);
		int primosep = messaggio.indexOf(';');
		int secondosep = 0;

		int i = 0;
		while(i < lunghezzasms)
		{
			while(i < primosep)
			{
				pswsms += messaggio.charAt(i);
				i++;
			}
			//Serial.print("Password: "); Serial.println(pswsms);
			break;
		}
		if (pswsms == password2)
		{
			String comando = "";
			while(i < lunghezzasms)
			{
				i++;
				secondosep = messaggio.indexOf(';',i);

				if(secondosep != -1)
				{
					while(i < secondosep)
					{
						comando += messaggio.charAt(i);
						i++;
					}
				}
				else
				{
					while(i < lunghezzasms)
					{
						comando += messaggio.charAt(i);
						i++;
					}
				}
				//Serial.print("comando: "); Serial.println(comando);	

				smscomando = 1;
				comandosms(numerosms,comando);
				comando = "";		

			}
		}

	}

	rispostasms = 0;
}

//********************** Decodifica comandi in arrivo da SMS
void comandosms(char numerosms[20], String smscomando)
{
	String passwordrx = "";
	String comando = "";
	String nome = "";
	String valore = "";
	int i = 0;

		i = 0;
		if (smscomando.charAt(4) == ':')
		{
			smscomando += "!";
			while (smscomando.charAt(i) != ':')
			{
				nome += smscomando.charAt(i);
				i++;
			}
			i++;
			while (smscomando.charAt(i) != '!')
			{
				valore += smscomando.charAt(i);
				i++;
			}

			eseguicmd(numerosms,nome,valore);
		}
		else
		{
			nome = smscomando;
			eseguicmd(numerosms,nome,valore);
		}	

}

//*********************** Lettura testi sms da memoria interna
void readtsutext(int startcella)
{
	int i = 0;
	int posizione = startcella;//Start cell
	int G = startcella + 64;//Stop cell
	while(posizione < G)
	{
		tsu[i] = EEPROM.read(posizione);
		i++;
		posizione++;
	}
}

void readtin1btext(int startcella)
{
	int i = 0;
	int posizione = startcella;//Start cell
	int G = startcella + 64;//Stop cell
	while(posizione < G)
	{
		tin1b[i] = EEPROM.read(posizione);
		i++;
		posizione++;
	}
}

void readtin1atext(int startcella)
{
	int i = 0;
	int posizione = startcella;//Start cell
	int G = startcella + 64;//Stop cell
	while(posizione < G)
	{
		tin1a[i] = EEPROM.read(posizione);
		i++;
		posizione++;
	}
}

void readtin1vtext(int startcella)
{
	int i = 0;
	int posizione = startcella;//Start cell
	int G = startcella + 64;//Stop cell
	while(posizione < G)
	{
		tin1v[i] = EEPROM.read(posizione);
		i++;
		posizione++;
	}
}

void readtin2btext(int startcella)
{
	int i = 0;
	int posizione = startcella;//Start cell
	int G = startcella + 64;//Stop cell
	while(posizione < G)
	{
		tin2b[i] = EEPROM.read(posizione);
		i++;
		posizione++;
	}
}

void readtin2atext(int startcella)
{
	int i = 0;
	int posizione = startcella;//Start cell
	int G = startcella + 64;//Stop cell
	while(posizione < G)
	{
		tin2a[i] = EEPROM.read(posizione);
		i++;
		posizione++;
	}
}

void readtin2vtext(int startcella)
{
	int i = 0;
	int posizione = startcella;//Start cell
	int G = startcella + 64;//Stop cell
	while(posizione < G)
	{
		tin2v[i] = EEPROM.read(posizione);
		i++;
		posizione++;
	}
}

void readthitext(int startcella)
{
	int i = 0;
	int posizione = startcella;//Start cell
	int G = startcella + 64;//Stop cell
	while(posizione < G)
	{
		thi[i] = EEPROM.read(posizione);
		i++;
		posizione++;
	}
}

void readtlotext(int startcella)
{
	int i = 0;
	int posizione = startcella;//Start cell
	int G = startcella + 64;//Stop cell
	while(posizione < G)
	{
		tlo[i] = EEPROM.read(posizione);
		i++;
		posizione++;
	}
}

void readtcatext(int startcella)
{
	int i = 0;
	int posizione = startcella;//Start cell
	int G = startcella + 64;//Stop cell
	while(posizione < G)
	{
		tca[i] = EEPROM.read(posizione);
		i++;
		posizione++;
	}
}
//*****************************************************************
//*           Routine Gestione numeri in memoria                  *
//*****************************************************************

// ** Numero credito
void salvacred(String posscrivi)
{
	char numeromasterx[16];
	int	 posizionex = 1;
	char carattereappx;
	char * thisCharx;
	int decimalix;
	//credit_num
	int i = 0;

		int G = (3976 + (posizionex * 16));//Stop cell
		int p = ((3976 + (posizionex * 16)) - 16);//Start cell

		int v = 0;
		//while (posscrivi.charAt(i) != '!')
		while(p<G)
		{
			if(posscrivi.charAt(i) == '!')
			i++;
			numeromasterx[v] = posscrivi.charAt(i);
			EEPROM.write(p,numeromasterx[v]);
			i++;
			v++;
			p++;
		}

	posscrivi = "";

	Serial.print("Numero credito da Memorizzare: ");
	Serial.println(numeromasterx);

}

String legginumecred()
{
	char numeromasterx[16];
	String numero = "";
	int	 posizionex = 1;
	char carattereappx;
	char * thisCharx;
	int decimalix;
	String risposta;

	int G = (3976 + (posizionex * 16));
	int P = ((3976 + (posizionex * 16)) - 16);
	int i = 0;

	while(P<G)//14
	{
	char num2 = EEPROM.read(P);
	numeromasterx[i] = num2;
	i++;
	P++;
	}
	if(numeromasterx[0]  == '+')
	{
		risposta = numeromasterx;
		numero = numeromasterx;
		numero.toCharArray(credit_num, 20);
		String ritorno = numeromasterx;
		//Serial.print("Lettura numero credito: ");Serial.println(ritorno);
		return(ritorno);
	}
	else
	{
		Serial.print("Posizione Vuota");
		return("Posizione Vuota");
	}

}
//** memorizza numeri in e2prom interna (inviare  String "posizione,numero")
void scrivinumeep(String posscrivi)
{
	char numeromasterx[16];
	int	 posizionex = 0;
	char carattereappx;
	char * thisCharx;
	int decimalix;

	int i = 0;
	carattereappx = posscrivi.charAt(i);
	thisCharx = &carattereappx;
	posizionex = atoi(thisCharx);
	i++;
	if(posscrivi.charAt(i) != ',')
	{
		posizionex = posizionex * 10;
		carattereappx = posscrivi.charAt(i);
		thisCharx = &carattereappx;
		decimalix = atoi(thisCharx);
		posizionex = posizionex + decimalix;
		i++;
		if(posscrivi.charAt(i) != ',')
		{
			posizionex = posizionex * 10;
			carattereappx = posscrivi.charAt(i);
			thisCharx = &carattereappx;
			decimalix = atoi(thisCharx);
			posizionex = posizionex + decimalix;
			i++;
		}
	}
	i++;
	String smsvoc = "";
	while(posscrivi.charAt(i) != ',')
	{
		smsvoc += posscrivi.charAt(i);
		i++;
	}
	if (posizionex < 9)
	{
		int G = (34 + (posizionex * 16));//Stop cell
		int p = ((34 + (posizionex * 16)) - 16);//Start cell
		if(smsvoc == "SMS")
		{
			EEPROM.write(G,1);
		}
		if(smsvoc == "VOC")
		{
			EEPROM.write(G,2);
		}
		if(smsvoc == "SV")
		{
			EEPROM.write(G,3);
		}
		i++;
		int v = 0;
		//while (posscrivi.charAt(i) != '!')
		while(p<G)
		{
			if(posscrivi.charAt(i) == '!')
			i++;
			numeromasterx[v] = posscrivi.charAt(i);
			EEPROM.write(p,numeromasterx[v]);
			i++;
			v++;
			p++;
		}

	}

	posscrivi = "";
	Serial.print("Posizione da Memorizzare: ");
	Serial.println(posizionex);
	Serial.print("Numero da Memorizzare: ");
	Serial.println(numeromasterx);
	Serial.print("Tipo Avviso: ");
	Serial.println(smsvoc);
}

//** memorizza numeri per apricancello
void scrivinumcanc(String posscrivi)
{
	char numeromasterx[16];
	int	 posizionex = 0;
	char carattereappx;
	char * thisCharx;
	int decimalix;

	int i = 0;
	carattereappx = posscrivi.charAt(i);
	thisCharx = &carattereappx;
	posizionex = atoi(thisCharx);
	i++;
	if(posscrivi.charAt(i) != ',')
	{
		posizionex = posizionex * 10;
		carattereappx = posscrivi.charAt(i);
		thisCharx = &carattereappx;
		decimalix = atoi(thisCharx);
		posizionex = posizionex + decimalix;
		i++;
		if(posscrivi.charAt(i) != ',')
		{
			posizionex = posizionex * 10;
			carattereappx = posscrivi.charAt(i);
			thisCharx = &carattereappx;
			decimalix = atoi(thisCharx);
			posizionex = posizionex + decimalix;
			i++;
		}
	}

	if (posizionex > 8)
	{
		int G = (832 + ((posizionex-8) * 16));//Stop cell
		int p = ((832 + ((posizionex-8) * 16)) - 16);//Start cell

		i++;
		int v = 0;
		//while (posscrivi.charAt(i) != '!')
		while(p<G)
		{
			if(posscrivi.charAt(i) == '!')
			i++;
			numeromasterx[v] = posscrivi.charAt(i);
			EEPROM.write(p,numeromasterx[v]);
			i++;
			v++;
			p++;
		}
	}
	posscrivi = "";
	Serial.print("Posizione da Memorizzare: ");
	Serial.println(posizionex);
	Serial.print("Numero da Memorizzare: ");
	Serial.println(numeromasterx);

}
//** ROUTINE VERIFICA ESISTENZA NUMERO IN MEMORIA INTERNA ritorna 1 se esiste, 0 se non esiste
int verificanumeri(char numerosms[20])
{
	int i = 1;
	String numeroletto = "";
	String posizionenum = "";
	String appoggio = "";
	appoggio = numerosms;
	int ritorno = 0;

	while(i < 9)
	{
		posizionenum = i;
		posizionenum += "!";
		numeroletto = legginumeep(posizionenum);
		delay (5);
		String appoggio2 = "SMS," + appoggio;
		if(appoggio2 == numeroletto)
		{
			ritorno = 1;
			i = 11;
		}
		appoggio2 = "VOC," + appoggio;
		if(appoggio2 == numeroletto)
		{
			ritorno = 1;
			i = 11;
		}
		appoggio2 = "SV," + appoggio;
		if(appoggio2 == numeroletto)
		{
			ritorno = 1;
			i = 11;
		}
		i++;
	}

	return(ritorno);

}

//** ROUTINE VERIFICA ESISTENZA NUMERO apricancello IN MEMORIA ritorna 1 se esiste, 0 se non esiste
int verificanumcanc(char numerosms[20])
{
	int i = 9;
	String numeroletto = "";
	String posizionenum = "";
	String appoggio = "";
	appoggio = numerosms;
	int ritorno = 0;

	while(i < 201)
	{
		posizionenum = i;
		posizionenum += "!";
		numeroletto = legginumeepcanc(posizionenum);
		delay (5);
		String appoggio2 = "CAN," + appoggio;
		if(appoggio2 == numeroletto)
		{
			ritorno = 1;
			i = 220;
		}
		appoggio2 = appoggio;
		i++;
	}

	return(ritorno);
}
//** Routine lettura numeri da eeprom interna ritorna  'numero' se esiste, 'posizione vuota' se non esiste
String legginumeep(String posleggi)
{
	char numeromasterx[16];
	String numero = "";
	int	 posizionex = 0;
	char carattereappx;
	char * thisCharx;
	int decimalix;
	String risposta;
	posleggi += "!";
	carattereappx = posleggi.charAt(0);
	thisCharx = &carattereappx;
	posizionex = atoi(thisCharx);

	if(posleggi.charAt(1) != '!')
	{
		posizionex = posizionex * 10;
		carattereappx = posleggi.charAt(1);
		thisCharx = &carattereappx;
		decimalix = atoi(thisCharx);
		posizionex = posizionex + decimalix;
		if(posleggi.charAt(2) != '!')
		{
			posizionex = posizionex * 10;
			carattereappx = posleggi.charAt(2);
			thisCharx = &carattereappx;
			decimalix = atoi(thisCharx);
			posizionex = posizionex + decimalix;
		}
	}

	int G = (34 + (posizionex * 16));
	int P = ((34 + (posizionex * 16)) - 16);
	int i = 0;

	while(P<G)//14
	{
	char num2 = EEPROM.read(P);
	numeromasterx[i] = num2;
	i++;
	P++;
	}
	if(numeromasterx[0]  == '+')
	{
		risposta = numeromasterx;
		String tipo;
		if(EEPROM.read(G) == 1)
		{
			tipo = "SMS,";
			tipochiamata = 1;
		}
		if(EEPROM.read(G) == 2)
		{
			tipo = "VOC,";
			tipochiamata = 2;
		}
		if(EEPROM.read(G) == 3)
		{
			tipo = "SV,";
			tipochiamata = 3;
		}
		numero = numeromasterx;
		numero.toCharArray(numeromaster1, 20);
		String ritorno = tipo + numeromasterx;
		return(ritorno);
	}
	else
	{
		return("SMS,Posizione Vuota");
	}

}

//** Routine lettura numeri da eeprom per apricancello  'numero' se esiste, 'posizione vuota' se non esiste
String legginumeepcanc(String posleggi)
{
	char numeromasterx[16];
	String numero = "";
	int	 posizionex = 0;
	char carattereappx;
	char * thisCharx;
	int decimalix;
	String risposta;

	posleggi += "!";

	carattereappx = posleggi.charAt(0);
	thisCharx = &carattereappx;
	posizionex = atoi(thisCharx);

	if(posleggi.charAt(1) != '!')
	{
		posizionex = posizionex * 10;
		carattereappx = posleggi.charAt(1);
		thisCharx = &carattereappx;
		decimalix = atoi(thisCharx);
		posizionex = posizionex + decimalix;
		if(posleggi.charAt(2) != '!')
		{
			posizionex = posizionex * 10;
			carattereappx = posleggi.charAt(2);
			thisCharx = &carattereappx;
			decimalix = atoi(thisCharx);
			posizionex = posizionex + decimalix;
		}
	}

	int G = (832 + ((posizionex-8) * 16));
	int P = ((832 + ((posizionex-8) * 16)) - 16);
	int i = 0;

	while(P<G)//14
	{
	char num2 = EEPROM.read(P);
	numeromasterx[i] = num2;
	i++;
	P++;
	}
	if(numeromasterx[0]  == '+')
	{
		risposta = numeromasterx;
		String tipo = "CAN,";

		numero = numeromasterx;
		String ritorno = tipo + numeromasterx;
		return(ritorno);
	}
	else
	{
		return("CAN,Posizione Vuota");
	}

}
//*****************************************************************
//*           Routine recupero informazioni dal Modem GSM         *
//*****************************************************************
void serialemodul()
{
	Serial1.flush();
	Serial1.print("AT+CGSN\r");
	delay(300);
	if (Serial1.available() > 0)
	{
		imei = "";
		buf = Serial1.available();
		while ((buf - 10) != (Serial1.available()))
		{
		  rxrs232 = Serial1.read();
		}

		while (Serial1.available() != 7)
		{
		  rxrs232 = Serial1.read();
		  imei += (char)rxrs232;
		}
	}
}
void modellomodul()
{
	Serial1.flush();
	Serial1.print("AT+GMM\r");
	delay(300);
	if (Serial1.available() > 0)
	{
		modello = "";
		buf = Serial1.available();
		while ((buf - 9) != (Serial1.available()))
		{
		  rxrs232 = Serial1.read();
		}

		while (Serial1.available() != 7)
		{
		  rxrs232 = Serial1.read();
		  modello += (char)rxrs232;
		}
	}
}
void firmwmodul()
{
	Serial1.flush();
	Serial1.print("AT+GMR\r");
	delay(300);
	if (Serial1.available() > 0)
	{
		firmware = "";
		buf = Serial1.available();
		while ((buf - 9) != (Serial1.available()))
		{
		  rxrs232 = Serial1.read();
		}

		while (Serial1.available() != 7)
		{
		  rxrs232 = Serial1.read();
		  firmware += (char)rxrs232;
		}
	}
}
void opersim()
{
	Serial1.flush();
	Serial1.print("AT+COPS?\r");
	delay(300);
	if (Serial1.available() > 0)
	{
		operatore = "";
		buf = Serial1.available();
		while ((buf - 22) != (Serial1.available()))
		{
		  rxrs232 = Serial1.read();
		}

		while (Serial1.available() != 7)
		{
		  rxrs232 = Serial1.read();
		  operatore += (char)rxrs232;
		}
	}
}

 

 

 

Elenco comandi

 

Download

Dalla pagina http://code.google.com/p/tidigino potete scaricare le ultime release del firmware

Sketch completo
Librerie
Software configuratore


 


5 pensieri riguardo “TiDiGino il telecontrollo GSM basato su Arduino: il firmware di Felice Pascarelli

  • 10/12/2011 in 21:47
    Permalink

    Rileggendo la lista dei comandi mi sono reso conto di aver dimenticato di indicare il comando da inviare via SMS al TiDiGino per conoscere il traffico residuo della sim card inserita.
    Il comando è 0000;CREDITO (le cifre “0000” devono essere sostituite con la password scelta durante la configurazione del modulo mediante l’applicativo per Pc o via SMS).Il telecontrollo risponderà al numero master 1 con un SMS contenente il traffico residuo.
    Naturalmente, prima di poter utilizzare questa funzione, è necessario aver configurato il numero del cetro servizi dell’operatore per richiesta del credito via SMS (ad esempio nel caso di Vodafone è “+404”). Questo numero è possibile configurarlo sia tramite l’applicativo per PC e sia via SMS da numero master con il comando “0000;CRED:+404”.
    Purtroppo non ho avuto molto tempo per la fase di debug e correzione quindi se qualcuno nota delle imprecisioni o anomalie può segnalarmele e sarò ben lieto di correggerle.
    Felice Pascarelli

    Risposta
    • 07/03/2013 in 21:08
      Permalink

      Salve io ho scaricato questo firmware ma al momento della compilazione mi da tanti errori. come devo fare? sono disperato

      Risposta
  • 16/01/2013 in 22:11
    Permalink

    Salve.. sarei molto interessato all’acquisto di questo tipo di apparecchio..
    è in vendita?

    Risposta
  • 30/12/2014 in 18:42
    Permalink

    Ho acquistato di recente (dic. 2014) un TIDIGINO, ed ho installato il firmaware di F. Pascarelli proposto in allegato tramite Arduino 0023.
    Purtroppo il configuratore jar mi dà solo N.A. in tutti i campi, ed indica costantemente un messaggio di errore 5.
    Il fatto inspiegabile per me è che nonostante le inizializzazioni sembrino essere andate a buon fine, non riesco a far funzionare in particolare il modulo GSM SIM900, nè in ricezione e neppure in uscita, seppure il led lampeggia in sincronia con arduino che elabora periodicamente un Tx.
    Qualcuno sa fornirmi un aiuto?.
    Grazie

    Risposta
    • 31/12/2014 in 10:14
      Permalink

      Buongiorno,
      provi a mandare un ticket al nostro supporto tecnico, tramite il nostro sito http://www.futurashop.it, oppure
      chiami al 0331/245587 nei giorni di lunedì, mercoledì, venerdì, dalle 14 alle 17.

      Cordiali saluti

      Risposta

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Ricevi un avviso se ci sono nuovi commenti. Oppure iscriviti senza commentare.