Buonasera a tutti!
Volevo condividere un piccolo progetto che ho creato grazie all'aiuto di questo forum e di tutte le informazioni trovate in rete.
Avevo la necessità di comandare a distanza la caldaia di una seconda casa in montagna e così ho acquistato quasi per gioco una scheda Arduino Uno ed una Shield GPRS SIM900. Dopo innumerevoli prove, ed infiniti SMS, sono riuscito a creare (copiando parti di codice trovati in rete, ci tengo a precisarlo..) questo sketch che consente di accendere/spegnere la caldaia, inviare via sms la temperatura rilevata in casa ed avvisare in caso di fughe di gas e mancanza di corrente.
La batteria tampone utilizzata per l'invio dell'avviso di mancanza corrente, è una banale batteria per la ricarica d'emergenza dei cellulari dal costo di pochi euro.
Questo lo sketch:
/* -----------------------------------------------------------------------------------
Accende e spegne un RELE a secondo dell'SMS inviato:
ON => Accende il RELE
OFF => Spegne il RELE
STATO => Comunica stato della caldaia/rele
TEMP => Comunica la temperatura in casa
Altro => Messaggio di errore sul Serial Monitor
Fuga di Gas => invio sms con allarme
Mancanza rete => invia sms con avviso (se collegata una batteria tampone su usb)
---------------------------------------------------------------------------------- */
#include "SIM900.h"
#include <SoftwareSerial.h> // necessaria alla libreria gsm.h richiamata in sms.h
#include "sms.h" // Libreria per la gestione degli SMS
// temperatura con DS18B20 su pin digitale 4
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
SMSGSM sms;
int led = 13; // Il Pin 13 è quello connesso al rele
int numdata;
int rele=12; // il Pin 12 legge il segnale di mancanza rete
int rel=0;
int sensore=2; // sensore fughe di gas su pin digitale 2
int val=0;
int interrCount=0;
boolean started=false;
char smsbuffer[160];
char Mittente[20];
char Mittente1[20];
float tempC;
char tempB[6];
String tempA="";
void setup()
{
Serial.begin(9600);
pinMode (sensore, INPUT);
pinMode (rele, INPUT);
//digitalWrite(rele, LOW);
digitalWrite(sensore, HIGH);
Serial.println("ESEMPIO INVIO/RICEZIONE SMS");
pinMode(led, OUTPUT); // imposta il pin 13 come pin di OUTPUT.
digitalWrite(led, HIGH); // spegne inizialmente il led
pinMode (sensore, INPUT);
strcpy(Mittente1,"Mio numero");
SIM900power();
sensors.begin();
// Inizializzo la connessione GSM impostando il baudrate
// Per l'utilizzo di HTTP è opportuno usare 4800 baud o meno
if ( gsm.begin(2400) )
{
Serial.println("STATUS Modulo GSM = PRONTO");
started=true;
}
else
Serial.println("STATUS Modulo GSM = INATTIVO");
}
void SIM900power()
// software equivalent of pressing the GSM shield "power" button
{
digitalWrite(9, HIGH);
delay(2000);
digitalWrite(9, LOW);
delay(5000);
}
void loop()
{
interrCount++; // contatore dei cicli loop
val=digitalRead(sensore);
rel=digitalRead(rele);
char inSerial[50];
char position;
Serial.println(interrCount); // stampa il numero dei cicli su seral monitor
if (started)
{
if ( interrCount == 30 ) // ogni 30 cicli
{
interrCount = 0; // azzero il contatore
gsm.CheckRegistration(); // controllo se la sim è connessa alla rete
if (gsm.IsRegistered()==0) // se disconnessa, riavvia il modulo GSM
{
Serial.println("disconnesso, riavvio"); // messaggio su serial monitor
digitalWrite(9, HIGH);
delay(2000);
digitalWrite(9, LOW);
delay(5000);
digitalWrite(9, HIGH);
delay(2000);
digitalWrite(9, LOW);
delay(5000);
}
}
if (rel==HIGH){ // se si diseccita il rele connesso ai 9v invia un sms
sms.SendSMS(Mittente1, "Attenzione Manca la Corrente!"); // restituisce true se invia l'SMS
Serial.println(" => Manca Corrente");
delay(3600000); // attende 1 ora prima di riprendere il loop
}
if(val==LOW) { // se il sensore MQ-5 rileva una fuga di gpl, cambia stato ed invia un sms
sms.SendSMS(Mittente1, "Attenzione fuga di GAS!"); // restituisce true se invia l'SMS
Serial.println(" => Fuga di Gas");
delay(1800000); // attende 30 min prima di riprendere il loop
}
// Legge se ci sono messaggi disponibili sulla SIM Card
// e li visualizza sul Serial Monitor.
position = sms.IsSMSPresent(SMS_ALL); // Valore da 1..20
if (position)
{
// Leggo il messaggio SMS e stabilisco chi sia il mittente
sms.GetSMS(position, Mittente, smsbuffer, 160);
Serial.print("Comando Ricevuto [tel. "+String(Mittente)+String("]: ") + String(smsbuffer));
if (strcmp(smsbuffer,"ON")==0) // se riveve il messaggio ON via sms
{
digitalWrite(led, LOW); // Accende il LED/rele impostando il voltaggio a HIGH
Serial.println(" => Accendo la Caldaia");
}
else if (strcmp(smsbuffer,"OFF")==0) // se riveve il messaggio OFF
{
digitalWrite(led, HIGH); // Spengo il LED/rele impostando il voltaggio a LOW
Serial.println(" => Spengo la caldaia");
}
else if (strcmp(smsbuffer,"TEMP")==0) // se riceve il messaggio TEMP
{
sensors.requestTemperatures(); // legge il sensore/sonda DS18B20
float tempC = sensors.getTempCByIndex(0)-1.5; // sottraggo 1 grado per riscaldamento interno al contenitore
dtostrf(tempC, 2, 2, tempB);
Serial.print("tempB: ");
for (int i = 0; i < sizeof(tempB); i++)
{
Serial.print(tempB[i]);
}
Serial.println();
//convert chararray
for (int i = 0; i < sizeof(tempB); i++)
{
tempA += tempB[i];
}
sms.SendSMS(Mittente, tempB); // invia sms con valore temperatura - restituisce true se invia l'SMS
delay(5000);
}
else if (strcmp(smsbuffer,"STATO")==0) // altrimenti se riceve il messaggio STATO
{
if (digitalRead(led)==LOW) // se il rele è acceso (stato invertito..)
{
sms.SendSMS(Mittente, "STATO: Caldaia Accesa"); // invia sms con caldaia accesa - restituisce true se invia l'SMS
Serial.println(" => La Caldaia e' Accesa");
delay(5000);
}
else // altrimenti
{
sms.SendSMS(Mittente, "STATO: Caldaia Spenta"); // invia sms con caldaia spenta - restituisce true se invia l'SMS
Serial.println(" => La Caldaia e' Spenta");
delay(5000);
}
}
else
Serial.println(" => non riconosciuto!");
sms.DeleteSMS(position); // Elimina l'SMS appena analizzato
}
}
delay(1000);
}
In allegato lo schema.
Ora una richiesta di aiuto...
Come si nota dal programma, per leggere lo stato della caldaia, invio l'sms STATO, ed ottengo la risposta "Caldaia Accesa/Spenta" mentre per sapere la temperatura in casa invio TEMP, e ricevo i gradi. Ho tentato di accorpare le risposte, ma non ci sono mai riuscito ed infine ho installato il tutto. Se qualche buona anima mi indirizzasse, gliene sarei grato.... Ho provato ad unire le due stringhe char con i vari const char, ma alla fine ho rinunciato. Volendo poi inserire una seconda sonda per la temperatura esterna, la cosa sarebbe ancora più utile per risparmiare qualche sms.
Grazie in anticipo a tutti.
Emanuele