Serial com RS232 - problème temps de réponse

cs_jeanmi45 Messages postés 27 Date d'inscription mercredi 31 mars 2004 Statut Membre Dernière intervention 6 avril 2010 - 7 nov. 2009 à 13:27
Adn56 Messages postés 1172 Date d'inscription jeudi 24 mai 2007 Statut Membre Dernière intervention 28 septembre 2013 - 29 janv. 2010 à 17:24
Bonjour à tous,

J'ai 2 applis qui tournent en même temps sur le même processeur (quad core)

Le principe est très simple - j'utilise une carte de com avec 8 ports:

la première appli envoit sur le port com (19200,n,8,1) une trame ascii, quand la 2ème la reçoit, elle répond avec une trame ascii vers la première et ainsi de suite.

J'utilise tout bêtement l'événement DataReceived dans les 2 appli en ayant paramétré le threshold sur les ports.

Mon pb est que je vois que ma cadence d'aller - retour est très médiocre (environ 57000 par heure). j'ai besoin de monter à 100000 minimum.

- question de fond: l'évènement "datareceived" lance t il bien une tache secondaire dédiée à ça comme semble le dire microsoft ?


J'ai essayé une autre manip: l'appli 1 a une tache de fond qui va srcuter en // que le temps de réponse est bon. L'évènement "datareceived" met à jour une variable, cette tache de fond regarde si la réponse a été faite des les temps (utilisation threed.sleep).
Et là même constat, si je suis trop contraignant au niveau sleep(<80ms), j'ai des non réponses.

Des idées ?
A voir également:

9 réponses

cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
7 nov. 2009 à 16:36
Salut
Je ne saurais te répondre sur la question .Net, mais sur le principe :
Pourquoi ne pas avoir utiliser les sockets ?
Ils sont beaucoup plus performants en terme de temps de réponse.
9600 bits/sec, ça ne fait que 1200 caractères à la seconde et ces caractères ne correspondnet pas à la quantité de Data, mais de la trame entière, avec Stop Bit, contrôle de flux, CRC, etc.
Certains diront que c'est déjà pas mal, mais on ne sait pas les quantités de données que tu transfères.
Le principe des Sockets est pratiquement le même qu'un port COM : L'évènement DataArrival se déclenche dès qu'il y a des données disponibles ET que la machine a le temps de donner la main au programme.
Le DataReceived : dans mes souvenirs, tu pouvais paramétrer la quantité de données à attendre dans le buffer avant de délcencher cet évènement. Si ce réglage est trop bas, ton programme n'aura que peu de données à traiter et fera perdre du temps à la machine. S'il est trop haut, tu risques d'attendre des données courtes qui sont présentes dans le buffer mais insuffisantes pour déclencher l'évènement.

Avantage des sockets : Rapidité et garantie du transfert (si TCP)
Inconvénient : Les flux des sockets peuvent être interceptés par les parefeux et créer des problèmes lors des installations.

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
0
cs_jeanmi45 Messages postés 27 Date d'inscription mercredi 31 mars 2004 Statut Membre Dernière intervention 6 avril 2010
7 nov. 2009 à 16:45
Merci Jack, mais la liaison RS est impértive car liée au matériel qui ne possède que ce moyen de com. La qté de données est ridicule, à savoir 9 caractères ascii ds un sens et 1 caractère ascii dans l'autre. Donc le traitement est ridicule je pense.
D'où mon incompréhension quand à la vitesse de tout ça qui me semble trop faible. Je pense que je traine qq chose....
0
Adn56 Messages postés 1172 Date d'inscription jeudi 24 mai 2007 Statut Membre Dernière intervention 28 septembre 2013 1
8 nov. 2009 à 16:38
Salut, j'utilse aussi les ports rs232, mais j'ai jamais eu à faire ta course au débit ^^
Pour le datareceived c'est bien un second thread . Il te suffit par exemple de ne pas envoyer ta fin de trame (crlf en régle général) pour voir ton appli principal bloqué.
Tu as pensé à paramétrer ta fin de trame ? ou tu lis les bytes dés qu'il arrivent ?
Ex :
    Private Sub SerialPort4_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort4.DataReceived
        Try
            buffer = SerialPort4.ReadLine()
        Catch ex As Exception
        End Try
    End Sub lit la ligne entiére défini par la fin de trame

paramétrage des ports com via un fichier ini :
        ' Configuration du port série utilisé par le module secheur
        Try
            With SerialPort3
                .PortName = LireINI("com3", "Portname")
                .BaudRate = CInt(LireINI("com3", "Vitesse"))
                .DataBits = CInt(LireINI("com3", "Databits"))
                .StopBits = CType(LireINI("com3", "Stopbit"), Ports.StopBits)
                .Handshake = CType(LireINI("com3", "protocole"), Ports.Handshake)
                .NewLine = vbCrLf 'Chr(10) & Chr(13) ' défini la fin de trame (CR+LF) différent de vbcrlf !
                .Open()
            End With
        Catch ex As Exception
            MsgBox("COM3 plus disponible", MsgBoxStyle.Critical)
        End Try
        ' Configuration du port série utilisé par le module mousse
        Try
            With SerialPort4
                .PortName = LireINI("com4", "Portname")
                .BaudRate = CInt(LireINI("com4", "Vitesse"))
                .DataBits = CInt(LireINI("com4", "Databits"))
                .StopBits = CType(LireINI("com4", "Stopbit"), Ports.StopBits)
                .Handshake = CType(LireINI("com4", "protocole"), Ports.Handshake)
                .NewLine = Chr(32) & Chr(60) ' défini la fin de trame du th200
                .Open()
            End With
        Catch ex As Exception
            MsgBox("COM4 plus disponible", MsgBoxStyle.Critical)
        End Try

@ ++
0
Adn56 Messages postés 1172 Date d'inscription jeudi 24 mai 2007 Statut Membre Dernière intervention 28 septembre 2013 1
8 nov. 2009 à 16:43
Pour l'écriture lecture j'ai bidouillé une petite boucle, c'est pas top jolie mais c'est efficasse

    Private Function lecturePoids() As Double
        buffer = String.Empty ' efface les anciennes valeurs
        Dim data As Double
        Dim out As Boolean = False 'pour sortir de la boucle 
        Dim ok As Boolean = False ' test si on doit traduire la réception ou pas
        Dim fin As Double
        fin = Environment.TickCount + 500 ' On ajoute 1/2sec au compteur programme pour avoir le temps
        Do
            'ecriture 
            SerialPort1.WriteLine("GR10")
            Application.DoEvents()
            Pause(100) ' diminuer selon ton besoin
            ' si il y a une réception dans le buffer et s'il contient un poids
            If Not buffer Is Nothing AndAlso buffer.Contains("kg") Then
                out = True
                ok = True
            ElseIf ((Environment.TickCount >= fin)) Then 'And buffer Is Nothing Then
                out = True
                ok = False
                ' affiche le défaut dans la listview
                Ajout_ligne_LV1(4, "pas de réponse du module de pesage")
            End If
        Loop While (out = False)


Tiens les balises ne sont pas reconnues ^_____^, zut alors.....
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_jeanmi45 Messages postés 27 Date d'inscription mercredi 31 mars 2004 Statut Membre Dernière intervention 6 avril 2010
8 nov. 2009 à 18:34
Merci tes réponses.
J'attrape le code ascii de réponse, il n'y a pas de fin de ligne définit.
Entre temps j'ai avancé un peu. Je pense avoir mis en valeur que ma carte de com déconne car certainement mal installée (le pb est que je ne vois pas comment faire autrement au inveau instal !) Donc comment j'ai vu, tout simplement en utilisant les mêmes soft avec des ports com soit passant par la carte, soit passant par des émulateurs usb/rs, et ces derniers donnent un résultat de 20ms avec qqs rare râtés parfois.
Pas facile de tout expliquer et je ne veux pas vous embrouiller avec trop de détails, mais néanmoins:
mes 2 applis tournent avec la même logique de fonctionnement, à savoir déclenchement sur évenement port série(datareceived). Dans ma petite tête, cela est géré par le processeur comme une interruption, donc je ne peux faire mieux que ça, non ? Même si je faisais une tache de fond dédiée à ça, qui scruterait les caractères entrant, je n'irai pas plus vite non ? Y a t-il qq chose à creuser du côté du CTS/RTS ??
Merci à tous ceux qui passent par là et qui s'arrêteront peut être pour m'aider....et merci à ceux qui l'ont déjà fait ;o)
0
cs_mat1x Messages postés 8 Date d'inscription mardi 8 janvier 2008 Statut Membre Dernière intervention 2 février 2010
29 janv. 2010 à 11:33
Comment peut ton savoir le protocole utilisé par une balance sans avoir la notice et ne connaissant rie nsur cette derniere a part le dispositif d'affichage qui et un dip 206 mais sur le net aucune ou peut d'info sur ce dernier et dans le manuel aucun sujet sur le protocole
merci


Le principe de l'évolution est beaucoup plus rapide en informatique que chez le bipède.
0
Adn56 Messages postés 1172 Date d'inscription jeudi 24 mai 2007 Statut Membre Dernière intervention 28 septembre 2013 1
29 janv. 2010 à 12:45
@ mat1x : fait toi un topic pour toi, ici c'est le soucis de jeanmi !
sinon pour t'aider branche ta balance sur l'hyperterminal est regarde à taton.
@ jeanmi :J'attrape le code ascii de réponse, il n'y a pas de fin de ligne définit.
comment fais tu sans fin de trame ? tu as régler la taille d'octet de réponse ? tu lis les octets à la volé ? tu peux poster ton code dans le datareceive ?
++



Tiens les balises ne sont pas reconnues ^_____^, zut alors.....
0
cs_jeanmi45 Messages postés 27 Date d'inscription mercredi 31 mars 2004 Statut Membre Dernière intervention 6 avril 2010
29 janv. 2010 à 13:25
Bonjour adn56, par défaut de temps, g implémenté mscomm32 dans mon projet à la place du fameux serialport et ça marche nickel.

J'ai reporté le pb à microsoft, en cherchant dans les forums, d'autres ont signalés le même pb à savoir l'évenement "datareceived" ne se d'enclenche pas.

pour info j'ai mis le threshold sur 1 caractère (mon code de retour de trame est 1 caractère ascii)

Je vais voir avec un copain qui developpe en c++ pour voir si il a le même pb sachant que je crois que le composant devrait être le même.

ci dessous code avec serial port:

SP.ReceivedBytesThreshold = 1

Private Sub SP_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SP.DataReceived

Ret_trame = SP.ReadExisting

If Len(Ret_trame) = 1 Then
Check_OK = True
CPT += 1
End If

SP.Write("123456789")

End Sub

en mscomm:

MSCOM.InputLen = 0
MSCOM.RThreshold = 1

Private Sub MSCOM_OnComm(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MSCOM.OnComm

Ret_trame = MSCOM.Input

If Len(Ret_trame) = 1 Then
Check_OK = True
CPT += 1
MSCOM.Output = "123456789"
End If

end sub

rien de plus....
0
Adn56 Messages postés 1172 Date d'inscription jeudi 24 mai 2007 Statut Membre Dernière intervention 28 septembre 2013 1
29 janv. 2010 à 17:24
ben écoute, je pense que le DataReceived se déclenche sur la fin de trame défini dans les paramétre, je n'ai jamais reussi à recevoir à la volé

bon courage pour la suite.
0
Rejoignez-nous