Click here to Skip to main content
15,886,362 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am developing an HMI for displaying the data acquired from 8 (Data Acquisition DAQ) cards each having 8 channels through serial port (RS-232).

I want to implement a time-out operation in which the HMI should dispay a message if a particular DAQ card wasn't able to serially send its acquired data within a specific time interval (let's say 20 seconds), and then continue to acquire data from the remaining cards.

For this I am setting the serialPort.ReadTimeout = 20000 but the operation isn't getting properly timed out as expected.

I am using the BackgroundWorker class to serially send and acquire data of 4000 samples from the cards and it is working fine except for the time-out function. Can anyone point out the issue?

What I have tried:

//code snippet
    serialP.DataBits = 8;
    serialP.StopBits = StopBits.One;
    //serialP.Handshake = Handshake.RequestToSend;
    serialP.Parity = Parity.None;
    
    serialP.DataReceived += serialP_DataReceived;

    serialP.WriteTimeout = 20000; 
    serialP.ReadTimeout = 20000;
    
    serialP.Open();            
   
    serialRtx.DoWork += serialRtx_DoWork;            

    if (!serialRtx.IsBusy)
        serialRtx.RunWorkerAsync();

    serialRtx.RunWorkerCompleted += serialRtx_RunWorkerCompleted;
    
}

    private void serialRtx_DoWork(object sender, DoWorkEventArgs e)
    {
     //Send token packets to DAQ cards sequentially
    }

    private void serialP_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        while (serialP.BytesToRead > 0)
        {                
            dataBytet1 = serialP.ReadByte();                
            dataByte2 = serialP.ReadByte();                               
                           
            try
            {               
                logData[sample_No, chNo - 1] = ((dataBytet1 * 256) + dataByte2 );                     

                chNo++;

                if (chNo > 8)
                {
                    sample_No++;
                    chNo = 1;
                }

                if (sample_No > 3999)//total 4000 samples of 8 channels
                {
                    cardNo++;
                    sample_No = 0;
                }                
            }
            catch (IndexOutOfRangeException)
            { }                
        }
    }
Posted
Updated 18-Dec-22 19:24pm

1 solution

The read timeout is per character, not per card: so if you have 8 cards using a single serial port then whenever any of the devices sends anything, the whole port timeout is reset.

The way I'd do it is to set up a single receiver, which "pushes" data to separate BackgroundWorker threads for processing (and which dispatches messages from those threads back to the single serial port if that's necessary) - each thread representing a separate DA card. That thread is then responsible for timing out rather than the main receiver thread.

Make sense, or am I misunderstanding exactly what you are doing here?
 
Share this answer
 
Comments
qandeel fazal 23-Dec-22 2:01am    
Can you post any helpful resource or link on how to proceed since I am fairly new to C# programming especially threading? I am already making use of two forms running in parallel, one form acquires and stores serial data to SQL database while a background form has a displayed clock running continuously so two threads are already in use. Won't a separate thread for each DA card cause issues?
OriginalGriff 23-Dec-22 2:11am    
No, all forms share the same thread.
If you want a new thread, you have to explicitly activate one (though some classes do spawn a new thread to process data, like the SerialPort.DataRecieved event for example)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900