[PYTHON] Obtenez votre position actuelle avec un récepteur GPS USB

J'ai un récepteur USB à portée de main, je vais donc le joindre à une tarte à la râpe et obtenir mon emplacement actuel. [BU-353S4](https://www.amazon.co.jp/GlobalSat-BU-353S4-GLOBALSAT-BU-353S4-SiRFstarIV%E6%90%AD%E8%BC%89-GPS%E3%83% AC% E3% 82% B7% E3% 83% BC% E3% 83% 90USB-% E6% 9D% B1% E4% BA% AC% E9% 80% 9A% E5% 95% 86% E6% AD% A3 % E8% A6% 8F% E8% B2% A9% E5% A3% B2 / dp / B00HZCQYLU) a été utilisé.

Bien qu'il s'agisse d'une méthode analogique, exécutez la commande suivante avant et après l'insertion et le retrait du récepteur GPS pour identifier l'appareil cible.

$ ls /dev/ttyUSB*
/dev/ttyUSB0  /dev/ttyUSB1  /dev/ttyUSB2  /dev/ttyUSB3  /dev/ttyUSB4

Cette fois, nous allons procéder en supposant qu'il est reconnu comme / dev / ttyUSB4.

Script pour obtenir la valeur GPS

gps.py


#!/usr/bin/env python
# -*- coding: utf-8 -*-

import time
import serial

#Spécification de l'appareil
DEV = '/dev/ttyUSB4'

#Notation fractionnaire de latitude et de longitude ⇒ Fonction de conversion en notation de fréquence
def convert(x):
    result = (float(x[0:-7])+(float(x[-7:])/60))
    return result

#Une fonction qui renvoie la valeur requise sous forme de chaîne
def get_str(x):
    result =""
    if (x[2] == "A") and (x[2] != ""):
        result += "state:"+"ok "
    elif (x[2] == "V") and (x[2] != ""):
        result += "state:"+"alert "
    else:
        result += "state:"+"no data "
    if x[7] != "":
        result += 'speed:'+ '%.1f' % (float(x[7])*1.852) + "km/h "
    else:
        result += "speed:"+"no data "
    if (x[4] == "N")  and ( x[4] != "" ):
        result += "north latitude:" + '%.4f' % convert(x[3]) +' '
    elif (x[4] == "S")  and ( x[4] != "" ):
        result += "south latitude:" + '%.4f' % convert(x[3]) +' '
    else:
        result += "latitude:"+"no data "
    if (x[6] == "E") and ( x[6] != ""):
        result += "east longitude:" + '%.4f' % convert(x[5]) +' '
    elif (x[6] == "W") and ( x[6] != ""):
        result += "west longitude" + '%.4f' % convert(x[5]) +' '
    else:
        result += "logitude:"+"no data "
    return result

#Vérification de la somme de contrôle
def checksum_verify(c_sum,data):
    c_data = '0x00'
    for i in range(1,len(data)-3):
        c_data = hex(int(c_data,16) ^ int(hex(ord(data[i])),16))
    if int(c_sum,16) == int(c_data,16):
        return True
    else:
        return False


#Boucle principale
#Traiter uniquement la valeur GPRMC, ne pas traiter si le nombre d'éléments de cette valeur est inférieur à 13 et si elle n'est pas bien acquise
try:
    #Obtenir la série
    sr = serial.Serial(DEV, 4800)
    while 1:
        #Code de saut de ligne exclu
        tmp = sr.readline().rstrip()
        #Vérifier la somme de contrôle
        if checksum_verify(tmp[-2:],tmp):
            tmp2 = tmp.split(",")
            #Traiter uniquement GPRMC
            if (tmp2[0] == '$GPRMC'):
                line = get_str(tmp2)
                print 'OK:'+tmp
                print line
                time.sleep(0.5)
        else:
            print 'NG:'+tmp
finally:
    print 'serial_close'
    sr.close()

Explication supplémentaire

Chaque valeur de GPRMC est la suivante

tmp2[1]Heure UTC Heure standard japonaise-9 heures
tmp2[2]L'état A est normal V est un avertissement
tmp2[3]latitude(Notation fractionnaire)
tmp2[4](N)Latitude nord(S)Latitude sud
tmp2[5]longitude(Notation fractionnaire)
tmp2[6](E)est(W)Est-ce Nishikei?
tmp2[7]Noeud de vitesse de déplacement
tmp2[8]Véritable orientation
tmp2[9]Accord temps du monde(UTC)format jjmmaa
tmp2[12]Somme de contrôle

※Vitesse de déplacement noeud est 1,852 fois et km / h

※ Somme de contrôle XOR calcule les caractères entre «» et «*» et vérifie s'ils ont la même valeur  `GPRMC,034357.279,V,,,,,,,020117,,,N*42 Si ci-dessus,  GPRMC,034357.279,V,,,,,,,020117,,,N` Est la cible du calcul

Comment réparer lors du référencement de l'appareil

Il n'est pas pratique de changer à chaque fois en / dev / ttyUSB0 ou / dev / ttyUSB4 en fonction de l'appareil connecté et de l'environnement. Il ne peut pas être utilisé dans le script de démarrage automatique. C'est une contre-mesure dans un tel cas.

Utilisation de l'identifiant de l'appareil

Si vous avez choisi le port USB à brancher, vérifiez les informations ci-dessous et utilisez-le.

$ ls -al /dev/serial/by-path
total 0
drwxr-xr-x 2 root root 140 Jan  2 01:30 .
drwxr-xr-x 4 root root  80 Jan  1 20:03 ..
lrwxrwxrwx 1 root root  13 Jan  2 01:30 platform-3f980000.usb-usb-0:1.3:1.0-port0 -> ../../ttyUSB4
lrwxrwxrwx 1 root root  13 Jan  1 20:03 platform-3f980000.usb-usb-0:1.4:1.0-port0 -> ../../ttyUSB0
lrwxrwxrwx 1 root root  13 Jan  1 20:03 platform-3f980000.usb-usb-0:1.4:1.1-port0 -> ../../ttyUSB1
lrwxrwxrwx 1 root root  13 Jan  1 20:03 platform-3f980000.usb-usb-0:1.4:1.2-port0 -> ../../ttyUSB2
lrwxrwxrwx 1 root root  13 Jan  1 20:03 platform-3f980000.usb-usb-0:1.4:1.3-port0 -> ../../ttyUSB3

Si le périphérique cible est / dev / ttyUSB4, corrigez-le comme suit

#Spécification de l'appareil
DEV = '/dev/ttyUSB4'
↓
DEV = '/dev/serial/by-path/platform-3f980000.usb-usb-0:1.3:1.0-port0'

Description dans la règle udev (le port USB peut être modifié)

Voir [À propos des règles udev] d'Oracle (https://docs.oracle.com/cd/E39368_01/e48214/ch07s03.html) pour les règles ʻudev`.

Exécutez la commande suivante pour vérifier les informations (lorsque / dev / ttyUSB4 est le périphérique cible) udevadm info -a -p $(sudo udevadm info -q path -n /dev/ttyUSB4) Vérifiez les éléments suivants à partir du

  looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.3':
    KERNELS=="1-1.3"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{devpath}=="1.3"
    ATTRS{idVendor}=="067b"
    ATTRS{speed}=="12"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{busnum}=="1"
    ATTRS{devnum}=="21"
    ATTRS{configuration}==""
    ATTRS{bMaxPower}=="100mA"
    ATTRS{authorized}=="1"
    ATTRS{bmAttributes}=="80"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{maxchild}=="0"
    ATTRS{bcdDevice}=="0400"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{quirks}=="0x0"
    ATTRS{version}==" 1.10"
    ATTRS{urbnum}=="65169"
    ATTRS{ltm_capable}=="no"
    ATTRS{manufacturer}=="Prolific Technology Inc. "
    ATTRS{removable}=="removable"
    ATTRS{idProduct}=="2303"
    ATTRS{bDeviceClass}=="00"
    ATTRS{product}=="USB-Serial Controller D"

Extrayez les trois points suivants

ATTRS{idProduct}=="2303"
ATTRS{idVendor}=="067b"
ATTRS{product}=="USB-Serial Controller D"

Créez un fichier tel que 70-bu353s4.rules sous / etc / udev / rules.d et entrez les informations suivantes.

70-bu353s4.rules


ATTRS{idProduct}=="2303",ATTRS{idVendor}=="067b",ATTRS{product}=="USB-Serial Controller D",SYMLINK+="bu353s4"

Après avoir créé le fichier, insérez et retirez le récepteur GPS Vous pouvez maintenant vous connecter au récepteur GPS avec / dev / bu353s4, alors corrigez-le comme suit

#Spécification de l'appareil
DEV = '/dev/ttyUSB4'
↓
DEV = '/dev/bu353s4'

Recommended Posts

Obtenez votre position actuelle avec un récepteur GPS USB
Obtenez une liste des packages installés dans l'environnement actuel avec python
Obtenir les informations de localisation actuelles et l'agent utilisateur en Python
Obtenez un environnement local pour DynamoDB avec Docker
Recevez beaucoup de vos tweets avec Tweepy
[Python] Récupérez les fichiers dans le dossier avec Python
Obtenez un billet pour un parc à thème avec python
J'obtiens une UnicodeDecodeError lors de l'exécution avec mod_wsgi
Obtenir une liste d'utilisateurs IAM avec Boto3
Zubu amateur veut démarrer Python
Obtenez un environnement de développement Python rapide avec Poetry