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
