简体   繁体   中英

Strange behavior form C# serial port

I'm getting strange behavior from simple program, which I'm using to learn how to use the serial port. The form have just one serial port control and one TextBox. Because it's just a test program I have disabled the thread call check. I forgot to mention,that I'm using micro-controller to send 1000 bytes of data (read EEPROM). The strange thing is that, when I read the data and just append it directly to the text box in the DataReceived event, everything is fine, but when I first pass the values to int[] array,and then use a loop to convert them to strings in HEX format and append them to the TextBox, there are some zeros, between the values.

Some code with results.

Case 1: read data and directly append to TextBox

private void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        while (sp1.BytesToRead > 0)
        {
            textBox1.AppendText(sp1.ReadByte().ToString("X")+ " ");
        }

    }

And the result is (well,part of it,as i said there are 1000 bytes to receive...)

0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C..... and so on

Case 2: first store the values to int array,and than convert them to string, and append to TextBox

 private void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        int[] buffer = new int[1000];
        int i = 0;
        while (sp1.BytesToRead > 0)
        {
            //textBox1.AppendText(sp1.ReadByte().ToString("X")+ " ");
            buffer[i] = sp1.ReadByte();
            i++;
        }
        int j = 0;
        while (j < 1000)
        {
            textBox1.AppendText(buffer[j].ToString("X"));
            j++;
        }

I get a lot of 0's at random places, and it reads 4-5 times more data, than the 1000 in the loop

0123456789ABCDEF101112131415161718191A1B1C1D1E1F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF0123456789ABCDEF101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF0123456789ABCDEF101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF0123456789ABCDEF101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

What might be the reason for this strange behavior? Thanks in advance

sp1_DataReceived is typically not called only once. Typically your computer handles received data faster than received. This means at some point the loop

while (sp1.BytesToRead > 0)

is left before all 1000 bytes are received. Just a short time later sp1_DataReceived is already called again because more of the 1000 bytes are now available. Since your first implementation only appends the bytes it doesen't matter. But your second implementation differs because you are always appending 1000 characters to your text. This could lead to a result of a multiple of 1000 characters with zeros appended.

To fix your problem you need to combine the bytes of multiple events. One solution could be to use a list like

private List<byte> buffer = new List<byte>();
private void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    while (sp1.BytesToRead > 0)
    {
        buffer.Add(sp1.ReadByte());
    }

    //Print if all bytes are available
    if (buffer.Count >= 1000)
    {
        //Join the bytes to a string using LINQ
        textBox1.Text = String.Join("", buffer.Select(b => b.ToString("X")));
        buffer.Clear();
    }
}

or an array like

private byte[] buffer = new byte[1000];
private int bufferIndex = 0;
private void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    while (sp1.BytesToRead > 0 && bufferIndex  < 1000)
    {
        buffer[bufferIndex ] = sp1.ReadByte();
        bufferIndex ++;
    }

    //Print if all bytes are available
    if (bufferIndex  >= 1000)
    {
        //Join the bytes to a string using LINQ
        textBox1.Text = String.Join("", buffer.Select(b => b.ToString("X")));
        bufferIndex = 0;
    }
}

Note that this are only some ideas and example implementations. Since I do not know if you are also receiving other messages at the port it is not possible to give a perfect suitable solution to solve your problem.

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