kopia lustrzana https://github.com/jacklinquan/usbserial4a
rodzic
fe48e8224f
commit
24e127b4c4
|
@ -12,6 +12,7 @@ from kivy.uix.button import Button
|
|||
from kivy.clock import mainthread
|
||||
from kivy.utils import platform
|
||||
import threading
|
||||
import sys
|
||||
|
||||
if platform == 'android':
|
||||
from usb4a import usb
|
||||
|
@ -133,7 +134,7 @@ class MainApp(App):
|
|||
8,
|
||||
'N',
|
||||
1,
|
||||
timeout=0.5)
|
||||
timeout=1)
|
||||
else:
|
||||
self.serial_port = Serial(
|
||||
device_name,
|
||||
|
@ -141,7 +142,7 @@ class MainApp(App):
|
|||
8,
|
||||
'N',
|
||||
1,
|
||||
timeout=0.5)
|
||||
timeout=1)
|
||||
|
||||
if self.serial_port.is_open and not self.read_thread:
|
||||
self.read_thread = threading.Thread(target = self.read_msg_thread)
|
||||
|
@ -151,22 +152,27 @@ class MainApp(App):
|
|||
|
||||
def on_btn_write_release(self):
|
||||
if self.serial_port and self.serial_port.is_open:
|
||||
self.serial_port.write(
|
||||
bytes(self.uiDict['txtInput_write'].text + '\n'))
|
||||
if sys.version_info < (3, 0):
|
||||
data = bytes(self.uiDict['txtInput_write'].text + '\n')
|
||||
else:
|
||||
data = bytes(
|
||||
(self.uiDict['txtInput_write'].text + '\n'), 'utf8')
|
||||
self.serial_port.write(data)
|
||||
self.uiDict['txtInput_read'].text += '[Sent]{}\n'.format(
|
||||
self.uiDict['txtInput_write'].text)
|
||||
self.uiDict['txtInput_write'].text = ''
|
||||
|
||||
def read_msg_thread(self):
|
||||
while True:
|
||||
if not self.serial_port.is_open:
|
||||
break
|
||||
try:
|
||||
if not self.serial_port.is_open:
|
||||
break
|
||||
received_msg = self.serial_port.read()
|
||||
if received_msg:
|
||||
self.display_received_msg(str(received_msg))
|
||||
except:
|
||||
break
|
||||
except Exception as ex:
|
||||
raise ex
|
||||
# break
|
||||
|
||||
@mainthread
|
||||
def display_received_msg(self, msg):
|
||||
|
|
2
setup.py
2
setup.py
|
@ -2,7 +2,7 @@ from setuptools import setup
|
|||
|
||||
setup(
|
||||
name="usbserial4a",
|
||||
version="0.1.4",
|
||||
version="0.1.5",
|
||||
description="Python package for Kivy Android USB serial port.",
|
||||
long_description="https://github.com/jacklinquan/usbserial4a",
|
||||
long_description_content_type="text/markdown",
|
||||
|
|
|
@ -9,4 +9,4 @@ Requires: kivy, pyjnius, pyserial, usb4a
|
|||
'''
|
||||
|
||||
# Project version
|
||||
__version__ = '0.1.4'
|
||||
__version__ = '0.1.5'
|
||||
|
|
|
@ -4,8 +4,8 @@ Classes:
|
|||
CdcAcmSerial(serial.serialutil.SerialBase)
|
||||
'''
|
||||
|
||||
import time
|
||||
from serial.serialutil import SerialBase, SerialException
|
||||
from serial.serialutil import SerialBase, SerialException, to_bytes, \
|
||||
portNotOpenError, writeTimeoutError, Timeout
|
||||
from usb4a import usb
|
||||
|
||||
class CdcAcmSerial(SerialBase):
|
||||
|
@ -34,11 +34,11 @@ class CdcAcmSerial(SerialBase):
|
|||
'M':3,
|
||||
'S':4}
|
||||
|
||||
DEFAULT_READ_BUFFER_SIZE = 16 * 1024
|
||||
DEFAULT_READ_BUFFER_SIZE = 1024
|
||||
DEFAULT_WRITE_BUFFER_SIZE = 16 * 1024
|
||||
|
||||
USB_READ_TIMEOUT_MILLIS = 1
|
||||
USB_WRITE_TIMEOUT_MILLIS = 5000
|
||||
USB_READ_TIMEOUT_MILLIS = 5000
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._device = None
|
||||
|
@ -153,6 +153,17 @@ class CdcAcmSerial(SerialBase):
|
|||
self._connection = None
|
||||
self.is_open = False
|
||||
|
||||
@property
|
||||
def in_waiting(self):
|
||||
'''Return the number of bytes currently in the input buffer.
|
||||
|
||||
Returns:
|
||||
Length (int): number of data bytes in the input buffer.
|
||||
'''
|
||||
# Read from serial port hardware and put the data into read buffer.
|
||||
self._read_buffer.extend(self._read())
|
||||
return len(self._read_buffer)
|
||||
|
||||
def read(self, size=1):
|
||||
'''Read data from the serial port.
|
||||
|
||||
|
@ -162,40 +173,18 @@ class CdcAcmSerial(SerialBase):
|
|||
Returns:
|
||||
read (bytes): data bytes read from the serial port.
|
||||
'''
|
||||
if not self.is_open:
|
||||
return None
|
||||
if not self._read_endpoint:
|
||||
raise SerialException("Read endpoint does not exist!")
|
||||
|
||||
read = bytearray()
|
||||
timeout = Timeout(self.timeout)
|
||||
|
||||
if (size <= len(self._read_buffer)):
|
||||
# There is enough data in read buffer.
|
||||
# Get data from read buffer.
|
||||
read = self._read_buffer[:size]
|
||||
self._read_buffer = self._read_buffer[size:]
|
||||
else:
|
||||
timeout = int(
|
||||
self._timeout * 1000 if self._timeout \
|
||||
else self.USB_READ_TIMEOUT_MILLIS)
|
||||
|
||||
# Get raw data from hardware.
|
||||
buf = bytearray(1024)
|
||||
totalBytesRead = self._connection.bulkTransfer(
|
||||
self._read_endpoint,
|
||||
buf,
|
||||
1024,
|
||||
timeout)
|
||||
if totalBytesRead < 0:
|
||||
# Read timeout. Set totalBytesRead to 0.
|
||||
totalBytesRead = 0
|
||||
# Keep reading until there is enough data or timeout.
|
||||
while self.in_waiting < size:
|
||||
if timeout.expired():
|
||||
break
|
||||
|
||||
# Get data from read buffer.
|
||||
read = self._read_buffer[:size]
|
||||
self._read_buffer = self._read_buffer[size:]
|
||||
|
||||
# Put serial port data into read buffer.
|
||||
self._read_buffer.extend(buf[:totalBytesRead])
|
||||
# Get data from read buffer.
|
||||
read = self._read_buffer[:size]
|
||||
self._read_buffer = self._read_buffer[size:]
|
||||
|
||||
return bytes(read)
|
||||
|
||||
def write(self, data):
|
||||
|
@ -230,13 +219,34 @@ class CdcAcmSerial(SerialBase):
|
|||
wrote += i
|
||||
return wrote
|
||||
|
||||
def flush(self, flush_time=0.2):
|
||||
'''Simply wait some time to allow all data to be written.
|
||||
def flush(self):
|
||||
'''Simply wait some time to allow all data to be written.'''
|
||||
pass
|
||||
|
||||
def _read(self):
|
||||
'''Hardware dependent read function.
|
||||
|
||||
Parameters:
|
||||
flush_time (float): time in seconds to wait.
|
||||
Returns:
|
||||
read (bytes): data bytes read from the serial port.
|
||||
'''
|
||||
time.sleep(flush_time)
|
||||
if not self.is_open:
|
||||
raise portNotOpenError
|
||||
if not self._read_endpoint:
|
||||
raise SerialException("Read endpoint does not exist!")
|
||||
|
||||
# Get raw data from hardware.
|
||||
buf = bytearray(self.DEFAULT_READ_BUFFER_SIZE)
|
||||
totalBytesRead = self._connection.bulkTransfer(
|
||||
self._read_endpoint,
|
||||
buf,
|
||||
self.DEFAULT_READ_BUFFER_SIZE,
|
||||
self.USB_READ_TIMEOUT_MILLIS)
|
||||
if totalBytesRead < 0:
|
||||
# Read timeout. Set totalBytesRead to 0.
|
||||
totalBytesRead = 0
|
||||
|
||||
read = buf[:totalBytesRead]
|
||||
return bytes(read)
|
||||
|
||||
def _send_acm_control_message(self, request, value, buf=None):
|
||||
'''USB control transfer.
|
||||
|
|
|
@ -4,8 +4,8 @@ Classes:
|
|||
FtdiSerial(serial.serialutil.SerialBase)
|
||||
'''
|
||||
|
||||
import time
|
||||
from serial.serialutil import SerialBase, SerialException
|
||||
from serial.serialutil import SerialBase, SerialException, to_bytes, \
|
||||
portNotOpenError, writeTimeoutError, Timeout
|
||||
from usb4a import usb
|
||||
|
||||
class FtdiSerial(SerialBase):
|
||||
|
@ -61,9 +61,6 @@ class FtdiSerial(SerialBase):
|
|||
BAUDRATE_TOLERANCE = 3.0 # acceptable clock drift, in %
|
||||
BITBANG_CLOCK_MULTIPLIER = 4
|
||||
|
||||
DEFAULT_READ_BUFFER_SIZE = 16 * 1024
|
||||
DEFAULT_WRITE_BUFFER_SIZE = 16 * 1024
|
||||
|
||||
FTDI_DEVICE_OUT_REQTYPE = usb.build_usb_control_request_type(
|
||||
usb.UsbConstants.USB_DIR_OUT,
|
||||
usb.UsbConstants.USB_TYPE_VENDOR,
|
||||
|
@ -73,8 +70,11 @@ class FtdiSerial(SerialBase):
|
|||
usb.UsbConstants.USB_TYPE_VENDOR,
|
||||
usb.USB_RECIPIENT_DEVICE)
|
||||
|
||||
USB_WRITE_TIMEOUT_MILLIS = 5000
|
||||
DEFAULT_READ_BUFFER_SIZE = 1024
|
||||
DEFAULT_WRITE_BUFFER_SIZE = 16 * 1024
|
||||
|
||||
USB_READ_TIMEOUT_MILLIS = 5000
|
||||
USB_WRITE_TIMEOUT_MILLIS = 5000
|
||||
|
||||
# Length of the modem status header, transmitted with every read.
|
||||
MODEM_STATUS_HEADER_LENGTH = 2
|
||||
|
@ -162,6 +162,17 @@ class FtdiSerial(SerialBase):
|
|||
if result != 0:
|
||||
raise SerialException("Reset failed: result={}".format(result))
|
||||
|
||||
@property
|
||||
def in_waiting(self):
|
||||
'''Return the number of bytes currently in the input buffer.
|
||||
|
||||
Returns:
|
||||
Length (int): number of data bytes in the input buffer.
|
||||
'''
|
||||
# Read from serial port hardware and put the data into read buffer.
|
||||
self._read_buffer.extend(self._read())
|
||||
return len(self._read_buffer)
|
||||
|
||||
def read(self, size=1):
|
||||
'''Read data from the serial port.
|
||||
|
||||
|
@ -171,49 +182,18 @@ class FtdiSerial(SerialBase):
|
|||
Returns:
|
||||
read (bytes): data bytes read from the serial port.
|
||||
'''
|
||||
if not self.is_open:
|
||||
return None
|
||||
if not self._read_endpoint:
|
||||
raise SerialException("Read endpoint does not exist!")
|
||||
|
||||
read = bytearray()
|
||||
timeout = Timeout(self.timeout)
|
||||
|
||||
if (size <= len(self._read_buffer)):
|
||||
# There is enough data in read buffer.
|
||||
# Get data from read buffer.
|
||||
read = self._read_buffer[:size]
|
||||
self._read_buffer = self._read_buffer[size:]
|
||||
else:
|
||||
timeout = int(
|
||||
self._timeout * 1000 if self._timeout \
|
||||
else self.USB_READ_TIMEOUT_MILLIS)
|
||||
|
||||
# Get raw data from hardware.
|
||||
buf = bytearray(1024)
|
||||
totalBytesRead = self._connection.bulkTransfer(
|
||||
self._read_endpoint,
|
||||
buf,
|
||||
1024,
|
||||
timeout)
|
||||
if totalBytesRead < self.MODEM_STATUS_HEADER_LENGTH:
|
||||
raise SerialException(
|
||||
"Expected at least {} bytes".format(
|
||||
self.MODEM_STATUS_HEADER_LENGTH))
|
||||
# Keep reading until there is enough data or timeout.
|
||||
while self.in_waiting < size:
|
||||
if timeout.expired():
|
||||
break
|
||||
|
||||
# Get data from read buffer.
|
||||
read = self._read_buffer[:size]
|
||||
self._read_buffer = self._read_buffer[size:]
|
||||
|
||||
# Translate raw data into serial port data.
|
||||
dest = bytearray()
|
||||
self._filterStatusBytes(
|
||||
buf,
|
||||
dest,
|
||||
totalBytesRead,
|
||||
self._read_endpoint.getMaxPacketSize())
|
||||
|
||||
# Put serial port data into read buffer.
|
||||
self._read_buffer.extend(dest)
|
||||
# Get data from read buffer.
|
||||
read = self._read_buffer[:size]
|
||||
self._read_buffer = self._read_buffer[size:]
|
||||
|
||||
return bytes(read)
|
||||
|
||||
def write(self, data):
|
||||
|
@ -248,13 +228,9 @@ class FtdiSerial(SerialBase):
|
|||
wrote += i
|
||||
return wrote
|
||||
|
||||
def flush(self, flush_time=0.2):
|
||||
'''Simply wait some time to allow all data to be written.
|
||||
|
||||
Parameters:
|
||||
flush_time (float): time in seconds to wait.
|
||||
'''
|
||||
time.sleep(flush_time)
|
||||
def flush(self):
|
||||
'''Simply wait some time to allow all data to be written.'''
|
||||
pass
|
||||
|
||||
def purgeHwBuffers(self, purgeReadBuffers, purgeWriteBuffers):
|
||||
'''Set serial port parameters.
|
||||
|
@ -285,6 +261,39 @@ class FtdiSerial(SerialBase):
|
|||
|
||||
return True
|
||||
|
||||
def _read(self):
|
||||
'''Hardware dependent read function.
|
||||
|
||||
Returns:
|
||||
read (bytes): data bytes read from the serial port.
|
||||
'''
|
||||
if not self.is_open:
|
||||
raise portNotOpenError
|
||||
if not self._read_endpoint:
|
||||
raise SerialException("Read endpoint does not exist!")
|
||||
|
||||
# Get raw data from hardware.
|
||||
buf = bytearray(self.DEFAULT_READ_BUFFER_SIZE)
|
||||
totalBytesRead = self._connection.bulkTransfer(
|
||||
self._read_endpoint,
|
||||
buf,
|
||||
self.DEFAULT_READ_BUFFER_SIZE,
|
||||
self.USB_READ_TIMEOUT_MILLIS)
|
||||
if totalBytesRead < self.MODEM_STATUS_HEADER_LENGTH:
|
||||
raise SerialException(
|
||||
"Expected at least {} bytes".format(
|
||||
self.MODEM_STATUS_HEADER_LENGTH))
|
||||
|
||||
# Translate raw data into serial port data.
|
||||
read = bytearray()
|
||||
self._filterStatusBytes(
|
||||
buf,
|
||||
read,
|
||||
totalBytesRead,
|
||||
self._read_endpoint.getMaxPacketSize())
|
||||
|
||||
return bytes(read)
|
||||
|
||||
def _set_baudrate(self, baudrate):
|
||||
'''Change the current UART baudrate.
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue