从 C# 中的 FTDI 串口读取 22 字节太慢 [英] read 22 byte from FTDI serial port in c# is too slow

查看:91
本文介绍了从 C# 中的 FTDI 串口读取 22 字节太慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 FTDI 串口,我必须在串口中写一些东西才能开始读取 22 字节我有一个很奇怪的问题.我读这个数据太慢了

I have a FTDI serial port and I have to write something in serial port to start reading 22 byte I have a very strange problem. I read this data too slow

我不知道我的问题是什么

I don't know what is my problem

这是我的代码:`

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    int count;

    private void button1_Click(object sender, EventArgs e)
    {
       // serialPort1.Open();

       // serialPort1.Write(Convert.ToString(0x02));  //here we converted the same method to convert hex to string to be send using serial port
        //textBox3.Text = (Convert.ToString(0x02));   //here we will see what will be sent with serial port
        serialPort1.Write(textBox5.Text);
     //   serialPort1.Close();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        serialPort1.PortName = textBox1.Text;
        serialPort1.BaudRate = Convert.ToInt32(textBox2.Text);


    }

    // int rs;
    byte[] rs=new byte[22];

    private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        try
        {
           // rs = serialPort1.ReadByte();
            serialPort1.Read(rs, 0, 22);
            this.Invoke(new EventHandler(type));

        }
        catch (System.TimeoutException) { }
    }
    void type(object s,EventArgs e)
    {
        textBox4.Text = rs.ToString(); //this method should view what is being recieve by the serial port :)

        label4.Text =rs[0].ToString();
        label5.Text = "" + rs[1];
        label6.Text = "" + rs[2];
        label7.Text = "" + rs[3];
        label8.Text = "" + rs[4];
        label9.Text = "" + rs[5];
        label10.Text = "" + rs[6];
        label11.Text = "" + rs[7];
        label12.Text = "" + rs[8];
        label13.Text = "" + rs[9];
        label14.Text = "" + rs[10];
        label15.Text = "" + rs[11];
        label16.Text = "" + rs[12];
        label17.Text = "" + rs[13];
        label18.Text = "" + rs[14];
        label19.Text = "" + rs[15];
        label20.Text = "" + rs[16];
        label21.Text = "" + rs[17];
        label22.Text = "" + rs[18];
        label23.Text = "" + rs[19];
        label24.Text = "" + rs[20];
        label25.Text = "" + rs[21];

        count++;

    }

    private void button3_Click(object sender, EventArgs e)
    {
        serialPort1.Open();
        // start timer to count

        serialPort1.Write("?");
        serialPort1.Write("5");
        serialPort1.Write("1");
        serialPort1.Write("&");

        timer1.Start();

    }

    private void button4_Click(object sender, EventArgs e)
    {
        serialPort1.Close();

    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        // after 1000 mili second this timer will do the following 
        timer1.Stop();

        textBox6.Text = count.ToString();
        count = 0; // re initialize the count variable :)
        timer1.Start();
    }
}

}

当我使用 serialport1-readExisting(); 时间是真的(正是我想要的(5/5))但数据是字符串而我的数据是整数所以它没有用.

when I use serialport1-readExisting(); the time is true (exactly thing I want (5/5)) but the data is string and my data is integer so it is not useful.

我确定我的问题与使用 serialport1.Read(rs,0,22) 有关,但我真的不知道我必须做什么

I sure my problem is related to use serialport1.Read(rs,0,22) but I really don't know what I have to do

如果有人可以帮助我,我会很感激..

I would have be thankful if someone could help me please..

推荐答案

        serialPort1.Read(rs, 0, 22);

你不能忽略Read()的返回值,它不会是22.如果你马上调用,你也不能忽略e.EventType.你不应该这样做,在你做之前收集整个响应.您只需要另一个变量来跟踪您收到的字节数.修复:

You cannot ignore the return value of Read(), it will not be 22. Nor can you ignore e.EventType if you invoke right away. Which you shouldn't, collect the entire response before you do. You just need another variable to keep track of how many bytes you've received. Fix:

    byte[] rs = new byte[22];
    int rsCnt = 0;

    private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) {
        if (e.EventType != SerialData.Chars) return;
        rsCnt += serialPort1.Read(rs, rsCnt, 22 - rsCnt);
        if (rsCnt == 22) {
            this.BeginInvoke(new Action(() => type(rs)));
            rs = new byte[22];
            rsCnt = 0;
        }
    }

    private void type(byte[] data) {
        // etc...
    }

检查 e.EventType 避免了 TimeoutException,当您将 ReadTimeout 设置为 0 时,您将不需要它.使用 BeginInvoke() 而不是 Invoke() 可避免在调用 serialPort1.Close() 方法时出现死锁.当 type() 忙于处理数据而端口继续接收数据时,重新创建缓冲区可以避免线程竞争.

Checking e.EventType avoids the TimeoutException, you won't need it when you set the ReadTimeout to 0. Using BeginInvoke() instead of Invoke() avoids a deadlock when you call the serialPort1.Close() method. Re-creating the buffer avoids a threading race when the type() is busy processing the data while the port continues receiving data.

这篇关于从 C# 中的 FTDI 串口读取 22 字节太慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆