En utilisant les techniques de la partie précédente, le code de la tache de récupération des infos GPS effectuant le travail suivant :

  • Initialiser la connexion
  • En boucle :
    • lire tout ce qui vient de la carte GPS
    • Analyser toutes les données pour juste donner juste la position (quand il y en a une)
    • Pose le verrou GPS : Bloquer la mémoire pour la dernière position GPS
      • Action sécurisée : Mettre de côté la dernière position trouvée avec l’heure
    • Débloquer le verrou GPS (cela a duré quelque millisecondes)
    • Attendre un peu pour avoir des nouvelles données de la carte

ressemble à :

def watch_gps( gpsPort):
    # la demande d'utilisation des variables dans lesquelles la thread GPS stocke ce qu'elle a trouvé
    global lastGpsPositionMeasured;
    global lastGpsLongitude;
    global lastGpsLattitude;
    global lastGpsSpeed
    global lastGpsElevation;
    global lastGpsMeasureTime;
    global lastGpsTime

    # ?
    GPIO.setmode(GPIO.BOARD)

    # Enable Serial Communication
    port = serial.Serial(gpsPort, 115200);
    port.timeout=1;

    print ("GPS : Starting Up Serial Monitor")

    # on vide toutes les entrees et sorties du ports USB pour la carte GPS
    port.flushInput()
    port.flushOutput()

    # la sequence d initialisation
    
    port.write('AT\r\n'.encode('ascii'))
    rcv = port.read(100)
    print(C_GPS_READ+"GPS : ",rcv, ENDC)
    time.sleep(.1)

    port.write('AT+CGNSPWR=1\r\n'.encode('ascii'))     # to power the GPS
    rcv = port.read(100)
    print(C_GPS_READ+"GPS : ",rcv, ENDC)
    time.sleep(.1)

    port.write('AT+CGNSIPR=115200\r\n'.encode('ascii')) # Set the baud rate of GPS
    rcv = port.read(100)
    print(C_GPS_READ+"GPS : ",rcv, ENDC)
    time.sleep(.1)

    port.write('AT+CGNSTST=1\r\n'.encode('ascii'))    # Send data received to UART
    rcv = port.read(100)
    print(C_GPS_READ+"GPS : ",rcv, ENDC)
    time.sleep(.1)

    port.write('AT+CGNSINF\r\n'.encode('ascii'))       # Print the GPS information
    rcv = port.read(200)
    print(C_GPS_READ+"GPS : ",rcv, ENDC)
    time.sleep(.1)
    
    ck=1
    while ck==1:
        # lecture de la prochaine ligne depuis la carte GPS
        line = port.read_until("\r\n".encode('ascii'));
        lineStr = line.decode('ascii');

        # en mode debug complet, on affiche chaque ligne renvoyée par la carte 
        if FULL_DEBUG_GPS == True :
            if (len(lineStr)>2):
                lineStr2 = lineStr[0: len(lineStr)-2];        
                print(C_GPS_READ+"GPS :",lineStr2, ENDC);
        
        # si la ligne est une ligne de position GPS (commencent par $GNRMC
        if (lineStr.startswith("$GNRMC")) :
            # on extrait la ligne sans les deux caracteres de fin de ligne
            lineStr = lineStr[0: len(lineStr)-2];
            
            # en mode debug GPS seulement, on affiche ces lignes
            if SMALL_DEBUG_GPS == True :
                print(C_GPS_READ+"GPS :",lineStr, ENDC);
                
            # on decoupe la ligne selon les morceaux séparés par des virgules
            items = lineStr.split(",");
            
            # on recupere les morceaux de la ligne qui correspondent au champs utiles
            timeStr = items[1]; # l'heure connue par le GPS
            lat = items[3];     # la latitude
            lon = items[5];     # la longitude
            speed = items[7];   # la vitesse
            elevation=items[8]  # l'altitude
            dateStr = items[9]; # la date connue par le GPS
            
            # si les champs longitude et latitude ne sont pas vide, alors on va memoriser les
            if ((len(lat)>0) and (len(lon)>0)) :
                # on decode la latitude comme dans le programme d'exemple
                s3=lat[2:len(lat)]
                s3=Decimal(s3)
                s3=s3/60
                s33=int(lat[0:2])
                s3 = s3 + s33
                s3 = int(s3*1000000)/1000000

                # on decode la longituide comme dans le programme d'exemple
                s5=lon[3:len(lon)]
                s5=Decimal(s5)
                s5=s5/60
                s55=int(lon[0:3])
                s5 = s5 + s55
                s5 = int(s5*1000000)/1000000

                # on crée une chaine datetime au format ISO avec les morceaux optebnus de la carte,
                # et on la fait analyser par le datetime python
                theDatetime = datetime.strptime(dateStr+'-'+timeStr+'000Z+0000',"%d%m%y-%H%M%S.%fZ%z");
                # on cree le timestamp (Unix) correspondant : le nombre de secondes depuis le 1/1/1970
                theDateTimeTimestamp = datetime.timestamp(theDatetime);
                
                # on decode la vitesse , et on la convertit de mph to kph
                theSpeed = float(speed)*1.609; 
                
                #on decode l'altitude
                theElevation = float(elevation);
                
                # en mode debug standard, on fait un joli affichage des infos GPS
                # la constante C_GPS permet d'afficher dans une couleur particulière pour le GPS (facile à lire)
                if DEBUG_GPS == True :
                   print(C_GPS+"--------------------------------------------", ENDC)
                   print(C_GPS+"GPS :  TIME  :", datetime.fromtimestamp(theDateTimeTimestamp), ENDC )
                   print(C_GPS+"GPS :  LAT.  :", s3 , ENDC)
                   print(C_GPS+"GPS :  LONG. :", s5 , ENDC)
                   print(C_GPS+"GPS :  ELEV  :", theElevation , ENDC)
                   print(C_GPS+"GPS :  SPEED :", theSpeed , ENDC)
                   print(C_GPS+"--------------------------------------------", ENDC)
                
                # on va placer les valeurs lues dans les variables globales
                # mais pour eviter qu'une autre thread les lise pendant qu'on les modifie on demande le verrou
                # et on le libère une fois les valeurs stoquées
                threadGpsLock.acquire()
                # on indique qu'on a eu une nouvelle mesure reussie
                lastGpsPositionMeasured = True
                # on memorise l'heure
                lastGpsMeasureTime = int(datetime.timestamp(datetime.now()));
                # on memorise le resultta du GPS
                lastGpsLongitude = s5;
                lastGpsLattitude = s3;
                lastGpsSpeed = theSpeed;
                lastGpsElevation = theElevation;
                lastGpsTime = int(theDateTimeTimestamp)
                # et on  libère le verrou une fois les valeurs stoquées           
                threadGpsLock.release()