VB.NET中使用AT指令发送SMS时程序卡顿问题求助
VB.NET 串口AT指令发送SMS卡顿/失效问题排查方案
以下是针对问题的核心排查点和解决方法:
1. 串口配置必须和PuTTY完全一致
PuTTY能正常工作,说明模块参数是对的,代码里的串口配置必须1:1匹配:
- 波特率、数据位、停止位、奇偶校验要和PuTTY设置完全相同
- 关键:硬件流控,绝大多数GSM模块默认启用RTS/CTS流控,代码里必须显式设置:
serialPort.Handshake = Handshake.RequestToSend - 超时设置不能用无限等待,否则没收到响应就会卡死:
serialPort.ReadTimeout = 5000 ' 5秒超时 serialPort.WriteTimeout = 2000
2. 指令发送必须等待响应,避免同步阻塞硬读
直接发完指令就调用ReadTo()或ReadLine()很容易卡顿,因为模块响应有延迟,要做带超时的响应等待逻辑:
Private Function SendATCommand(ByVal cmd As String, ByVal expectedResponse As String) As Boolean serialPort.DiscardInBuffer() ' 清空接收缓冲区,避免残留数据干扰 serialPort.WriteLine(cmd & vbCr) ' 指令结尾必须加CR(vbCr),部分模块需要CRLF Dim startTime As DateTime = DateTime.Now Dim response As String = "" Do While DateTime.Now.Subtract(startTime).TotalMilliseconds < serialPort.ReadTimeout If serialPort.BytesToRead > 0 Then response &= serialPort.ReadExisting() If response.Contains(expectedResponse) Then Return True End If End If System.Threading.Thread.Sleep(100) ' 避免CPU空转 Loop Return False End Function
3. AT+CMGS的特殊处理逻辑
CMGS指令分三步执行,不能一次性发送,必须等待模块返回的>提示符:
' 步骤1:发送CMGS指令,等待>提示符 If SendATCommand("AT+CMGS=""13800138000""", ">") Then ' 步骤2:发送短信内容,结尾加Ctrl+Z(Chr(26))触发发送 serialPort.Write("测试短信内容" & Chr(26)) ' 步骤3:等待最终的OK/ERROR响应 Dim startTime As DateTime = DateTime.Now Dim response As String = "" Do While DateTime.Now.Subtract(startTime).TotalMilliseconds < 10000 ' 短信发送超时设10秒 If serialPort.BytesToRead > 0 Then response &= serialPort.ReadExisting() If response.Contains("OK") Then MessageBox.Show("短信发送成功") Exit Do ElseIf response.Contains("ERROR") Then MessageBox.Show("发送失败:" & response) Exit Do End If End If System.Threading.Thread.Sleep(100) Loop Else MessageBox.Show("未收到CMGS提示符") End If
4. 调试技巧:对比串口收发日志
在代码里打印所有收发的数据,和PuTTY的日志对比,就能快速定位差异:
' 给SerialPort的DataReceived事件加处理,打印接收的数据 AddHandler serialPort.DataReceived, AddressOf SerialDataReceived Private Sub SerialDataReceived(sender As Object, e As SerialDataReceivedEventArgs) Dim data As String = serialPort.ReadExisting() Debug.WriteLine("收到:" & data) End Sub
发送指令前也打印:Debug.WriteLine("发送:" & cmd),这样就能看到代码和PuTTY的收发流程哪里不一致。
内容的提问来源于stack exchange,提问作者Reirou
相关产品推荐
相关产品推荐

