Partage
  • Partager sur Facebook
  • Partager sur Twitter

Thermostat programmable par SMS

4 janvier 2018 à 19:37:46

Bonsoir,

Je suis entrain de faire (voir titre), la partie thermostat ne m'a pas posé de pb, par contre la partie SMS me donne du fil à retordre.

le but est d'envoyer une consigne comprise entre 11 et 22 degré et de recevoir un ar

j'arrive bien à envoyer une consigne par SMS mais pour le traitement, ça ne veut rien savoir,

je n'arrive pas à maitriser le " indexof" je l'ai essaué à l'endroit et à l'envers et avec from...

la fonction "traitement" ne fonctionne pas, je pense que c'est la partie loop avec la reception de caracteres qui foire, mais je suis à cours d'idée

je joins la partie du code ainsi que la partie monitoring à linit, le "11" à la fin est le SMS que j'ai envoyé

merci de m'avoir lu et j'espère votre aide

#include <SoftwareSerial.h> //Librairie utilisée pour communiquer avec le shield GSM/GPRS
SoftwareSerial SIM900(7, 8);
// Mémoire tampon de type string pour les messages du shield GPRS 
String msg;
int consigne;// consigne de la temperature du thermostat
// Code PIN de la carte SIM  qui s'insère dans le shield GSM : A remplacer !
String SIM_PIN_CODE = String( "" );
// Le numero de téléphone portable sur lequel envoyer le SMS
String TEL_NUM = String( "6xxxxxx61" );


//**********************************************************************************
void setup() 
 {
        clear_msg();
        Serial.begin(19200);
        Serial.println("*****************************");
        Serial.println("Debut initialisation");
        SIM900.begin(19200);  
        delay(100);      
        Serial.println("Liaison serie GSM initialisée.");
        delay(1000);
        Serial.println("pas de Code PIN");
        SIM900.print("AT+CMGF=1\r"); // GSM en mode texte
        delay(300);
        SIM900.print("AT+CNMI=2,2,0,0,0\r");//******************************************************
        delay(300);
        effacetouslesSMS ();
        Serial.println("Fin initialisation");
        Serial.println("*****************************");
 }

 
 
//**************************************************************************************************************
//FONCTION PRINCIPALE LOOP QUI S'EXECUTE EN BOUCLE (COEUR DU PROGRAMME) ATTEND LES INFORMATIONS DU SHIELD GSM
//**************************************************************************************************************

void loop()
{
  
    char in_Caractere;
    
    if(SIM900.available()>0)
      {
         in_Caractere = SIM900.read(); 
         msg = in_Caractere;
         Serial.print(msg);
        // Serial.println(msg.length());
       if( msg.indexOf("11") >= 0 )
        {
         delay(200);
        Serial.println( "*" );
        }       
 //**************************************        
      }
       traitement_entrant();
 }
 
      
 //***************************************************/         



//************************************************************************************* 
 
// FONCTION QUI DEMANDE AU SHIELD GPRS D'UTILISER LE MODE TEXT POUR LES MESSAGES
//*******************************************************************************************


 }
//FONCTION QUI EFFACE LE CONTENU DE LA MEMOIRE TAMPON DES MESSAGES DU GPRS SHIELD
//*********************************************************************************************

void clear_msg()
 {
 msg = "";
 consigne="";
 return;
 }
//*******************************************************************************************



// FONCTION QUI TRAITE LES MESSAGES DU SHIELD GPRS ET AGIT EN CONSEQUENCE
//***************************************************************************************
void traitement_entrant() 
 {
  if( msg.indexOf("11") >= 0 )
  {
  delay(200);
  consigne== 11;
  return;
  }
  
  else if ( msg.indexOf("12") >= 0 )
     {
      delay(200);
      consigne=12;
      Serial.println(consigne);
      return;
     }
    
     else if ( msg.indexOf("13") >= 0 )
     {
      delay(200);
      consigne=13;
      Serial.println(consigne);
      return;
     }
    
     else if ( msg.indexOf("14") >= 0 )
     {
      delay(200);
      consigne=14;
      Serial.println(consigne);
      return;
     }
    
     else if ( msg.indexOf("15") >= 0 )
     {
      delay(200);
      consigne=15;
      Serial.println(consigne);
      return;
     }
    
     else if ( msg.indexOf("16") >= 0 )
     {
      delay(200);
      consigne=16;
      Serial.println(consigne);return;
     }
    
     else if ( msg.indexOf("17") >= 0 )
     {
      delay(200);
      consigne=17;
      Serial.println(consigne);
      return;
     }
    
     else if ( msg.indexOf("18") >= 0 )
     {
      delay(200);
      consigne=18;
      Serial.println(consigne);
     }
    
     else if ( msg.indexOf("19") >= 0 )
     {
      delay(200);
      consigne=19;
      Serial.println(consigne);
      return;
     }
    
     else if ( msg.indexOf("20") >= 0 )
     {
      delay(200);
      consigne=20;
      Serial.println(consigne);
      return;
     }
    
     else if ( msg.indexOf("21") >= 0 )
     {
      delay(200);
      consigne=21;
      Serial.println(consigne);
      return;
     }
    
     else if ( msg.indexOf("22") >= 0 )
     {
      delay(200);
      consigne == 22;
      Serial.println(consigne);
      envoiSms();//*********************************************************************************************************************************************************
      return;
     }
    }
  //   FONCTION QUI ENVOIE UN AR DE LA BONNE PRISE DE CONSIGNE
  //**************************************************************************************************************
void envoiSms()
 {
   Serial.println( "Envoi reponse consigne" );
   //envoi du SMS de réponse
   SIM900.println("AT+CMGF=1"); //On passe les messages en mode text AT+CMGF=1\r
   delay(200);
   SIM900.print( "AT+CMGS=\"+33" ); // Envoi du numero de telephone à joindre
   SIM900.print( TEL_NUM );
   SIM900.println("\""); 
   delay(200);
   SIM900.print("consigne  "); // Contenu du message
   delay(200);
   SIM900.println(consigne);
   delay(200);
   SIM900.println((char)26); // Envoi le code ASCII de Ctrl+z pour signaler la fin du message et l'envoi
   delay(200);
   SIM900.println();
   clear_msg();
   return;
  }
// efface les SMS******************************************************************************************************************
void effacetouslesSMS ()
{
  SIM900.print("AT+CMGDA=\"");
  SIM900.println("DEL ALL\"");
  delay(500);
  Serial.println( "les SMS sont effacés" );
return;

le monitoring....

Debut initialisation
Liaison serie GSM initialisée.
pas de Code PIN
les SMS sont effacés
Fin initialisation
*****************************
AT+CMGF=1

OK
AT+CNMI=2,2,0,0,0

OK
AT+CMGDA="DEL ALL"

O
+CMT: "+33651915461","","18/01/04,18:49:40+04"
11


  • Partager sur Facebook
  • Partager sur Twitter
5 janvier 2018 à 9:31:02

Tu fais msg = in_Caractere pour chaque caractère dispo donc ta string ne contient forcément que le dernier caractère reçu...

Du coup, impossible qu'elle contienne un nombre à 2 caractères ;)

Mais pour être honnête, tu devrais abandonner les strings et tes 36 IndexOf pour faire un traitement manuel ;)

Exemple:

int rxNbCons = 0;
bool rxValid = true;


void loop()
{
	char c;
	
	if ( SIM900.available() > 0 ) {
	
		c = SIM900.read();
		
		Serial.print(c);
		
		if ( c == '\n' ) {
			
			Serial.print("END: cons=");
			if ( rxValid ) {
				Serial.println(rxNbCons);
			} else {
				Serial.println("INVALID");
			}
			
			rxNbCons = 0;
			rxValid = true;
			
		} else if ( ( c >= '0' ) && ( c <= '9' ) ) {
			
			rxNbCons = ( ( rxNbCons * 10 ) + ( c - '0' ) );
			
		} else {
			
			rxNbCons = 0;
			rxValid = false;
			
		}
		
	}
	
}



-
Edité par lorrio 5 janvier 2018 à 9:32:01

  • Partager sur Facebook
  • Partager sur Twitter
5 janvier 2018 à 12:38:35

@lorrio, merci, j'applique ton idée dés que je peux, surement demain
  • Partager sur Facebook
  • Partager sur Twitter
12 juillet 2018 à 22:19:16

Le topic est intéressant, quel en a été la suite? pourriez vous partager le code final de ce projet?
  • Partager sur Facebook
  • Partager sur Twitter
26 janvier 2020 à 17:37:37

Bonjour,

Je viens juste de m'apercevoir que celà pouvait interessé des personnes, je joins le code mais je précise que ça ne fonctionne pas toujours à cause de la carte SIM, (c'est ma déduction) en effet les SIM pour portables des opérateurs ne sont pas faites pour la domotique, et donc il faut une SIM spéciale... mais j'en ai déduit que sil'on ne fait pas trop d'envoi de SMS, il n'y a pas de pb

Mais je mets le code, j'ai  également fait une video (très amateur, ne vous moquez pas) sur youtube :

https://www.youtube.com/watch?v=LSRPiDZVf2U&t=1s

//***************************************************************Déclaration des variables globales ************************************
#include <EEPROM.h>
#include <SoftwareSerial.h> //Librairie utilisée pour communiquer avec le shield GSM/GPRS
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
//#define DS3231_I2C_ADDRESS 0x68
int nbsms=0;
float temp;           // temperature mesuree
float hysteresis=0.5; // delta pour hysteresis
int relais1Pin=4;           //relais de thermostat
LiquidCrystal_I2C lcd(0x3F,20,4);
// fil de data sur pin 2 de l'Arduino
#define ONE_WIRE_BUS 2
// Configurer une instance oneWire pour communiquer avec tous les périphériques OneWire
OneWire oneWire(ONE_WIRE_BUS);
// Passez notre référence oneWire à Dallas Temperature.
DallasTemperature sensors(&oneWire);
SoftwareSerial SIM900(7, 8);
char octetReception=0; // variable de stockage des valeurs reçues sur le port Série (ASCII)
char caractereRecu=0; // variable pour stockage caractère recu
int compt=0; // variable comptage caractères reçus
String chaineReception=""; // déclare un objet String vide pour reception chaine
String tel="";
String telmaitre=String ("+33602500267");
String consigne="";
int longueur;
String chaudiere="off";
int adresse=0;
int consigneEcrit;
int DTRpin=5;
int razpin=6; 
//****************************************SETUP*****************************************************************
void setup()   { 
Serial.begin(19200); // initialise connexion série ARDUINO <-> pc à 19200 bauds
SIM900.begin(19200); // initialise connexion série ARDUINO <-> SIM900 à 19200 bauds

// *********************************************INIT LCD*********************************************************
  //Serial.println("init LCD");
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Init LCD ok");

//************************************INIT SORTIE ARDUINO POUR RELAIS**********************************************
//Serial.println("init relais");
pinMode(relais1Pin, OUTPUT);
digitalWrite(relais1Pin, LOW);// le relais inactif
//*******************************************************INIT RESET***************************************************
// active la broche en sortie (OUTPUT)  
pinMode(razpin, OUTPUT); 
digitalWrite( razpin, HIGH);
//************************************MISE EN ROUTE SIM900****************************************************************
pinMode(DTRpin, INPUT);

//Serial.println ("powerup");
powerUp();
delay(10000);
lcd.setCursor(0, 1);
lcd.print("Init sim900 ok");
//Serial.println ("fin powerup");
//*****************************SI PERTE DE RESEAU***********************************************
/*if (digitalRead(DTRpin)==LOW){
lcd.setCursor(0, 1);
lcd.print("Init sim900 ko");
//Serial.print("power up ");  
powerUp();
delay(10000); 
lcd.setCursor(0, 2);
lcd.print("Init Sim900 ok"); 
//Serial.print("power up ok");
}*/


//************************************INIT SIM900*******************************************************************
//SIM900.print("AT+CMGF=1"); // GSM en mode texte
SIM900.print("AT+CNMI=2,2,0,0,0\r");//*****************************************************************************************************************************************
//*******************************************LECTURE DE CONSIGNE EEPROM SUITE A CCOUPURE SECTEUR********************
//Serial.println("lecture EEPROM");
int consignelu=(consigne.toInt());
 EEPROM.get(adresse, consignelu);
// Serial.print("consignelue  =");
//Serial.println(consignelu);
lcd.setCursor(0, 3);
lcd.print("lecture EEPROM ok");

consigne=String(consignelu);
//*****************************************INIT SENSOR 18B20****************************************************
//Serial.println("prise de temperature");
 sensors.begin();


//*****************************************PRISE DE TEMPERATURE***************************************************
 //sensors.setResolution(resolutions[10]);
 sensors.requestTemperatures(); // envoie la commande de prise de temperature
 // temp contient la prise de temperature
  temp= (sensors.getTempCByIndex(0));
 // Serial.print(temp); 
//*******************************liste les messages*************************************************************
  listeSMS ();
 delay(10000);
 //**************************************APPEL FONCTION effacetouslesSMS****************************************** 
  effacetouslesSMS (); 
  
 }
//************************************************FIN DE SETUP***************************************************

// **************************************************LOOP********************************************************

void loop()
{
//******************************************PRISE DE TEMPERATURE BIS*********************************************
 //sensors.setResolution(resolutions[10]);
 sensors.requestTemperatures(); // envoie la commande de prise de temperature
 // temp contient la prise de temperature
  temp= (sensors.getTempCByIndex(0));
 // Serial.print(temp);

//******************************************COMMANDE CHAUDIERE (LOOP) & AFFICHAGE****************************************
   if(temp >=consigne.toInt()+hysteresis)
   {
   digitalWrite(relais1Pin, LOW);// le relais inactif
   chaudiere="off";
   }
    else if(consigne.toInt()>temp)
   {
   digitalWrite(relais1Pin, HIGH);// le relais actif
   chaudiere="on";
   }
lcd.setCursor(0,0);
lcd.print("Tel:");
lcd.setCursor(5,0);
lcd.print("           ");
lcd.setCursor(5,0);
lcd.print(tel);
lcd.setCursor(18,0);
lcd.print(nbsms);  
lcd.setCursor(0, 1);
lcd.print("Thermostat :  ");
lcd.setCursor(16,1);
lcd.print("      ");
lcd.setCursor(15,1);
lcd.print(consigne);
lcd.setCursor(17,1);
lcd.write(0b11011111);
lcd.print("C");
lcd.setCursor(0, 2);
lcd.print("Temperature:   ");
lcd.setCursor(12, 2);
lcd.print("     ");
lcd.setCursor(12, 2);
lcd.print(temp);
lcd.setCursor(17, 2);
lcd.write(0b11011111);
lcd.print("C");
lcd.setCursor(0, 3);
lcd.print("Etat relais th : ");
lcd.setCursor(17, 3);
lcd.print("   ");
lcd.setCursor(17, 3);
//lcd.print("off"); 
lcd.print(chaudiere); 

//*****************************SI PERTE DE RESEAU EN COURS***********************************************

/*if (digitalRead(DTRpin)==LOW){
lcd.init();
lcd.setCursor(0, 1);
lcd.print("Init sim900 ko");
//**************************************a faire****************************************************
lcd.setCursor(0, 2);
lcd.print("reset en cours  "); 
delay (5000);
// active le reset forçant la sortie au niveau bas 
  digitalWrite(razpin, LOW);
}*/
    
//***********************************RECEPTION DES CARACTERES ET TRAITEMENT***************************************

  while (SIM900.available()>0) { // tant qu'un octet en réception
  Serial.println("attente de reception caracteres");
  octetReception=SIM900.read(); // Lit le 1er octet reçu et le met dans la variable
  delay(200);
  compt=compt+1;
  Serial.println("Ascii Caractere "+ String(compt) +" = "+ String(octetReception)); // affiche code ASCII Octet reçu
  delay(100);
  if (octetReception=='\n') { // si Octet reçu est le saut de ligne
    longueur=(chaineReception.length());
      if (longueur>=47){
          tel="";
           for (int i = 7; i <= 18; i++){
           tel=(tel+chaineReception[i]);
           }
           Serial.println(tel);           
      }
      Serial.print("nb caracteres :");
      Serial.println(longueur);
       if ( chaineReception. toInt()>=10 && chaineReception. toInt() <23 && longueur <=3){
          consigne=chaineReception;
          
//***********************************************DEMANDE ETAT THERMOSTAT**********************************
   
 
 // ******************************************ECRITURE DE CONSIGNE EN  EEPROM SI CHANGEMENT *********************************
 if (consigne.toInt()!=consigneEcrit && consigne.toInt()<23 )
{
 consigneEcrit=(consigne.toInt());
  EEPROM.put(adresse, consigneEcrit);
  Serial.println("Ecriture-EEPROM");
  //Serial.println(consigneEcrit);
 consigne=String(consigneEcrit);
}
//***********************************************COMMANDE CHAUDIERE (WHILE)********************************************************************
if(temp >=consigne.toInt()+hysteresis && consigne.toInt()<23 )
   {
   digitalWrite(relais1Pin, LOW);// le relais inactif
   chaudiere="off";
   }
 else if(consigne.toInt()>temp && consigne.toInt()<23)
   {
   digitalWrite(relais1Pin, HIGH);// le relais actif
   chaudiere="on";
   }

//*********************************************APPEL DES FONTIONS EMISSION SMS*****************************************************************
  envoiSms();
  nbsms = nbsms+1;
  lcd.setCursor(18,0);
  lcd.print(nbsms); 
  
  envoiSmsmaitre();
 
  //*************************************************************************************************************        
  //Serial.println("retour envoi maitre");
  
  
//********************************************ENCORE DES CAR A TRAITER***************************************************************
        }

if (chaineReception.toInt()==99){
  envoiSms();
  nbsms = nbsms+1;
  //nbsms=1;
  lcd.setCursor(18,0);
  lcd.print(nbsms); 
 
  envoiSmsmaitre();
  effacetouslesSMS (); 
  delay(2000);
  Serial.print("etat");
  }

        
    chaineReception=""; //RAZ le String de réception
    compt=0; // RAZ compteur
    break; // sort de la boucle while******************************************************************************************************************************
     }

     
     else { // si le caractère reçu n'est pas un saut de ligne
     caractereRecu=char(octetReception); // convertit l'octet reçu en caractère
     chaineReception=chaineReception+caractereRecu; // ajoute le caratère au String 
          
           }
      
     }



}
      
//****************************************************************ENVOI DE SMS*************************************************************************
void envoiSms()
{
//***************************************************Envoi du numero de telephone à joindre*************************************************************
   SIM900.print( "AT+CMGS=\"" );
   SIM900.print( tel );  
   SIM900.println("\"");
   delay(200); 
  // Serial.println(tel);
  // delay(100); 
   //************************************************************Contenu du message*********************************************************************
   SIM900.print("Thermostat : ");
   delay(100); 
   SIM900.print(consigne);
  // delay(100);
   SIM900.println("");
  // delay(100);
   SIM900.print("Temperature : ");
  // delay(100); 
   SIM900.print
   (temp);
  // delay(100);
   SIM900.println("");
   //delay(100);
   SIM900.print("Etat chaudiere : "); 
   //delay(100); 
   SIM900.print(chaudiere); 
   //delay(200);
   SIM900.println((char)26); // Envoi de Ctrl+z pour signaler la fin du message et l'envoi
   delay(5000);
  // Serial.println("fin envoi AR");
   
   return;
  }
//**************************************************************FONCTION  ENVOI SMS MAITRE********************************************************************
void envoiSmsmaitre()
{
   SIM900.print( "AT+CMGS=\"" ); // Envoi du numero de telephone à joindre
   SIM900.print( telmaitre );  
   SIM900.println("\"");
   delay(100);
   //SIM900.println("AT+CSQ=?\r");  //****************************************************************************************************************************
   //Serial.println(telmaitre);
   SIM900.print("appelant");
   SIM900.print(tel);
   delay(100);
   SIM900.println("");
   //delay(100);
   SIM900.print("Thermostat : ");
   SIM900.print(consigne);
   //delay(200);
   SIM900.println("");
   //delay(100);
   SIM900.print("Temperature : ");
   SIM900.print(temp);
   //delay(200);
   SIM900.println("");
   //delay(100);
   SIM900.print("Etat  : "); 
   SIM900.print(chaudiere); 
   //delay(100);
   SIM900.println((char)26); // Envoi de Ctrl+z pour signaler la fin du message et l'envoi
   delay(5000);
   //Serial.println("fin envoi");
   pinMode(razpin, OUTPUT); 
digitalWrite( razpin, HIGH);

   return;
  }

//**************************************************************EFFACE LES SMS*****************************************************
void effacetouslesSMS ()
{
  //SIM900.print("AT+CMGD=4\"\r");// a tester
  //SIM900.println("DEL ALL\"");
  //SIM900.print("AT+CMGD=1,4\"");
  SIM900.print("AT+CMGD=4\r");//a tester
  delay(1000);
 // Serial.println( "les SMS sont effacés" );
  //SIM900.print("AT+CMGDA=\"");
 // SIM900.println("DEL ALL\"");
  
return;
}
//****************************************************************MISE EN ROUTE SIM900********************************************

void powerUp()
{
  pinMode(9, OUTPUT); 
  digitalWrite(9,LOW);
  delay(1000);
  digitalWrite(9,HIGH);
  delay(2000);
  digitalWrite(9,LOW);
  delay(3000);
}
//**********************************************************LISTE DES MESSAGES***************************************************
void listeSMS ()
{
SIM900.print("AT+CMGL=\"ALL\"\r"); // a tester
SIM900.println();
}



  • Partager sur Facebook
  • Partager sur Twitter