Le BerryGPS-IMU utilise un module GPS CAM-M8C U-Blox, ce module GPS comprend une interface DDC entièrement compatible I2C.
Ce guide montrera comment lire des phrases NMEA à partir du module GPS via I2C, à l’aide d’un Raspberry Pi. Cela laisse l’interface série du Raspberry Pi libre pour d’autres utilisations. Vous pouvez également utiliser un connecteur QWIIC pour connecter le BerryGPS-IMU au Raspberry Pi
Nous allons créer un nœud virtuel où nous enverrons les phrases NMEA, nous allons ensuite configurer GPSD pour lire ce nœud virtuel.
Caveat: Il existe un bug d’étirement de l’horloge I2C bien connu sur le Raspberry Pi qui sera rencontré lors de la tentative de communication avec le module uBlox via I2C natif. Cela se traduit par des caractères aléatoires apparaissant dans les données récupérées.
Nous allons couvrir deux méthodes pour contourner ce problème;
Méthode 1 – Incluez de nombreuses vérifications pour ignorer les phrases NMEA contenant des données corrompues.
Le nombre total de phrases NMEA qui seront corrompues est très faible (20 sur 1 000), ce qui rend cette méthode très utilisable.
Méthode 2 – Utilisant peu cogner pour surmonter le bug d’étirement de l’horloge. Cela n’entraînera aucune erreur, mais nécessite la désactivation d’I2C sur le Raspberry Pi.
Par défaut, le module GPS du BerryGPS-IMU n’est pas connecté au bus I2C. Cela peut être corrigé en plaçant une goutte de soudure sur les cavaliers JP11 et JP10 au dos du PCB.
Activez I2C sur votre Raspberry Pi et réglez la vitesse sur 400Khz.
pi@raspberrypi ~ $ sudo nano /boot/config.txt
Vers le bas, ajoutez la ligne suivante
dtparam=i2c_arm=on,i2c_arm_baudrate=400000
Maintenant, redémarrez.
Vous pouvez confirmer si vous voyez le module GPS en utilisant la commande ci-dessous.
pi@raspberrypi ~ $ sudo i2cdetect -y 1
Voici la sortie lorsqu’un BerryGPS-IMU est connecté. 42 est le module GPS
pi@raspberrypi ~ $ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 abcdef
00 : — — — — — — — — — — — — —
10: — — — — — — — — — — — — 1c — — —
20: — — — — — — — — — — — — — — — —
30 : — — — — — — — — — — — — — — — —
40 : — — 42 — — — — — — — — — — — — —
50 : — — — — — — — — — — — — — — — —
60 : — — — — — — — — — — 6a — — — — —
70 : — — — — — — — 77
Créez le script python qui lira les données via I2C depuis le module GPS
pi@raspberrypi ~ $ nano i2c-gps.py
Copiez dans le code ci-dessous;
#! /usr/bin/python import time import smbus import signal import sys BUS = None address = 0x42 gpsReadInterval = 0.03 def connectBus(): global BUS BUS = smbus.SMBus(1) def parseResponse(gpsLine): if(gpsLine.count(36) == 1): # Check #1, make sure '$' doesnt appear twice if len(gpsLine) < 84: # Check #2, 83 is maximun NMEA sentenace length. CharError = 0; for c in gpsLine: # Check #3, Make sure that only readiable ASCII charaters and Carriage Return are seen. if (c < 32 or c > 122) and c != 13: CharError+=1 if (CharError == 0):# Only proceed if there are no errors. gpsChars="".join(chr(c) for c in gpsLine) if (gpsChars.find('txbuf') == -1): # Check #4, skip txbuff allocation error gpsStr, chkSum = gpsChars.split('*',2) # Check #5 only split twice to avoid unpack error gpsComponents = gpsStr.split(',') chkVal = 0 for ch in gpsStr[1:]: # Remove the $ and do a manual checksum on the rest of the NMEA sentence chkVal ^= ord(ch) if (chkVal == int(chkSum, 16)): # Compare the calculated checksum with the one in the NMEA sentence print gpsChars def handle_ctrl_c(signal, frame): sys.exit(130) #This will capture exit when using Ctrl-C signal.signal(signal.SIGINT, handle_ctrl_c) def readGPS(): c = None response = [] try: while True: # Newline, or bad char. c = BUS.read_byte(address) if c == 255: return False elif c == 10: break else: response.append(c) parseResponse(response) except IOError: connectBus() except Exception,e: print e connectBus() while True: readGPS() time.sleep(gpsReadInterval)
Vous pouvez tester le script avec python i2c-gps.py. Si vous avez une position GPS, vous obtiendrez une sortie similaire à celle ci-dessous.
pi@raspberrypi ~ $ python i2c-gps.py
$GNRMC,071423.00,A,3254.18201,S,15243.27916,E,0.252,,110721,,,A*72
$GNVTG,,T,,M,0.252,N,0.466,K,A*3C
$GNGGA,071423.00,3254.18201,S,15243.27916,E,1,10,1.01,29.0,M,22.6,M,,*63
$ GNGSA,A,3,30,14,07,17,13,19,15,,,,,,1,66,1.01,1.31*17
$GNGSA,A,3,73,74,72,,,,,,,,,,1,66,1,011,1,31*1C
$GPGSV,3,1,12,01,21,124,,06,13,009,20,07,11,048,21,13,47,286,34*70
$GPGSV,3,2,12,14,54,143,27,15,25,253,31,17,84,132,28,19,70,328,31*7D
$GPGSV,3,3,12,21,09,139,,24,08,225,18,28,,,29,30,49,052,26*45
$GLGSV,3,1,10,65,14,243,16,71,00,330,,72,15,287,21,73,39,099,22*65
$GLGSV,3,2,10,74,53,176,19,75,16,227,,80,000,070,,83,24,149,*64
Créez un nœud virtuel, c’est là que nous enverrons les phrases NMEA du module GPS.
pi@raspberrypi ~ $ mknod /tmp/gps p
Exécutez maintenant le script python et redirigez la sortie vers le nœud virtuel que nous venons de créer.
Nous utiliserons également stdbuf ainsi la sortie du script est envoyée au nœud virtuel une ligne à la fois. Sans cela, la sortie est mise en mémoire tampon et n’est envoyée au nœud virtuel que lorsque la mémoire tampon est pleine.
pi@raspberrypi ~ $ stdbuf -oL python i2c-gps.py > /tmp/gps
Configurer GPSD pour utiliser le tampon virtuel
Non, vous pouvez configurer GPSD pour qu’il pointe vers le tampon virtuel.
pi@raspberrypi ~ $ sudo nano /etc/default/gpsd
Chercher
APPAREILS= » »
et le changer en
APPAREILS= »/tmp/gps »
Redémarrez GPSD pour que les nouveaux paramètres prennent effet.
pi@raspberrypi ~ $ sudo systemctl redémarrer gpsd.socket
Vous pouvez maintenant commencer à utiliser votre module GPS avec votre Raspberry Pi
Confirmez que vous faites ne pas avoir I2C activé. Il ne devrait y avoir aucun périphérique i2c sous /dev/
pi@raspberrypi ~ $ ls /dev/i2c*
ls : impossible d’accéder à ‘/dev/i2c*’ : aucun fichier ou répertoire de ce type
Si I2C est activé, la commande ci-dessus renverra un fichier dans le répertoire /dev/.
Vous pouvez désactiver I2C dans /boot/config.txt
pi@raspberrypi ~ $ sudo nano /boot/config.txt
Recherchez la ligne ci-dessous et commentez-la en ajoutant un « https://www.raspberryme.com/accessing-gps-via-i2c-on-a-berrygps-imu/# » devant.
dtparam=i2c_arm=on
Maintenant, redémarrez.
Créez le script python qui lira les données par bit banging I2C à partir du module GPS
pi@raspberrypi ~ $ nano i2c-gps.py
Copiez dans le code ci-dessous;
import time import signal import sys import pigpio address = 0x42 gpsReadInterval = 0.03 SDA=2 SCL=3 pi = pigpio.pi() pi.set_pull_up_down(SDA, pigpio.PUD_UP) pi.set_pull_up_down(SCL, pigpio.PUD_UP) pi.bb_i2c_open(SDA,SCL,100000) def handle_ctrl_c(signal, frame): pi.bb_i2c_close(SDA) pi.stop() sys.exit(130) #This will capture exit when using Ctrl-C signal.signal(signal.SIGINT, handle_ctrl_c) def readGPS(): c = None response = [] while True: # Newline, or bad char. a=pi.bb_i2c_zip(SDA, [4, address, 2, 6, 1]) # Bit bang I2C read. 2 = Start, 6 = read, 1= How many bytes to read c = ord(a[1]) if c == 255: return False elif c == 10: break else: response.append(c) gpsChars="".join(chr(c) for c in response) #Convert list to string print gpsChars while True: readGPS() time.sleep(gpsReadInterval)
Créez un nœud virtuel, c’est ici que nous enverrons les phrases NMEA du module GPS à
pi@raspberrypi ~ $ mknod /tmp/gps p
Exécutez maintenant le script python et redirigez la sortie vers le nœud virtuel que nous venons de créer.
Nous utiliserons également stdbuf ainsi la sortie du script est envoyée au nœud virtuel une ligne à la fois. Sans cela, la sortie est mise en mémoire tampon et n’est envoyée au nœud virtuel que lorsque la mémoire tampon est pleine.
pi@raspberrypi ~ $ stdbuf -oL python i2c-gps.py > /tmp/gps
Configurer GPSD pour utiliser le tampon virtuel
Non, vous pouvez configurer GPSD pour pointer vers le tampon virtuel
pi@raspberrypi ~ $ sudo nano /etc/default/gpsd
Chercher
APPAREILS= » »
et le changer en
APPAREILS= »/tmp/gps »
Redémarrez GPSD pour que les nouveaux paramètres prennent effet.
pi@raspberrypi ~ $ sudo systemctl redémarrer gpsd.socket
Vous pouvez maintenant commencer à utiliser votre module GPS avec votre Raspberry Pi