Lire un GPS avec la carte micro:bit - Niveau intermédiaire
Dans ce mini projet, nous lirons les informations en provenance d'un GPS avec une carte micro:bit. Nous verrons au passage quelques éléments de micropython pour
lire des informations en provenance du port série
écrire des informations dans un fichier texte
envoyer des informations par radio
Texte légal : Extraits du programme SNT
Les récepteurs GPS fournissent la localisation sous une forme normalisée facilement décodable, par exemple selon le protocole NMEA 0183 (National Marine Electronics Association), ou directement dans les métadonnées EXIF d'une photo. La localisation et les cartes se couplent dans le suivi permanent de la position sur la carte ou sur un itinéraire précalculé.
Capacité attendue : Décoder une trame NMEA pour trouver des coordonnées géographiques.
Le GPS que nous allons utiliser dans ce projet communique via le port série avec la carte microbit pour envoyer des informations selon le protocole NMEA 0183 dont il est justement question dans le programme. Ce projet peut donc être utilisé pour faire le lien entre les thèmes "Objets connectés", "Localisation, cartographie" et "données structurées" du programme SNT. Cette activité permet donc de donner du sens à la notion de trame NMEA sinon bien abstraite...
Matériel nécessaire pour réaliser ce projet
Une ou deux cartes micro:bit (selon la configuration choisie pour ce projet)
Un récepteur GPS VK2828U7G5LF série
Ce récepteur GPS est largement répandu et relativement bon marché. Il est possible de se le procurer sur amazon pour 13€ ou sur des sites de vente chinois type banggood pour moins de 7€
La documentation technique du récepteur GPS se trouve ici.
Méthode : Le montage
Le montage technique est extrêmement simple car le module GPS peut se contenter des 3,3V délivrés par la carte micro:bit (et peut aussi fonctionner en 5V sur une arduino par exemple). Il suffira de relier 4 fils :
le fil noir (G) sur GND
le fil rouge (V) sur 3V
le fil vert (R) sur la broche 1 (émission vers le GPS)
le fil bleu (T) sur la broche 2 (réception depuis le GPS)
Pour les branchements il est possible de se connecter directement à la carte en utilisant des pinces crocos ou des fiches banane.
Les autres fils du GPS ne seront pas connectés à la carte.
Nous allons voir deux déclinaisons possibles du projet :
scénario 1 : nous utiliserons deux cartes, l'une sera branchée au GPS et transmettra par radio les trames NMEA à la seconde carte qui les affichera dans la console REPL.
scénario 2 : nous utiliserons une seule carte qui enregistrera les trames NMEA dans des fichiers texte au format CSV.
Scénario 1 : Émission des trames NMEA par radio
Ce scénario part du principe qu'une carte est déposée en extérieur et est connectée au dispositif GPS selon le branchement qui a été décrit précédemment. Une seconde carte est à portée de réception, connectée à un ordinateur, et affiche dans le REPL les trames NMEA que l'on pourra faire par exemple analyser/décoder aux élèves en guise d'exercice.
Remarque : Plusieurs cartes réceptrices
Le nombre de cartes réceptrices n'est à priori pas limité à une. Il est donc possible d'avoir plusieurs cartes recevant les trames NMEA de l’émetteur afin de travailler à plusieurs groupes d'élèves sur les jeux de données qui arrivent en temps réel de la carte émettrice.
Méthode : Programme émetteur
from microbit import *
import radio
BUFFLEN = 128
radio.config(length=BUFFLEN)
radio.on()
def initGPS():
uart.init(baudrate=9600, bits=8, parity=None, stop=1, tx=pin1, rx=pin2)
sleep(500)
INIT_SEQUENCE_RMC = [
b"\xB5\x62\x06\x08\x06\x00\x20\x4E\x01\x00\x01\x00\x84\x00\xB5\x62\x06\x08\x00\x00\x0E\x30", # Frequence
b"\x24\x45\x49\x47\x50\x51\x2c\x44\x54\x4d\x2a\x33\x42\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x0a\x00\x04\x23", # Disable GPDTM
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x42\x53\x2a\x33\x30\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x09\x00\x03\x21", # Disable GPGBS
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x47\x41\x2a\x32\x37\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x00\x00\xfa\x0f", # Disable GPGGA
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x52\x53\x2a\x32\x30\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x06\x00\x00\x1b", # Disable GPGRS
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x53\x41\x2a\x33\x33\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x02\x00\xfc\x13", # Disable GPGSA
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x53\x54\x2a\x32\x36\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x07\x00\x01\x1d", # Disable GPGST
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x53\x56\x2a\x32\x34\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x03\x00\xfd\x15", # Disable GPGSV
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x4c\x4c\x2a\x32\x31\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x01\x00\xfb\x11", # Disable GPGLL
b"\x24\x45\x49\x47\x50\x51\x2c\x56\x54\x47\x2a\x32\x33\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x05\x00\xff\x19", # Disable GPVTG
b"\x24\x45\x49\x47\x50\x51\x2c\x5a\x44\x41\x2a\x33\x39\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x08\x00\x02\x1f", # Disable GPZDA
b"\x24\x45\x49\x47\x50\x51\x2c\x52\x4d\x43\x2a\x33\x41\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x04\x01\xff\x18" # Enable GPRMC
]
INIT_SEQUENCE_ALL = [
b"\xB5\x62\x06\x08\x06\x00\x20\x4E\x01\x00\x01\x00\x84\x00\xB5\x62\x06\x08\x00\x00\x0E\x30", # Frequence
b"\x24\x45\x49\x47\x50\x51\x2c\x44\x54\x4d\x2a\x33\x42\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x0a\x01\x05\x24",#Enable_GPDTM
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x42\x53\x2a\x33\x30\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x09\x01\x04\x22",#Enable_GPGBS
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x47\x41\x2a\x32\x37\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x00\x01\xfb\x10",#Enable_GPGGA
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x4c\x4c\x2a\x32\x31\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x01\x01\xfc\x12",#Enable_GPGLL
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x52\x53\x2a\x32\x30\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x06\x01\x01\x1c",#Enable_GPGRS
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x53\x41\x2a\x33\x33\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x02\x01\xfd\x14",#Enable_GPGSA
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x53\x54\x2a\x32\x36\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x07\x01\x02\x1e",#Enable_GPGST
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x53\x56\x2a\x32\x34\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x03\x01\xfe\x16",#Enable_GPGSV
b"\x24\x45\x49\x47\x50\x51\x2c\x52\x4d\x43\x2a\x33\x41\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x04\x01\xff\x18",#Enable_GPRMC
b"\x24\x45\x49\x47\x50\x51\x2c\x56\x54\x47\x2a\x32\x33\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x05\x01\x00\x1a",#Enable_GPVTG
b"\x24\x45\x49\x47\x50\x51\x2c\x5a\x44\x41\x2a\x33\x39\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x08\x01\x03\x20",#Enable_GPZDA
]
for i in INIT_SEQUENCE_ALL:
uart.write(i)
sleep(100)
def sendNMEA(m):
if m != "" and m[0] == '$':
if m[-1] == "\n":
radio.send(m)
else:
radio.send(m+"\n")
msg=""
initGPS()
while True:
if uart.any():
incoming = uart.readline().format("%s")
sp=incoming.split("$")
msg += sp[0]
if len(sp)>1:
for m in sp[1:]:
sendNMEA(msg)
msg="$"+m
Complément : Quelques explications
Sous ses airs impressionnants ce programme est en réalité assez simple.
La fonction initGPS permet de configurer notre GPS pour
n'envoyer qu'une trame toutes les 20 secondes
sélectionner le type d'informations à envoyer :
INIT_SEQUENCE_RMC permet de n'envoyer que les informations RMC (heure, date, position et vitesse)
INIT_SEQUENCE_ALL permet de tout envoyer.
Voir la doc page 6 pour plus d'informations. Les codes hexadécimaux ont été copiés depuis la documentation technique. Il peut être intéressant de demander aux élèves de retrouver dans la doc la signification des codes utilisés.
Modifiez la fonction initGPS par rapport au mode souhaité. Dans le listing ci-dessus, j'utilise INIT_SEQUENCE_ALL afin d'envoyer toutes les types de trames NMEA possibles.
La fonction sendNMEA() permet d'envoyer les trames par radio
La boucle principale va scruter le port série dans l'attente de données. Lorsque celle-ci sont disponibles, nous allons les mettre en forme de manière à ce que chaque ligne corresponde au début d'une trame. Une trame NMEA commence toujours par $GP...
Méthode : Programme récepteur
from microbit import *
import radio
BUFFLEN = 128
radio.config(length=BUFFLEN)
radio.on()
while True:
incoming = radio.receive()
if incoming:
print(incoming[0:-1])
Difficile de faire plus simple. Cela se passe ici de commentaires...
Exemple : Exemple de trame reçue :
$GPGBS,173302.00,14.5,11.7,23.4,,,,*77
$GPDTM,W84,,0.0,N,0.0,E,0.0,W84*6F
$GPRMC,173322.00,A,4218.07822,N,00122.48902,W,0.703,,260519,,,A*64
$GPVTG,,T,,M,0.703,N,1.301,K,A*24
$GPGGA,173322.00,4218.07822,N,00122.48902,W,1,11,0.83,13.2,M,45.9,M,,*76
$GPGSA,A,3,27,16,20,10,28,08,18,11,22,01,32,,1.45,0.83,1.19*0A
$GPGSV,4,1,14,01,29,261,22,08,84,273,25,10,47,061,21,11,41,281,33*7B
$GPGSV,4,2,14,14,08,129,,16,10,177,14,18,57,270,23,20,25,051,23*70
$GPGSV,4,3,14,21,00,076,,22,19,207,17,27,59,126,24,28,11,326,23*74
$GPGSV,4,4,14,30,06,292,21,32,15,118,14*7B
$GPGLL,4218.07822,N,00122.48902,W,173322.00,A,A*70
$GPGRS,173322.00,1,2.9,6.8,-1.2,9.6,-3.3,-5.0,0.8,4.0,-0.3,-3.9,-23.1,*5F
$GPGST,173322.00,55,,,,24,16,29*75
$GPZDA,173322.00,26,05,2019,00,00*6B
Scénario 2 : Stockage des trames NMEA dans un fichier CSV
Dans ce second scénario, nous allons enregistrer les informations en provenance du GPS dans des fichiers textes sur la carte micro:bit. On peut imaginer utiliser cela lors d'une sortie scolaire avec des élèves pour enregistrer le parcours réalisé et ensuite exploiter ces données pour les afficher par exemple sur une carte. Une telle activité permet de relier ensemble plusieurs thèmes SNT : cartographie, objets connectés, traitement automatisé des données, voir pourquoi pas, web si on demande aux élèves de faire une page web relatant la sortie...
Remarque : Limitations techniques
La mémoire de travail sur un microcontrôleur - en particulier sous micropython - est très limitée. La carte ne peut donc pas mémoriser un grand nombre de données en mémoire RAM. Toutes les 20 lignes, j'écris donc le contenu des trames capturées en mémoire dans un fichier texte nommé gpsXX.csv.
D'autre part, le micropython présent sur la carte micro:bit n'autorise pas l'ajout de données à la suite d'un fichier texte déja existant. Il faut donc faire un fichier texte différent à chaque écriture. La numérotation des noms de fichiers est faite automatiquement par le programme : gps01.cvs, gps02.csv etc... . Il faudra ensuite récupérer tous ces fichiers un par un via l'outil Fichiers de l'éditeur Mu.
Le port série (uart) est utilisé pour la communication USB avec l'ordinateur, mais aussi avec la communication avec le GPS. Ces deux dispositifs ne peuvent pas être utilisés en même temps. Quand on communique avec le GPS, on perd la liaison USB (plus de REPL, plus d'accès à fichiers). Le programme proposé ci-dessous permet de prendre en compte cette contrainte en permettant à l'utilisateur de choisir entre le mode USB (symbolisé par le une tête souriante Image.HAPPY) et le mode GPS (symbolisé par une croix Image.TARGET).
Méthode : Le programme
from microbit import *
def initGPS():
uart.init(baudrate=9600, bits=8, parity=None, stop=1, tx=pin1, rx=pin2)
sleep(500)
INIT_SEQUENCE_RMC = [
b"\xB5\x62\x06\x08\x06\x00\x20\x4E\x01\x00\x01\x00\x84\x00\xB5\x62\x06\x08\x00\x00\x0E\x30", # Frequence
b"\x24\x45\x49\x47\x50\x51\x2c\x44\x54\x4d\x2a\x33\x42\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x0a\x00\x04\x23", # Disable GPDTM
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x42\x53\x2a\x33\x30\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x09\x00\x03\x21", # Disable GPGBS
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x47\x41\x2a\x32\x37\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x00\x00\xfa\x0f", # Disable GPGGA
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x52\x53\x2a\x32\x30\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x06\x00\x00\x1b", # Disable GPGRS
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x53\x41\x2a\x33\x33\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x02\x00\xfc\x13", # Disable GPGSA
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x53\x54\x2a\x32\x36\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x07\x00\x01\x1d", # Disable GPGST
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x53\x56\x2a\x32\x34\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x03\x00\xfd\x15", # Disable GPGSV
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x4c\x4c\x2a\x32\x31\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x01\x00\xfb\x11", # Disable GPGLL
b"\x24\x45\x49\x47\x50\x51\x2c\x56\x54\x47\x2a\x32\x33\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x05\x00\xff\x19", # Disable GPVTG
b"\x24\x45\x49\x47\x50\x51\x2c\x5a\x44\x41\x2a\x33\x39\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x08\x00\x02\x1f", # Disable GPZDA
b"\x24\x45\x49\x47\x50\x51\x2c\x52\x4d\x43\x2a\x33\x41\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x04\x01\xff\x18" # Enable GPRMC
]
INIT_SEQUENCE_ALL = [
b"\xB5\x62\x06\x08\x06\x00\x20\x4E\x01\x00\x01\x00\x84\x00\xB5\x62\x06\x08\x00\x00\x0E\x30", # Frequence
b"\x24\x45\x49\x47\x50\x51\x2c\x44\x54\x4d\x2a\x33\x42\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x0a\x01\x05\x24",#Enable_GPDTM
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x42\x53\x2a\x33\x30\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x09\x01\x04\x22",#Enable_GPGBS
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x47\x41\x2a\x32\x37\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x00\x01\xfb\x10",#Enable_GPGGA
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x4c\x4c\x2a\x32\x31\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x01\x01\xfc\x12",#Enable_GPGLL
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x52\x53\x2a\x32\x30\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x06\x01\x01\x1c",#Enable_GPGRS
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x53\x41\x2a\x33\x33\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x02\x01\xfd\x14",#Enable_GPGSA
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x53\x54\x2a\x32\x36\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x07\x01\x02\x1e",#Enable_GPGST
b"\x24\x45\x49\x47\x50\x51\x2c\x47\x53\x56\x2a\x32\x34\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x03\x01\xfe\x16",#Enable_GPGSV
b"\x24\x45\x49\x47\x50\x51\x2c\x52\x4d\x43\x2a\x33\x41\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x04\x01\xff\x18",#Enable_GPRMC
b"\x24\x45\x49\x47\x50\x51\x2c\x56\x54\x47\x2a\x32\x33\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x05\x01\x00\x1a",#Enable_GPVTG
b"\x24\x45\x49\x47\x50\x51\x2c\x5a\x44\x41\x2a\x33\x39\x0d\x0a\xb5\x62\x06\x01\x03\x00\xf0\x08\x01\x03\x20",#Enable_GPZDA
]
for i in INIT_SEQUENCE_RMC:
uart.write(i)
sleep(100)
uart.init(115200) # on redonne la main pour la communication USB
def saveFile():
global noFile
noFile += 1
with open("gps{:02d}.csv".format(noFile),'wt') as myCSV :
for m in listeNMEA:
if m != "" and m[0] == '$':
if m[-1] == "\n":
myCSV.write(m)
else:
myCSV.write(m+"\n")
myCSV.close()
listeNMEA.clear()
# Debut du programme
initGPS()
# Variables globales
msg=""
listeNMEA=[]
captureMode=False
display.show(Image.HAPPY)
noFile=0
while True:
if button_a.was_pressed():
# Bouton a : change le mode capture
captureMode = not captureMode
if captureMode:
uart.init(baudrate=9600, bits=8, parity=None, stop=1, tx=pin1, rx=pin2)
display.show(Image.TARGET)
msg=""
else:
saveFile()
uart.init(115200)
display.show(Image.HAPPY)
if button_b.was_pressed():
# Affiche l'etat
display.show(len(listeNMEA))
sleep(1000)
display.show(Image.TRIANGLE)
sleep(500)
display.show(noFile)
sleep(1000)
if captureMode:
display.show(Image.TARGET)
else:
display.show(Image.HAPPY)
if captureMode :
if uart.any():
incoming = uart.readline().format("%s")
sp=incoming.split("$")
msg += sp[0]
if len(sp)>1:
for m in sp[1:]:
listeNMEA.append(msg)
msg="$"+m
if len(listeNMEA)>20:
saveFile()
Complément : Explications
Le fonctionnement du programme est similaire au scénario précédent pour la partie GPS. La fonction initGPS() utilise ici la séquence INIT_SEQUENCE_RMC qui permet d'utiliser moins de mémoire car il n'y a qu'une ligne de générée toutes les 20 secondes. Un fichier sera donc enregistré sur la carte toutes les 400 secondes soit toutes les 6 minutes et demi environ.
Les données en provenance du GPS sont stockées dans la liste listeNMEA. Celle-ci est vidée dans un fichier texte quand elle atteint une taille de 20 enregistrements par la fonction saveFile(). L'utilisation des fichiers texte sur la micro:bit est similaire à ce que l'on trouve sur le python 3, à l'exception près de ne pas pouvoir ajouter du contenu à la fin d'un fichier existant.
Pour utiliser le programme, nous définissons les fonctions des 2 boutons :
le bouton A permet de passer du mode USB (pour récupérer les fichiers) au mode GPS (capture des données)
le bouton B en mode GPS affiche le nombre d'enregistrements dans la liste listeNMEA en cours et le nombre de fichiers gpsXX.csv écrits
Voici ce que l'on obtient en mode fichiers après une séquence de capture de données
Exemple : Contenu d'un fichier CSV
Voici ce que contient un fichier ainsi capturé. Vous apercevez ci-contre le dispositif de capture, totalement autonome sur batterie, qui peut être emmené lors d'une sortie scolaire ou d'un trajet en voiture.
$GPRMC,183728.00,A,4218.07826,N,00126.48281,W,0.649,,260519,,,A*6E
$GPRMC,183729.00,A,4218.07815,N,00126.48316,W,0.435,,260519,,,A*69
$GPRMC,183730.00,A,4218.07789,N,00126.48332,W,0.139,,260519,,,A*64
$GPRMC,183731.00,A,4218.07776,N,00126.48359,W,0.127,,260519,,,A
$GPRMC,183734.00,A,4218.07714,N,00126.48466,W,0.120,,260519,,,A*6A
$GPRMC,183735.00,A,4218.07709,N,00126.48487,W,0.206,,260519,,,A
$GPRMC,183738.00,A,4218.07723,N,00126.48539,W,1.346,,260519,,,A*6A
$GPRMC,183739.00,A,4218.07711,N,00126.48559,W,0.235,,260519,,,A*68
$GPRMC,183740.00,A,4218.07696,N,00126.48561,W,0.340,,260519,,,A*60
$GPRMC,183741.00,A,4218.07676,N,00126.48517,W,1.002,,260519,,,A*6A
$GPRMC,183742.00,A,4218.07645,N,00126.48507,W,0.597,,260519,,,A*60
$GPRMC,183743.00,A,4218.07652,N,00126.48474,W,0.636,,260519,,,A*6A
$GPRMC,183744.00,A,4218.07640,N,00126.48514,W,0.363,,260519,,,A*6C
$GPRMC,183745.00,A,4218.07636,N,00126.48541,W,0.344,,260519,,,A*69
$GPRMC,183746.00,A,4218.07617,N,00126.48548,W,0.427,,260519,,,A*62
$GPRMC,183747.00,A,4218.07572,N,00126.48583,W,0.248,,260519,,,A*6B
$GPRMC,183748.00,A,4218.07568,N,00126.48609,W,0.217,,260519,,,A*64
$GPRMC,183749.00,A,4218.07524,N,00126.48597,W,0.707,,260519,,,A*6D
$GPRMC,183750.00,A,4218.07535,N,00126.48635,W,0.089,,260519,,,A*6F
Voici ce contenu ouvert dans LibreOffice. Saurez-vous retrouver l'heure et la date de capture des données ?
Pour aller plus loin
Ce que nous venons de voir peut servir de base technique à plusieurs activités SNT assez riches dans la mesure où elles font intervenir plusieurs thèmes. On peut en effet imaginer utiliser le tableur puis un peu de programmation Python avec le module folium pour représenter sur une carte le tracé d'une sortie scolaire par exemple.