Serial port writing style

2024/10/15 23:23:14

I am using two libraries to connect with a port, and two of them uses different styles in writing these commands. I want to understand the difference because I want to use the second one, but it results in port becoming unresponsive after some time, I wonder if it causes a kind of overloading. Here are the methods.

Method 1:

 if self.port:self.port.flushOutput()self.port.flushInput()for c in cmd:self.port.write(c)self.port.write("\r\n")

Method 2:

if self.port:cmd += b"\r\n"self.port.flushInput() self.port.write(cmd)self.port.flush()

The major difference I first encounter is that the first one splitting the command in to letters then send it. I wonder if this makes any difference. And as I said the second code fails after some time( it is unclear, if these methods are the problem). I don't understand what flushes do there. I want to understand the difference between these and know if the second one prone to errors.

Note: Please note that self.port is serial.Serial object.

Any advice appreciated.

Answer

Well, from the pySerial documentation the function flushInput has been renamed to reset_input_buffer and flushOutput to reset_output_buffer:

reset_input_buffer()

Flush input buffer, discarding all it’s contents.

Changed in version 3.0: renamed from flushInput()

reset_output_buffer()Clear output buffer, aborting the current output and discarding all that is in the buffer.

Changed in version 3.0: renamed from flushOutput()

The first method is less likely to fail because the output buffer is reset before attempting a write. This implies that the buffer is always empty before writing, hence the odds the write will fail are lower.

The problem is that both the methods are error prone:

There is no guarantee that all the data you are attempting to write will be written by the write() function, either with or without the for loop. This can happen if the output buffer is already full. But the write() functions returns the number of bytes successfully written to the buffer. Hence you should loop untill the number of written bytes is equal to the number of bytes you wanted to write:

toWrite = "the command\r\n"
written = 0while written < len(toWrite) :written += self.port.write(toWrite[written:])if written == 0 :# the buffer is full# wait untill some bytes are actually transmitted time.slepp(100)

Note that "writing to the buffer" doesn't mean that the data is instantly trasmitted on the serial port, the buffer will be flushed on the serial port when the operative system thinks is time to do so, or when you force it by calling the flush() function which will wait for all the data to be written on the port.

Note also that this approach will block the thread execution untill the write is successfully completed, this can take a while if the serial port is slow or you want to write a big amount of data.

If your program is ok with that you are fine, otherwise you can dedicate a different thread to serial port communication or adopt a non-blocking approach. In the former you will have to handle multithread communication, in the latter you will have to manage internally your buffer and delete only the successfully written bytes.

Finally if your program is really simple an approach like this should do the trick:

if self.port:cmd+=b"\r\n"for c in cmd:self.port.write(c)self.port.flush()

But it will be extremely unefficient.

https://en.xdnf.cn/q/117777.html

Related Q&A

matplotlib plot to fill figure only with data points, no borders, labels, axes,

I am after an extreme form of matplotlibs tight layout. I would like the data points to fill the figure from edge to edge without leaving any borders and without titles, axes, ticks, labels or any othe…

Chromedriver: FileNotFoundError: [WinError 2] The system cannot find the file specified Error

Have looked for an answer, but couldnt find anything. It seems insistent on saying it cant find the file specified and then checks PATH, but cant see it even then :/ Ive put the directory in PATH: http…

Python - mutable default arguments to functions

I was going through https://docs.python.org/3.5/tutorial/controlflow.html#default-argument-values. I modified the example there a little bit as below:x = [4,5] def f(a, L=x):L.append(a)return Lx = [8,9…

Python: remove duplicate items from a list while iterating

I have a list named results, I want to get rid of the duplicate items in the list, the expected result and my results does not match, I checked my code but cannot find what is the problem, what happene…

Python - SciPy Kernal Estimation Example - Density 1

Im currently working through this SciPy example on Kernal Estimation. In particular, the one labelled "Univariate estimation". As opposed to creating random data, I am using asset returns. …

PyQt QFileDialog custom proxy filter not working

This working code brings up a QFileDialog prompting the user to select a .csv file:def load(self,fileName=None):if not fileName:fileName=fileDialog.getOpenFileName(caption="Load Existing Radio Log…

If I have Pandas installed correctly, why wont my import statement recognize it?

Im working on a project to play around with a csv file, however, I cant get pandas to work. Everything I have researched so far has just told me to make sure that pandas is installed. Using pip I have …

Python Issues with a Class

I am having issues with my below class. I keep getting the below traceback, butI am not sure were I am going wrong. I am expecting to see a dictionary with photo tags. Any help would be great. Tracebac…

Dynamically populate drop down menu with selection from previous drop down menu

I have a cgi script written in Python. There are two drop down menus and then a submit button. Id like to be able to make a selection from the first menu, and based off that choice, have the second dro…

Web Scrape page with multiple sections

Pretty new to python... and Im trying to my hands at my first project.Been able to replicate few simple demo... but i think there are few extra complexities with what Im trying to do.Im trying to scrap…