serialwin32.py and serialutil.py error when run Invensense demo python client

匿名 (未验证) 提交于 2019-12-03 01:06:02

问题:

Good days, I'm new to python and trying to run a demo provided by Invensense.(9-axis MPU9250 connects a STM32F407G discovery board, I used code and python client in motion_driver_6.12 which downloaded from Invensense website.) the whole python part are python2.7, pysearil, pygame. I searched my issues in Stackoverflow, but the specific situations are a little different, and most of the solutions are useless for me. First, I show my issues.

UART connects the PC, run Invensense's python client through cmd.exe, pygame window appears briefly and disappear and I get the following error

D:\motion_driver_6.12\eMPL-pythonclient>python eMPL-client.py 7 Traceback (most recent call last): File "eMPL-client.py", line 273, in <module> def four_bytes(d1, d2, d3, d4): File "eMPL-client.py", line 12, in __init__  File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 31, in  __init__ super(Serial, self).__init__(*args, **kwargs) File "C:\Python27\lib\site-packages\serial\serialutil.py", line 218, in  __init__ self.port = port File "C:\Python27\lib\site-packages\serial\serialutil.py", line 264, in port raise ValueError('"port" must be None or a string, not  {}'.format(type(port))) ValueError: "port" must be None or a string, not <type 'int'> 

Second, through the similar questions, what I have done until now:

  1. open the file "serialwin32.py" .Change port = self.name to port = str(self.name). It doesn't work, same error messages.
  2. uninstall the pyserial3.3(the lastest version), using a pyserial2.7. The error meesages were gone but Pygmae now just sits there with a black screen.The old answer said "Invensense tells me that means it is connected and waiting for data".

----------------followed is eMPL-client.py, line 21 and line 273 are marked-----

#!/usr/bin/python    # eMPL_client.py  # A PC application for use with Embedded MotionApps.  # Copyright 2012 InvenSense, Inc. All Rights Reserved.    import serial, sys, time, string, pygame  from ponycube import *    class eMPL_packet_reader: //*********************line 21 __init__ begins********************//     def __init__(self, port, quat_delegate=None, debug_delegate=None, data_delegate=None ):          self.s = serial.Serial(port,115200)          self.s.setTimeout(0.1)          self.s.setWriteTimeout(0.2)  # TODO: Will this break anything?              ##Client attempts to write to eMPL.              #try:              #self.s.write("\n")              #except serial.serialutil.SerialTimeoutException:              #pass # write will timeout if umpl app is already started.            if quat_delegate:              self.quat_delegate = quat_delegate          else:              self.quat_delegate = empty_packet_delegate()            if debug_delegate:              self.debug_delegate = debug_delegate          else:              self.debug_delegate = empty_packet_delegate()            if data_delegate:              self.data_delegate = data_delegate          else:              self.data_delegate = empty_packet_delegate()            self.packets = []          self.length = 0          self.previous = None        def read(self):          NUM_BYTES = 23          p = None          while self.s.inWaiting() >= NUM_BYTES:              rs = self.s.read(NUM_BYTES)              if ord(rs[0]) == ord('$'):                  pkt_code = ord(rs[1])                  if pkt_code == 1:                      d = debug_packet(rs)                      self.debug_delegate.dispatch(d)                  elif pkt_code == 2:                      p = quat_packet(rs)                      self.quat_delegate.dispatch(p)                   elif pkt_code == 3:                      d = data_packet(rs)                      self.data_delegate.dispatch(d)                  else:                      print "no handler for pkt_code",pkt_code              else:                  c = ' '                  print "serial misaligned!"                  while not ord(c) == ord('$'):                      c = self.s.read(1)                  self.s.read(NUM_BYTES-1)        def write(self,a):          self.s.write(a)        def close(self):          self.s.close()        def write_log(self,fname):          f = open(fname,'w')          for p in self.packets:              f.write(p.logfile_line())          f.close()    # ===========  PACKET DELEGATES  ==========    class packet_delegate(object):      def loop(self,event):          print "generic packet_delegate loop w/event",event      def dispatch(self,p):          print "generic packet_delegate dispatched",p    class empty_packet_delegate(packet_delegate):      def loop(self,event):          pass      def dispatch(self,p):          pass    class cube_packet_viewer (packet_delegate):      def __init__(self):          self.screen = Screen(480,400,scale=1.5)          self.cube = Cube(30,60,10)          self.q = Quaternion(1,0,0,0)          self.previous = None  # previous quaternion          self.latest = None    # latest packet (get in dispatch, use in loop)        def loop(self,event):          packet = self.latest          if packet:              q = packet.to_q().normalized()              self.cube.erase(self.screen)              self.cube.draw(self.screen,q)              pygame.display.flip()              self.latest = None        def dispatch(self,p):          if isinstance(p,quat_packet):              self.latest = p    class debug_packet_viewer (packet_delegate):      def loop(self,event):          pass      def dispatch(self,p):          assert isinstance(p,debug_packet);          p.display()    class data_packet_viewer (packet_delegate):      def loop(self,event):          pass      def dispatch(self,p):          assert isinstance(p,data_packet);          p.display()    # =============== PACKETS =================     # For 16-bit signed integers.  def two_bytes(d1,d2):      d = ord(d1)*256 + ord(d2)      if d > 32767:          d -= 65536      return d    # For 32-bit signed integers. //**************************273 begins*********************************// def four_bytes(d1, d2, d3, d4):      d = ord(d1)*(1<<24) + ord(d2)*(1<<16) + ord(d3)*(1<<8) + ord(d4)      if d > 2147483648:          d-= 4294967296      return d 

----------------followed is serialutil.py(version 3.3) from line1 to line272, 218 and 264 are marked-------------

#! python # # Base class and support functions used by various backends. # # This file is part of pySerial. https://github.com/pyserial/pyserial # (C) 2001-2016 Chris Liechti <cliechti@gmx.net> # # SPDX-License-Identifier:    BSD-3-Clause  import io import time  # ``memoryview`` was introduced in Python 2.7 and ``bytes(some_memoryview)`` # isn't returning the contents (very unfortunate). Therefore we need special # cases and test for it. Ensure that there is a ``memoryview`` object for older # Python versions. This is easier than making every test dependent on its # existence. try:     memoryview except (NameError, AttributeError):     # implementation does not matter as we do not really use it.     # it just must not inherit from something else we might care for.     class memoryview(object):   # pylint: disable=redefined-builtin,invalid-name         pass  try:     unicode except (NameError, AttributeError):     unicode = str       # for Python 3, pylint: disable=redefined-builtin,invalid-name  try:     basestring except (NameError, AttributeError):     basestring = (str,)    # for Python 3, pylint: disable=redefined-builtin,invalid-name   # "for byte in data" fails for python3 as it returns ints instead of bytes def iterbytes(b):     """Iterate over bytes, returning bytes instead of ints (python3)"""     if isinstance(b, memoryview):         b = b.tobytes()     i = 0     while True:         a = b[i:i + 1]         i += 1         if a:             yield a         else:             break   # all Python versions prior 3.x convert ``str([17])`` to '[17]' instead of '\x11' # so a simple ``bytes(sequence)`` doesn't work for all versions def to_bytes(seq):     """convert a sequence to a bytes type"""     if isinstance(seq, bytes):         return seq     elif isinstance(seq, bytearray):         return bytes(seq)     elif isinstance(seq, memoryview):         return seq.tobytes()     elif isinstance(seq, unicode):         raise TypeError('unicode strings are not supported, please encode to bytes: {!r}'.format(seq))     else:         # handle list of integers and bytes (one or more items) for Python 2 and 3         return bytes(bytearray(seq))   # create control bytes XON = to_bytes([17]) XOFF = to_bytes([19])  CR = to_bytes([13]) LF = to_bytes([10])   PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE = 'N', 'E', 'O', 'M', 'S' STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO = (1, 1.5, 2) FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS = (5, 6, 7, 8)  PARITY_NAMES = {     PARITY_NONE: 'None',     PARITY_EVEN: 'Even',     PARITY_ODD: 'Odd',     PARITY_MARK: 'Mark',     PARITY_SPACE: 'Space', }   class SerialException(IOError):     """Base class for serial port related exceptions."""   class SerialTimeoutException(SerialException):     """Write timeouts give an exception"""   writeTimeoutError = SerialTimeoutException('Write timeout') portNotOpenError = SerialException('Attempting to use a port that is not open')   class Timeout(object):     """\     Abstraction for timeout operations. Using time.monotonic() if available     or time.time() in all other cases.      The class can also be initialized with 0 or None, in order to support     non-blocking and fully blocking I/O operations. The attributes     is_non_blocking and is_infinite are set accordingly.     """     if hasattr(time, 'monotonic'):         # Timeout implementation with time.monotonic(). This function is only         # supported by Python 3.3 and above. It returns a time in seconds         # (float) just as time.time(), but is not affected by system clock         # adjustments.         TIME = time.monotonic     else:         # Timeout implementation with time.time(). This is compatible with all         # Python versions but has issues if the clock is adjusted while the         # timeout is running.         TIME = time.time      def __init__(self, duration):         """Initialize a timeout with given duration"""         self.is_infinite = (duration is None)         self.is_non_blocking = (duration == 0)         self.duration = duration         if duration is not None:             self.target_time = self.TIME() + duration         else:             self.target_time = None      def expired(self):         """Return a boolean, telling if the timeout has expired"""         return self.target_time is not None and self.time_left() <= 0      def time_left(self):         """Return how many seconds are left until the timeout expires"""         if self.is_non_blocking:             return 0         elif self.is_infinite:             return None         else:             delta = self.target_time - self.TIME()             if delta > self.duration:                 # clock jumped, recalculate                 self.target_time = self.TIME() + self.duration                 return self.duration             else:                 return max(0, delta)      def restart(self, duration):         """\         Restart a timeout, only supported if a timeout was already set up         before.         """         self.duration = duration         self.target_time = self.TIME() + duration   class SerialBase(io.RawIOBase):     """\     Serial port base class. Provides __init__ function and properties to     get/set port settings.     """      # default values, may be overridden in subclasses that do not support all values     BAUDRATES = (50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,                  9600, 19200, 38400, 57600, 115200, 230400, 460800, 500000,                  576000, 921600, 1000000, 1152000, 1500000, 2000000, 2500000,                  3000000, 3500000, 4000000)     BYTESIZES = (FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS)     PARITIES = (PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE)     STOPBITS = (STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO)      def __init__(self,                  port=None,                  baudrate=9600,                  bytesize=EIGHTBITS,                  parity=PARITY_NONE,                  stopbits=STOPBITS_ONE,                  timeout=None,                  xonxoff=False,                  rtscts=False,                  write_timeout=None,                  dsrdtr=False,                  inter_byte_timeout=None,                  exclusive=None,                  **kwargs):         """\         Initialize comm port object. If a "port" is given, then the port will be         opened immediately. Otherwise a Serial port object in closed state         is returned.         """          self.is_open = False         self.portstr = None         self.name = None         # correct values are assigned below through properties         self._port = None         self._baudrate = None         self._bytesize = None         self._parity = None         self._stopbits = None         self._timeout = None         self._write_timeout = None         self._xonxoff = None         self._rtscts = None         self._dsrdtr = None         self._inter_byte_timeout = None         self._rs485_mode = None  # disabled by default         self._rts_state = True         self._dtr_state = True         self._break_state = False         self._exclusive = None          # assign values using get/set methods using the properties feature //**************218**************//         self.port = port  //**************218**************//         self.baudrate = baudrate         self.bytesize = bytesize         self.parity = parity         self.stopbits = stopbits         self.timeout = timeout         self.write_timeout = write_timeout         self.xonxoff = xonxoff         self.rtscts = rtscts         self.dsrdtr = dsrdtr         self.inter_byte_timeout = inter_byte_timeout         self.exclusive = exclusive          # watch for backward compatible kwargs         if 'writeTimeout' in kwargs:             self.write_timeout = kwargs.pop('writeTimeout')         if 'interCharTimeout' in kwargs:             self.inter_byte_timeout = kwargs.pop('interCharTimeout')         if kwargs:             raise ValueError('unexpected keyword arguments: {!r}'.format(kwargs))          if port is not None:             self.open()      #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -      # to be implemented by subclasses:     # def open(self):     # def close(self):      #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -      @property     def port(self):         """\         Get the current port setting. The value that was passed on init or using         setPort() is passed back.         """         return self._port      @port.setter     def port(self, port):         """\         Change the port.         """ //*************************line 263**********************//         if port is not None and not isinstance(port, basestring):             raise ValueError('"port" must be None or a string, not {}'.format(type(port)))         was_open = self.is_open         if was_open:             self.close()         self.portstr = port         self._port = port         self.name = self.portstr         if was_open:             self.open() 

-------------followed is serialwin32.py(version 3.3), 31 is marked-----------------------------------------

#! python # # backend for Windows ("win32" incl. 32/64 bit support) # # (C) 2001-2015 Chris Liechti <cliechti@gmx.net> # # This file is part of pySerial. https://github.com/pyserial/pyserial # SPDX-License-Identifier:    BSD-3-Clause # # Initial patch to use ctypes by Giovanni Bajo <rasky@develer.com>  # pylint: disable=invalid-name,too-few-public-methods import ctypes import time from serial import win32  import serial from serial.serialutil import SerialBase, SerialException, to_bytes, portNotOpenError, writeTimeoutError   class Serial(SerialBase):     """Serial port implementation for Win32 based on ctypes."""      BAUDRATES = (50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,                  9600, 19200, 38400, 57600, 115200)      def __init__(self, *args, **kwargs):         self._port_handle = None         self._overlapped_read = None         self._overlapped_write = None //**************31**************//         super(Serial, self).__init__(*args, **kwargs) //**************31**************// 

Questions:

回答1:

Looking online, I found this Github repo that appears to correspond to the code you are working with. It appears eMPL-client.py is incompatible with newer versions of pyserial. Specifically, the __main__ routine requires numeric port identifiers, but the pyserial 3.3 serial.Serial requires textual port identifiers. I do not have the setup to test this, but you can try the following.

  1. Install a fresh copy of Python 2.7, which is what eMPL-client.py targets. This is unrelated to pyserial 2.7.
  2. In the fresh copy, install pyserial 2.7 and the other dependencies. Per the source, pyserial 2.7 uses numbers for ports. Pyserial 3.3 uses names for ports, whence the "port must be a string" error.

That should get you past the initial error, which is similar to this answer to the question you linked. At that point, it's probably time to pull out your oscilloscope and make sure the board is generating signals. If so, check the speed/baud/parity. I see that the source runs at 115200bps; maybe try 57600 instead, if your hardware supports it.

An alternative

To use eMPL-client.py with pyserial 3.3, in eMPL-client.py, look for the lines:

if __name__ == "__main__":     if len(sys.argv) == 2:         comport = int(sys.argv[1]) - 1      #### This is the line that triggers the issue     else:         print "usage: " + sys.argv[0] + " port"         sys.exit(-1) 

Change the ####-marked line to

        comport = sys.argv[1] 

(make sure to keep the indentation the same!)

Then, in cmd.exe, run

python eMPL-client.py COM7 

with the string port name, e.g., COM7, instead of a port number, e.g., 7.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!