2

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

#!/usr/bin/python3

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
    else:
        raise EnvironmentError('Unsupported platform')
    return ports

try:
    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')
            time.sleep(10)
            continue    

        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:    
                # 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):
                        ser.readline()
                    # 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())
                            f.write(line)

            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')
        time.sleep(10)
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
    ser.close()
    
  • 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
    print(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

Hans Jürgen
  • 53
  • 1
  • 7

0 Answers0