How to calculate LIN message time?

The free LIN software API (Application Programming Interface) for Windows® (only for usage with the PCAN-USB Pro CAN/LIN interface)
Post Reply
colnewman
Posts: 8
Joined: Fri 28. Oct 2016, 19:42

How to calculate LIN message time?

Post by colnewman » Thu 1. Dec 2016, 15:53

So I am using a PCAN USB Pro. I am getting about 0.5msec to 1.5 msec message time when recorded in my code. (start stopwatch, send query (call write), (read until response), receive response, stop stopwatch.)

Baud rate is 9600

however that seems to be shorter than the theoretically message time that I calculated, which was about 13ms.

An 8 byte LIN header and response is 124bits long from what I read.

I did 1/9600 = 0.000104s bit time. Then 124bits * 0.000104s = 0.012896s. Which is slower than my measured time. Am I misunderstanding something?

M.Maidhof
Support
Support
Posts: 1269
Joined: Wed 22. Sep 2010, 14:00

Re: How to calculate LIN message time?

Post by M.Maidhof » Thu 1. Dec 2016, 18:09

Hi,

writing to our LIN API and driver is asynchronous. This means the API returns when the Write() was done to the driver. It will not block until the hardware has sent the data on the LIN bus.

Without seeing the code, it will not be possible to understand what you are measuring in your application.

regards

Michael

colnewman
Posts: 8
Joined: Fri 28. Oct 2016, 19:42

Re: How to calculate LIN message time?

Post by colnewman » Thu 1. Dec 2016, 20:16

Well it writing asynchronously to the driver may explain what's going on. I think I may have been reading in old messages in the read buffer.

Is there a way to clear the read buffer before writing to ensure the next message I read is the response?

Here is my code for my query method. If you want more I can provide it.

Code: Select all

        public bool Query(byte id, out byte[] data, byte NumberOfBytesToFetch)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            TLINMsg msgSend = new TLINMsg { FrameId = id, ChecksumType = TLINChecksumType.cstAuto, Length = NumberOfBytesToFetch, Direction = TLINDirection.dirSubscriber};
            PLinApi.CalculateChecksum(ref msgSend);
            var errWrite = PLinApi.Write(hClient, handle, ref msgSend);

            if(errWrite != TLINError.errOK)
            {
                //** fix me throw exception
            }

            TLINRcvMsg msgRcv;

            var run = true;
            TLINError errRead;
             
            do
            {
                errRead = PLinApi.Read(hClient, out msgRcv);
                if(msgRcv.FrameId != id)
                {
                    Log.Logger.Warning("{Class}.{Method} : Next message did no match sent ID", nameof(PeakLIN_Adapter), nameof(Query));
                    continue;
                }
                data = msgRcv.Data;
                if (msgRcv.Type != TLINMsgType.mstStandard)
                {
                    
                    continue;
                }
                if(msgRcv.ErrorFlags != 0)
                {
                    Log.Logger.Warning("{Class}.{Method} : Message Error Flag {flag}", nameof(PeakLIN_Adapter), nameof(Query),msgRcv.ErrorFlags);

                    sw.Stop();
                    return false;
                    
                }

                if (errRead == TLINError.errRcvQueueEmpty)
                {
                    sw.Stop();
                    return false;                    
                }
                else if(errRead == TLINError.errOK)
                {
                    break;
                }
                else
                {
                    //** fix me throw exception
                }

                
            }
            while (run);

            if(errRead != TLINError.errOK)
            {
                //** fix me throw exception
            }


            data = msgRcv.Data;

            sw.Stop();
            //Log.Verbose("Query time: {time}",sw.Elapsed);
            if (sw.Elapsed.TotalMilliseconds > 15)
            {
                Log.Logger.Warning("Query time exceeded 15ms: {time}", sw.Elapsed);
            }
            else if (sw.ElapsedMilliseconds > 100)
            {
                Log.Logger.Error("Query time exceeded 100ms: {time}", sw.Elapsed);
            }

            return true;
        }

User avatar
M.Riedl
Software Development
Software Development
Posts: 26
Joined: Wed 22. Sep 2010, 13:28

Re: How to calculate LIN message time?

Post by M.Riedl » Fri 2. Dec 2016, 11:39

Hi,

you can possibly use the PlinApi function ResetClient to clear the client receive queue or ResetHardware for the hardware receive queue.

Another important thing: If your client is connected as master, all publisher frames that you send with the Write function will be placed into your receive queue. This behavior also occurs if publisher frames are sent using a schedule table on the LIN hardware. You should ignore any publisher frames you get, for example, processing in your code only those frames of type subscriber.

Regards
M.Riedl
Last edited by K.Wagner on Fri 2. Dec 2016, 12:20, edited 1 time in total.
Reason: Engl

Post Reply