Nabil Fikri
Nabil Fikri

Reputation: 25

Read string from serial port and store into 2 different arrays

I'm making a keypad project. 1st user input is a 10-digit id. Then follow with 6-digit password. I've been thinking how to assign both input into different arrays upon receiving them from the serial port. Here is my attempt so far.

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

After debugging, the problem are:

  1. The MessageBox.Show() would only display empty char array.
  2. The arrays maybe did not contain anything.
  3. Using the ReadTimeout ,user need to press the keypad in a given time which is not so flexible in design.

Any help or tips are really welcomed. Thanks in advance. I don't mind to built from scratch if you suggest so.

Upvotes: 0

Views: 2190

Answers (2)

Zulfahmi Ahmad
Zulfahmi Ahmad

Reputation: 44

My suggestion is to:

  • unhook event DataReceived on the first line of method serialPort1_DataReceived from serialPort1 object
  • for the id char array, reduce to size of 10 instead of 11 because you're reading 10 digits ID
  • same goes to pass char array, reduce it to 6

Suggested code:

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

Upvotes: 3

Viet Nguyen
Viet Nguyen

Reputation: 406

This is where it goes wrong

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

the code means that try to read 11 byte into id, then return the actual number of byte read. So if there are 100 bytes available, length will be 11. If there are only 5 bytes available to read, length will be 5. Because length > 0, it loops again to try to read 11 bytes again until it reads nothing. Subsequent read will override data in the previous read as you are reading data into the same array.

Same goes with

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

Upvotes: 3

Related Questions