Vinnaren i pepparkakshustävlingen!
2018-01-19, 16:52
  #1
Medlem
Det är så att jag försöker läsa av värdena från en sensor Pico 5000 för att vara exakt. När användaren trycker på streaming skall hen se en plott av mätvärdena i realtid.

Kod:
        private async void btnStreaming_Click(object sender, EventArgs e)
        {
            if (PicoSetup != null && Condition())
            {
                await Task.Run(() => PicoSetup.Streaming());
            }
            else
            {
                MessageBox.Show("Click on Open first");
            }


        }
PicoStreaming består av flera undermetoder:
Kod:
        public void Streaming()
        {
            if (_handle != 0)
            {
                // Find Max to scaling
                FindMax();

                // Set the channel
                SetChannel();

                // Set buffering()
                SetBuffer();

                // Set up Streaming
                SetStreaming();

                // Get latest value
                GetLatestValues();

            }
        }
Alla dessa metoder funkar bra tills vi kommer till GetLAtestValues där de ska plottas i realtid
Kod:
private void GetLatestValues()
        {

            // Initial values of sample and triggers
            Thread.Sleep(0);

            plotRealTime = new PlotRealTime();

            int totalSamples = 0;
            uint triggeredAt = 0;
            _ready = false;


            // Get the latest value for one channel.
            uint status;
            status = Imports.GetStreamingLatestValues(_handle, streamingCallback, IntPtr.Zero);

            // Place for values
            maxValue = new int[_startIndex + _sampleCount];
            minValue = new int[_startIndex + _sampleCount];


            // Initiate the graph
            plot Plot = new plot();



            // Tell user
            //int sampleTimeStreaming;
            while (!_autoStop)
            {
                Thread.Sleep(0);
                appBuffersPinned[0] = new PinnedArray<short>(buffers[0]);

                if (_ready && _sampleCount > 0)
                {
                    if (_trig > 0)
                    {
                        triggeredAt = (uint)totalSamples + _trigAt;
                    }
                    totalSamples += _sampleCount;

                    for (uint i = _startIndex; i < (_startIndex + _sampleCount); i++)
                    {
                        int maxValue = adc_to_mv(appBuffersPinned[0].Target[0], inputRanges[SelChannelIndex]);

                        int sampleTimeStreaming = (int)(1 * SampleInterval);


                        plotRealTime.addPoints(maxValue, sampleTimeStreaming);
                        plotRealTime.updatePlot();
                       

                        //minValue[i] = adc_to_mv(appBuffersPinned[1].Target[i], (int)_channelSettings[0].range);
                    }

                }
            }
        }

där addPoints och updatePlot metoderna i plotrealtime klassen är:
Kod:
using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Series;
using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Windows.Media;
using System.Windows.Threading;

namespace PVLab
{
    public partial class PlotRealTime : Form
    {
        private readonly LineSeries _lineSeries1 = new LineSeries();
        private readonly LineSeries _lineSeries2 = new LineSeries();
        private readonly Stopwatch _stopwatch = new Stopwatch();
        private readonly LinearAxis _xAxis = new LinearAxis();
        private readonly LinearAxis _yAxis = new LinearAxis();
        private IPlotController _controller;
        private bool _haveNewPoints;
        private long _lastUpdateMilliseconds;
        private int _xMax;
        private int _yMax;
        DispatcherTimer timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(0.001) };

        PlotModel myModel;
        //public PlotModel PlotModel { get; private set; }

        public PlotRealTime()
        {
            InitializeComponent();
            initPlot();
            addPoints();
            updatePlot();
            _stopwatch.Start();
        }

        public IPlotController Controller
        {
            get
            {
                if (_controller == null)
                {
                    // show tracker with mouse move
                    _controller = new PlotController();
                    _controller.BindMouseEnter(PlotCommands.HoverPointsOnlyTrack);
                }
                return _controller;
            }
        }



        public PlotModel PlotModel { get; set; }

        private void addLineSeries1()
        {
            _lineSeries1.MarkerType = MarkerType.Circle;
            _lineSeries1.StrokeThickness = 2;
            _lineSeries1.MarkerSize = 3;
            _lineSeries1.Title = "Start";
            _lineSeries1.MouseDown += (s, e) =>
            {
                if (e.ChangedButton == OxyMouseButton.Left)
                {
                    PlotModel.Subtitle = "Index of nearest point in LineSeries: " + Math.Round(e.HitTestResult.Index);
                    PlotModel.InvalidatePlot(false);
                }
            };
            PlotModel.Series.Add(_lineSeries1);
        }

        private void addLineSeries2()
        {
            _lineSeries2.MarkerType = MarkerType.Circle;
            _lineSeries2.Title = "End";
            _lineSeries2.StrokeThickness = 2;
            _lineSeries2.MarkerSize = 3;

            PlotModel.Series.Add(_lineSeries2);
        }

        public void addPoints(int sample, int sampleTime)
        {
            var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(0.001) };
            timer.Tick += (sender, args) =>
            {
                var x = sampleTime;
                updateXMax(x);
                var y = sample;
                updateYMax(y);

                _lineSeries1.Points.Add(new DataPoint(x, y));

                _haveNewPoints = true;
            };
            timer.Start();

        }

        private void addXAxis()
        {
            _xAxis.Minimum = 0;
            _xAxis.MaximumPadding = 1;
            _xAxis.MinimumPadding = 1;
            _xAxis.Position = AxisPosition.Bottom;
            _xAxis.Title = "X axis";
            _xAxis.MajorGridlineStyle = LineStyle.Solid;
            _xAxis.MinorGridlineStyle = LineStyle.Dot;
            PlotModel.Axes.Add(_xAxis);
        }

        private void addYAxis()
        {
            _yAxis.Minimum = 0;
            _yAxis.Title = "Y axis";
            _yAxis.MaximumPadding = 1;
            _yAxis.MinimumPadding = 1;
            _yAxis.MajorGridlineStyle = LineStyle.Solid;
            _yAxis.MinorGridlineStyle = LineStyle.Dot;
            PlotModel.Axes.Add(_yAxis);
        }

        private void createPlotModel()
        {

            PlotModel = new PlotModel
            {
                Title = "سرى خطوط",
                Subtitle = "Pan (right click and drag)/Zoom (Middle click and drag)/Reset (double-click)"
            };
            PlotModel.MouseDown += (sender, args) =>
            {
                if (args.ChangedButton == OxyMouseButton.Left && args.ClickCount == 2)
                {
                    foreach (var axis in PlotModel.Axes)
                        axis.Reset();

                    PlotModel.InvalidatePlot(false);
                }
            };
        }

        private string getCustomTooltip(TrackerHitResult hitResult)
        {
            var lineSeries = hitResult.Series as LineSeries;
            var nearestPointIndex = hitResult.Index;
            return "nearestPointIndex: " + nearestPointIndex;
        }

        private void initPlot()
        {
            createPlotModel();
            addXAxis();
            addYAxis();
            addLineSeries1();

        }

        public void updatePlot()
        {
            CompositionTarget.Rendering += (sender, args) =>
            {
                if (_stopwatch.ElapsedMilliseconds > _lastUpdateMilliseconds + 2000 && _haveNewPoints)
                {
                    if (_yMax > 0 && _xMax > 0)
                    {
                        _yAxis.Maximum = _yMax + 3;
                        _xAxis.Maximum = _xMax + 1;
                    }

                    PlotModel.InvalidatePlot(false);

                    _haveNewPoints = false;
                    _lastUpdateMilliseconds = _stopwatch.ElapsedMilliseconds;
                }
            };
        }

        private void updateXMax(int value)
        {
            if (value > _xMax)
            {
                _xMax = value;
            }
        }

        private void updateYMax(int value)
        {
            if (value > _yMax)
            {
                _yMax = value;
            }
        }



    }


}

Problemet är att varje gång en punkt tilläggas så skapas en ny timer och compostion Target renderas varje 2 sek. Jag skulle vilja göra så att kompositen uppdateras varje gång det kommer en nytt värde samt att det ska skapas så många timer. Jag vet inte hur jag kan komma runt det här så att hela programmet inte fryser. Problemet nu är att programmet fryser och inte visar några grafer alls. Uppskattar om någon kunde ge mig en ledtråd.
Citera
2018-01-23, 00:13
  #2
Medlem
Kallan.s avatar
Problemet med att det fryser är för att du ockuperar tråden som sköter fönsterhanteringen.

Du får sköta Streaming() och övriga funktioner i en separat tråd.

Googla C# Threads.

När det gäller problemet att den inte ritar ut något så kan jag inte svara på det. Det kanske löser sig när du trådar om du har tur.
Citera
c#

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback