简体   繁体   中英

read 22 byte from FTDI serial port in c# is too slow

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

this is my code:`

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();
    }
}

}

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.

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);

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...
    }

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.

BaudRate is set in bits per second, so make sure this is high enough for what you expected transfer speed to be, so 8192 baud will be 1KB (1024 bytes) per second.

Here is an article that might help you: http://www.codeproject.com/Articles/75770/Basic-serial-port-listening-application

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM