Raspberry Pi > pySerial 2.6 > [CR]はreadline()のdelimiterに使えない | [CR]まで読込む実装

```txt:動作環境
Raspberry Pi 2 Model B (以下RPi)
Raspbian Jessie
Python 2.7.9
pySerial 2.6-1.1
```

```
$ pip show pyserial
---
Name: pyserial
Version: 2.6
Location: /usr/lib/python2.7/dist-packages
Requires: 
```

### 注意点

[Python 2.6 以降だと PySerial で '\r' が readline の delimiter に使えない](http://oxon.hatenablog.com/entry/20111108/1320680175)
> PySerial では Python 2.6 以降の場合には、'\r' (CR) が readline のときの delimiter に使えません。つまり、装置側の出力に '\r' が delimiter として使われている場合、次の code だと '\n' (LF) を待ってしまうために time out してしまいます。

ということで、readline()は用途によっては使えない。

### 実装

CR終端文字列の受信を実装してみた。

- 参考1: https://stackoverflow.com/questions/16470903/pyserial-2-6-specify-end-of-line-in-readline
- 参考2: [pyserialでreadしたデータの文字比較](https://ja.stackoverflow.com/questions/8532/pyserial%E3%81%A7read%E3%81%97%E3%81%9F%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E6%96%87%E5%AD%97%E6%AF%94%E8%BC%83)


CRコード自身は受信文字列から除外するように実装した。

### タイムアウトなし

```test_recv_170825b.py
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import time
import serial
import datetime

def recvCommand_CRterminated():
    if con1.inWaiting() == 0:
        return

    EOL_CODE = '\r'
    buf = ""
    while True:
        c = con1.read(1)  # 1: byte
        if c:
            if c == EOL_CODE:
                break
            buf += c            

    print(datetime.datetime.today(), end='')
    print("recvd:", end='')
    print(buf)

with serial.Serial('/dev/ttyUSB1', 9600, timeout=10) as con1:
    recvCommand_CRterminated()
    #con1.flushOutput()
    #con1.flushInput()
    #time.sleep(.1)
```

### タイムアウトあり

- 受信ありかどうかは10msecごとにチェックしている

```test_recv_170825.py
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import time
import serial
import datetime

def recvCommand_CRterminated(tmout_sec):
    EOL_CODE = '\r'
    buf = ""
    start_time = time.time()
    while True:
        # print('.', end='')
        if con1.inWaiting() == 0:
            if (time.time() - start_time > tmout_sec):
                return
            time.sleep(0.01)
            continue
        code = con1.read(1)  # 1: byte
        if code:
            if code == EOL_CODE:
                break
            buf += code            

    print(datetime.datetime.today(), end='')
    print("recvd:", end='')
    print(buf)

with serial.Serial('/dev/ttyUSB1', 9600, timeout=10) as con1:
    recvCommand_CRterminated(0.1)  # [sec]
    #con1.flushOutput()
    #con1.flushInput()
    #time.sleep(.1)

```

### 関連

[Raspberry Pi > pySerial 2.6 > bug? > 受信バッファにデータが残る場合がある](http://qiita.com/7of9/items/52bc4892ce07d90437ac)

### import用

- import用に変更
- LFコードは無視

```util_recv_170825.py
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import time
import serial
import datetime


def recvCommand_CRterminated(acon, tmout_sec):
    CR_CODE = '\r'
    LF_CODE = '\n'
    buf = ""
    start_time = time.time()
    while True:
        # print('.', end='')
        if acon.inWaiting() == 0:
            if (time.time() - start_time > tmout_sec):
                return
            time.sleep(0.01)
            continue
        code = acon.read(1)  # 1: byte
        if code:
            if code == LF_CODE:  # ignore LF
                continue
            if code == CR_CODE:
                break
            buf += code            

    print(datetime.datetime.today(), end='')
    print("recvd:", end='')
    print(buf)


if __name__ == '__main__':
    print('start receiving')
    with serial.Serial('/dev/ttyUSB1', 9600, timeout=10) as con1:
        recvCommand_CRterminated(con1, 0.1)  # [sec]
        #con1.flushOutput()
        #con1.flushInput()
        #time.sleep(.1)

```