2011-10-18 3 views
1

Je suis en communication avec l'appareil utilisant SerialPort. L'appareil a RS-485, de l'autre côté (PC) est RS-232 (port virtuel). L'appareil fonctionne, envoie et reçoit des données correctement.L'événement DataReceived ne se déclenche parfois pas

Le problème est que l'événement DataReceived n'est parfois pas déclenché. J'envoie des données à l'appareil en utilisant System.Timer, une fois toutes les 10 secondes. La plupart du temps cela fonctionne bien, mais toutes les 1-10 minutes je n'ai pas de réponse, puis, après 2-4 fois plus l'événement DataReceived est finalement déclenché et j'obtiens un groupe de données (tout ce que j'ai précédemment "demandé" car est dans le tampon). La question est: Comment est-ce possible? Je ne peux pas mettre d'exemple de code ici, je suis désolé, mais il n'y a pas de multithreading dans mon application (seulement le thread principal et les threads avec les événements Timer_Elapsed et DataReceived, je pense qu'ils sont élevés sur des threads séparés) mon événement DataReceived est traité rapidement et ne doit pas être déclenché en parallèle (10 secondes suffisent, le temps de réponse de l'appareil est inférieur à 1 seconde). Si j'utilise Thread.Sleep, c'est dans des endroits où je suis sûr que ça ne va pas interférer avec quoi que ce soit. Il peut s'agir plus d'un problème de matériel que de logiciel, car le port COM fonctionne de la même manière lorsque je le teste en utilisant d'autres applications (l'une d'entre elles, que le fabricant du périphérique a fournie pour tester la connexion, ne le fait pas). on dirait qu'il a été écrit en C#). Mais je ne suis pas très bon avec le matériel. Peut-être qu'il y a un problème avec le PC ou le port COM (ce n'est pas intégré mais externe)? Ou peut-il s'agir d'une chose liée au système d'exploitation (mon application est un service Windows fonctionnant sous Windows Server 2003).

Répondre

1

Il s'est avéré que c'était un problème matériel.

La connexion Situés entre appareils ressemble à ceci: appareil <> RS-485 <> Converter1 <> LAN <> Converter2 <> RS-232 <> Ordinateur <> COM virtuel

Converter1 semble mal fonctionner, Il regroupe et conserve les données que mon appareil lui envoie. Maintenant, je sais ce qui ne va pas, je peux laisser les gens compétents en prendre soin :)

Merci @Matthew Rodatus pour votre aide. Votre réponse de manière détournée m'a guidé pour vérifier exactement et quand exactement vient à mon COM.

+0

pourquoi ne lui donnez-vous pas un upvote alors? – jgauffin

+0

Pas de problème, @Arie. Je suis content que vous l'aillez compris. –

3

Il me semble que le tampon n'est pas vidé quand vous vous attendez.

L'événement DataReceived n'est pas garanti d'être déclenché pour chaque octet reçu. Utilisez la propriété BytesToRead pour déterminer combien de données reste à lire dans le tampon.

Voir http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.datareceived.aspx

(BTW, l'événement DataReceived est en effet élevé sur un fil secondaire.)

Avez-vous essayé les peaufinage ReadBufferSize et ReceivedBytesThreshold propriétés? C'est là que je commencerais à enquêter. Connaissez-vous la taille approximative des messages? Vous voulez probablement définir la propriété ReceivedBytesThreshold juste en dessous de la taille de message minimale que vous prévoyez recevoir de l'appareil. Ensuite, vous aurez peut-être besoin d'une courte période d'attente pour obtenir les derniers octets pour compléter le message.

+0

ReceivedBytesThreshold = 1 dans mon application (par défaut). MSDN dit que ReadBufferSize ne peut pas être plus petit que 4096. Bizarrement, j'ai deux autres services Windows qui communiquent avec le port COM (un type d'appareil légèrement différent, connecté à l'ordinateur par un simple RS-232) fonctionnant sur la même machine. re fonctionne bien. Les événements sont levés et exécutés correctement dans leur cas. La base de code pour tous les 3 est la même, avec quelques modiffications pour la 3ème. La structure du programme assure qu'aucune donnée n'arrive avant la fin de l'exécution de l'événement DataReceived précédent. – Arie