从串行端口读取字符串并存储到 2 个不同的数组中

Read string from serial port and store into 2 different arrays

我正在做一个键盘项目。第一个用户输入是一个 10 位数的 ID。然后输入 6 位密码。我一直在考虑如何在从串口接收到两个输入时将它们分配给不同的数组。这是我到目前为止的尝试。

private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    char[] id = new char[11];
    char[] pass = new char[7];
    int length;

    try
    {
        serialPort1.ReadTimeout = 100;
        do
        {
            length = serialPort1.Read(id, 0, 11);
        } while (length > 0);
    }
    catch (TimeoutException) { MessageBox.Show(id.ToString()); }

    try
    {
        serialPort1.ReadTimeout = 100;
        do
        {
            length = serialPort1.Read(pass, 0, 7);
        } while (length > 0);
    }
    catch (TimeoutException) { MessageBox.Show(pass.ToString()); }
}

经过调试,问题是:

  1. MessageBox.Show() 只会显示空字符数组。
  2. 数组可能不包含任何内容。
  3. 使用ReadTimeout,用户需要在给定的时间内按下键盘,这在设计上不太灵活。

非常欢迎任何帮助或提示。提前致谢。如果您建议的话,我不介意从头开始构建。

这是错误的地方

do
{
     length = serialPort1.Read(id, 0, 11);
} while (length > 0);

代码的意思是尝试将11个字节读入id,然后return实际读取的字节数。因此,如果有 100 个字节可用,则长度将为 11。如果只有 5 个字节可供读取,则长度将为 5。因为长度 > 0,它会再次循环尝试再次读取 11 个字节,直到读取不到任何内容。当您将数据读入同一数组时,后续读取将覆盖先前读取中的数据。

也一样
do
{
     length = serialPort1.Read(pass, 0, 7);
} while (length > 0);

我的建议是:

  • unhook 事件 DataReceived 第一行 来自 serialPort1 对象
  • 的方法 serialPort1_DataReceived
  • 对于 id char 数组,减少到 10 的大小而不是 11 因为你正在读取 10 位数字 ID
  • 同样进入pass char数组,将其减少为6

建议代码:

private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    // unhook event
    serialPort1.DataReceived -= serialPort1_DataReceived;

    char[] id = new char[10];
    char[] pass = new char[6];

    try
    {
        // send unique start bit from connected serial port device to indicate begin of transmission
        byte ack = serialPort1.ReadByte();
        while (ack != 0xC0)
        {
            ack = serialPort1.ReadByte(); // <- continuously read from serial port until start bit is found
        }

        // try to increase timeout as 100 ms is too fast
        serialPort1.ReadTimeout = 1000;
        for (int i = 0; i < 10; i++)
        {
            id[i] = (char)serialPort1.ReadByte();
        }
    }
    catch (TimeoutException) { MessageBox.Show(id.ToString()); }

    try
    {
        // send unique start bit from connected serial port device to indicate begin of transmission
        byte ack = serialPort1.ReadByte();
        while (ack != 0xC0)
        {
            ack = serialPort1.ReadByte(); // <- continuously read from serial port until start bit is found
        }

        // try to increase timeout as 100 ms is too fast
        serialPort1.ReadTimeout = 1000;
        for (int i = 0; i < 6; i++)
        {
            pass[i] = (char)serialPort1.ReadByte();
        }
    }
    catch (TimeoutException) { MessageBox.Show(pass.ToString()); }

    // rehook event
    serialPort1.DataReceived += serialPort1_DataReceived;
}