【问题标题】:read 22 byte from FTDI serial port in c# is too slow从 C# 中的 FTDI 串口读取 22 字节太慢
【发布时间】:2025-12-08 12:45:01
【问题描述】:

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

我不知道我的问题是什么

这是我的代码:`

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)),但数据是字符串,我的数据是整数,所以它没有用。

我确定我的问题与使用 serialport1.Read(rs,0,22) 有关,但我真的不知道该怎么办

如果有人可以帮助我,我将不胜感激..

【问题讨论】:

    标签: c# visual-studio-2010 serial-port windows-xp ftdi


    【解决方案1】:
            serialPort1.Read(rs, 0, 22);
    

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

        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() 忙于处理数据而端口继续接收数据时,重新创建缓冲区可避免线程竞争。

    【讨论】:

    • 这个程序在 Windows XP 中运行良好,但是当我在 Windows 7 中编写和测试它时速度很慢,并且在停止工作后有点停止!!我不知道为什么?..我在这里写这个问题..*.com/questions/31510232/…
    【解决方案2】:

    BaudRate 以每秒位数为单位设置,因此请确保该值足以满足您预期的传输速度,因此 8192 波特将是每秒 1KB(1024 字节)。

    这里有一篇文章可能对你有所帮助:http://www.codeproject.com/Articles/75770/Basic-serial-port-listening-application

    【讨论】:

    • 我的波特率是 115200,我认为这应该足够了,另一个奇怪的事情是其他人在 MATLAB 中阅读了一个程序并且该程序运行良好......所以 C# orogram 有问题或者可能是串口属性