相关文章推荐
深情的山羊  ·  WPF ...·  3 月前    · 
粗眉毛的柑橘  ·  HttpClient Stack and ...·  1 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I currently have a script in Python (v3.6) that initializes a connection to a serial port and creates a serial object that can be called whenever I need to reset the buffer, read a register address, etc. The issue is I would like to use LabVIEW instead to call this Python initialization script, create the serial object, and store it (in the LabVIEW session) so it can be used later in LabVIEW without having to reinitialize the object. I do not want to keep the python session open in LabVIEW either as I need to run other scripts unassociated with this python object (i.e. move stages around, control a camera, etc.). Here is the sort of block diagram I'm testing with. screenshot Clearly, it does not work because the python object is being casted to array.

Here is the snippet of code I am using to initialize the object:

ser = serial.Serial(port=port, baudrate=115200,
                    bytesize=serial.EIGHTBITS, 
                    parity=serial.PARITY_NONE,
                    stopbits=serial.STOPBITS_ONE, timeout=10,
                    xonxoff=False, rtscts=False, dsrdtr=False)

And here is an example of a function I would like to call later in LabVIEW, but requires the object to be initialized:

def set_LED_RGB_currents(ser, currents=[100, 100, 100]):
    set_LED_current(ser, 'R', currents[0])
    set_LED_current(ser, 'G', currents[1])
    set_LED_current(ser, 'B', currents[2])

I know there is a serial connection example VI in LabVIEW and maybe I can use this sample VI to create the object and pass it into Python, but I'm not sure how to do the passing. Note, the above functions are just examples, I have more convoluted scripts I need to perform and it would be easier just to call them from LabVIEW rather than rewrite them so Python is not called at all.

I hope this all makes sense, I'm not great at explaining. Ultimately, my question is how do I pass serial objects between the two languages while maintaining the object's integrity without reinitializing a connection every time? Thanks in advance!

My understanding is that the Python integration library form NI does not support persistent data between calls. Alternatives would be rewrite your python code to use NI VISA for serial Comms or wrap your python code into a separate server application which you start and then communicate with via TCP or similar protocols. – John Jun 6, 2022 at 16:50 Thanks John! So, for the case of using LabVIEW to create the serial object, how would that be passed to Python? I know I can pass the initializing parameters (port, baud rate, etc.), but how about handles? So I do not need to re-init in python. – ekorb Jun 7, 2022 at 18:04

To pass an arbitrary Python object to LabVIEW and back I guess you should be able to use pickle.dumps to turn the object into a bytes stream which you can pass across and pickle.loads to go back the other way. But I'm pretty sure that won't persist the state of a serial port object on the Python side.

I also don't know any meaningful way in which you can pass a LabVIEW serial 'object' to Python and use it in Python. Maybe this can be done by digging into to the lower levels of VISA.

From your description it sounds as though the overall control of your process or experiment is going to be in LabVIEW? In that case I think your options are:

  • rewrite all the serial port code in LabVIEW, so all the persistent data stays in LabVIEW. This is what I'd probably do, and the easiest way is probably a 'functional global' style VI using an uninitialised shift register to maintain internal state and an enum input to select the operation to be performed e.g. open, send and receive, close etc. You can still call out to Python if you have existing code there that builds the message to be sent or interprets the response, just keep the actual comms in LV.
  • do all the serial port operations in LabVIEW but implement a TCP or similar interface, as per John's comment, where the Python code can tell the LabVIEW 'server' what to send and get back what is received. This is only worthwhile if it's somehow too hard to pull the serial comms out of the existing Python code, which seems unlikely.
  • just open the port before every serial transaction in the Python code and close it again afterwards. If you're only doing this every few seconds and the small time overhead isn't critical then this ought to be fine; if it's frequent and time-critical maybe not. As a first step I would probably try this and see how well it works. Keep an eye out for possible memory leaks if the code has to keep running for long periods without a restart.
  • Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.