LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

LabVIEW Serial Communication (38400 baud, 100Hz): RX/TX timing issues, UI freeze, and VISA session problems(VI file is updated)

System Overview

I am developing a LabVIEW application that communicates with an external device over serial.

Baud rate: 38400
Receive: 5 bytes at 100 Hz
Transmit: 4-byte ACK for every received packet
UI: Displays parsed data (LEDs, switches, graphs)
Control: Connect / Disconnect buttons to open/close the serial port

 

The requirement is:

Reliable 1:1 RX → ACK response
Stable UI updates
Clean connect/disconnect behavior (no freezes, proper VISA release)


Initial Implementation (Event Structure-based)

Initially, I implemented everything inside a single while loop using an Event Structure:

Button events (connect, disconnect, send commands)
Timeout event used for:
VISA Read
Packet parsing
UI updates
VISA Write (ACK)


Problems:
TX packets are grouped (e.g., 3 ACKs sent at once)
Timing is inconsistent

Possible causes I suspect:

1. Loop condition or structure issue(event structure)
2. UI Freeze and Event Blocking
When debugging, execution often pauses inside the Event Structure
Timeout events seem to block other UI events
UI becomes unresponsive
3. TX Timing Still Not Perfect

Even with separated TX loop:

ACK packets are sometimes sent in bursts rather than evenly
Possibly due to USB-Serial buffering or loop timing
What is the best way to safely handle

image.png

I fixed the vi file due to my fault.

0 Kudos
Message 1 of 6
(314 Views)

I cannot open your vi because I don't have LV2025 installed, like many people in this forum (can you Save for previous... at least to LV2021 or earlier and re-post?).

However, using an event structure may not be the right choice for this application. LabVIEW may freeze if you interact with the UI elements while the structure is not in the execution path. Furthermore, you need to pay attention to the structure's Timeout setting. Why not using a simple polling for buttons?

Paolo
-------------------
LV 7.1, 2011, 2017, 2019, 2021
Message 2 of 6
(275 Views)

Thank you for your reply.

I understand the compatibility issue. Unfortunately, I am currently using the Community Edition (LabVIEW 2025), and I could not find an option to save it back to LV2021 or earlier. Instead, I have attached a screenshot of the block diagram for reference.

image.png

Regarding the system, here is a brief explanation:

  • The application is based on a simple state machine with two states: Connected and Disconnected.

  • When the user presses the connect button, the serial port is opened and the system transitions to the Connected state.

  • In the Connected state:

    • I continuously check Bytes at Port.

    • If the value is greater than 0, I read a fixed-length packet (5 bytes).

    • Immediately after parsing, I send a 4-byte ACK response.

The communication runs at 38400 baud and approximately 100 Hz.

You mentioned that using an Event Structure may not be appropriate. In my initial implementation, I used an Event Structure (with a timeout case) to handle:However, I experienced UI freezing and timing issues, which is why I am reconsidering the architecture.

Based on your suggestion, I am considering replacing the Event Structure with a polling-based loop for handling buttons and separating the communication logic into independent loops.이벤트 구조를 완전히 제거하고 while 루프와 폴링 기반 접근 방식을 사용하여 애플리케이션을 다시 구축해 보았습니다.

  • All UI interactions are now handled via simple polling (no Event Structure at all)

  • Unnecessary button-related logic has been removed

  • The communication logic is separated from UI handling as much as possible

However, the same issues still persist:RX/TX timing instability

  • ACK packets are sometimes sent in bursts instead of one-to-one

If you have any suggestions on what could cause this behavior even in a polling-based design, I would greatly appreciate your insight.

0 Kudos
Message 3 of 6
(199 Views)

Hi ylseo,

 


@ylseo wrote:

Thank you for your reply.

I understand the compatibility issue. Unfortunately, I am currently using the Community Edition (LabVIEW 2025), and I could not find an option to save it back to LV2021 or earlier. 


Usually there is a menu item File->Save for previous…

(Btw I prefer LV2019.)

 


@ylseo wrote:

Instead, I have attached a screenshot of the block diagram for reference.


Why are there so many local variables?

When you want to check for bits in an U8 then you should:

  • show the radix on those numeric constants!
  • compare with "unequal to zero" instead of "> 0" and also avoid that coercion dot on each comparison!
  • use "numeric to boolean" with IndexArray instead of comparing each bit with repetitive code…

You don't need 3 IndexArray nodes to index consecutive bytes from your U8 array…

Your controls and indicators seem to have the same label: use unique labels…

 


@ylseo wrote:
  • In the Connected state:

    • I continuously check Bytes at Port.

    • If the value is greater than 0, I read a fixed-length packet (5 bytes).

    • Immediately after parsing, I send a 4-byte ACK response.


Why do you need BytesAtPort?

Just read 5 bytes, as VISARead will wait for those bytes!

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
Message 4 of 6
(192 Views)

Hi GerdW,

Thank you for your reply and for pointing out the “Save for previous” option. I really appreciate it.
I have now saved the VI for an earlier version (LV2019 as you suggested) and attached it.

I also applied your recommendations:

  • Reduced the use of local variables as much as possible
    (I am using them mainly to read control values like SW1, SW2, SW3, SW2&3)
  • Displayed the radix for numeric constants
  • Removed coercion dots
  • Used Number to Boolean Array + Index Array instead of repetitive bit masking
  • Simplified the indexing logic (no longer using multiple Index Array nodes unnecessarily)
  • Changed the logic to directly read 5 bytes using VISA Read instead of checking Bytes at Port

The code is now much cleaner thanks to your suggestions.

However, I am still experiencing an issue with communication timing:ACK packets are not sent one-to-one with received packets

  • Instead, they are sometimes sent in bursts (e.g., multiple ACKs sent together)
  • This happens even after removing the Event Structure and switching to a polling-based design

I wanted:

image.png

And, now:

image.png

Do you have any idea what could cause this kind of packet batching behavior?

Best regards,
ylseo

0 Kudos
Message 5 of 6
(152 Views)

Hi ylseo,

 


@ylseo wrote:

Do you have any idea what could cause this kind of packet batching behavior?


Yes.

You are sending an ACK message IN EACH iteration…

 


@ylseo wrote:

I also applied your recommendations:

  • Reduced the use of local variables as much as possible
    (I am using them mainly to read control values like SW1, SW2, SW3, SW2&3)
  • Displayed the radix for numeric constants
  • Removed coercion dots
  • Used Number to Boolean Array + Index Array instead of repetitive bit masking
  • Simplified the indexing logic (no longer using multiple Index Array nodes unnecessarily)
  • Changed the logic to directly read 5 bytes using VISA Read instead of checking Bytes at Port

See this for even more simplifications:

  • You should show the radix (or the display mode of strings) WHENEVER you don't use the default mode. No need to show its "decimal", but it is needed to show "hexadecimal"…
  • No need to build a 2D boolean array when all you need are two bytes (aka two 1D boolean array).
  • Use only one IndexArray node instead of 4 or 5 to index the bits…
  • No need for the index constants as IndexArray automatically counts up!
  • Inside a case structure you only need to place the different code parts: in your message building the only difference is ONE BYTE (pc control vs. machine control), so the remaining code doesn't need to be duplicated!

 

Additional (and more serious) problems:

  • You initialize the serial communication to use a (default) TermChar, but your messages seem to contain "binary"** data: that TermChar may occur inside a message and will then disturb your message handling! Switch OFF the TermChar at VISAConfigureSerialPort!
    (** "binary" in the sense of "any byte value is possible" in contrast to "only readable ASCII chars are possible")
  • What happens when your device sends a message that doesn't start with "0x89 0x17"?
    Then you may read only a partial message and all following messages will be read incorrectly!
    I recommended to read full messages, but you still decided to split the reading in two VISARead requests…

Learn all you need to know about PROPER serial communication by watching this video!

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 6 of 6
(112 Views)