How to stream data from handheld gps connected via either usb port or serial com port in python?

时间:2019-04-08 13:45:51

标签: python-3.x windows gps serial-port usb

Godd day y'all!

I'm developping an application for windows computers that should record gps locations from an external device continuously in the background. There are a lot of tutorials when using Arduino / UNIX systems, however, I am designing specifically for windows, therefore many of the tut's are not easily portable (also: I am completely new to device I/O in python).

Installing external software like gpsd on the user PC is not an option. I've downloaded the libusb drivers for windows though, which will be supplied with the final product (I guess, unless you folks point out it's not neccessary).

From my understanding, pyserial should be able to communicate both to usb ports and hardware com ports since win7+ technically treats usb ports as virtual COM ports - is that true?

I have succesfully used pyusb to browse the devices connected to my computer. Opening the device for I/O was not allowed though (potentially because a GPS is not supposed to receive inputs?).

I have included my code to connect and stream data (containing some code I found on other SO posts, e.g. Reading USB-GPS info with Python & others, sorry I can't remember the original authors, I forgot to note it down in the source. If you happen to stumble upon your own code, feel free to request an edit and I will oblige).

import usb
import usb.backend.libusb1

def streamDevice(dev: usb.core.Device = None):
    print(dev)
    if dev.is_kernel_driver_active(0) is True: dev.detach_kernel_driver(0)
    # use the first/default configuration
    dev.set_configuration(0)
    # first endpoint
    endpoint = dev [0][(0,0)][0]
    print(endpoint)
    # read a data packet
    data = None
    while True:
        try:
            data = dev.read(endpoint.bEndpointAddress,endpoint.wMaxPacketSize)
            print(data)

        except usb.core.USBError as e:
            data = None
            if e.args == ('Operation timed out',): continue

backend = usb.backend.libusb1.get_backend(find_library= lambda x: "DLL/MinGW64/dll/libusb-1.0.dll")
devices = usb.core.find(find_all = True, backend=backend)
mouse = None
for idx,dev in enumerate(devices):
    print(dev) #class 9 (hubs) cannot easily be printed using __str___
    if dev.bDeviceClass != 9: print(dev)
    else:
        print(" + Class: %s" % dev.bDeviceClass)
        print(" + Subclass: %i" % dev.bDeviceSubClass)
        print(" + Protocol: %i" % dev.bDeviceProtocol)
        print(" + Length  : %s" % dev.bLength)
        print(" + Configurations: %i" % dev.bNumConfigurations)
    if dev.bDeviceClass == '0xef':
        print('GPS found!')
        print(dev)
        streamDevice(dev)

In summary:

1. how can I stream the NMEA string from a gps device connected to a physical COM port in python 3+, using windows7+?

2. how can I detect the device reliably and stream from a gps device connected to a USB COM port in python 3+, using windows7+?

Cheers and many thanks in advance!

PS: Feel free to point out any misconceptions I have about serial communication in python and windows; like I said: I am completely new to device I/O in python and will gladly redact my question!

0 个答案:

没有答案