Plotting voltage in a chart..

Oct 13, 2011 at 3:33 PM

 

Hi folks.. I'm trying to make a chart display a voltage as you would on a scope.. Only...
I can stop the default 'autozoom' function. I have had a look at the following links / suggestions.. but I have not had my eureka moment!
http://dynamicdatadisplay.codeplex.com/discussions/210225
http://dynamicdatadisplay.codeplex.com/discussions/71063

I have done a screencast that demonstrates the problem..
http://www.jnewcomb.com/share/perm/soft/chartscreenshot.wmv

The x axis seems to be OK.. but the Y zooms in so I cant see the full scale.

I have screen cast that demonstrates what Im trying to do..
Any help will be welcome..

I am using the latest 'stable' release (0.3.1) from...
http://dynamicdatadisplay.codeplex.com/SourceControl/changeset/changes/31108
(mainly because I cant build the latest version due to missing assembly errors / warnings etc..) Win7/VS2010
.. I think this could be my problem.. have things moved on since the last stable release..?

____________

   public partial class MainWindow : Window
    {
        // Application specific code
        private ClassController hardwareDataCollector;
        // Timers to trigger updates on the UI
        private readonly DispatcherTimer textUpdateTimer = new DispatcherTimer();
        private readonly DispatcherTimer graphUpdateTimer = new DispatcherTimer();
        // The Datasources charded on the graph
        private EnumerableDataSource<float> animatedDataSourceY = null;
        private EnumerableDataSource<UInt32> animatedDataSourceX = null;
        // These arrays are attacted to the datasource in 'Window_Loaded()'
        private readonly float[] animatedY = new float[10];
        private readonly UInt32[] animatedX = new UInt32[10];

        // Start this window with a ref to the hardware that generates the data for display
        public MainWindow(ref ClassController controller)
        {
            InitializeComponent();
            // Keep a local copy to the hardware object..
            hardwareDataCollector = controller;
        }
 
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // Init the Controller object - this collects the data.
            hardwareDataCollector.Launch();
            // Setup the datasources
            animatedDataSourceX = new EnumerableDataSource<UInt32>(animatedX);
            animatedDataSourceX.SetXMapping(x => x);
            animatedDataSourceY = new EnumerableDataSource<float>(animatedY);
            animatedDataSourceY.SetYMapping(y => y);
           
            // Try o Try to stop the stuptid thing from zooming in on the y axis..
            //
            // This seems to do bugger all!
              //VoltageChart.Viewport.MaxHeight = 10000;
              //VoltageChart.Viewport.Restrictions.Add(new MaxSizeRestriction { IsActive = true });

            // This gives a nice margin above and below the line.. but not really what I need
              //VoltageChart.Viewport.Restrictions.Add(new PhysicalProportionsRestriction { ProportionRatio = .5 });

            // This fixes the chart.. but it affects BOTH axis.. not good for a timestamp that keeps getting bigger!!
              //DataRect visible = new DataRect(0, 0, 50000, 50000);
              //VoltageChart.Visible = visible;
           
            VoltageChart.AddLineGraph(new CompositeDataSource(animatedDataSourceX, animatedDataSourceY),
                new Pen(Brushes.Red, 3),
                new PenDescription("VMon)"));

            // Initalise timer for screen update..
            textUpdateTimer.Interval = TimeSpan.FromMilliseconds(50);
            textUpdateTimer.Tick += new EventHandler(timer_Tick);
            textUpdateTimer.IsEnabled = true;

            // Initalise timer for graph update..
            graphUpdateTimer.Interval = TimeSpan.FromMilliseconds(100);
            graphUpdateTimer.Tick += new EventHandler(graphTimer_Tick);
            graphUpdateTimer.IsEnabled = false;
        }


        void graphTimer_Tick(object sender, EventArgs e)
        {
            ConcurrentQueue<RegulatingParams>[] arrayResults;
            // Collect the information from the converter about the last couple of seconds
            arrayResults = hardwareDataCollector.GetConverterMesasurmentsDataset();
            // Take one stram of data from the hardware.. and update the array that is associated with the CompositeDataSource
            int index = 0;
            foreach (RegulatingParams data in arrayResults[1])
            {
                animatedY[index] = data.VMon; // The voltage
                animatedX[index] = (UInt32)data.Timestamp; // The timestamp .. increments upwards in ms. Does not reset.
                index++;
            }
            // now all the data has been updated in the array, raise a notification that updates the display
            // Dont know if we need to do this on both arrays??
            animatedDataSourceX.RaiseDataChanged();
            animatedDataSourceY.RaiseDataChanged();
        }
    }

Oct 14, 2011 at 6:02 PM

OK.. progress.. this is what I did..
Got the nightly build from:
http://d3commdev.codeplex.com/SourceControl/changeset/changes/4274
Fixed missing assembly compile errors by browsing to the DLLs  (ShaderBuildTask.dll, System.Threading.dll etc..) in d3commdev-4274\DynamicDataDisplay.DirectX2D\Libraries
Copied the denerated DLL into my project.

Then.. followed the advice of sascharu:
http://dynamicdatadisplay.codeplex.com/discussions/210225

I created a subclass of ViewportRestriction

 

public class HWZoomRestriction : ViewportRestriction
    {
    private double _xmaxval = 0;
        private double _xsize = 0;
        private double _ysize = 0;

        public HWZoomRestriction(double xmaxval, double xsize, double ysize)
            : base()
        {
            _xmaxval = xmaxval;
            _xsize = xsize;
            _ysize = ysize;
        }

        public double XMaxValue
        {
            get { return _xmaxval; }
            set
            {
                if (_xmaxval != value)
                {
                    _xmaxval = value;
                    RaiseChanged();
                }
            }
        }

        public double XSize
        {
            get { return _xsize; }
            set
            {
                if (_xsize != value)
                {
                    _xsize = value;
                    RaiseChanged();
                }
            }
        }

        public double YSize
        {
            get { return _ysize; }
            set
            {
                if (_ysize != value)
                {
                    _ysize = value;
                    RaiseChanged();
                }
            }
        }

        public override DataRect Apply(DataRect previousDataRect, DataRect proposedDataRect, Viewport2D viewport)
        {
            DataRect newRect = new DataRect();
            if (XMaxValue - XSize > 0)
            {
                newRect.XMin = XMaxValue - XSize;
            }
            else
            {
                newRect.XMin = 0;
            }
            newRect.Width = XSize;
            newRect.YMin = 0;
            newRect.Height = YSize;

            return newRect;
        }
    }

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        // Application specific code
        private ClassController hardwareDataCollector;
        // Timers to trigger updates on the UI
        private readonly DispatcherTimer textUpdateTimer = new DispatcherTimer();
        private readonly DispatcherTimer graphUpdateTimer = new DispatcherTimer();
        // The Datasources charded on the graph
        private EnumerableDataSource<float> animatedDataSourceY = null;
        private EnumerableDataSource<UInt32> animatedDataSourceX = null;
        // These arrays are attacted to the datasource in 'Window_Loaded()'
        private readonly float[] animatedY = new float[300];
        private readonly UInt32[] animatedX = new UInt32[300];
        // Viewport settings
        HWZoomRestriction voltageViewport;

        // Start this window with a ref to the hardware that generates the data for display
        public MainWindow(ref ClassController controller)
        {
            InitializeComponent();
            // Keep a local copy to the hardware object..
            hardwareDataCollector = controller;
        }
 
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // Init the Controller object - this collects the data.
            hardwareDataCollector.Launch();
            // Setup the datasources
            animatedDataSourceX = new EnumerableDataSource<UInt32>(animatedX);
            animatedDataSourceX.SetXMapping(x => x);
            animatedDataSourceY = new EnumerableDataSource<float>(animatedY);
            animatedDataSourceY.SetYMapping(y => y);
           
            // Set the init viewport
            voltageViewport = new HWZoomRestriction(0, 3000, 6000);
            VoltageChart.Restrictions.Add(voltageViewport);
            // Add the VMon to the graph
            VoltageChart.AddLineGraph(new CompositeDataSource(animatedDataSourceX, animatedDataSourceY),
                new Pen(Brushes.Red, 1),
                new PenDescription("VMon"));

            // Initalise timer for screen update..
            textUpdateTimer.Interval = TimeSpan.FromMilliseconds(50);
            textUpdateTimer.Tick += new EventHandler(timer_Tick);
            textUpdateTimer.IsEnabled = true;

            // Initalise timer for graph update..
            graphUpdateTimer.Interval = TimeSpan.FromMilliseconds(100);
            graphUpdateTimer.Tick += new EventHandler(graphTimer_Tick);
            graphUpdateTimer.IsEnabled = false;
        }

        void graphTimer_Tick(object sender, EventArgs e)
        {
            ConcurrentQueue<RegulatingParams>[] arrayResults;
            // Collect the information from the converter about the last couple of seconds
            arrayResults = hardwareDataCollector.GetConverterMesasurmentsDataset();
            // Take one stram of data from the hardware.. and update the array that is associated with the CompositeDataSource
            // Last timestamp
            UInt32 lasttimestamp=0;
            int index = 0;
            foreach (RegulatingParams data in arrayResults[1])
            {
                if (index < animatedY.Length && index < animatedX.Length)
                {
                    animatedY[index] = data.VMon; // The voltage
                    animatedX[index] = (UInt32)(data.Timestamp&0xFFFFFFFF); // The timestamp .. increments upwards in ms. Does not reset.
                    lasttimestamp = (UInt32)data.Timestamp;
                }
                else
                {
                    index = index;
                }
                index++;
            }
            // now all the data has been updated in the array, raise a notification that updates the display
            // Dont know if we need to do this on both arrays??
            voltageViewport.XMaxValue = lasttimestamp;

            animatedDataSourceX.RaiseDataChanged();
           // animatedDataSourceY.RaiseDataChanged(); // dont think you need to do this..?
        }
    }

 

Oct 22, 2013 at 1:41 PM
Hi,

How can i implement this solution into a normal double array which is received from serial port and show the received time?

Regards
Ebru