Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Incorrect timescale in waveform graph

I'm making a GUI for analyzing waveform data. It can, amongst others, measure time between two cursors. What I see is that when I set the the DefaultStart property of the WaveformPlot to the actual time (eg DateTime.Now), the time measurements are completely wrong. It is about 20% too small. When I set the DefaultStart property to 0, the time measurement is OK. I use a sample frequency of 108kHz. When I lower the sample frequency, e.g. 10800Hz, and set the DefaultStart property to the current time, the error is much less, but it is still wrong. It looks like MeasurementStudio messes around with the significancy of digits. Or am I dooing something wrong?


Greetings,
 RMW
0 Kudos
Message 1 of 11
(5,976 Views)
Yes, don't use DateTime.Now if you want anything more precise than 20ms, even if the theorical resolution of DateTime.Now.Ticks is of 100ns unit, you can't really rely on it.
If you want a precise timer, prefer use of System.Diagnostic.StopWatch class.
0 Kudos
Message 2 of 11
(5,954 Views)

Thanks for the reply, but this is not exactly what I mean. I am not measuring a time at run-time, but I am measuring the elapsed time between two cursors in a graph. I attached a sample program and added some screendumps that demonstrate the problem. When the button 'Generate' is pressed, it generates an array of samples having a flank at exactly every second, and uses PlotY to plot it as a waveform in the graph. The DefaultIncrement of the WaveFormPlot is set to 1/108000. With the checkbox it can be configured if the DefaultStart is set to zero or set to DateTime.Now. The text-boxes below the graph show the positions of the cursors and the defference between them. The screenshots below show that the time measured is wrong when the DefaultStart has been set to 'Now', and that is the issue here.

Anybody knows what is going on here?

RMW



OK when DefaultStart has been set to 0.



Not OK when DefaultStart has been set to DateTime.Now:

0 Kudos
Message 3 of 11
(5,948 Views)
Should I still have hope that this will be resolved, or should I just give up?
0 Kudos
Message 4 of 11
(5,828 Views)
Hello RMW,

I'd like to have a look at your sample project, but it doesn't look like it is attached anymore.  Is there any chance you could attach it again so that I could have a look at it?  Thanks!

NickB
National Instruments
0 Kudos
Message 5 of 11
(5,820 Views)
Sorry, I thougt I already did. But here it is.
0 Kudos
Message 6 of 11
(5,817 Views)
Hello RMW,

I was able to reproduce the issue you were seeing, and it seems to be in some way related to the very large value double that DateTime.Now is returning.  This issue has been reported to R&D (ID 119840) for further investigation.  In the meantime, as a workaround, you should be able to display the month, day, hour, etc. data if you remove the year data, as this will drastically reduce the value of the double being passed to DefaultStart.  This would basically be calculating the month, day, hour, etc. since 1/1/0001, so the only thing that would be incorrect would be the year.  You could accomplish this by modifying your code to look something like this:

waveformPlot1.DefaultStart = (double)DataConverter.Convert(DateTime.Now - DateTime.Parse("1/1/" + DateTime.Now.Year.ToString()), typeof(double));

Please let me know if this is a suitable workaround for you, or if you have any other questions!

NickB
National Instruments
0 Kudos
Message 7 of 11
(5,797 Views)
Nick,

Thank you for your response. I have to discuss this with our customer. If they agree in adjusting the requirements on the timescale, I will apply it. I think they will.




Robert
0 Kudos
Message 8 of 11
(5,780 Views)
Hello RMW,

I just thought I would report back with some of our findings as we have investigated this scaling issue you have run into.  What you are seeing is actually a limitation of the precision that can be achieved with a double when you are adding such a large number (DateTime.Now) with such a small number (the increments between each of your data points - 1/108000).  This is the root cause of the crunching that you have reported.  While we will continue to work to simplify the implementation of cases such as yours, I thought I would expand on my prior suggestion.  Below are two additional workarounds that will retain the year information, as well as provide results that contain none of the crunching you originally reported, which was present to some small extent in my previous workaround.

First, you could create your own new class that inherits from our FormatString class.  In this class, you would only need to override one method of the base class, although overriding the constructor may be helpful as well.  The only method you would need to override would be the FormatDouble method.  What this would allow us to do is further reduce the value of the double that is used for the DefaultStart property, and then, when we format the string to be displayed on the labels, add in the remaining necessary double value to account for the year information.  The implementation of this new class may look something like the following:

    class CustomFormatString : FormatString
    {
        // override the base constructor, specifying that the format string mode is DateTime,
        // and that the format string is "MMM-dd-yyyy h:mm:ss.fff" for all who implement this class
        public CustomFormatString()
            : base(FormatStringMode.DateTime, "MMM-dd-yyyy h:mm:ss.fff")
        {
        }

        public override string FormatDouble(double value)
        {
            // Take the value of double that is passed in to be formatted, (the current day and time)
            // and add the current year and month information back to it
            return base.FormatDouble(value + (double)DataConverter.Convert(DateTime.Parse(DateTime.Now.Month +
                "/1/" + DateTime.Now.Year.ToString()), typeof(double)));
        }
    }

You would then use this new custom FormatString class to specify the format string for the xAxis1.MajorDivisions.LabelFormat property.  I have attached a modified version of your original example showing the full implementation of this idea.

Second, you could create custom divisions that would basically map to the current divisions of the x-axis.  This way, you could start DefaultStart at 0, turn of the visibility of the default xAxis major division labels, and write the current DateTime string to the value field of each custom division.  Please let me know if you have any questions, or if I can clarify anything for you!

NickB
National Instruments
0 Kudos
Message 9 of 11
(5,739 Views)
Hello RMW,

As soon as I hit the "Submit Post" button, I realized there was a way that I could clean up my first suggestion even more.  I have made a couple small modifications to the example I just posted, and attached them below.  Thanks!

NickB
National Instruments


Message Edited by nickb on 07-18-2008 10:01 AM
0 Kudos
Message 10 of 11
(5,738 Views)