串口数据读取问题

掉毛天使 2018-08-30 05:59:42
首先声明一下,我是初学者不是业余开发人员,在学校也没有学过,勿喷,谢谢!

自己为生产线编写了一个串口读码程序,如果按照图示代码的话没有问题,我想实现只显示最新数据,新数据来的时候把旧数据覆盖掉,
现在扫码枪的数据总是追加在textbox1中,我试过了直接“=”,总是丢失数据,显示不全,不知道该怎么改代码,求助大师们指点一下,多谢多谢。
...全文
855 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_35226435 2018-09-04
  • 打赏
  • 举报
回复
串口接收数据一次接受不完是常有的事,一般的处理方法是在内存中开辟一个缓冲区,然后将接收到的数据放在缓冲区中。因为一般扫码枪的数据长度是固定的,或者有固定的数据包格式,所以每当接受到新的数据后,就扫描一遍缓冲区,如果接收到的数据符合要求(长度符合,或者数据包格式正确),说明已经接收完全了,这时候再用赋值显示到textbox中,就不会有问题了。
wanghui0380 2018-09-04
  • 打赏
  • 举报
回复
解决方式1:扫码枪都可以设置为后跟回车。所以你可以检查有回车字符没有

解决方式2:扫码枪出字符是快速连续的,当间隔大于200毫秒时候,认为一次扫码完成。
Maybe_ch 2018-09-04
  • 打赏
  • 举报
回复

int currentReadLengh = 0;
int lastReadLengh = -1;

while (gateComPort.BytesToRead != lastReadLengh)
{
currentReadLengh = gateComPort.BytesToRead;
lastReadLengh = currentReadLengh;
System.Threading.Thread.Sleep(20);
}
byte[] bytes = new Byte[lastReadLengh];
gateComPort.Read(bytes, 0, bytes.Length);


试下这样读取数据,确保每次拿到完整数据,根据你的操作舍弃或取得数据
  • 打赏
  • 举报
回复
固然,接收数据然后判断消息结束符号方面,这个程序没有做到位。但是 UI 显示混乱最主要的问题还是坑爹的 CheckForIllegalCrossThreadCalls 这个问题。当收到数据时在子线程中会触发事件回调 DataReceived 过程,你看到哪一个做真正大产品的人告诉你 CheckForIllegalCrossThreadCalls 要设置为 false 才=能保证产品质量的?!
  • 打赏
  • 举报
回复
引用 7 楼 t15032286291 的回复:
   
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false; //引用它之后就不会有receiveedit.appendtext();运行时的线程错误了


代码是不会抛出异常了,但是程序 UI 表现照样会非常混乱地胡乱覆盖、丢失数据啊?!!本来使用 CheckForIllegalCrossThreadCalls 就是为了防止胡乱编程的,你怎么能给它设置为 false?
qq_42917498 2018-09-02
  • 打赏
  • 举报
回复
不好意思爱上初三
LQ_DaYuRen 2018-08-31
  • 打赏
  • 举报
回复
首先,你不要连续的读COM口的数据,读一次数据之后让线程休眠一下;其次,你的数据格式是什么不要读到什么都直接写,先把想要的数据取出来,然后再放出来,别直接放原始数据。第三,textBox2.Text = (Received_Count - 1).ToString();你这行代码什么意思?这个只是计数器,并不是数据啊。
第四,我是刚入WPF的,我知道在WPF中你这么刷新前台控件是不行的。一个刚入行的新手,帮不了你太多。
Vito1993 2018-08-31
  • 打赏
  • 举报
回复
你这样不对吧 至少要处理一下数据后再显示在前台(包头 长度 包尾)
余缺 2018-08-31
  • 打赏
  • 举报
回复
 byte[] recb = mycom1.Read(30);
掉毛天使 2018-08-30
  • 打赏
  • 举报
回复
不好意思,忘记了,哎我很笨
掉毛天使 2018-08-30
  • 打赏
  • 举报
回复
     private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            
            try
            {

                System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false; //引用它之后就不会有receiveedit.appendtext();运行时的线程错误了
                int n = serialPort1.BytesToRead;//先记录下来,避免某种原因,人为的原因,操作几次之间时间长,缓存不一致
                byte[] buf = new byte[n];//声明一个临时数组存储当前来的串口数据
                Received_Count += n;//增加接收计数
                serialPort1.Read(buf, 0, n);//读取缓冲数据

                builder.Clear();//清除字符串构造器的内容

                builder.Append(Encoding.ASCII.GetString(buf));
                
                //直接按ASCII规则转换成字符串
                builder.Append(Encoding.ASCII.GetString(buf));

                textBox1.AppendText(builder.ToString());//可以使用

                textBox2.Text = (Received_Count - 1).ToString();
掉毛天使 2018-08-30
  • 打赏
  • 举报
回复
引用 2 楼 qq_36843830 的回复:
可以在赋值前判断下,如果文本框值长度>0,你可以清理下文本框内容再赋值,不知道符合你的要求不
这个方法测试过了,增加后就会丢数据,我用的.clear
xuzuning 2018-08-30
  • 打赏
  • 举报
回复
既没看到代码,也没看到数据
stherix 2018-08-30
  • 打赏
  • 举报
回复
串口扫码枪的话,大多是结束的时候会带一个回车,而且数据未必是一次性传过来的
你判断它发来的数据里有回车,就把清除状态设为true
每次数据来的时候,判断清除状态是否为true,是true则用=,否则用+=
然后将清除状态设为false,在判断新数据里是否有回车
Blithe239 2018-08-30
  • 打赏
  • 举报
回复
串口接收数据一次接受不完是常有的事,一般的处理方法是在内存中开辟一个缓冲区,然后将接收到的数据放在缓冲区中。因为一般扫码枪的数据长度是固定的,或者有固定的数据包格式,所以每当接受到新的数据后,就扫描一遍缓冲区,如果接收到的数据符合要求(长度符合,或者数据包格式正确),说明已经接收完全了,这时候再用赋值显示到textbox中,就不会有问题了。
余缺 2018-08-30
  • 打赏
  • 举报
回复
可以在赋值前判断下,如果文本框值长度>0,你可以清理下文本框内容再赋值,不知道符合你的要求不
掉毛天使 2018-08-30
  • 打赏
  • 举报
回复
先谢谢各位大神了。

110,561

社区成员

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

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

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