I am working on a NMEA(GPS)-datalogger for a drone. I followed the tutorial from fishandwhistle and createt this script:


import os, time, sys, glob, datetime, syslog, pynmea2, serial

def logfilename():
    now = datetime.datetime.now()
    return 'NMEA_%0.4d-%0.2d-%0.2d_%0.2d-%0.2d-%0.2d.nmea' % \
                (now.year, now.month, now.day,
                 now.hour, now.minute, now.second)

def _scan_ports():
    if sys.platform.startswith('win'):
        ports = ['COM%s' % (i + 1) for i in range(256)]
    elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
        # this excludes your current terminal "/dev/tty"
        patterns = ('/dev/tty[A-Za-z]*', '/dev/ttyUSB*')
        ports = [glob.glob(pattern) for pattern in patterns]
        ports = [item for sublist in ports for item in sublist]  # flatten
    elif sys.platform.startswith('darwin'):
        patterns = ('/dev/*serial*', '/dev/ttyUSB*', '/dev/ttyS*')
        ports = [glob.glob(pattern) for pattern in patterns]
        ports = [item for sublist in ports for item in sublist]  # flatten
        raise EnvironmentError('Unsupported platform')
    return ports

    while True:
        ports = _scan_ports()
        if len(ports) == 0:
            sys.stderr.write('No ports found, waiting 10 seconds...press Ctrl-C to quit...\n')
            syslog.syslog('No ports found, waiting 10 seconds...\n')

        for port in ports:
            # try to open serial port
            sys.stderr.write('Trying port %s\n' % port)
            syslog.syslog('Trying port %s\n' % port)
                # try to read a line of data from the serial port and parse
                with serial.Serial(port, 57600, timeout=1) as ser:
                    # 'warm up' with reading some input
                    for i in range(10):
                    # try to parse (will throw an exception if input is not valid NMEA)
                    pynmea2.parse(ser.readline().decode('ascii', errors='replace'))

                    # log data
                    outfname = logfilename()
                    sys.stderr.write('Logging data on %s to %s\n' % (port, outfname))
                    syslog.syslog('Logging data on %s to %s\n' % (port, outfname))
                    with open(outfname, 'wb') as f:
                        # loop will exit with Ctrl-C, which raises a
                        # KeyboardInterrupt
                        while True:
                            line = ser.readline()
                            print(line.decode('ascii', errors='replace').strip())

            except Exception as e:
                sys.stderr.write('Error reading serial port %s: %s\n' % (type(e).__name__, e))
                syslog.syslog('Error reading serial port %s: %s\n' % (type(e).__name__, e))
            except KeyboardInterrupt as e:
                sys.stderr.write('Ctrl-C pressed, exiting log of %s to %s\n' % (port, outfname))
                syslog.syslog('Ctrl-C pressed, exiting log of %s to %s\n' % (port, outfname))

        sys.stderr.write('Scanned all ports, waiting 10 seconds...press Ctrl-C to quit...\n')
        syslog.syslog('Scanned all ports, waiting 10 seconds...\n')
except KeyboardInterrupt:
    sys.stderr.write('Ctrl-C pressed, exiting port scanner\n')
    syslog.syslog('Ctrl-C pressed, exiting port scanner\n')

My Script is starting as service and I can see that it is running and searching for ports. But it never finds an incoming stream at /dev/ttyAMA0 when I connect my rpi to the drone via tx(drone) to rx(rpi). There could be serveral reasons for that and I am trying to delimit the possible error sources. One could be that the drone is not sending a signal.

Therefor I would like to test if the serial_nmealog.py script is working when I simulate an incoming stream.

  • I connected my rpis pin 8(tx) to pin 10(rx).
  • I try to send a simple message with:

    import serial
    ser = serial.Serial('/dev/ttyAMA0', 57600)  # open serial port
    print(ser.name) # check which port was really used
    ser.write(b'hello test') # write a string
  • Now I expect the string 'hello test' to be logged with my serial_nmealog.py script. But its not... Still no stream found.
  • Ok my next try to see if my UART-ports are working:

    import serial
    with serial.Serial('/dev/ttyAMA0', 57600, timeout=1) as ser:
    x = ser.read()          # read one byte
    s = ser.read(10)        # read up to ten bytes (timeout)
    line = ser.readline()   # read a '\n' terminated line
  • this returns one empty line with no string.

As I am not really clear about how pyserial works and I am more copy pasting than programming it is really hard for me to get behind the functionality of the things I am trying. Can someone please give me an easy to understand and commented minimal example of how to send an stream with uart and how to receive and log it or print it.

EDIT: I am using pi zero w and 2017-11-29-raspbian-stretch-lite

  • 2
    Because (among other things) /dev/ttyAMA0 is connected to Bluetooth. There is NO REASON to use antything other than /dev/serial0 in recent Raspbian. How-do-i-make-serial-work-on-the-raspberry-pi3 – Milliways Mar 6 '18 at 9:40
  • 3
    Possible duplicate of How do I make serial work on the Raspberry Pi3 – Milliways Mar 6 '18 at 9:41
  • DO NOT post detail in Comments; edit your question. This Question is seriously lacking in detail - What Pi? What OS? Have you enabled serial? If you read the linked answer this explains most issues. – Milliways Mar 6 '18 at 10:01
  • I am already trying to figure it out with you linked question. I am using pi zero w and 2017-11-29-raspbian-stretch-lite. – Hans Jürgen Mar 6 '18 at 10:05
  • Jürgen, you mention rx and tx pins. Aren't you missing one? Or is that only to let the RPi talk to itself? – Gerard H. Pille Mar 6 '18 at 10:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.