我也是自己摸索开发出来的每一款VBtoCOM通讯,有具体的思路如下:
给你推荐一个工具“com串口测试工具 ComTone V1.0 中文绿色版”
1、打开你的噪音计的测试软件,调整好串口号、通讯频率等等,我用温度计举例说明。
开始查询后有返回数值,这个Receive:就是返回的数值000304012200004b05,
打开串口监视精灵,监视软件的com口事件:
这里面的Write是测试软件发出的查询指令,read是设备返回的数据指令
Private Sub Command1_Click() '发送指令If Not MSComm1.PortOpen Then
MSComm1.CommPort = 7 '串口为7
MSComm1.Settings = "9600,n,8,1"
MSComm1.InBufferCount = 0 '清除接收缓冲区
MSComm1.OutBufferCount = 0 '清除发送缓冲区
MSComm1.InputMode = comInputModeBinary '二进制接收
MSComm1.InputLen = 0 '读取接收缓冲区的所有字符
MSComm1.PortOpen = True '打开串口
MSComm1.RTSEnable = False '置为发送状态
End If
Dim pu() As Byte
Dim strdata As String
Dim crc_js() As Byte
ReDim pu(7) '这个数组是8位的查询指令
pu(0) = "&H00" '温度计地址
pu(1) = "&H03" '查询指令
pu(2) = "&H00" '2、3为温度计地址
pu(3) = "&H00" '2、3为温度计地址
pu(4) = "&H00" '4、5为读取寄存器长度
pu(5) = "&H02" '4、5为读取寄存器长度
pu(6) = "&HC5" '6、7为CRC校验码 因为我们不知道设备的CRC校验规则所以用测试软件产生的校验码
pu(7) = "&HDA" '6、7为CRC校验码
MSComm1.Output = pu
'不做任何事情,仅仅允许其它应用程序处理它们的事件。
DoEvents
MSComm1.InBufferCount = 0 '清除接收缓冲区
MSComm1.RThreshold = 9 '所要接收的数据长度,我们通过COM检测精灵看到了回传数据一共是9字节
MSComm1.RTSEnable = True '转为接收状态
End Sub
Private Sub Command2_Click()
Timer1.Enabled = False
End Sub
Private Sub Form_Unload(Cancel As Integer)
If MSComm1.PortOpen Then
MSComm1.PortOpen = False '关闭串口
End If
Timer1.Enabled = False
End Sub
Private Sub MSComm1_OnComm() 'COM事件
Dim PA() As Byte
Dim PB As String
Select Case MSComm1.CommEvent
Case comEvReceive
MSComm1.InputLen = 0 '读取接收缓冲区的所有字符
PB = MSComm1.Input
PA() = PB
For i = 0 To UBound(PA())
'Print "PA(" & i & ")" PA(i)
If Len(Hex(PA(i))) = 1 Then
strdata = strdata & "0" & Hex(PA(i))
Else
strdata = strdata & Hex(PA(i))
End If
Next
'回传的数据串:000304012600000AC4,这9字节根据通讯协议我们进行拆分
'00为协议内回传机号,03为读命令,04为返回的数据长度 0126 为我要的温度数据为十六进制表达,下面我进行数据处理
wd = CLng("&H" & Left(Right(strdata, 12), 4)) / 10 & "℃" '根据通讯协议换算成温度
Text1 = Text1 & vbCrLf & strdata & " " & wd
strdata = ""
MSComm1.PortOpen = False '关闭串口
End Select
End Sub
Private Sub Timer1_Timer()
Call Command1_Click
End Sub
这是我的测试结果。
下面是通讯协议
这个是我的软件用检测精灵检测的结果
ESP32通过硬串口通信程序案例如下:
HardwareSerial Myserial(1) // D5 - 接TXD, D18 - 接RXD
char Speed_Off[8] = {0x80,0x06,0x00,0x40,0x00,0x00,0x96,0x0F} // 电机驱动板的 停止命令
char Speed_Align[8]= {0x80,0x06,0x00,0x40,0x03,0xe7,0xd6,0xb5}// 电机驱动板的正转命令
char Speed_Open[8] = {0x80,0x06,0x00,0x40,0xfc,0x19,0x16,0xc5}// 电机驱动板的反转命令
void Align(){
for(int i =0i<8i++){
Myserial.write(Speed_Align[i]) // 通过ESP32串口发送电机正转数据
}
}
void Open(){
for(int i =0i<8i++){
Myserial.write(Speed_Open[i]) // 通过ESP32串口发送电机反转命令
}
}
void MotorOff(){
for(int i =0i<8i++){
Myserial.write(Speed_Off[i]) // // 通过ESP32串口发送电机停止命令
}
}
void Delay_one(){
for(int i =0i <6i++){
delay(1000)
}
}
void Delay_Two(){
for(int i =0i <12i++){
delay(1000)
}
}
void setup() {
// put your setup code here, to run once:
Myserial.begin(9600,SERIAL_8E1,5,18) // 配置串口参数
}
void loop() {
//Myserial.println("Hello world!")
delay(2000)
Align()
delay(2000)
MotorOff()
Delay_one()
Open()
delay(2000)
MotorOff()
Delay_Two()
}
C#串口 *** 作之读取串口数据:try
{
axMSComm2.CommPort = 1i
axMSComm2.InputMode =
MSCommLib.InputModeConstants.comInputModeBinary
//用于设置或返回传输数据的类型,
//此例程是通过Input属性以二进制方式检取回数据
axMSComm2.PortOpen = true
//打开端口
axMSComm2.InBufferCount = 0
//用于返回输入缓冲区内的等待读取得字节个数
}
catch (Exception e)
{
MessageBox.Show(e.ToString())
}
在axMSComm的OnComm事件里写:
private void axMSComm2_OnComm(object sender, EventArgs e)
{
switch (axMSComm2.CommEvent) //查询CommEvent属性
{
case (short)(MSCommLib.OnCommConstants.comEvReceive):
//当接收缓冲区内字符数达到RThreshold值,
//进入CommData()子程序
CommData() //接收缓冲区内数据
break
}
}
private void CommData() //接收数据
{
int BufferDataNumStart = 0
//定义第一次查询缓冲区内数据个数
int BufferDataNumEnd = 0
//定义最后一次查询缓冲区内数据个数
byte[] CommBufferData = new byte[1024]
byte[] ComByte = new byte[8]
BufferDataNumStart = axMSComm2.InBufferCount
//将缓冲区内等待读取的字节个数赋给BufferDataNumStart
if (BufferDataNumStart == 0) return
//如果缓冲区为空,说明还没有数据传来,
//则返回;若不为空,进入下面的循环
//读取缓冲区内全部内容
axMSComm2.InputLen = 0
while (true)
{
System.Threading.Thread.Sleep(50)
//延时,以确保数据完全接收
BufferDataNumEnd = axMSComm2.InBufferCount
//再次读取缓冲区内字节个数
if (BufferDataNumStart == BufferDataNumEnd) break
//如果BufferDataNumStart==BufferDataNumEnd,
//说明本帧数据已经读完,退出循环
BufferDataNumStart = BufferDataNumEnd
//否则,将BufferDataNumEnd赋给BufferDataNumStart,
//并继续循环,直到完全接收
}
object objIn
objIn = axMSComm2.Input
//这里注意MSComm.Input返回的是一个object的类型,
//所以必须使用显式的类型转换
CommBufferData = (byte[])objIn
//CommBufferData为串口缓冲区内所有数据
//存取最后一次接收到的缓冲区的数据,
//存储部分时作为后期数据处理所用,
//以便于程序员分析数据。使用StreamWriter,
//需在添加命名控件using System.IO
//将上次未处理的数据和本次存储数据在ReceivedData相连,
//此部分是防止发送过来的数据本身就不完整,
//以至于数据处理不能进行完全,故保留并与新接收的数据相连
for (int i = 0 i < BufferDataNumEnd i++)
{
ReceiveDataNum++
UnsettledDataNum++
ReceivedData[ReceiveDataNum - 1] = CommBufferData[i]
}
//进入数据处理字程序
}
private void DealData() //数据处理
{
for (int i = 0 i < ReceivedData.Length - 7 i++)
{
if (ReceivedData[i] ==
0xff && ReceivedData[i + 1] == 0x04)判断通讯头
{
zhou++
INTzhouzhong[zhou] =
int.Parse(ReceivedData[i + 4].ToString("X")) * 10000 +
int.Parse(ReceivedData[i + 3].ToString("X")) * 100 +
int.Parse(ReceivedData[i + 2].ToString("X"))
}
}
ReceiveDataNum = 0
UnsettledDataNum = 0
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)