Télécommandez par SMS !

In: ELECTRONIQUE PRATIQUE AVEC L'ARDUINO On: Comment: 0 Hit: 1638

Imaginez un petit module GSM, pas cher, que vous doterez d'une carte SIM, et que vous pourrez ensuite gérer de multiples manières pour réaliser votre automatisme sur mesure...

Allez, juste 2 exemples:

  • Quand votre voiture bouge, vous envoyez chaque minute un SMS contenant ses coordonnées GPS.
  • vous envoyer un sms à votre automate pour provoquer des actions. Il vous répond lui aussi par SMS

Il vous faudra quoi ?

Nous allons apprendre à:

  • communiquer avec le module GSM en utilisant de simples commandes AT
  • envoyer des SMS
  • recevoir des SMS

Vous pourrez ensuite vous "amuser" à transmettre des ordres par SMS, à déclencher des action, et à transmettre, toujours par SMS, des accusés de réception ou des informations plus complètes

Si vous avez consulté tous les articles et forums sur le sujet, vous avez dû croiser beaucoup de personnes dans la galère, qu'ils soient à la recherche du bon module GSM, du bon firmware pour que ça fonctionne (notamment chez nous et pas juste en Asie), ou encore de la bonne alimentation électrique.

Nous avons choisi un module GSM doté du processeur GSM/GRPS A6 et disponible ici, ou en option avec notre carte Arduino. Premier avantage: vous l'alimenterez tout simplement avec le +5V de votre carte Arduino, même lorsque celle-ci est elle-même alimentée par le port USB de votre ordinateur (Mac ou PC).

Pour passer à un système autonome, il suffira de débrancher votre cordon Usb et d'utiliser un petit adaptateur secteur 9V DC, proposé ici en option avec notre carte Arduino.

Les seules liaisons nécessaires entre la carte Arduino et le module GSM sont l'alimentation (+5V et GND) et la liaison série. Nous allons utiliser RX2 et TX2 sur la carte Arduino, à relier sur U_TXD et U_RXD du module GSM (Receive sur Transmit et inversement).

Vous pouvez lancer votre logiciel Arduino et tester quelques commandes AT, manière la plus directe pour contrôler vos actions. Il existe très probablement des bibliothèque pour "simplifier" la prise de contrôle du module GSM, mais ce sera moins souple et vous risquez des surprises, sans pouvoir comprendre alors d'où vient le problème.

Les commandes AT, c'est le langage universel pour tous les périphériques de communication, même s'ils ne répondent pas forcément tous à toutes les commandes existantes. Celles de notre module GSM sont très largement documentées (177 pages) par le fabricant et nous fournissons le pdf avec le module.

Avant de brancher votre cordon Usb (et donc d'alimenter la carte et le module), insérez votre carte SIM (format micro). Si vous n'en avez pas encore, vous pouvez tout de même tester la communication avec le module, mais sans pouvoir évidemment communiquer. Pour nos essais, nous avons d'abord démonté une carte BandYou d'un téléphone, puis acheté une carte SIM chez Prixtel (forfait 2 €).

Le point faible de ce genre de modules, c'est leur support de carte SIM; Il vaut mieux assurer sa bonne fermeture avec un trombone par exemple. La carte SIM doit être bien en place avant d'alimenter le module.

ICI EST PREVUE LA PHOTO DE NOTRE MONTAGE

On peut passer à un premier programme qui nous permettra de tester la communication avec le module; il consiste à envoyer quelques commandes AT de base à notre module et d'afficher ses réponses sur le Moniteur Série de notre application Arduino.

#include <SoftwareSerial.h>

// https://www.1ou2clics.com/forum-alarme/electronique-pratique-avec-l-arduino-c8.html

// d'abord la phase d'initialisation de notre programme: vitesse de communication sur les 2 ports série utilisés

void setup()
{
  Serial.begin(9600);  // on affiche les résultats sur le Moniteur série du logiciel Arduino (via le port Usb)
  Serial2.begin(9600);   // le GSM est connecté sur Serial2 de la carte Arduino Mega 2560 R3
}


// CommSerie est un petit sous-programme qui va faire 2 choses, dans cet ordre: transmettre au module GSM les données que nous envoyons à la carte Arduino
// et envoyer sur le port série de l'Arduino (relié à notre ordinateur) les données série en provenance du module

void CommSerie()
{
   delay(200);
   while(Serial.available()) {
   Serial2.write(Serial.read());
   }
 
   while (Serial2.available()) {
   Serial.write(Serial2.read());
   }
}

void loop()
{
  Serial2.println("ATI");        //permet de récupérer des informations sur le module de communication
  CommSerie();

  Serial2.println("AT+CCID");    //permet de vérifier la présence de la carte SIM (retourne le n° EMEI)
  CommSerie();
 
  Serial2.println("AT+CPIN=0000");  // on fournit le code PIN de la carte SIM (ici 0000)
  CommSerie();

  Serial2.println("AT+CMGF=1");    //format texte pour les sms
  CommSerie(); 
   
  Serial2.println("AT+CSQ");      //indique la qualité du signal, de 0 à 31 (31 étant la meilleure qualité)
  CommSerie();
   
  Serial2.println("AT+CREG?");    //est-on connecté au réseau GSM ? Le retour espéré est +CREG: 1,1
  CommSerie();   

// petite boucle finale pour rester à l'écoute et afficher les données transmises par le module GSM
  while(1) {
  CommSerie(); 
  }
}

Charger puis exécutez ce programme, affichez le Moniteur Série en veillant bien à définir la bonne vitesse (9600 bauds). En réponse, vous devriez obtenir ceci (avec évidemment un numéro de carte SIM et un niveau de réception différents). Si vous n'avez pas mis de carte SIM ou que le code PIN est erroné, vous obtiendrez des messages d'erreur en retour.

ATI

Ai Thinker Co.LTD
A6
V03.03.20161229019H03

OK
AT+CCID

+CCID:89331043170034022395
OK


AT+CPIN=0000
OK


AT+CMGF=1
OK


AT+CSQ
+CSQ: 10,99

OK
AT+CREG?

+CREG: 1,1
OK

Si tout fonctionne bien, vous pouvez dès à présent, avec un autre téléphone, envoyer un SMS au numéro de la carte SIM et observer ce qui se passe sur votre Moniteur. Parce que notre programme, après avoir transmis quelques codes AT, attend d'éventuelles données en provenance du module.

Vous pouvez aussi appeler le numéro de la carte SIM et observer le résultat sur votre Moniteur série.

Vous devriez obtenir des messages RING en appelant le numéro, et quelques-choses comme ceci à la réception d'un SMS:

+CMT: "+336XXXXXXXX",,"2018/04/12,23:09:21+02"
LE TEXTE DE VOTRE SMS
Il vous manquera peut-être un morceau... pas d'inquiétude, nous allons corriger ce petit point. Il faut augmenter la taille de la mémoire tampon du port série. Sur Mac, faites un clic droit sur l'application Arduino et choisissez "afficher le contenu du paquet". Allez dans Contents/Java/hardware/arduino/avr/cores/arduino, ouvrez le fichier HardwareSerial.h et modifiez la taille du Buffer de réception: mettez 256 au lieu de 64

Voici un extrait de ce fichier et la valeur à modifier (en gras):

#ifndef HardwareSerial_h
#define HardwareSerial_h

#include <inttypes.h>

#include "Stream.h"

// Define constants and variables for buffering incoming serial data.  We're
// using a ring buffer (I think), in which head is the index of the location
// to which to write the next incoming character and tail is the index of the
// location from which to read.
// NOTE: a "power of 2" buffer size is reccomended to dramatically
//       optimize all the modulo operations for ring buffers.
// WARNING: When buffer sizes are increased to > 256, the buffer index
// variables are automatically increased in size, but the extra
// atomicity guards needed for that are not implemented. This will
// often work, but occasionally a race condition can occur that makes
// Serial behave erratically. See https://github.com/arduino/Arduino/issues/2405
#if !defined(SERIAL_TX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_TX_BUFFER_SIZE 16
#else
#define SERIAL_TX_BUFFER_SIZE 64
#endif
#endif
#if !defined(SERIAL_RX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_RX_BUFFER_SIZE 16
#else
#define SERIAL_RX_BUFFER_SIZE 256
#endif
#endif
#if (SERIAL_TX_BUFFER_SIZE>256)
typedef uint16_t tx_buffer_index_t;
#else
typedef uint8_t tx_buffer_index_t;
#endif
#if  (SERIAL_RX_BUFFER_SIZE>256)
typedef uint16_t rx_buffer_index_t;
#else
typedef uint8_t rx_buffer_index_t;
#endif

Pour envoyer un SMS:

revenez à votre programme Arduino et ajoutez, après la série de commandes AT, ces quelques lignes (en précisant le numéro de téléphone à joindre par SMS):

delay(300);
Serial2.println("AT+CMGF=1");   
delay(2000);
Serial2.println("AT+CMGS="06XXXXXXXX"");
delay(2000);
Serial2.print("Test envoi automatique de SMS");
Serial2.println (char(26)); //il faut terminer avec CTRL Z

Voilà, vous savez l'essentiel; il ne vous reste plus qu'à analyser les SMS qui parviennent à votre système pour réaliser des actions (déclencher des relais ou n'importe quoi d'autre). ci-dessous un exemple assez simple:

si vous lui envoyez un SMS contenant la chaîne de caractères @1234 (que l'on considère comme le code), il vous renverra un SMS de confirmation.

Dans le sous programme de communication, on regarde si on reçoit le caractère @. Si oui, on vérifie si les 4 caractères suivants sont 1234, auquel cas on valide l'émission d'un SMS de confirmation. Dans le sous-programme confirmerParSMS(), il est facile d'ajouter quelques actions supplémentaires.

#include <SoftwareSerial.h>

// https://www.1ou2clics.com/forum-alarme/electronique-pratique-avec-l-arduino-c8.html

// d'abord la phase d'initialisation de notre programme: vitesse de communication sur les 2 ports série utilisés

char recu;
char code1,code2,code3,code4;
byte AR=0;

void setup()
{
  Serial.begin(9600);  // on affiche les résultats sur le Moniteur série du logiciel Arduino (via le port Usb)
  Serial2.begin(9600);   // le GSM est connecté sur Serial2 de la carte Arduino Mega 2560 R3
}

// petit sous-programme qui fait 2 choses, dans cet ordre: transmettre au module GSM les données que nous envoyons à la carte Arduino
// et envoyer sur le port série de l'Arduino (relié à notre ordinateur) les données série en provenance du module

void CommSerie()
{
    delay(200);
    while(Serial.available()) {
    Serial2.write(Serial.read());
  }
 
  while (Serial2.available()) {
    recu=Serial2.read();
    Serial.write(recu);
    if (recu=='@') {
      if (Serial2.available()>=4) {
        code1=Serial2.read();
        code2=Serial2.read();
        code3=Serial2.read();
        code4=Serial2.read();
        Serial.write(code1);
        Serial.write(code2);
        Serial.write(code3);
        Serial.write(code3);
        if (code1=='1' & code2=='2' & code3=='3' & code4=='4') {
          Serial.write(" (CODE OK) ");
          AR=1;
        }
      }
    }
  }
    if (AR==1) {
    AR=0;
    confirmerParSMS();
    }
}  

void confirmerParSMS() {

  delay(300);
  Serial2.println("AT+CMGF=1");   
  delay(2000);
  Serial2.println("AT+CMGS="06XXXXXXXX"");
  delay(2000);
  Serial2.print("OK - LUMIERES ALLUMEES");
  Serial2.println (char(26)); //il faut terminer avec CTRL Z
}


void loop() {
 
  Serial2.println("AT+CPIN=0000");  // on indique le code PIN de la carte SIM (ici 0000)
  CommSerie();

  Serial2.println("AT+CMGF=1");    //format texte pour les sms
  CommSerie(); 
   
  Serial2.println("AT+CSQ");      //indique la qualité du signal, de 0 à 31 (31 étant la meilleure qualité)
  CommSerie();
   
  Serial2.println("AT+CREG?");    //est-on connecté au réseau GSM ? Le retour espéré est +CREG: 1,1
  CommSerie();   

  while(1) {
  CommSerie(); 
  }

}

Commentaires

Leave your comment