2
votes

i am an engineering student and i am currently working on my final year project. i am trying to build a rfid-based parking lot management system in C#. based on some research i have written the following code to read data from rfid reader but i am facing this problem. the event handler
which i use to read the received data fires twice, which i don't understand how...i did some research on the internet and found many people are facing similar problem of an event handler firing twice but most of them are button-click events. i could only find a few threads on custom event handler but those solutions don't seem to work in my project. any possible solutions to this problem?

private void Parking_layout_Load(object sender, EventArgs e)
{
    foreach (string port in System.IO.Ports.SerialPort.GetPortNames())
    {
        comboBox1.Items.Add(port);
        if (comboBox1.Items.Count > 0)
            comboBox1.SelectedIndex = comboBox1.Items.Count - 1;
    }

    RFID = new SerialPort();
    RFID.PortName = comboBox1.Text;
    RFID.BaudRate = 9600;
    RFID.DataBits = 8;
    RFID.Parity = Parity.None;
    RFID.StopBits = StopBits.One;
    RFID.Open();
    RFID.DataReceived += new SerialDataReceivedEventHandler(RFID_DataReceived);

}

private void RFID_DataReceived(object sender, SerialDataReceivedEventArgs e)
{            
    try
    {                
        tag_id = RFID.ReadExisting().ToString();              
        SetLabel(tag_id);                
    }
    catch (Exception ex)
    {
        throw new Exception(ex.Message);
    }
}

the RFID_DataReceived executes twice. if i put a messageBox.show() statement to test it, it shows the message twice. how do i fix this problem?

2
Not have the device send more than one piece of data? This seems like a very hardware-dependent question. - Jesse C. Slicer
You should remove your catch block; all it does is destroy information. - SLaks
Is it the same data twice? - Idle_Mind
Serial ports are slow, your ReadExisting() call usually only returns 1 or 2 characters. So of course DataReceived fires more than once. You must not call SetLabel() until you got the entire response. What that takes is unclear from the question, using ReadLine() instead of ReadExisting() tends to get the job done. Tweak the NewLine property as necessary. - Hans Passant
You'd be better off with try { ... } catch () { throw; } or without any try...catch at all. And I'd be curious to know what happens if you actually remove the event subscription as suggested by Babak Naffas. Have you tried it? I know that RFID scans occur repeatedly as long as the chip is within reach of the RFID reader, have you handled this to filter all those readings as a single one so that you perhaps may filter the raise of the RFID_DataReceived event? - Will Marcouiller

2 Answers

1
votes

Set a break point on the RFID_DataReceived method in order to see why it is firing twice. You can then take a look at the stack window to see the stack trace of the code.

You can also do the same for the original method Parking_layout_Load to see if perhaps it is being called more then once from another piece of code. You can also place code inside the function in order for the stacktrace to be written to the output window.

private void RFID_DataReceived(object sender, SerialDataReceivedEventArgs e)
{   Debug.WriteLine("StackTrace: '{0}'", Environment.StackTrace);         
    try
    {                
        tag_id = RFID.ReadExisting().ToString();              
        SetLabel(tag_id);                
    }
    catch (Exception ex)
    {
        throw new Exception(ex.Message);
    }
}

For even more detail then use the stacktrace class as in this example : StackTrace Class

Environment.StackTrace Property

How to: Use the Call Stack Window

-1
votes

What is the incoming data? Looking at your code, I notice you have the line

RFID.DataBits = 8;

In .NET, a char is 2 bytes. If you are reading a character from your device, then it would in fact need to call your event handler twice to process all 16 bits. Can you change the value to 16?