Serial Port interbyte delay accuracy

Dakta

Member
Joined
Dec 12, 2012
Messages
7
Programming Experience
Beginner
Hello, I've another serial port challenge, if anyones got any tips or ideas.

I'm writing an application that updates the firmware on an embedded microcontroller, and so I'm working to a protocol specification set by the device developer.
In the specification, I have to transmit bytes to the micro with an interbyte delay of 5 milliseconds, the lower limit is 3 milliseconds and the upper limit is 20 milliseconds.
If I send bytes outside of this threshold, the whole command that is being transmitted (even if some bytes are within the limits) is discarded and I receive no response.

So what I do when transmitting a command, I store the data in a byte array, called TXBUff() and when it comes to transmit I use a delay routine like thus:

VB.NET:
for i = 0 to messagelength - 1         
   Delay(5)
   SerialPort.Write(TXBuff, i, 1)
next i

My delay routine looks like this:

VB.NET:
Public Sub Delay(ByVal DelayMilliseconds As Integer)
        'function for super delay
        Dim delaywatch As New Stopwatch
        delaywatch.Start()
        Do Until delaywatch.ElapsedMilliseconds >= DelayMilliseconds
            Application.DoEvents()
        Loop
        delaywatch.Stop()




    End Sub

It's not perfect but it's actually the most accurate delay routine i've been able to dig up.

The sequence of commands used to write the firmware to the micro are all done in the GUI thread (I don't use a background worker or anything), I don't mind if the GUI was to lock up etc (in fact it wouldnt be far from ideal if it did as I don't want users to use the computer if possible for other tasks as the process is quite crucial).

Anyway, it actually all works rather well 99% of the time, however with one major flaw - I miss messages now and then. After doing a lot of hair tearing and debugging I've realised theres no actual data loss on transmit or receiving, it's just simply the computer has a spike of activity enough to throw the delay between bytes being transmitted over the 20msec threshold, and the microcontroller doesn't respond.

I can replicate the issue by pressing the screenshot button during communication, that causes enough of a 'hiccup' to throw the message out.

Now I'm going to add code to try and detect messages that are not acknowledged and re-transmit if necessary, but I'd rather try and transmit with a more accurate timing - (during the actual writing process, data is streamed so I can't always tell if the error is occuring) reducing the interbyte delay between bytes to the minumum accepted has helped but not solved the problem.

So, the bottom line is, can anyone think of a creative way to try and guarentee bytes will be sent not less than 3msec apart and not more than 20msec apart?

I've a feeling vb.net might be a poor choice of language for this :(

thanks
Kris
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,397
Location
Sydney, Australia
Programming Experience
10+
I would suggest that you DO use a secondary thread. That way, you can set the Priority of that Thread object and hopefully reduce the likelihood of its being trumped by another thread. You would then use Thread.Sleep to impose the delay.

You're still not guaranteed to get the outcome you want though. The system doesn't have to honour that priority and a consumer system only has so many resources available. If timing like that is critical then you should probably look into real-time programming.
 

Dakta

Member
Joined
Dec 12, 2012
Messages
7
Programming Experience
Beginner
Yes, thanks for that I'll give it a try.

I've been doing some reading and I do seem really limited that way.

It might sound daft but similar programs that do a similar job with these micros are often written in the older visual C++ or delphi, this might be an idiots question but would it be worth in any case seeing if a library or anything can be used as a go-inbetween. My own program is far more relaxed with timing when receiving, but the device i'm communicating with is stubborn about it's own receive timing.

It might just be the nature of the windows operating system in that you simply cannot guarentee timing, that'd be a kick in the face :(

I can appreciate you couldnt guarentee saving a large amount of data to disk or drawing a graphic in time, but making sure one byte follows another within 20ms should be acheivable.

I did actually try sending the bytes without any delay but it was too fast for the micro to pick up.
 

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,517
Location
Norway
Programming Experience
10+
A similar problem was discussed here: Accurate timing of serial breakstate
UI thread and Application.DoEvents should be out of the question, Thread.Sleep may also be too inaccurate.
 

Dakta

Member
Joined
Dec 12, 2012
Messages
7
Programming Experience
Beginner
Looking at that thread, the OP wants a breakstate high then low for 25msec - i've a feeling he's talking to the same sort of device as me (automotive controller).

These are very particular about timing!

Just doing some mods to a test project to run the serial port transfer through a new, high priority thread, hopefully this might work
 

Dakta

Member
Joined
Dec 12, 2012
Messages
7
Programming Experience
Beginner
I'm having some fun working with threads (its not something I've done before) and my test code has a tendency to hang up the program (no error, just hang) so I'm handling the threading wrong, however it has to be said that before this happens, communication is a lot more reliable.

Still interested in any other creative solutions! Will read a bit more into threading and try and stop it hanging- ive always been a bit nervous about getting into it but i guess its time.

Thankyou everyone so far.
 
Last edited:
Top Bottom