Skyduino:~#
Articles
programmation, python, test

[Test] La GPRS Shield de seeedstudio

Salut à tous !

Aujourd’hui c’est samedi, c’est donc l’heure du test !
Qu’avons nous à nous mettre sous la dent aujourd’hui ?
Une petite GPRS shield ça vous tente ?

La GPRS Shield permet d’ajouter à n’importe quelle carte arduino des capacités gsm.
En « gros » vous pourrez faire des appels, recevoir des appels, géré les fréquences DTMF ou utiliser le modem gprs pour connecter à internet votre arduino partout dans le monde (dans la mesure ou votre carte sim puisse le faire bien sur ;))

La GPRS Shield ce commande via de simple commandes AT envoyé sur le port série.
Le module en charge du réseau GSM est un SIM900, module GSM dont la stabilité n’est plus à démontrer, souvent employé dans les « vieux » téléphones nokia par exemple.

La GPRS Shield fonctionne en interne en 2v8, j’ai fait le test, cette shield fonctionne sans probléme sous les arduino 5v mais aussi sur les arduino 3v3 grâce à un systéme ingénieux de mosfet pour la conversion 5v/3v3 -> 2v8.

LA GPRS Shield comporte plusieurs led et boutons, un bouton power qui mais en marche le module GSM, une led pour l’état de la shield et une autre pour l’état du module GSM.

La GPRS Shield est très bien conçu même si elle n’est pour le moment qu’en beta, un systéme de cavalier permet de choisir quel interface série utiliser, soit le port série arduino hardware soit un softwareSerial sur les broches D7 et D8.

Voici une liste des différentes capacité de la GPRS Shield (tiré du wiki seeedstudio):
Quad-Band 850 / 900/ 1800 / 1900 MHz – would work on GSM networks in all countries across the world.
GPRS multi-slot class 10/8
GPRS mobile station class B
Compliant to GSM phase 2/2+
Class 4 (2 W @ 850 / 900 MHz)
Class 1 (1 W @ 1800 / 1900MHz)
Control via AT commands – Standard Commands: GSM 07.07 & 07.05 | Enhanced Commands: SIMCOM AT Commands.
Short Message Service – so that you can send small amounts of data over the network (ASCII or raw hexadecimal).
Embedded TCP/UDP stack – allows you to upload data to a web server.
Speaker and Headphone jacks – so that you can send DTMF signals or play recording like an answering machine.
SIM Card holder and GSM Antenna – present onboard.
12 GPIOs, 2 PWMs and an ADC (all 2.8 volt logic) – to augment your Arduino.
Low power consumption – 1.5mA(sleep mode)

Autre point important c’est que comme le module SIM900 était à l’origine intégré dans des téléphone portable, il possède donc un systéme de gestion pour un batterie, des entrées/sorties normalement utilisé pour la gestion des touches 0-9#* et plein d’autre truc sympa !

Pour le moment j’en suis encore dans ma phase de test, je n’est pas encore bien pris en main les différentes commande AT disponible.
Mais si vous aussi vous voulez vous lancer dans l’aventure je vous link le wiki de seeedstudio sur la gprs shield :
http://seeedstudio.com/wiki/index.php?title=GPRS_Shield

Au niveau des commandes AT le pdf de simcom est vraiment trés complet et explique bien toute les commandes cependant il m’as était nécessaire de faire un petit tours sur wikipedia & co pour bien comprendre toute les subtilités des commandes AT.
http://garden.seeedstudio.com/images/a/a8/SIM900_AT_Command_Manual_V1.03.pdf

Au niveau de l’utilisation c’est vraiment relativement simple, il faut appuyé sur le bouton power jusqu’à ce que la led status s’allume puis entrés les commandes AT qui vont bien (code pin & co).

Voici un script python que j’ai réalisé pour tentez une sorte de systéme de géolocalisation via le numéro d’identification du relay gsm.

#!/usr/bin/python

# Nom mobile pour camoufler l'appelle d'api
MOBILE = "Nokia N95 8Gb" # ne pas modifier !

# Version du script
VERSION = 1.1

# Code Pin pour dévérouiller la carte SIM
CODEPIN = "1234"

# Port Série utilisez par l'arduino
SERIALPORT = "COM9"

# Vitesse du port série
SERIALSPEED = 19200

print "Chargement ... ",
try:
    from struct import pack, unpack
    from httplib import HTTP
    import serial, time
except:
    print "Impossible de charger une des dépendances requise !"
    exit(-1)
print "Dépendances chargées !"
print " "
print " "

print "~ SkyWodd - Géolocalisation par GSM ~"
print "Le GPS du geek ! Version %d " % VERSION
print "Powered by Arduino !"
print " "

# Ouverture de la Gateway Arduino -> SoftSerial -> SIM900
print "ouverture du port série ... ",
try:
    arduino = serial.Serial(SERIALPORT, SERIALSPEED, timeout=1)
except:
    print "FAIL ! =("
    exit(-2)
print "OK !"

# Fonction pour libérer le port série
def sClose():
    print "Fermeture du port série ... ",
    arduino.close()
    print "OK !"

# ligne servira dans tout le script comme buffer série
ligne = ""

# La carte arduino met 10 secondes pour booter
print "Boot de la carte arduino ... ",
time.sleep(10)
print "Ok !"

# Attente de l'allumage du module SIM900
print "Tentative de communication avec le module SIM900 ...",
arduino.write("AT" + '\n')
ligne = arduino.readline()
if not "AT" or "OK" in ligne:
    print ""
    print "Veuillez appuyer sur le bouton power du module SIM900"
    print "jusqu'a l'allumage de la led status."
    print ""
    print "Attente ...",
    while not "RDY" in ligne: 
        ligne = arduino.readline()
else:
    print " Ok !"

print "Module SIM900 pret !"

# Fonction pour géolocaliser une BTS depuis son LAC (Local Area Code) et son CID (Cell ID)
# Arguments :
# CID : (Cell ID) - obligatoire
# LAC : (Local Area Code) - obligatoire
# MNC : (Mobile Network Code) - optionnel
# MCC : (Mobile Country Code) - optionnel
# PAYS : (captain obvious ?) - optionnel, par défaut fr (france)
def getCoord(cid, lac, mnc=0, mcc=0, pays='fr'):
    print "Tentative de localisation ..."
    print "CID %d, LAC %d" % (cid, lac)
    print "MNC %d, MCC %d" % (mnc, mcc)
    print "Pays %s" % pays
    
    # Mise en forme des arguments pour l'envoi
    print "Mise en forme des données ..."
    request = pack('>hqh2sh13sh5sh3sBiiihiiiiii',
                    21, 0,
                    len(pays), pays,
                    len(MOBILE), MOBILE,
                    len('1.3.1'), "1.3.1",
                    len('Web'), "Web",
                    27, 0, 0,
                    3, 0, cid, lac,
                    0, 0, 0, 0)

    # Fabrication de la réquete HTTP POST
    print "Envoi de la requéte HTTP aux serveurs de Google ... ",
    http = HTTP('www.google.com', 80)
    http.putrequest('POST', '/glm/mmap')
    http.putheader('Content-Type', 'application/binary')
    http.putheader('Content-Length', str(len(request)))
    http.endheaders()

    # Ok let's GO !
    http.send(request)
    code, msg, headers = http.getreply()
    if code != 200:
        print "Une erreur est survenue lors de la requéte HTTP !"
        print "Code : ",
        print "%d" % code
        print "Message : ",
        print "%s" % msg
        sClose()
        exit(-3)
    else:
        print "Requéte HTTP réussi !"
    reponse = http.file.read()

    # Si tous ce passe bien latitude et longitude contiendront les coordonnées du relay sinon ...
    print "Mise en forme de la réponse ..."
    (a, b, codeErreur, latitude, longitude, c, d, e) = unpack(">hBiiiiih",reponse)
    if codeErreur != 0:
        print "Une erreur est survenue lors de la géolocalisation !"
        print "Code : ",
        print "%d" % codeErreur
        print "Extra : A:%d B:%d C:%d D:%d E:%d" % (a, b ,c ,d ,e)
        sClose()
        exit(-4)

    # On passe les décimaux en réel pour reformer les "vrai" coordonnées
    print "Mise en forme des coordonnées ..."
    if latitude == 0 or longitude == 0:
        print "Les coordonnées semblent fausses !"
        sClose()
        exit(-5)
    latitude /= 1000000.0
    longitude /= 1000000.0

    # Et c'est tout bon !
    print "Géolocalisation Réussi !"
    return latitude, longitude

# Fonction low-level pour transmettre une command AT au module SIM900
# Arguments :
# Command : (captain obvious ?)
def ATCommand(command):
    arduino.write(command + '\n')
    reponse = []
    ok = 0
    ligne = arduino.readline()
    print "debug A", ligne
    while ok == 0:
        print "debug B"
        if ligne != "":
            if "OK" in ligne:
                ok = 1
            else:
                if "ERROR" in ligne:
                    ok = 2
                else:   
                    reponse.append(ligne)
        ligne = arduino.readline()
        print ligne, ok
        
    return ok, reponse

# Fonction high-level pour dévérouiller la carte SIM
# Arguments :
# codePin : (captain obvious ?)
def unlockSIM(codePin):
    print "Dévérouillage de la carte SIM ... ",
    reponse = ATCommand("AT+CPIN=%s" % codePin);
    if reponse[0] == 0:
        print "Echec ! Code Pin Incorrecte !"
        sClose()
        exit(-6)
    else:
        print "OK !"

    print "Attente de la disponibilité du réseau GSM ..."
    ligne = arduino.readline()
    while not "Call Ready" in ligne:
        try:
            ligne = arduino.readline()
        except:
            print "Pas de réseau GSM disponible ! =("
            sClose()
            exit(-7)
    else:
        print "Réseau GSM Disponible et UP !"

# Fonction high-level pour obtenir le CID et le LAC du réseau courant
# Arguments :
# Aucun.
def getInfoReseau():
    print "Activation de l'affichage des informations réseau ... ",
    reponse = ATCommand("AT+CREG=2");
    if reponse[0] == 0:
        print "Echec ! WTF !"
        sClose()
        exit(-8)
    else:
        print "OK !"
        
    print "Obtention du CID et du LAC ... ",
    reponse = ATCommand("AT+CREG?");
    if reponse[0] == 0:
        print "Echec ! Quelque chose à buggé =("
        sClose()
        exit(-9)
    else:
        print "OK !"

    # Mise en forme de la réponse
    print "Mise en forme de la réponse ... ",
    data = ""
    for i in range(0, len(reponse[1])):
        if "+CREG:" in reponse[1][i]:
            data = reponse[1][i]
                   
    data = data.trim().replace("+CREG:", "").replace(",", " ").replace("\"", "")
    reseau = data.split(" ")
    print "OK !"

    if len(reseau) != 4:
        print "La réponse ne correspond pas au template prévu !"
        sClose()
        exit(-10)

    if reseau[1] != "1":
        print "Le module SIM900 n'est pas connecté au BTS !"
        sClose()
        exit(-11)

    cid = int(reseau[3], 16)
    lac = int(reseau[2], 16)
    print "Info réseau : LAC:%d CID:%d" % (lac, cid)

    return cid, lac

# Le module SIM900 met un peut moins de 5 secondes pour initialiser la carte SIM
time.sleep(5)

# 3 lignes les plus importantes xD
#unlockSIM(CODEPIN)
#cid, lac = getInfoReseau() # la fonction ATcommand bug par conséquent c'est deux fonction aussi


cid, lac = (36130, 228) # lac et cid d'un relay gsm pour test
latitude, longitude = getCoord(cid, lac)
print " "
print "URL Google Map : " 
print "http://maps.google.fr/maps?q=%d,%d" % (latitude, longitude)

sClose()  

# C'est la fin ! Adieu monde cruel !
print " "
print "Exécution terminé !"
exit(0)

Je prévient tout de suite la fonction ATcommand NE FONCTIONNE PAS par conséquent il faut débloquer et récupérer le lac/cid soit même puis modifier les valeurs dans le script

Les commandes pour ce faire sont :

AT+CPIN=
AT+CREG=2
AT+CREG?

type de réponse : +CREG: 2,1,"-lac-","-cid-"

Pour les débutants en AT commandes qui se débrouille en anglais je vous donne le lien d’un article trés bien expliquer que j’ai pu trouvé sur le sujet, je m’en suis servit comme base pour le script :
http://www.shapeshifter.se/2008/04/30/list-of-at-commands/

Je me suis aussi énormément basé sur ce morceau de script trouvé sur code overflow pour la technique je géolocalisation avec les serveurs google :
http://stackoverflow.com/questions/1598696/google-maps-cellid-to-location
et sur ce wiki google code :
http://code.google.com/intl/fr-FR/apis/gears/geolocation_network_protocol.html

Dans la prochaine version de cette shield seeedstudio a prévu de faire géré la gestion de l’alimentation du module SIM900 par la carte arduino directement via un transistor ou assimilé et faire correspondre le pinout du header série avec le pinout des modules FTDI ou UartSBee.
Que du bon en perspective !

Conclusion :
C’est une shield sympa, un peu complexe à prendre en main mais avec un potentielle extraordinaire !
C’est aussi une des rares (voir la seul) shield gsm qui supporte la voix et data et qui ne soit pas à 100 ou 150€ !
Je la recommande vivement si vous avez pour projet un systéme utilisant le réseau GSM.

Discussion

7 réflexions sur “[Test] La GPRS Shield de seeedstudio

  1. Bonsoir
    A ta connaissance, quels « vieux » Nokia utiliseraient ce chipset ?
    J’ai un vieux 5110 que j’ai commencé à démonter pour récupérer l’écran mais je ne vois pas ce SIM900 à l’intérieur.

    Publié par Barbudor | 7 avril 2012, 21 h 20 min
    • Les téléphones (enfin plus les pda) pas un peu ancien, utilise souvent des puces du fabricant simcom, mais pas forcément le module SIM900.

      Quelques que soit le chipset utilisé il doit normalement répondre au standard AT+T, sinon c’est qu’il ya un truc pas nette avec le chipset.

      Publié par skywodd | 7 avril 2012, 21 h 26 min
  2. Ou peut-on se procurer le Shield GPS en france ?

    Publié par Benachenhou | 1 juin 2012, 18 h 09 min
    • Chez watterott (il ajouterons 10€ de fps + TVA, -> leur envoyer un mail, c’est chez eu que j’ai acheté la mienne) ou chez seedstudio directement (avec envoi international).

      Publié par skywodd | 1 juin 2012, 18 h 49 min
  3. Savez-vous si la connexion est stable ?

    Je peux laisser le Arduino connecté pendant 24h sans interuptions ?
    (avec reco si deco bien entendu)

    Publié par vlp | 26 septembre 2012, 14 h 59 min
    • C’est du gsm, donc aussi stable qu’avec un téléphone classique.
      Si il n’y as pas de variations dans le signal gsm il n’y a pas de raison que la connexion coupe.

      Personnellement je ne me suis pas amusé à laisser tourner ma shield h24 pendant une longue période.

      Publié par skywodd | 26 septembre 2012, 18 h 12 min
  4. Bonjour,
    Pouvons nous envoyer des SMS avec cette SIM900 avec AT et arduino?

    Publié par JeanNos | 15 novembre 2017, 8 h 43 min

Skyduino devient Carnet du Maker

Le site Carnet du Maker remplace désormais le blog Skyduino pour tout ce qui touche à l'Arduino, l'informatique et au DIY.