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 directoryDownload 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:
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:
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 Sub3. Periodic Sending
cTimer triggers every 2 seconds, sending hello:
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 Sub4. Event-Driven Receiving
When new data arrives in the input buffer, the DataReceived event automatically triggers, reads and displays:
Private Sub m_Port_DataReceived(ByVal BytesCount As Long)
Dim s As String
s = m_Port.ReadExisting()
Logs "[RX] " & s
End Sub5. Error Handling
Serial communication errors are captured via event callback:
Private Sub m_Port_ErrorOccurred(ByVal ErrorCode As Long, ByVal ErrorMsg As String)
Logs "[ERR] " & ErrorMsg
End Sub6. Stop and Cleanup
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 SubFunction Description
Continuous Communication
- Uses
cTimertimer to automatically sendhelloevery 2 seconds - Starts event monitoring via
StartMonitoringfor automatic data reception
- Uses
Event-Driven Architecture
DataReceivedevent: automatically triggers when data arrivesErrorOccurredevent: automatically triggers on communication errorsm_Tmr_Timerevent: triggers on periodic send
Real-Time Logging
- Send/receive records displayed in
ListBoxin real-time - Each record has a timestamp, new records appear at the top
- Send/receive records displayed in
Technical Points
WithEventsEvent Binding: Declare object variables withWithEvents, VB6 automatically generates event handler procedures, no need for manual callback registration.Asynchronous Monitoring Mode:
StartMonitoring 50polls the serial port buffer at 50ms intervals, triggersDataReceivedevent when new data is detected, does not block UI thread.Object Lifecycle Management: In
StopCOM4, stop timer, close serial port, and release objects in sequence to avoid resource leaks. FirstEnabled = False, thenSet Nothing.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 receivinghello. - VBMAN.dll must be registered, or source code added to project.
Extension Suggestions
- Use Other Ports: Modify
m_Port.PortName = "COM3"etc. to adapt to actual hardware. - Dynamic Configuration: Add port name, baud rate input boxes on the form for runtime dynamic settings.
- Hex Display: Display received data in hexadecimal for debugging binary protocols.
- Send Custom Data: Add text box and send button for manual sending of arbitrary data.
- Signal Line Monitoring: Subscribe to
PinChangedevent to monitor CTS/DSR/RING status changes. - Modbus Protocol: Extend from this example to implement Modbus RTU master/slave communication.
- 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:
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 SubPlan C: Protocol Frame Parser
Precisely split by device protocol (e.g., by \r\n delimiter):
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 SubFor detailed framing principles, four protocol modes (delimiter/start-end markers/length prefix/fixed length), tuning and troubleshooting, see Serial Port Framing Protocol Guide.