I am using pySerial
to read TTL byte stream. To read two bytes:
CheckSumByte = [ b for b in ser.read(2)]
print( CheckSumByte)
print( type(CheckSumByte))
print( str(len(CheckSumByte)))
print( CheckSumByte[0])
Output:
[202, 87]
<class 'list'>
2
IndexError: list index out of range
I cannot access any elements of CheckSumByte
by index (0 or 1). What is wrong?
Here is my code:
while(ReadBufferCount < 1000):
time.sleep(0.00002)
InputBuffer = ser.inWaiting()
if (InputBuffer > 0):
FirstByte = ser.read(1)
if ord(FirstByte) == 0xFA:
while ser.inWaiting() < 21: pass
IndexByte = ser.read(1)
SpeedByte = [ b for b in ser.read(2)]
DataByte0 = [ b for b in ser.read(4)]
DataByte1 = [ b for b in ser.read(4)]
DataByte2 = [ b for b in ser.read(4)]
DataByte3 = [ b for b in ser.read(4)]
CheckSumByte = [ b for b in ser.read(2)]
print( CheckSumByte[0]) #Out of Range??`
Traceback (most recent call last):
File "<ipython-input-6-5233b0a578b1>", line 1, in <module>
runfile('C:/Users/Blair/Documents/Python/Neato XV-11 Lidar/Serial9.py', wdir='C:/Users/Blair/Documents/Python/Neato XV-11 Lidar')
File "C:\Program Files (x86)\WinPython-32bit-3.4.3.3\python-3.4.3\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 682, in runfile
execfile(filename, namespace)
File "C:\Program Files (x86)\WinPython-32bit-3.4.3.3\python-3.4.3\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 85, in execfile
exec(compile(open(filename, 'rb').read(), filename, 'exec'), namespace)
File "C:/Users/Blair/Documents/Python/Neato XV-11 Lidar/Serial9.py", line 88, in <module>
print( CheckSumByte[0]) #Out of Range??
IndexError: list index out of range
Kenny: Thanks. Even simpler for the two bytes:
CheckSumByte.append(ser.read(1))
CheckSumByte.append(ser.read(1))
Works properly, but awkward. The items are type bytes. How to add items to the list using list comprehension? I would like to avoid the append function because it is slow.
I notice it does not work when the items of CheckSumByte are integer. Does Python 3 list comprehension require special format to add the bytes as byte (not convert to integer)?
According to your most recent comment you have constructed ser
as:
ser = serial.Serial(
port=PortName, baudrate=115200, parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS,
timeout=0)
According to the documentation this means that ser
is non-blocking (despite your assertion it is blocking!).
As it is in non-blocking mode there is absolutely no reason to expect ser.read(n)
to return exactly n
bytes. Instead, if you wish to read n
bytes you should either:
ser
as blocking (use timeout=None
) in the constructor; or The latter for example means that if you wish to read n
bytes you will need to do something like:
def read_exactly(ser, n):
bytes = b""
while len(bytes) < n:
bytes += ser.read(n - len(bytes))
return bytes
In your particular case, you seem to be monitoring the the input buffer to ensure there is adequate data for the following reads. But this monitoring is only occurring some of the time, not all of the time. Thus when FirstByte != 0xFA
you could exhaust the read buffer unless you take one of the approachs given above.
donkopotamus - You found the answer. I confused the blocking terms. I set timeout=0 to try other setup. You are right, ser could read zero bytes. I forgot to set it back to timeout=None. Now always reads some bytes. No more IndexError. Thank you very much.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.