2017-03-26 168 views
4

訪問我正在使用pySerial讀取TTL字節流。讀取兩個字節:Python IndexError:列表索引超出範圍。無法通過索引

CheckSumByte = [ b for b in ser.read(2)] 
print(CheckSumByte) 
print(type(CheckSumByte)) 
print(str(len(CheckSumByte))) 
print(CheckSumByte[0]) 

輸出:

[202, 87] 
<class 'list'> 
2 
IndexError: list index out of range 

我無法通過索引來訪問的任何CheckSumByte元件(0或1)。哪裏不對?

這裏是我的代碼:

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 

肯尼:謝謝。更簡單的兩個字節:

CheckSumByte.append(ser.read(1)) 
    CheckSumByte.append(ser.read(1)) 

工作正常,但很尷尬。這些項目是類型字節。如何使用列表理解將項添加到列表中?我想避免追加功能,因爲它很慢。

我注意到CheckSumByte的項目是整數時它不起作用。 Python 3列表理解是否需要特殊格式才能將字節添加爲字節(而不是轉換爲整數)?

+0

你能展示完整的追溯? – falsetru

+2

如果循環直通,會發生什麼情況。閱讀(2)並打印結果 - 對於ser.read(2)中的b:print(b,type(b)) – user1245262

+0

user1245262 - 我喜歡你的想法。我無法得到正確的語法:CheckSumByte = [b爲ser.read(2)中的b: print(b,type(b))] – Blair

回答

1

根據您最近的評論,你已經構建ser爲:

ser = serial.Serial(
    port=PortName, baudrate=115200, parity=serial.PARITY_NONE, 
    stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, 
    timeout=0) 

按照documentation這意味着ser無阻塞(儘管你斷言它擋住!)。

由於處於非阻塞模式,絕對沒有理由期望ser.read(n)返回完全n字節。相反,如果你想讀n字節,你應該:

  • 結構ser如堵在構造函數(使用timeout=None);或
  • 環路,同時監測的字節數實際讀取(就像你讀網絡插槽時)

意味着,如果你想讀n字節,你需要做這樣的事情,後者例如:

def read_exactly(ser, n): 
    bytes = b"" 

    while len(bytes) < n: 
     bytes += ser.read(n - len(bytes)) 

    return bytes 

在您的具體情況下,您似乎在監視輸入緩衝區以確保有足夠的數據用於以下讀取。但是這種監測只發生在的一些的時間,而不是全部的時間。因此,如果FirstByte != 0xFA可能會耗盡讀緩衝區,除非採取上述方法之一。

0

donkopotamus - 你找到了答案。我混淆了阻止條款。我設置超時= 0來嘗試其他設置。你說得對,ser可以讀取零字節。我忘了將它重新設置爲超時=無。現在總是讀取一些字節。沒有更多的IndexError。非常感謝你。

+1

這可能應已被添加爲對我的答案的評論,而不是作爲對這個問題的另一個「答案」。此外,如果它解決了您的問題,您應該「接受」我的答案(我很高興它!) – donkopotamus

+0

再次感謝。這是我在StackOverflow上的第一個問題。我以爲我正在回答這個問題。答案是:你解決了它。我不想添加另一條評論,並將其打開。我沒有看到接受按鈕。我仍然看不到一個。 – Blair

相關問題