Cet article fait office de tutoriel. Vous apprendrez à envoyer des commandes AT au SIM900 et à afficher les réponses correspondantes dans un moniteur série. Par ailleurs vous trouverez sur cette page l’ensemble de mes tutoriels dédiés à Arduino. Jetez-y un coup d’oeil. Bonne lecture !

Je travaille actuellement sur un projet qui fait usage du GSM pour envoyer des SMS. Il est également question d’échanger des informations avec un serveur FTP en utilisant le GPRS. En effet je travaille avec d’autres élèves ingénieurs à la conception d’un CanSat afin de participer au C’Space. Un CanSat est une sonde spatiale pas plus grande qu’une canette de soda et qui présente toutes les fonctions de base d’un satellite (alimentation, communication, géolocalisation, relevés atmosphériques …). Pour ce faire j’ai choisi le module SIM900 de SIMCom. C’est l’objet de cette série d’article que j’inaugure aujourd’hui. J’ai interfacé ce module GSM avec une carte Arduino au moyen d’une simple liaison série (UART). Je vous propose dans cet article de découvrir quelques-unes des fonctionnalités offertes par le SIM900 et de comprendre leur mise en oeuvre.

La carte Arduino commande le module GSM en utilisant des commandes AT. Retenez bien ce nom ! Les commandes AT (ou commandes de Hayes) constituent un langage de commande développé afin de commander les modems. Ce langage a été créé initialement pour le modem Smatmodem 300 de Hayes. Par exemple la commande « ATZn » réinitialise le modem. Nous étudierons dans le détail la syntaxe de ces commandes dans les lignes qui suivent. En attendant je vous renvoies à cette page dédiée sur Wikipedia pour plus d’informations sur les commandes de Hayes.

Revenons en au module SIM900 de SIMCom. J’ai choisi celui-ci avant tout pour sa simplicité d’utilisation. Ce module a fait ses preuves et est très répandu dans le monde du DIY. Vous trouverez ainsi de nombreux shields GSM pour Arduino construit autour de ce module. Par ailleurs celui-ci est compatible avec les bandes de fréquences 1800MHz, 1900MHz, 850MHz et 900MHz ce qui vous permet de l’utiliser dans tous les pays munis d’un réseau GSM. Voici les principales caractéristiques du SIM900.

  • Module Quadri-Bande 850 / 900/ 1800 / 1900 MHz
  • GPRS multi-slot class 10/8
  • GPRS mobile station class B
  • Class 4 (2 W @ 850 / 900 MHz)
  • Class 1 (1 W @ 1800 / 1900MHz)
  • Contrôle à l’aide de commandes AT – Commandes standard: GSM 07.07 & 07.05 – Commandes étendues: SIMCOM AT Commands
  • Envoi de SMS au format ASCII ou Hexadécimal
  • TCP/UDP
  • Présence de deux sorties PWM
  • Convertisseur analogique/numérique intégré (logique 2.8V)

Si ces chiffres ne vous parlent pas retenez que ce module peut envoyer et recevoir des SMS ou encore échanger des données avec un serveur Web en utilisant une connexion GPRS. Vous pouvez également passer des appels téléphoniques.

Néanmoins ce module ne peut fonctionner tel-quel. Vous devrez impérativement lui adjoindre un lecteur de carte SIM et un connecteur d’antenne. De même qu’il convient de prendre garde aux niveaux logiques utilisés par le module SIM900. En effet cette puce fonctionne sous la tension de 2.8V alors que la plupart des cartes Arduino fonctionnent sous la tension de 5V ! Il est donc impératif de convertir les niveaux logiques au risque de détruire le SIM900. C’est pourquoi il vous faudra choisir un shield GSM adapté pour utiliser le module SIM900 avec une carte Arduino. Si vous souhaitez vous affranchir des shields GSM du marché vous trouverez dans le datasheet du SIM900 de nombreux schémas de référence afin de vous aider à concevoir vos propres circuits. Vous pouvez également vous aidez des schémas des shields existants. Bien que ceux-ci ne soient pas toujours exempts de défauts !

Pour mes expérimentations je me suis orienté vers le module GPRSbee. En effet j’ai une contrainte d’encombrement très importante pour mon projet puisque tout l’électronique ne doit pas dépasser le volume d’une canette de soda ! Un défi de taille (sans jeux de mots). C’est pourquoi j’ai choisi cette carte à peine plus grande qu’un module XBee ! Celle-ci exploite uniquement la liaison série offerte par le SIM900 ce qui convient à la plupart des besoins mais ne permet pas de passer des appels téléphoniques. Soyez-en prévenus si vous envisagez de commander ce circuit. Le GPRSbee a été désigné par Gregory Knauff. Vous pouvez consulter son site internet en suivant ce lien. Toutefois si ce module est bien conçu je déplore qu’il n’existe aucune documentation à son sujet. Pas même sur le site internet qui lui est dédié ! Un comble. Ce n’est qu’après avoir attentivement étudié les schémas du GPRSbee que j’ai commencé à comprendre son fonctionnement. J’ai ensuite parcouru le Web afin de trouver quelques exemples de programmes Arduino faisant usage du SIM900.

Passons désormais à la pratique ! Voici un programme Arduino très simple qui permet d’envoyer des commandes AT au module GSM. Les réponses du module GSM s’affiche directement dans le moniteur série. J’ai utilisé une carte Arduino Méga pour réaliser ce programme. Pour rappel cette carte dispose de quatre ports séries ! Le port Serial est utilisé pour communiquer avec l’ordinateur et afficher les réponses dans le moniteur série tandis que le port Serial2 est utilisé pour communiquer avec le module SIM900 et envoyer les commandes AT. Si vous ne disposez pas d’une carte Arduino Méga vous pouvez créer un port série de manière logiciel en utilisant la bibliothèque newSoftSerial. Le fonctionnement de cette bibliothèque est très simple. N’hésitez pas à vous manifester dans les commentaires si vous avez besoin de précisions quant à son utilisation. Voici le programme Arduino en question.

//SIM900 - Prise en main
//Par Pierre Pelé
//http://upsilonaudio.com/
//Décembre 2013

int8_t answer;
int x ;
int onModulePin= 2; // Il s'agit du port DTR (ou PWR) du module SIM900.
char REPONSE[200];

void setup(){

    pinMode(onModulePin, OUTPUT);
    Serial2.begin(115200);
    Serial.begin(115200);
    Serial.println("------------------------------------------------------");
    Serial.println("----Upsilon Audio - Prise en main du module SIM900----");
    Serial.println("------------------------------------------------------");
    Serial.println("");
    Serial.println("Initialisation en cours ...");
    Serial.println("");
    power_on();
    delay(3000);
    Serial.println("------------------------------------------------------");
    Serial.println("Nom de votre operateur");
    sendATcommand_2("AT+COPS?","OK",5000);
    Serial.println("------------------------------------------------------");
    Serial.println("Etat de la connexion au reseau");
    Serial.println("La connexion est etablie si +CREG: 0,0 ou +CREG: 0,5");
    sendATcommand_2("AT+CREG?","OK",5000);
    Serial.println("------------------------------------------------------");
    Serial.println("Numero de telephone");
    sendATcommand_2("AT+CNUM","OK",5000);
    Serial.println("------------------------------------------------------");
    Serial.println("Numero IMSI");
    sendATcommand_2("AT+CIMI","OK",5000);
    Serial.println("------------------------------------------------------");
    Serial.println("Services offerts par le modem");
    sendATcommand_2("AT+GCAP","OK",5000);
    Serial.println("------------------------------------------------------");
    Serial.println("Qualitee du signal");
    sendATcommand_2("AT+CSQ","OK",5000);
    Serial.println("------------------------------------------------------");
    Serial.println("Numero IMEI");
    sendATcommand_2("AT+CGSN","OK",5000);
    Serial.println("------------------------------------------------------");
    Serial.println("Numero ICCID");
    sendATcommand_2("AT+CCID","OK",5000);
    Serial.println("------------------------------------------------------");
    Serial.println("Charge de la batterie");
    sendATcommand_2("AT+CBC","OK",5000);
    Serial.println("------------------------------------------------------");
    Serial.println("Nom du modele");
    sendATcommand_2("AT+GMM","OK",5000);
    Serial.println("------------------------------------------------------");
    Serial.println("Version du software");
    sendATcommand_2("AT+CGMR","OK",5000);
}


void loop() // Il n'y a aucune commandes dans la fonction loop.
{
}

// Définition des différentes fonctions.

void power_on(){

    uint8_t answer=0;
    
    // Cette commande vérifie si le module GSM est en marche.
    answer = sendATcommand_1("AT", "OK", 2000);
    if (answer == 0)
    {
        // Mise en marche du module GSM
        digitalWrite(onModulePin,HIGH);
        delay(3000);
        digitalWrite(onModulePin,LOW);
    
        // Envoie d'une commande AT toutes les deux secondes et attente d'une réponse.
        while(answer == 0){
            answer = sendATcommand_1("AT", "OK", 2000);    
        }
    }
    
}

// Cette fonction permet d'envoyer des commandes AT au module GSM.
int8_t sendATcommand_1(char* ATcommand, char* expected_answer, unsigned int timeout){

    uint8_t x=0,  answer=0;
    char response[100];
    unsigned long previous;

    // Initialisation de la chaine de caractère (string).
    memset(response, '\0', 100);
    
    delay(100);
    
    // Initialisation du tampon d'entrée (input buffer).
    while( Serial2.available() > 0) Serial2.read();
    
    // Envoi des commandes AT
    Serial2.println(ATcommand);


    x = 0;
    previous = millis();

    // Cette boucle attend la réponse du module GSM.
    
    do{
// Cette commande vérifie s'il y a des données disponibles dans le tampon.
//Ces données sont comparées avec la réponse attendue.
        if(Serial2.available() != 0){    
            response[x] = Serial2.read();
            x++;
            // Comparaison des données
            if (strstr(response, expected_answer) != NULL)    
            {
                answer = 1;
            }
        }
    // Attente d'une réponse.
    }while((answer == 0) && ((millis() - previous) < timeout));    

    return answer;
}

void sendATcommand_2(char* ATcommand, char* expected_answer, unsigned int timeout){

    uint8_t x=0,  answer=0;
    char response[100];
    unsigned long previous;

    // Initialisation de la chaine de caractère (string).
    memset(response, '\0', 100);
    
    delay(100);
    
    // Initialisation du tampon d'entrée (input buffer).
    while( Serial2.available() > 0) Serial2.read();
    
    // Envoi des commandes AT
    Serial2.println(ATcommand);


    x = 0;
    
    
    previous = millis();

    // Cette boucle attend la réponse du module GSM.
    
    do{
// Cette commande vérifie s'il y a des données disponibles dans le tampon.
//Ces données sont comparées avec la réponse attendue.
        if(Serial2.available() != 0){    
            response[x] = Serial2.read();
            x++;
            // Comparaison des données
            if (strstr(response, expected_answer) != NULL)    
            {
              response[x] = '\0';  
              answer = 1;
            }
        }
    // Attente d'une réponse.
    }while((answer == 0) && ((millis() - previous) < timeout));    

    if (answer == 0){
      Serial.println("");
      Serial.println("Erreur ! Temps depasse.");
      Serial.println("");
    }
    else
    {
      Serial.println("");
      Serial.println(response);
      Serial.println("");
    }
}

Vous pouvez télécharger ce programme en suivant ce lien (5,48 Ko). Vous pouvez également suivre l’évolution de ce programme sur GitHub ! Vous n’avez aucunes excuses pour ne pas télécharger ce programme.

Ce programme renvoi sur le moniteur série quelques informations utiles. Nous analyserons ces informations dans leur ordre d’apparition dans le programme. La fonction power_on allume le SIM900 si celui-ci est éteint. Pour cela une impulsion électrique est appliquée au port DTR du SIM900. Les commandes AT sont envoyées au module GSM via la fonction sendATCommand_2. Cette fonction fonction attend trois argument. Le premier argument est la commande AT à envoyer au SIM900. Le deuxième argument constitue la réponse attendue tandis que le dernier argument représente le temps d’attente maximal. Si au terme du temps d’attente maximal (troisième argument) le SIM900 ne renvoi pas la réponse attendue (deuxième argument) alors l’instruction s’interrompt et le programme continue son exécution. Si le SIM900 renvoi la réponse escomptée avant le temps maximal alors la réponse est envoyée au moniteur série. Cette réponse est stockée dans un tableau de caractères dont la taille est fixée à 100. C’est aussi simple que ça !

Intéressons nous désormais aux différentes commandes AT appelées par ce programme. Voici la première commande.

sendATcommand(« AT+CPIN=**** », « OK », 2000);
Activation de la carte SIM

La commande AT+CPIN=**** permet de déverrouiller la carte SIM. Vous devez remplacer les astérisques par votre code PIN. Supprimez simplement cette ligne si voter carte SIM ne possède pas de code PIN. Cette commande renvoi le code OK en cas de réussite. Le temps d’attente maximal est de 2 secondes.

Je vous recommande pour vos expérimentations de supprimer le code PIN. En effet celui-ci peut-être source de problèmes si vous faites des RESET à répétition. Par ailleurs le fonctionnement de la fonction sendATCommand est très similaire à celui de la fonction sendATCommand_2 si ce n’est que cette fonction ne transfère pas la réponse du module SIM900 sur le moniteur série.

Serial.println(« Nom de votre operateur »);
sendATcommand_2(« AT+COPS? », »OK »,5000);
Nom de l'opérateur

La commande AT+COPS? renvoi simplement le nom de l’opérateur auquel vous êtes connecté. Par exemple avec ma carte SIM Free Mobile j’obtient la réponse Orange F. En effet Free utilise en partie le réseau d’Orange afin d’élargir sa couverture 3G et 2G.

Serial.println(« Etat de la connexion au reseau »);
Serial.println(« La connexion est etablie si +CREG: 0,0 ou +CREG: 0,5 »);
sendATcommand_2(« AT+CREG? », »OK »,5000);
Etat de la connexion au reseau

La commande AT+CREG? renseigne l’état de la connexion au réseau. Le SIM900 est connecté au réseau si (et seulement si) la réponse est +CREG: 0,0 ou +CREG: 0,0. Autant vous prévenir tout de suite. Ca ne sert à rien d’essayer d’envoyer un SMS avec le SIM900 si vous n’êtes pas connectés au réseau ! Cette simple commande permet donc de faire cette vérification et d’éviter bien des problèmes.

Serial.println(« Numero de telephone »);
sendATcommand_2(« AT+CNUM », »OK »,5000);
Numero de telephone

La commande AT+CNUM renvoi le numéro de téléphone associé à la carte SIM.

Serial.println(« Numero IMSI »);
sendATcommand_2(« AT+CIMI », »OK »,5000);
Numero IMSI

La commande AT+CIMI renvoi votre numéro IMSI. Le numéro IMSI (International Mobile Subscriber Identity) est un identifiant privé qui est stocké dans la carte SIM. C’est ce numéro qui permet au réseau mobile de vous identifier de manière unique. Seul votre opérateur connaît la correspondance entre le numéro de téléphone (identifiant public) et le numéro IMSI (identifiant privé).

Serial.println(« Services offerts par le modem »);
sendATcommand_2(« AT+GCAP », »OK »,5000);
Services offerts par le modem

La commande AT+GCAP renvoi les différents services qui sont offerts par le modem comme le GSM le GPRS ou encore le FAX.

Serial.println(« Qualitee du signal »);
sendATcommand_2(« AT+CSQ », »OK »,5000);
Qualitee du signal

La commande AT+CSQ renvoi la qualité du signal.

  • Si le module renvoi la valeur 99 alors la qualité du signal est inconnue ou n’est pas décelable
  • Si le module renvoi la valeur 0 alors la qualité est inférieure à -115 dBm
  • Si le module renvoi la valeur 1 alors la qualité est de -111 dBm
  • Si le module renvoi une valeur comprise entre 2 et 30 alors la qualité est comprise entre -110 dBm et -54 dBm
  • Si le module renvoi la valeur 31 alors la qualité est supérieure à -52 dBm
Serial.println(« Numero IMEI »);
sendATcommand_2(« AT+CGSN », »OK »,5000);
Numero IMEI

La commande AT+CGSN renvoi le numéro IMEI du SIM900. Le numéro IMEI (International Mobile Equipment Identity) permet d’identifier de manière unique un équipement GSM ou UMTS. En d’autres termes le numéro IMEI est l’identifiant du SIM900 sur le réseau. C’est ce numéro qui permet de bloquer un téléphone volé auprès de l’ensemble des opérateurs utilisant la base de donnée IMEI. Ce qui est le cas de tous les opérateurs français.

Serial.println(« Numero ICCID »);
sendATcommand_2(« AT+CCID », »OK »,5000);
Numero ICCID

La commande AT+CCID renvoi le numéro ICCID de la carte SIM. Le numéro ICCID (Integrated Circuit Card Identifier) est le numéro de série unique de la carte SIM. À titre d’exemple c’est ce numéro qui vous est demandé lorsque vous activez votre carte SIM en ligne.

Serial.println(« Charge de la batterie »);
sendATcommand_2(« AT+CBC », »OK »,5000);
Charge de la batterie

 La commande AT+CBC renvoi la charge de la batterie. Cette commande renseigne la tension délivrée par la batterie ainsi que sa charge en pour cent.

Serial.println(« Nom du modele »);
sendATcommand_2(« AT+GMM », »OK »,5000);
Nom du modele

 La commande AT+GMM renvoi le nom du module GSM que vous utilisez. À savoir le module SIM900 dans notre cas !

Serial.println(« Version du software »);
sendATcommand_2(« AT+CGMR », »OK »,5000);
Version du software

 Nous terminons notre programme par la commande AT+CGMR. Celle-ci renvoi la version du firmware du SIM900. Le module GPRSBee possède un port de débogage qui permet de mettre à jour le SIM900 si besoin.

Voilà ! La liste des commandes AT compatibles avec le module SIM900 se trouvent dans ce document .pdf édité par SIMCom. Vous trouverez pour chaque commande la fonction associée, la syntaxe exacte ainsi que les différents codes de retours possibles. Par exemple la commande « ATZ » réinitialise les différents paramètres du module GSM à leur valeur d’usine. Cette commande retourne le code « OK » en cas de réussite ou « ERROR » le cas échéant. Je vous conseille de jetez un coup d’œil à ce document tant la liste de commandes est nombreuse …

Dans un prochain article nous avancerons dans nos expérimentations et verrons comment envoyer ou recevoir des SMS avec une carte Arduino en utilisant le SIM900. Patience !

Pierre Pelé

PS: Sur la photo d’illustration de cet article: le mont Vésuve qui borde la baie de Naples en Italie. Vous aurez reconnu les antennes Hertziennes …