Skip to content

SerialPort Send/Receive Example (Test1)

Overview

This example demonstrates how to use the cSerialPort class to implement continuous serial port send/receive communication. The program opens COM4, uses the cTimer timer to send hello every 2 seconds, and automatically receives data returned from the peer through event-driven mode, displaying it in a list box in real-time.

Project Structure

Test1/
  ├── Form1.frm       # Main form, serial send/receive logic
  ├── COM3_TEST.vbp   # VB6 project file
  ├── COM3_TEST.vbw   # Project group file
  └── pic/            # Screenshots directory

Download Source Code [ Note: Re-register the DLL file in the bin directory ]

Download the VBMAN project from the homepage, unzip it, and open all DEMO projects included.

Core Code Analysis

1. Object Declaration

Declare serial port and timer objects with WithEvents to receive event callbacks:

vb
Private WithEvents m_Port As cSerialPort   ' Serial port object (receive events)
Private WithEvents m_Tmr As cTimer         ' Timer object (periodic sending)

2. Start Serial Port

Automatically start COM4 communication when form loads:

vb
Public Sub StartCOM4()
    Set m_Port = New cSerialPort
    Set m_Tmr = New cTimer
    
    ' Configure serial port parameters
    m_Port.PortName = "COM4"
    m_Port.Config.BaudRate = br9600
    m_Port.Config.DataBits = 8
    m_Port.Config.Parity = ptNone
    m_Port.Config.StopBits = sb1
    
    If Not m_Port.OpenPort() Then
        Logs "[FAIL] Cannot open COM4: " & m_Port.LastErrorMsg
        Exit Sub
    End If
    
    ' Start serial port monitoring (triggers DataReceived event)
    m_Port.StartMonitoring 50
    
    ' Start timer, send hello every 2 seconds
    m_Tmr.Interval = 2000
    m_Tmr.Enabled = True
    
    Logs "[INFO] COM4 opened, sending hello every 2 seconds, continuously listening..."
End Sub

3. Periodic Sending

cTimer triggers every 2 seconds, sending hello:

vb
Private Sub m_Tmr_Timer()
    If Not m_Port Is Nothing Then
        If m_Port.IsOpen Then
            m_Port.WriteText "hello"
            Logs "[TX] hello"
        End If
    End If
End Sub

4. Event-Driven Receiving

When new data arrives in the input buffer, the DataReceived event automatically triggers, reads and displays:

vb
Private Sub m_Port_DataReceived(ByVal BytesCount As Long)
    Dim s As String
    s = m_Port.ReadExisting()
    Logs "[RX] " & s
End Sub

5. Error Handling

Serial communication errors are captured via event callback:

vb
Private Sub m_Port_ErrorOccurred(ByVal ErrorCode As Long, ByVal ErrorMsg As String)
    Logs "[ERR] " & ErrorMsg
End Sub

6. Stop and Cleanup

vb
Public Sub StopCOM4()
    If Not m_Tmr Is Nothing Then
        m_Tmr.Enabled = False
        Set m_Tmr = Nothing
    End If
    If Not m_Port Is Nothing Then
        If m_Port.IsOpen Then m_Port.ClosePort
        Set m_Port = Nothing
    End If
    Logs "[INFO] Stopped"
End Sub

Function Description

  1. Continuous Communication

    • Uses cTimer timer to automatically send hello every 2 seconds
    • Starts event monitoring via StartMonitoring for automatic data reception
  2. Event-Driven Architecture

    • DataReceived event: automatically triggers when data arrives
    • ErrorOccurred event: automatically triggers on communication errors
    • m_Tmr_Timer event: triggers on periodic send
  3. Real-Time Logging

    • Send/receive records displayed in ListBox in real-time
    • Each record has a timestamp, new records appear at the top

Technical Points

  1. WithEvents Event Binding: Declare object variables with WithEvents, VB6 automatically generates event handler procedures, no need for manual callback registration.

  2. Asynchronous Monitoring Mode: StartMonitoring 50 polls the serial port buffer at 50ms intervals, triggers DataReceived event when new data is detected, does not block UI thread.

  3. Object Lifecycle Management: In StopCOM4, stop timer, close serial port, and release objects in sequence to avoid resource leaks. First Enabled = False, then Set Nothing.

  4. Configuration Parameters: Example uses 9600/8/N/1 common configuration, with enum constants br9600, ptNone, sb1 (after compiling to DLL, enums are exported with the type library and can be used directly).

Runtime Output

2026/7/5 10:30:00   [INFO] COM4 opened, sending hello every 2 seconds, continuously listening...
2026/7/5 10:30:02   [TX]  hello
2026/7/5 10:30:02   [RX]  world
2026/7/5 10:30:04   [TX]  hello
2026/7/5 10:30:04   [RX]  world
...

Prerequisites

  • Requires an available serial port (COM4), or use virtual serial port software (e.g., com0com, Virtual Serial Port Driver) to create virtual port pairs.
  • Peer device should respond with data (e.g., world) after receiving hello.
  • VBMAN.dll must be registered, or source code added to project.

Extension Suggestions

  1. Use Other Ports: Modify m_Port.PortName = "COM3" etc. to adapt to actual hardware.
  2. Dynamic Configuration: Add port name, baud rate input boxes on the form for runtime dynamic settings.
  3. Hex Display: Display received data in hexadecimal for debugging binary protocols.
  4. Send Custom Data: Add text box and send button for manual sending of arbitrary data.
  5. Signal Line Monitoring: Subscribe to PinChanged event to monitor CTS/DSR/RING status changes.
  6. Modbus Protocol: Extend from this example to implement Modbus RTU master/slave communication.
  7. Data Framing: When device continuous transmission causes packet concatenation, use framing to identify each frame (see below).

Advanced: Using Framing to Solve Packet Concatenation

Problem Scenario

This example uses the DataReceived event + 50ms polling to read data. When the device continuously sends multiple frames of data (e.g., the device quickly sends several responses), multiple frames may accumulate in the buffer within 50ms, and ReadExisting() reads all data at once, causing frame concatenation that cannot be parsed.

Plan B: Frame Interval Timeout Framing

Use the brief pause after the device finishes sending one frame as a natural framing point:

vb
Public Sub StartCOM4()
    Set m_Port = New cSerialPort
    m_Port.PortName = "COM4"
    m_Port.Config.BaudRate = br9600

    If Not m_Port.OpenPort() Then
        Logs "[FAIL] Cannot open COM4: " & m_Port.LastErrorMsg
        Exit Sub
    End If

    ' Key: Enable framing, 30ms no new data = one frame ends
    m_Port.FrameInterval = 30

    ' Polling interval recommended <= FrameInterval/2
    m_Port.StartMonitoring 20

    Logs "[INFO] COM4 opened, framing mode enabled"
End Sub

' Use FrameReceived event instead of DataReceived
Private Sub m_Port_FrameReceived(FrameData() As Byte)
    Dim s As String
    s = StrConv(FrameData, vbUnicode)
    Logs "[RX Frame] " & s & " (" & UBound(FrameData) + 1 & " bytes)"
End Sub

Plan C: Protocol Frame Parser

Precisely split by device protocol (e.g., by \r\n delimiter):

vb
Private m_Parser As cSerialFrameParser

Private Sub Form_Load()
    Set m_Port = New cSerialPort
    Set m_Parser = New cSerialFrameParser

    ' Configure protocol framing
    m_Parser.SetDelimiterMode vbCrLf, False

    m_Port.PortName = "COM4"
    m_Port.Config.BaudRate = br9600
    m_Port.FrameInterval = 50       ' Plan B coarse splitting
    m_Port.OpenPort
    m_Port.StartMonitoring 20
End Sub

' Plan B triggers time frame -> feed to Plan C for precise splitting
Private Sub m_Port_FrameReceived(FrameData() As Byte)
    m_Parser.AppendData FrameData

    Do While m_Parser.HasFrame()
        Dim frame() As Byte
        frame = m_Parser.GetFrame()
        Logs "[Complete Frame] " & StrConv(frame, vbUnicode)
    Loop
End Sub

For detailed framing principles, four protocol modes (delimiter/start-end markers/length prefix/fixed length), tuning and troubleshooting, see Serial Port Framing Protocol Guide.

VB6 and LOGO copyright of Microsoft Corporation