2013-02-15 2 views
-2

Je suis en train de tester le signal en temps réel, le signal en fonction du temps, avec WPF et C# (Dynamic Data Display); Une fois qu'un signal est généré, il doit apparaître instantanément sur un graphique à courbes; Le signal peut être généré très rapidement (de l'ordre de la millième de seconde (0,001 seconde)); Quelle serait la meilleure façon de le faire? Toute suggestion est appréciée. Merci.Comment tracer un signal en temps réel dans WPF et C# .net 3.5?

EDIT: Un exemple de code sera très apprécié.

Voici ce que j'ai essayé:

Terrain initiation:

#region Constructor 
public SignalStatsDisplay() 
{ 
    InitializeComponent(); 

    plotter.Legend.Remove(); 

    _initialChildrenCount = plotter.Children.Count; 

    int count = plotter.Children.Count; 

    //do not remove the initial children 
    if (count > _initialChildrenCount) 
    { 
     for (int i = count - 1; i >= _initialChildrenCount; i--) 
     { 
      plotter.Children.RemoveAt(i); 
     } 
    } 

    _nColorChannels = 4; 

    _lineprofileColor = new Color[4]; 

    _lineprofileColor[0] = Colors.Transparent; 
    _lineprofileColor[1] = Colors.Red; 
    _lineprofileColor[2] = Colors.Black; 
    _lineprofileColor[3] = Colors.Blue; 


    //LineGraph lg = new LineGraph(); 
    LineAndMarker<MarkerPointsGraph> lg = new LineAndMarker<MarkerPointsGraph>(); 
    CirclePointMarker pm = new CirclePointMarker { Size = 10, Fill = Brushes.Green }; 

    // MarkerPointsGraph mpg = new MarkerPointsGraph(); 

    if (_nColorChannels > 0) // plotter init 
    { 
     _dataX = new List<int[]>(); 
     _dataY = new List<int[]>(); 

     int[] dataXOneCh = new int[1]; 
     int[] dataYOneCh = new int[1]; 

     dataXOneCh[0] = 0; 
     dataYOneCh[0] = 0; 

     /*CirclePointMarker marker = new CirclePointMarker(); 
     marker.Fill = new SolidColorBrush(_lineprofileColor[0]); 
     marker.Pen = new Pen(marker.Fill, 0); 

     marker.Size = 2; 
     int lineWidth = 1;*/ 




     for (int i = 0; i < 4; i++) 
     { 
      _dataX.Add(dataXOneCh); // data x-y mapping init 
      _dataY.Add(dataYOneCh); 

      EnumerableDataSource<int> xOneCh = new EnumerableDataSource<int>(dataXOneCh); 
      EnumerableDataSource<int> yOneCh = new EnumerableDataSource<int>(dataYOneCh); 

      xOneCh.SetXMapping(xVal => xVal); 
      yOneCh.SetXMapping(yVal => yVal); 

      CompositeDataSource dsOneCh = new CompositeDataSource(xOneCh, yOneCh); 

      // LineProfileColorSetup(); 

      lg = plotter.AddLineGraph(dsOneCh,      
       (new Pen(Brushes.Green, 2)), 
       pm, 
       (new PenDescription("Data"))); 

      // lg = plotter.AddLineGraph(dsOneCh, 
      // Colors.Transparent, 
      // 2, 
      // "Data"); 

      // pm.FilteringEnabled = false; 

     } 

     plotter.FitToView(); 
    } 
    else 
    { 
     return; 
    } 
} 

mise à jour des données:

for (int i = 0; i < 1; i++) 
       { 
        if (_dataX[i].Length == _dataY[i].Length) 
        { 
         EnumerableDataSource<int> xOneCh = new EnumerableDataSource<int>(_dataX[i]); 
         xOneCh.SetXMapping(xVal => xVal); 
         EnumerableDataSource<int> yOneCh = new EnumerableDataSource<int>(_dataY[i]); 
         yOneCh.SetYMapping(yVal => yVal); 
         CompositeDataSource ds = new CompositeDataSource(xOneCh, yOneCh); 

         Action UpdateData = delegate() 
         { 
          // ((LineGraph)plotter.Children.ElementAt(startIndex + i)).DataSource = ds; 
          // ((LineGraph)plotter.Children.ElementAt(startIndex + i)).LinePen = new Pen(new SolidColorBrush(Colors.Green), 1); 
          // ((PointsGraphBase)plotter.Children.ElementAt(startIndex + i)).DataSource = ds; 
          ((PointsGraphBase)plotter.Children.ElementAt(startIndex + i + 1)).DataSource = ds; 

          // } 
          // (plotter.Children.ElementAt(startIndex + i)).DataSource = ds; 

         }; 

         this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, UpdateData); 
        } 
       } 

Le problème que j'ai est quand le signal est en gras très, disent une nouvelle le signal est généré à chaque millième de seconde, il semble que le graphique ne génère un nouveau marqueur que toutes les secondes, ce que je ne comprends pas.

L'idée de base est de générer un plotter.AddLineGraph, puis seulement mettre à jour le DataSource. Mais cela ne semble pas fonctionner. J'ai donc pensé que je suis peut-être dans la mauvaise direction.

Je ne suis pas un expert C# ou WPF. Lorsque LineAndMarker ne fonctionne pas comme prévu, j'ai commencé à douter. Donc, je me demande quelle serait la façon générale pour les gens d'afficher le signal en temps réel (changement rapide, intervalle de temps entre les échantillons pourrait être sur mili-seconde) en utilisant WPF et C#.

+0

De quel type de signal parlez-vous? Comment voulez-vous générer le signal? Avez-vous un code ??? –

+0

Je me demande si cela a de l'importance? –

+0

@NickTsui: Il pourrait. Si vous essayez d'ajouter des points tous les ms, il sera difficile de suivre le rythme. Donc la question est, avez-vous besoin de toutes les données? Pourriez-vous tracer juste chaque * nième * point? Avez-vous besoin d'enregistrer toutes les données? Toutes les données doivent-elles être conservées en mémoire? –

Répondre

0

J'ai trouvé où j'ai mal fait. Voici la partie où le problème se produit:

_pxlValAllChan[0, signalIndex] = pxlValue; 
               DateTime currentTime = DateTime.Now; //has to come from real file: Tiff 
               TimeSpan timeSpan = currentTime - _startTime; 

               _timeStampAllChan[0, signalIndex] = Convert.ToInt16(timeSpan.TotalSeconds); 


               _pxlValOneChan = new int[_signalLength]; // no need to new it every time 
               _timeStampOneChan = new int[_signalLength]; 
               for (int i = 0; i <= signalIndex; i++) 
               { 
                _pxlValOneChan[i] = _pxlValAllChan[0, i]; 
                //_timeStampOneChan[i] = _timeStampAllChan[0, i]; 
                _timeStampOneChan[i] = i; 
               } 

               _signalDisplay.SetData(_timeStampOneChan, _pxlValOneChan, 0, true); 

Mes données x étaient basées sur l'heure. Je considère fondamentalement l'initiation du programme comme point de départ, puis je garde la trace du temps qui s'écoule en soustrayant l'heure de départ à l'heure actuelle. Ensuite, le temps écoulé est sauvegardé en tant que données de l'axe x (voir la ligne qui est mise en commentaire). Et cela cause réellement un problème. Quand je change simplement les données de l'axe x en tant qu'index, le problème est parti. La mise à jour du graphique assez rapidement. Bien que je n'ai pas compris comment je devrais changer la logique pour toujours utiliser le temps s'écouler comme mes données d'axe des x, mais c'est le coupable de mise à jour lente sur le graphique.