Python Event Driven Serial

 admin  
  1. Python Event Driven Serial
  2. Python Event Driven Serial Killer
Active2 months ago

I am reading serial data like this:

Asyncio is a library to write concurrent code using the async/await syntax. Asyncio is used as a foundation for multiple Python asynchronous frameworks that provide high-performance network and web-servers, database connection libraries, distributed task queues, etc.

The problem is that it prevents anything else from executing including bottle py web framework. Adding sleep() won't help.

Changing 'while True' to 'while ser.readline():' doesn't print 'test', which is strange since it worked in Python 2.7. Any ideas what could be wrong?

Event
  1. The purpose of this demo program (in Python 2.7): To detect an event using GPIO interrupts without declaring a global variable. Based on suggestions by Outis and AndrewS on the RasPiTV forum. The simple circuit is: 3V3 - Button - LED - 68ohm resistor - GPIO4. Every press of the button increases the value of count by 1.
  2. Parameters: port – Device name or None. Baudrate (int) – Baud rate such as 9600 or 115200 etc. Bytesize – Number of data bits. Possible values: FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS; parity – Enable parity checking. Possible values: PARITY_NONE, PARITY_EVEN, PARITY_ODD PARITY_MARK,.

Ideally I should be able to read serial data only when it's available. Data is being sent every 1,000 ms.

dda
5,5242 gold badges20 silver badges33 bronze badges
DominicMDominicM
1,83712 gold badges31 silver badges55 bronze badges

4 Answers

Put it in a separate thread, for example:

Chiramisu

Python Event Driven Serial

3,3106 gold badges39 silver badges71 bronze badges
Fredrik HåårdFredrik Håård

Python Event Driven Serial Killer

Using a separate thread is totally unnecessary. Just do this for your infinite while loop instead (Tested in Python 3.2.3):

This way you only read and print if something is there. You said, 'Ideally I should be able to read serial data only when it's available.' This is exactly what the code above does. If nothing is available to read, it skips on to the rest of your code in the while loop. Totally non-blocking.

(This answer originally posted & debugged here: Python 3 non-blocking read with pySerial (Cannot get pySerial's 'in_waiting' property to work))

pySerial documentation: http://pyserial.readthedocs.io/en/latest/pyserial_api.html

UPDATE:

  • 27 Dec. 2018: added comment about in_waiting vs inWaiting(). Thanks to @FurkanTürkal for pointing that out in the comments below. See documentation here: https://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial.in_waiting.
  • 27 Oct. 2018: Add sleep to let other threads run.
    • Documentation: https://docs.python.org/3/library/time.html#time.sleep
    • Thanks to @RufusV2 for bringing this point up in the comments.

Note on multi-threading:

Even though reading serial data, as shown above, does not require using multiple threads, reading keyboard input in a non-blocking manner does. Therefore, to accomplish non-blocking keyboard input reading, I've written this answer: How to read keyboard-input?.

Gabriel StaplesGabriel Staples
3,2523 gold badges21 silver badges48 bronze badges

I would warn against using blocking IO in a thread. Remember Python has a GIL and at one time only one thread can execute. Now please note that pyserial module is a wrapper over an OS implementation of accessing the serial port. That means it calls code external to the Python. If that code blocks, then the interpreter also get blocked and nothing will execute in the Python program, even the main thread.

This can even happen when using non-blocking IO or timeout based polling if the underlying device driver does not implement timeout well.

A more robust approach is to use multiprocessing module with a queue. Run serial read code in a separate process. This will make sure main and other threads don't block and the program can exit in clean way.

Mohammad AzimMohammad Azim

Use a timer driven event to test and read the serial port.Untested example:

Keren Caelen
1,3462 gold badges15 silver badges33 bronze badges
William KuipersWilliam Kuipers

Not the answer you're looking for? Browse other questions tagged pythonpython-3.xnonblockingpyserial or ask your own question.

   Coments are closed