Python Forum
Function to Continuasly monitor serial port and control other functions
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Function to Continuasly monitor serial port and control other functions
#1
Hi

I need to built a pythonfile.py that starts to do a task (monitor at all time a serial port)
And when a certain condition is true(receive a certain byte in serial) start/stop certain functions that I already have.

But is important that the task of reading the serial port is always running and never stops.

So imagine that I have

Readserial() 
  While true:
    Read the serial port (I know how to do this) 

    If readbyte = 0x65: #(for example) 
       Kill or start function1() #(but at the same time Readserial() should continue monitoring serial port) 

    If read byte = 0xFF: #example
       Kill or start function2() #(again readSerial() should continue to run) 

Function1() 
  Do something

Function2()
  Do something 
What is my best solution for this
Threading?
callback?
Watchdog?

If someone give a possible structure I would appreciate since I'm an not an expert at programming
thanks
Reply
#2
what is the device that you are using, raspberry pi, arduino?
I'm thinking there must be a way to trigger an interrupt (event in python)
when there is a charater in the UART buffer.
Tell me device you are using, and type of serial (i2c, usart, spi, etc.)
Once I know this, I can look at your available options.
Reply
#3
You may want to use a thread or a process depending on what your function1 and function2 are doing.

You can either start them manually, use a library like APScheduler to have a pool of threads/process and add your function to the job queue, or start thread/processes at the beginning of your code and have them read elements in a queue.

In the last case, your ReadSerial function would only have to put an element in a queue, which should minimize any interruption to the monitoring.
Reply
#4
(Mar-03-2018, 09:08 PM)Larz60+ Wrote: what is the device that you are using, raspberry pi, arduino? I'm thinking there must be a way to trigger an interrupt (event in python) when there is a charater in the UART buffer. Tell me device you are using, and type of serial (i2c, usart, spi, etc.) Once I know this, I can look at your available options.
Hi
I'm reading from uart (tx rx) of raspberry pi gpio.
Is there a trigger?
In the serial uart I'm reading the bytes sent from a NEXTION touch display (if this is important)

(Mar-03-2018, 09:33 PM)marsokod Wrote: You may want to use a thread or a process depending on what your function1 and function2 are doing. You can either start them manually, use a library like APScheduler to have a pool of threads/process and add your function to the job queue, or start thread/processes at the beginning of your code and have them read elements in a queue. In the last case, your ReadSerial function would only have to put an element in a queue, which should minimize any interruption to the monitoring.

Function1() acquires sensor data and show it on lcd
Function2() is the same as 1 but also writes the data to a text file

So threading?
Reply
#5
(Mar-03-2018, 10:16 PM)ricardons Wrote: Function1() acquires sensor data and show it on lcd
Function2() is the same as 1 but also writes the data to a text file

So threading?

Yes, threading since you will be mostly IO-bound so there is very little risk of suffering from global interpreter lock.

Unless Larz60+ has a better solution, I would advise going with the third option I gave you:

At the beginning of your code, create 2 queue.Queue() and start 2 threads fetching data from these queues with a timeout. This timeout shall be big enough not to impact your performances with too many loops, but small enough as it will be the time you may have to wait to shut down your program. I run CAN bus monitoring on a Raspberry Pi and had no problem with a loop of 10ms, but 100ms should be even safer.

Your serial monitor will just put a meaningful value in the corresponding queue. Your threads will pick this value up and act accordingly.

When the main program shuts down, you can put a None value in the queues and make sure that your threads interpret that as a signal they should leave the queue monitoring loop and return. This way, your threads close nicely.
Reply
#6
(Mar-03-2018, 11:08 PM)marsokod Wrote:
(Mar-03-2018, 10:16 PM)ricardons Wrote: Function1() acquires sensor data and show it on lcd Function2() is the same as 1 but also writes the data to a text file So threading?
Yes, threading since you will be mostly IO-bound so there is very little risk of suffering from global interpreter lock. Unless Larz60+ has a better solution, I would advise going with the third option I gave you: At the beginning of your code, create 2 queue.Queue() and start 2 threads fetching data from these queues with a timeout. This timeout shall be big enough not to impact your performances with too many loops, but small enough as it will be the time you may have to wait to shut down your program. I run CAN bus monitoring on a Raspberry Pi and had no problem with a loop of 10ms, but 100ms should be even safer. Your serial monitor will just put a meaningful value in the corresponding queue. Your threads will pick this value up and act accordingly. When the main program shuts down, you can put a None value in the queues and make sure that your threads interpret that as a signal they should leave the queue monitoring loop and return. This way, your threads close nicely.
Thank you for your advicebut I'm not sure I have enough knowledge to put all that in a syntax code. Do you have any similar code. Thread +queue
Reply
#7
You could use polling, and it is certainly an easier method to code, but it is extremely costly as far as CPU
usage is concerned, using up to 12 % of all allotted CPU cycles.

I have found two articles on how to wrap your code around the interrupt method.
First your Pi has two Uart's available, the PL011 (data sheet here: http://infocenter.arm.com/help/topic/com...p5_trm.pdf
or online here: http://infocenter.arm.com/help/index.jsp...index.html

I found two worthwhile articles on using the PL011 in interrupt mode.
The first: https://www.raspberrypi.org/forums/viewtopic.php?t=9207 gives some general information, and
the second: https://projects.drogon.net/raspberry-pi...functions/ gets down and dirty, showing
what you have to do to use this method.

You would have to spend some time developing this method, but the rewards received in speed would be great,
and you'd have something valuable to share with other Pi developers.
With a little more searching, perhaps here: http://nullege.com/ you might actually find completed code that does this.
Reply
#8
There is a asyncio module for pyserial. But you must be sure that there is no other blocking function called. For example time.sleep will block the whole loop.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#9
So, there you go. As per DeaD_EyE, check out asyncio/pyserial
Reply
#10
(Mar-03-2018, 09:33 PM)marsokod Wrote: You may want to use a thread or a process depending on what your function1 and function2 are doing. You can either start them manually, use a library like APScheduler to have a pool of threads/process and add your function to the job queue, or start thread/processes at the beginning of your code and have them read elements in a queue. In the last case, your ReadSerial function would only have to put an element in a queue, which should minimize any interruption to the monitoring.


Whoud the class threading.Event be helpful?
https://docs.python.org/3.5/library/thre...Event.wait
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  MCU reboots after opening Serial port when ran from Raspberry PI zazas321 3 332 Mar-19-2024, 09:02 AM
Last Post: zazas321
  Waiting for input from serial port, then move on KenHorse 2 833 Oct-17-2023, 01:14 AM
Last Post: KenHorse
  pyserial/serial "has no attribute 'Serial' " gowb0w 9 3,317 Aug-24-2023, 07:56 AM
Last Post: gowb0w
  Serial Port As Global Prasanjith 2 1,422 Mar-23-2023, 08:54 PM
Last Post: deanhystad
  Is it possible to make a program recognize how many clicks it has had on the monitor? jao 0 1,129 Feb-25-2022, 06:31 PM
Last Post: jao
  python serial port barryjo 2 1,601 Dec-27-2021, 11:09 PM
Last Post: barryjo
  is there a way to mention port range or search for port dynamically with qConnection Creepy 0 1,449 Sep-09-2021, 03:15 PM
Last Post: Creepy
  How to Properly Open a Serial Port in a Function bill_z 2 4,350 Jul-22-2021, 12:54 PM
Last Post: bill_z
Sad SyntaxError: from simple python example file from mind-monitor code (muse 2) warmcupoftea 4 2,751 Jul-16-2021, 02:51 PM
Last Post: warmcupoftea
Question Python3 - serial port reload parovelb 4 5,699 Apr-08-2021, 09:18 AM
Last Post: parovelb

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020