Reputation: 25
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:
MessageBox.Show()
would only display empty char array.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
Reputation: 44
My suggestion is to:
DataReceived
on the first line of
method serialPort1_DataReceived
from serialPort1
objectid
char
array, reduce to size of 10
instead of 11
because you're reading 10 digits IDpass
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
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