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.
där addPoints och updatePlot metoderna i plotrealtime klassen är:
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.
Kod:
PicoStreaming består av flera undermetoder: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"); } }
Kod:
Alla dessa metoder funkar bra tills vi kommer till GetLAtestValues där de ska plottas i realtidpublic 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(); } }
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.