Dans mon projet "Apaguard", j'ai eu besoin de rapatrier un certain nombre de données en temps réel. Un rucher étant généralement éloigné de toute civilisation, la transmission des informations collectées sur place ne peut se faire que par GSM, les abeilles étant rarement abonnées à l'ADSL !

En raison de son  prix modique et sa large utilisation, j'ai choisi d'utiliser un shield GSM SIM900.

Voici les quelques constatations faites lors de sa mise en service et son utilisation.

Interconnexion

Première mauvaise surprise, le shield SIM900 que j'ai acheté ne comporte pas de pins mâles sous la platine et je n'ai donc pas pu simplement l'enficher dans le UNO R3. Par ailleurs, le connecteur est du modèle pour UNO et le nombre de pin n'est pas identique à la version R3, bien que celles existantes soient compatibles entre elles.

Il a donc fallu que je le raccorde à l'aide de 4 fils :

ARDUINO SIM900  Usage
GND GND Masse
D9 D9 Software trigger
D7 D7 Software RxD
D8 D8 Software TxD

Alimentation et démarrage

Compte tenu de la consommation en émission qui peut atteindre 2A pendant des impulsions brèves, le shield sera alimenté à l'aide d'une batterie 12V et non le 5V de l'Arduino.

L'alimentation du shield se fera donc via le connecteur EXT POWER JACK, il faut alors basculer l'inverseur POWER SELECT sur  EXT.

Afin de limiter au maximum la consommation en veille, j'ai décidé de couper l'alimentation 12V à l'aide d'un MOSFET de puissance qui sera commandé par une pin digitale de l'Arduino au moment opportun.

Une fois le shield alimenté, il ne s'allume pas automatiquement, il faut donc passer par la procédure d'allumage... La mise en marche du module GSM se fait, soit manuellement en appuyant pendant au moins 1s sur le bouton "Power" ou par envoi d'une impulsion positive sur l'entrée D9 du shield d'un durée de 1s minimum suivi d'un état bas. Pour rendre cette fonction possible, il faut sur le shield SIM900 réaliser un pont par soudure sur les plots marqués R13.
Pour utiliser la version "soft" de l'interface série, il faut positionner les 2 cavaliers RX et TX présents sur le shield en position D7 et D8.

Une fois mis en marche, il faut compter au moins 6 s avant que la SIM soit reconnue et que toute commande soit reconnue. Compter 17 s avant d'être enregistré sur le réseau. Il faut donc tenir compte de ces délais dans le programme !
Au démarrage, la LED "Net light" clignote à un rythme de 800ms. Si la carte SIM est valable et si le réseau de votre opérateur est bien disponible, le rythme passera au bout à un rythme de 3s.

On peut utiliser la commande AT+CREG? pour vérifier si le shield est bien enregistré sur le réseau.

// fonction mise en marche GSM
void GSM_ON() {
if ( sendAT("AT", "OK", 1000) == 0 )  {             // test si le GSM ne pas répond, on l'allume
        Serial.println(F("GSM -> ON"));
        digitalWrite(pinPowerGSM,HIGH);             // MARCHE alim 12V module GSM
        delay(1000);                                // le temps que le GSM démarre
        digitalWrite(9,HIGH);                       // envoi d'une impulsion positive de mise en marche
        delay(1000);
        digitalWrite(9,LOW);
        delay(1000);
    }
// test si GSM enregistré sur le réseau, envoi commande CREG, 20 fois si nécessaire
    byte i = 20;    
    while ( i != 0 && sendAT("AT+CREG?", "+CREG: 0,1", 500) == 0  ) {
      --i; delay(3000);
      };
    if ( i == 0 ) {                                  // non enregistré !
       Serial.println(F("GSM problem ! STOP !"));

       digitalWrite(pinPowerGSM,LOW);
    }        
} // FIN GSM_ON

 

Arrêt

La mise à l'arrêt peut se faire soit par appui pendant 2 s sur le bouton power, soit par l'envoi d'une commande sur la pin D9 (software triggrer) ou enfin par la commande AT+CPOWD=1 qui permet également l'extinction du shield. 

Problème...., il n'y a pas de réelle différence entre la procédure de mise en marche ou arrêt par la commande software trigger qui se fait par envoi d'une impulsion d'au moins 1s sur la pin D9, il peut donc y avoir confusion des genres...

Afin d'être certain de ne pas allumer le GSM par erreur en éxécutant la fonction d'arrêt, il faut tester si le shield est allumé. Un moyen simple est d'envoyer la commande AT , qui répond par OK si le shield est allumé.

La commande AT+CPOWD=1, permettrait cependant de passer outre ce problème.

Une fois la commande ARRET envoyée, l'alimentation du shield sera également coupée par le MOSFET pour économiser la batterie.

// fonction arrêt GSM
void GSM_OFF(){
    if ( sendAT("AT", "OK", 900) == 1) {                      // test si le GSM est allumé     
       GPRS.println(F("AT+CPOWD=1"));
       Serial.println(F("GSM -> OFF"));
      }
       #if defined(DEVMODE)
            else  { 
                Serial.println(F("GSM already OFF")); 
                  }
       #endif
    digitalWrite(pinPowerGSM,LOW);                            // Coupure alim 12V module GSM
} // FIN GSM_OFF

Enregistrement sur le réseau

Une fois allumé, le shield met un certain temps avant d'être utilisable. Ce temps est variable suivant la qualité du signal reçu, la date du dernier enregistrement, etc...

Au démarrage, la LED "Net light" clignote à un rythme de 800ms. Si la carte SIM est valable et si le réseau de votre opérateur est bien disponible, le rythme passera au bout de quelques secondes à 3s.

La commande AT+CREG? permet de savoir si le terminal GSM est enregistré sur le réseau. La réponse est de la forme +CREG: <n>,<stat> , par exemple +CREG: 0,1. Le 2ème chiffre indique si le GSM est enregistré et sur quel réseau.
0 = non enregistré, 1 = opérateur hôte, 5 = opérateur roaming.

Il faut donc tester les 2 cas,  +CREG: 0,1 ET +CREG: 0,5 pour savoir si le GSM est bien enregistré. Le 2ème cas est celui d'un opérateur comme "free" qui a des accords d'itinérance (roaming) avec Orange.

Qualité du signal

Aux fins d'observations, j'ai souhaité enregistrer la qualité du signal GSM reçu sur site. Il existe une commande AT+CSQ qui retourne au terminal AT+CSQ: <rssi>,<ber> . Par exemple AT+CSQ: 18,0

Le niveau de signal est le 1er chiffre <rssi>, le second est le "bit error rate" BER qui donne le pourcentage d'erreurs. Il faut donc décoder la trame reçue et en extraire ce 1er chiffre. Dans mes recherches et écriture de fonctions, je suis passé par des décodages caractères par caractères et autres finesses qui toutes demandaient pas mal de lignes de code.
J'ai finalement adopté une solution utilisant les fonctions readStringUntil(), et parseint() qui, par un heureux hasard, retourne le premier nombre entier trouvé dans un flux série et permet d'écrire une fonction très compacte !

// lecture valeur CSQ
void GSM_CSQ() {
      CSQ=0;
      GPRS.println(F("AT+CSQ")); // envoi de la demande AT+CSQ au GSM

      if ( GPRS.readStringUntil('OK\n')){               // on attend la réception de OK dans la chaîne reçue
            CSQ = GPRS.parseInt();                      // on récupère la 1ère valeur INT, le reste est ignoré
            //byte BER =GPRS.parseInt();                // si on voulait afficher le BER
            }
} //FIN GSM_CSQ

 

Envoi de SMS

Pour envoyer un texte SMS avec le shield SIM900, il faut :

  1. Choisir le mode texte. On passe en mode "texte" à l'aide de la commande AT+CMGF=1
  2. Programmer le numéro du destinataire.  On utilise la commande AT + CMGS= "+33xxxxxxxxx". Le numéro DOIT être entré avec le préfixe international ! Le terminal répond par " > "
  3. Programmer le texte à envoyer. 
  4. Envoyer le message. On termine par le caractère de contrôle CTRL-Z, ou  ASCII 26 ou 0x1A

Si tout est OK, le terminal retourne OK

Initialisation du GSM et inscription APN

Afin de pouvoir utiliser le GSM il faut établir la connexion GPRS

  1. AT+SAPBR=3,1,CONTYPE,GPRS
  2. Envoi du nom de l'APN de l'opérateur AT+SAPBR=3,1,APN,xxx
  3. Envoi du nom de l'utilisateur de l'APN par AT+SAPBR=3,1,USER,xxx
  4. Envoi du mot de passe de l'APN par AT+SAPBR=3,1,PWD,xxx
  5. Etablissement de la connexion GPRS par AT+SAPBR=0,1

ATTENTION si la dernière commande est envoyée 2 fois, il y aura une erreur ERROR au lieur de OK. Il est donc conseillé d'envoyer une commande de fermeture de la connexion GPRS avant !

Envoi d'une requête GET en HTTP

Un fois le GSM enregistré sur le réseau, il est possible d'utiliser l'APN de votre opérateur afin d'envoyer et recevoir des données HTTP sur Internet.

  1. Pour cela, il faut initialiser le service HTTP avec le commande AT+HTTPINIT, qui doit répondre OK.
  2. Paramétrer le CID avec la commande AT+HTTPARA=CID,1
  3. Construire la requête à envoyer
  4. Envoyer cette requête à l'aide de la commande AT+HTTPACTION=0 , si tout va bien la réponse est +HTTPACTION:0,200
  5. Lire la réponse du serveur avec la commande AT+HTTPREAD
  6. Fermer le service HTTPD par AT+HTTPTERM
  7. Fermer la connexion GPRS par AT+SAPBR=0,1