c#串口通讯 DataReceived事件根据返回的字符串进行判断,有时触发有时又不触发

q516679383 2017-05-20 11:26:30
附上代码:我点击“录音”toolStripStatusLabel状态.Text = "开始录音";没有显示出来,但是录音是可以的,我点“停止”,然后将录音内容保存为文件,可以停止录音,但是文件没有保存,我需要根据返回的字符串然后响应其它,有没有好的处理方法?


private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int bufferlen = serialPort.BytesToRead;
if (bufferlen > 0)
{
byte[] bytes = new byte[bufferlen];
serialPort.Read(bytes, 0, bufferlen);
resultValue = System.Text.Encoding.ASCII.GetString(bytes);

if (resultValue.Contains("AT+CREC=1,1,0") && resultValue.Contains("\r\nOK"))
{
toolStripStatusLabel状态.Text = "开始录音";

}
if (resultValue.Contains("AT+CREC=2") && resultValue.Contains("\r\nOK") && resultValue.Contains("+CREC: 2,1,0"))
{
toolStripStatusLabel状态.Text = "停止录音";
GetRecordByteLength(resultValue);//得到录音字节长度
ReadRecordConnect();//发送读取录音内容指令
}
if (resultValue.Contains("AT+CREC=2") && resultValue.Contains("\r\nOK") && !resultValue.Contains("+CREC: 2,1,0"))
{
toolStripStatusLabel状态.Text = "查询录音";
SeachRecord();//发送查询录音指令
}
if (resultValue.Contains("AT+CREC=7") && resultValue.Contains("\r\nOK") && resultValue.Contains("+CREC: 7,1"))
{
toolStripStatusLabel状态.Text = "获取录音字节长度";
GetRecordByteLength(resultValue);
ReadRecordConnect();
}

if (resultValue.Contains("AT+CREC=6,1") && resultValue.Contains("+CREC: 6,1") && resultValue.Contains("\r\nOK"))
{
toolStripStatusLabel状态.Text = "获取录音内容";

GetByteData(resultValue);//将录音内容加入到List<string>中
DeleteRecord();//发送删除录音内容指令

}
if (resultValue.Contains("AT+CREC=3,1") && resultValue.Contains("\r\nOK"))
{
if (!_isEndRecord)
{//根据时间计时器间隔6S重新录音
toolStripStatusLabel状态.Text = "重新开始录音";
SetStartRecord();
timer.Start();
}
else
{//点击停止录音内容
toolStripStatusLabel状态.Text = "停止录音,并将录音内容保存录音文件";
ToFileAnInsertToSQL();
timer.Stop();
}
}
}
}
}

//时间计时器
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
StopRecord();//停止录音指令
timer.Stop();
}
private void FrmMain_Load(object sender, EventArgs e)
{

serialPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(Port_DataReceived);

timer = new System.Timers.Timer();

//设置timer可用
timer.Enabled = false ;
//设置timer
timer.Interval = 6200;

//设置是否重复计时,如果该属性设为False,则只执行timer_Elapsed方法一次。
timer.AutoReset = true;

timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);

}
...全文
596 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
q516679383 2017-05-26
  • 打赏
  • 举报
回复
每一次完整接收数据,最后是包含有OK字符的,接收数据的开头是发送指令的字符,例如发送“AT+CREC=1,1,0”指令,返回的数据中是包含“AT+CREC=1,1,0”这个字符的,然后数据尾部返回OK表示是成功的
ilikeff8 2017-05-25
  • 打赏
  • 举报
回复
要根据具体的通讯协议来 byte[] bytes = new byte[bufferlen]; serialPort.Read(bytes, 0, bufferlen); 这个只是让你得到这次在串口通讯接收缓冲区里能读到的字节的数目,但不保证是完整的指令,这个是通讯协议逻辑上来保证的,如果通讯方不能保证在一次通讯中发完整的一条指令
xuggzu 2017-05-25
  • 打赏
  • 举报
回复
修改代码的前提是发送端要有分隔标志或者包头,用以判读一次的命令数据接收完毕。
如果无法分隔或者不知道长度,那怎么做都解决不了。
q516679383 2017-05-25
  • 打赏
  • 举报
回复
具体可以怎么修改代码呢?
q516679383 2017-05-25
  • 打赏
  • 举报
回复
怎么判断接收到的数据是一条完整的数据呢?由于刚开始接触通讯,请各位说的详细一点,谢谢!
niegu9132 2017-05-22
  • 打赏
  • 举报
回复
楼主可以把接收的数据缓存下来,缓存数据较多时把前面的删掉。 每次接收数据到缓存区的末尾匹配即可
  • 打赏
  • 举报
回复
你怎么知道收完了一条完整的消息? serialPort.Read(bytes, 0, bufferlen); resultValue = System.Text.Encoding.ASCII.GetString(bytes); 这种代码肯定是不对的。你并不判断是否接受了一条完整的消息,而且你还假设 bytes 数组中在就收到的字节“后边”填充的多余字节也是你要转换为字符串的文字。 把这两行代码代码删除掉,然后去到你学习的地方,重新学习一下消息通讯和 Read(arr, index, len) 的真正的机制。
q516679383 2017-05-20
  • 打赏
  • 举报
回复
当我断点调试时,是可以进行的,录音内容也能保存成文件
xuggzu 2017-05-20
  • 打赏
  • 举报
回复
楼主的代码运行正确有个前提: 能一次接收到足够判断字符串内容的长度数据。 如果一次接收不全,那下面的逻辑肯定会出错。 所以应该在接收事件中先接收到足够数据再转string,然后再判读。

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧