3

For the life of me, I cannot figure out how to do a non-blocking serial read in Python 3 using my Raspberry Pi.

Here's my code:

import serial #for pySerial

ser = serial.Serial('/dev/ttyUSB0', 9600) #open serial port
print ('serial port = ' + ser.name) #print the port used

while (True):
    if (ser.in_waiting>0):
        ser.read(ser.in_waiting)

Result:
AttributeError: 'Serial' object has no attribute 'in_waiting'

Here's the reference page I'm referencing that told me "in_waiting" exists: http://pyserial.readthedocs.io/en/latest/pyserial_api.html

(Update) Related:

  1. PySerial non-blocking read loop
Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
  • Use dir and help to debug this method e.g. `print(dir(ser))`, `help(ser.in_waiting)` – Dan Aug 04 '16 at 03:19
  • 1
    What version of `pyserial` are you using? In pre-3.0, you need call the function `inWaiting()` rather than use the `in_waiting` property. – theorifice Aug 04 '16 at 04:19
  • I'm using Python 3.2.3. Am I even accessing the property correctly? I don't understand the difference between a property and a function really (new Python user). – Gabriel Staples Aug 04 '16 at 04:20
  • I didn't ask about your Python version. Check you version of PySerial. – theorifice Aug 04 '16 at 04:21
  • `serial.VERSION` shows 2.5 – Gabriel Staples Aug 04 '16 at 04:24
  • See answer below then. And don't forget to check that the documentation matches the module version that you're using. – theorifice Aug 04 '16 at 04:26
  • Also suggest removing python-3.x and nonblocking tags - they aren't relevant to the problem you described. – theorifice Aug 04 '16 at 04:27
  • Thanks. That's done now. I kept reading the pySerial documentation as referring to the *Python* version number for some reason. I guess I didn't understand. That's why I was so adamant about using the in_waiting property, as I knew I was using Python 3.2.3. It never occurred to me that was the pySerial version number. – Gabriel Staples Aug 04 '16 at 04:39

1 Answers1

2

The documentation link you listed shows in_waiting as a property added in PySerial 3.0. Most likely you're using PySerial < 3.0 so you'll have to call the inWaiting() function.

You can check the version of PySerial as follows:

import serial
print serial.VERSION

If you installed PySerial using pip, you should be able to perform an upgrade (admin privileges may be required):

pip install --upgrade pyserial

Otherwise, change your code to use the proper interface from PySerial < 3.0:

while (True):
    if (ser.inWaiting() > 0):
        ser.read(ser.inWaiting())
theorifice
  • 670
  • 3
  • 9
  • I notice that (in Python 3 at least) to print the received serial data, you can replace `ser.read(ser.inWaiting())` with `print(ser.read(ser.inWaiting()).decode('ascii')`. The decode function converts the binary array to a string. However, this still prints really weird as for some reason the print() function adds a new-line ('\n') at the end of every print. Is there a good way to suppress this behavior? ie: how would you do the print to show what data is arriving? – Gabriel Staples Aug 04 '16 at 04:41
  • Ok, I replaced the plain `print(my_str)` with `print(my_str, end='')`, and that suppresses the new-line, but now when I send the Python code a return key via serial it just prints out a funky character instead of doing a new-line; not sure why. – Gabriel Staples Aug 04 '16 at 04:47