c# serial port接收信息后转换格式再显示的问题

myway19891107 2014-09-23 06:30:27
可以确保发送出来的信息是对的,接收到的也是对的。可是我再把它从byte转换成float并显示为string,就不是每次都能成功了。拜托大神们具体说说怎么改。相信问题出在switch statement里面。谢谢!


private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
byte rxChar=0;
byte[] rxDataBuffer = new byte[240];
int rxdata = 0;

rxNumberDataBytes = (byte)serialPort.BytesToRead;
while (serialPort.BytesToRead > 0)
{
rxChar = (byte)serialPort.ReadByte(); // read data
// to display bytes received in hex,check was all data received
Invoke(new Action(() =>
{
textBox2.Text += " " + rxChar.ToString("X") + "\r\n";
}));
switch (rxState)
{
case RxIdleState:
if (rxChar == 0xEE)
{
rxState = RxInstructionState;
}
break;

case RxInstructionState:
if (rxChar == 0)
{
rxInstruction = 0; // coordinates
}
else if (rxChar == 1)
{
rxInstruction = 1; // voltage
}
else
{
rxInstruction = 2; //temperature
}
rxState = RxNumberofbytesState;
break;

case RxNumberofbytesState:
rxChar = rxNumberDataBytes;
rxState = RxDataState;
rxdata = 0;
break;

case RxDataState:
if (rxInstruction == 0)
{
// count number of rxdata until 8 bytes real data
rxDataBuffer[rxdata] = rxChar;
rxdata++;
if (rxdata == 8)
{
float f11 = BitConverter.ToSingle(rxDataBuffer, 0);
float f22 = BitConverter.ToSingle(rxDataBuffer, 4);
Invoke(new Action(() =>
{
textBox3.Text += "Lat="+f11.ToString() + " " + "Lng="+f22.ToString() + "\r\n";
}));
rxState = RxStopState;
}
}
else if (rxInstruction == 1)
{
rxDataBuffer[rxdata] = rxChar;
rxdata++;
if (rxdata == 1)
{
float voltage = BitConverter.ToSingle(rxDataBuffer, 0);
Invoke(new Action(() =>
{
textBox2.Text += "Current voltage is " + voltage.ToString() + "V" + "\r\n";
}));
rxState = RxStopState;
}
}
else
{
rxDataBuffer[rxdata] = rxChar;
rxdata++;
if (rxdata == 1)
{
float temp = BitConverter.ToSingle(rxDataBuffer, 0);
Invoke(new Action(() =>
{
textBox4.Text += "Current temperature is " + temp.ToString() + " degrees" + "\r\n";
}));
rxState = RxStopState;
}
}
break;

case RxStopState:
if (rxChar == 0xFF)
{
rxState = RxIdleState;
}
break;

default:
rxState = RxIdleState;
break;
}
}
}
...全文
122 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
於黾 2014-09-23
  • 打赏
  • 举报
回复
float f11 = BitConverter.ToSingle(rxDataBuffer, 0); float f22 = BitConverter.ToSingle(rxDataBuffer, 4); 那就是这里错了 你重新定义一个byte[4],把数据放到这个byte数组里,再转float 而不是直接8位一起转float
myway19891107 2014-09-23
  • 打赏
  • 举报
回复
引用 3 楼 Z65443344 的回复:
更进一步的,既然串口不能保证数据完整性,你需要通过通信协议,来校验数据的合法性 比如总共收到的字节数是否与预期的一致,开头,结尾,是否有起始符和结束符,最后是否有校验,等等 这样才能避免错误数据被正常计算
你好,谢谢你的回复! 我在一开始用了一个invoke来显示刚刚收到的信息,是hex的,然后才进入协议。我在正常运行的时候,进行了很多次的实验,确保每次接收到的信息(也就是hex形式的)都是对的。所以我认为可以收到正确的信息。请问您怎么看?谢谢!
於黾 2014-09-23
  • 打赏
  • 举报
回复
更进一步的,既然串口不能保证数据完整性,你需要通过通信协议,来校验数据的合法性 比如总共收到的字节数是否与预期的一致,开头,结尾,是否有起始符和结束符,最后是否有校验,等等 这样才能避免错误数据被正常计算
於黾 2014-09-23
  • 打赏
  • 举报
回复
另外,既然涉及到只读一次无法读到完整数据的问题 你处理的时候也应该先将读到的数据放到list里,等确定全部读完了,再统一处理 而不是收到1字节,就处理1字节 float占4字节,你只收到3个字节就开始计算,那能对吗
於黾 2014-09-23
  • 打赏
  • 举报
回复
while (serialPort.BytesToRead > 0) 这就不对了 你是如何确保收到的信息是对的?仅仅是断点调试? 要知道,你在断点调试的时候,程序走的是很慢的,而你正常运行的时候,是很快的 串口发送,跟TCP包不同,不能确保一次性收到完整的包,你必须循环,直到一定时间内不再有数据到达,才算完整 这个一定时间,可以根据波特率来确定,一般是3.5个字节周期 比如波特率9600,每秒1200字节,每字节大约1ms,那么如果超过4ms还没有数据到达,就可以认为此次发送已经结束 如果你另一头的设备也是自己编程,那么可以将协议做的更简单一些,就是发送间隔不要太短,接收的时候也就不用太严格按照3.5ms来做,直接在while里加个sleep(100),那么100ms之后没有新数据,while才退出循环
於黾 2014-09-23
  • 打赏
  • 举报
回复
一步一步跟呗 既然你确定收到的数据是正确的,那就看到底哪一步出现了乱码
myway19891107 2014-09-23
  • 打赏
  • 举报
回复
引用 5 楼 Z65443344 的回复:
float f11 = BitConverter.ToSingle(rxDataBuffer, 0); float f22 = BitConverter.ToSingle(rxDataBuffer, 4); 那就是这里错了 你重新定义一个byte[4],把数据放到这个byte数组里,再转float 而不是直接8位一起转float
你好!我也不认为是这个问题,因为,我在断电调试的时候,问题在rxdatastate之前就出现了,就是说,在byte转换float之前,乱码就自己出来了。谢谢!

110,555

社区成员

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

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

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