2017-06-13 1 views
0

J'ai écrit une application C# simple (ou si je pensais) pour lire les données série et les tracer dans un contrôle de jauge de formulaires de gain. Les lignes de données en série se produisent à intervalles de 5 secondes. Le problème est, l'application arrête de mettre à jour le graphique après un certain nombre de mises à jour, et je ne peux pas comprendre ce qui se passe. Voici le code:C# numéro de série de communications (threads?)

using System; 
using System.IO.Ports; 
using System.Windows.Forms; 

namespace SimplifiedTempChart 
{ 
    public partial class Form1 : Form 
    { 
     float frcvdata; 
     float test;   
     public delegate void DisplayTempChartDelegate(float temperature); 
     public DisplayTempChartDelegate _DisplayTempChart; 

     public Form1() 
     { 
      InitializeComponent();    
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      _DisplayTempChart = new DisplayTempChartDelegate(DisplayTempChart); 
     } 

     private void serialDataReceivedEventHandler(object sender, SerialDataReceivedEventArgs e) 
     { 
      SerialPort sData = sender as SerialPort; 
      string recvData = sData.ReadExisting(); 
      float.TryParse(recvData, out frcvdata); 
      test = frcvdata * 100; 
      gaugeControl1.Invoke((MethodInvoker)delegate { _DisplayTempChart(test); }); 
     } 

     public void DisplayTempChart(float temperature) 
     { 
      gaugeControl1.SetPointerValue("Scale1", "Pointer1", temperature); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      SerialPort aSerialPort = new SerialPort("COM17"); 
      aSerialPort.BaudRate = 9600; 
      aSerialPort.Parity = Parity.None; 
      aSerialPort.StopBits = StopBits.One; 
      aSerialPort.DataBits = 8; 
      aSerialPort.Open(); 
      aSerialPort.DataReceived += new SerialDataReceivedEventHandler(serialDataReceivedEventHandler); 
     } 
    } 
} 

J'ai ajouté un point d'arrêt pour indiquer quand le serialDataReceivedEventHandler est frappé. Voici la sortie de débogage pour une session:

serialDataReceivedEventHandler a frappé serialDataReceivedEventHandler a frappé serialDataReceivedEventHandler a frappé serialDataReceivedEventHandler a frappé serialDataReceivedEventHandler a frappé serialDataReceivedEventHandler a frappé serialDataReceivedEventHandler frappé Le fil 0x1a04 est sorti avec le code 0 (0x0). serialDataReceivedEventHandler hit hit serialDataReceivedEventHandler serialDataReceivedEventHandler hit hit serialDataReceivedEventHandler serialDataReceivedEventHandler hit hit serialDataReceivedEventHandler serialDataReceivedEventHandler frappé Le 0x2200 de fil est sorti avec le code 0 (0x0). serialDataReceivedEventHandler a frappé serialDataReceivedEventHandler a frappé serialDataReceivedEventHandler a frappé serialDataReceivedEventHandler frappé Le 0x22fc fil est sorti avec le code 0 (0x0). serialDataReceivedEventHandler hit hit serialDataReceivedEventHandler serialDataReceivedEventHandler hit hit serialDataReceivedEventHandler serialDataReceivedEventHandler hit hit serialDataReceivedEventHandler serialDataReceivedEventHandler frappé Le 0x1720 de fil est sorti avec le code 0 (0x0). Le thread 0x18a8 s'est terminé avec le code 0 (0x0). Le thread 0xed0 s'est terminé avec le code 0 (0x0). Le thread 0xf74 s'est terminé avec le code 0 (0x0). Le thread 0x5b4 s'est terminé avec le code 0 (0x0). Le thread 0x1b7c s'est terminé avec le code 0 (0x0). Le thread 0x1d2c s'est terminé avec le code 0 (0x0). Les événements 'thread existant' s'empilent réellement lorsque l'application arrête de mettre à jour le graphique. Cela semble suspect, mais je ne suis pas sûr et je ne comprends pas comment résoudre ce problème.

Je peux redémarrer la mise à jour du graphique en cliquant simplement sur button1 dans le formulaire.

Quelqu'un peut-il aider?

Répondre

1

Je pense que votre aSerialPort instance est en cours ordures recueillies au début. Vous le déclarez en tant que variable locale, de sorte qu'il devient possible de récupérer les ordures dès que votre gestionnaire button_1_Click se ferme.

Essayez de déclarer aSerialPort comme membre de la classe Form à la place afin de rooter la référence et d'éviter qu'elle soit collectée par la corbeille.

0

Je ne sais pas ce que le problème de communication est, mais

float.TryParse(recvData, out frcvdata); 
test = frcvdata * 100; 

est pas bon. Fondamentalement, vous dites, "essayez d'analyser recvData mais peu importe ce qui se passe, peu importe le résultat, même s'il n'a pas analysé, multipliez le résultat par 100."

Essayez plutôt:

bool parsed = float.TryParse(recvData, out frcvdata); 
if (parsed) 
{ 
    test = frcvdata * 100.0; 
    // invoke your delegate with known good data... 
} 
else 
    // do something else with parse failure, 
    // maybe print it so you can see why the parse to float failed? 
+0

bon point. Je suis allé de l'avant et inclus cela juste pour être sûr, mais il n'y a pas eu d'échecs d'analyse et le problème existe toujours. –

+0

Quelle est la taille de la valeur frcvdata? Multiplier un très grand nombre par 100 peut donner une erreur en virgule flottante avec une exception. – jdweng

+0

0.0