TRAME d'un terminal via Port série

basamir Messages postés 335 Date d'inscription vendredi 21 octobre 2005 Statut Membre Dernière intervention 8 mars 2008 - 4 avril 2007 à 13:32
42wawa42 Messages postés 143 Date d'inscription dimanche 28 septembre 2003 Statut Membre Dernière intervention 6 septembre 2011 - 8 avril 2007 à 12:05
bonjour,

j'ai un projet d'étude qui porte sur la communication d'un terminal de pesage (Balance) avec une application que je dois créer.
le port série de mon PC reçoit en continue une trame ayant la forme suivante :
[STX] [8 bits] [Cr]
le but de mon projet est, entre autres, afficher le poids de la balance d'un champ text.
mais je ne sais pas comment récupérer cette trame et la modeler pour l'afficher sous forme de numéro dans le champ Text (p.e: 20600)

Merci d'avance

19 réponses

cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
4 avril 2007 à 13:52
Ne serait-ce pas plutot [STX][8 octets][CR]

Plusieurs possibilités s'offre à toi. Par exemple :
- Tu configure le port pour lire octet par octet et tu analise chaque octet. Dès que tu tombe sur STX, tu reconfigure temporairement le port pour lire 8 octets que tu stocke dans une variable à traiter puis tu te remet à lire octet par octet.
- Tu lit chaque octet que tu empile dans une première variable, dès que tu tombe sur CR, tu prend les 8 derniers octets de la première variable que tu stocke dans une variable à traiter, puis tu réinitialise la première variable et tu recommence.

Autre possibilité un peu plus évoluée : Compte tenu que tu reçoi en permanence, que c'est une balance, par conséquent la vitesse ne doit pas etre bien élevée (9600 ou 19200 bds), tu peut mettre en place un buffer circulaire.
Un buffer circulaire est une variable tampon (buffer) de grande capacité (un tableau de 1024 caractères suffit largement ici) par rapport à la trame à recevoir, associée à 2 taches de traitement. Une première tache se charge de recevoir les caractères sans distinction depuis le port et les stocke dans le tampon. Une seconde tache indépendante se charge de venir lire le tampon et d'en traiter les données. Il te faut 2 pointeurs (index sur le tableau en VB), un à l'entrée pour savoir ou venir écrire les nouveaux octets, un à la sortie pour savoir ou venir lire les octets par encore traiter.
Le principe :
A chaque octet écrit ou lu tu incrémente l'index correspondant, si tu arrive à la fin du tableau pour un index, il repartiera au début (d'où le terme de circulaire). Si les 2 index sont égaux, il n'y a pas de nouveaux caractères à traiter, s'ils sont différents des caractères ne traiter sont présents dans le buffer.

EJ te laisse réfléchir au principe

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
4 avril 2007 à 13:56
Pardon, j'ai oublié

Pour le buffer circulaire, la tache de traitement aura pour role d'isoler dans les caractères à traiter, la valeur qui t'interesse que tu mettra dans une variable à traiter.

Dans tout les cas, le traitement de la variable àtraiter consistera à récupérer dans les 8 octets, la valeur de l'information qui t'interesse. Probablement avec des fonctions Left, Mid pour découper la chaine de caractères, Val pour convertir en nombre. Mais comme tu veux l'afficher dans une textbx, tu n'aura peut-etre même pas besoin de la convertir en nombre.

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
0
basamir Messages postés 335 Date d'inscription vendredi 21 octobre 2005 Statut Membre Dernière intervention 8 mars 2008
4 avril 2007 à 17:52
ce que tu dis là est parfaitement ce que j'attends, mais le problème provient de moi car je ne maitrise pas le VB.
par contre pour la conversion en numérique je sais le faire car je dois soustraire deux valeurs prises avec un décalage mais ça c'est une pure gestion de chaine de caractère.

voici comment j'ai procéder pour avoir ce qui est emis par ma balance:
Private Sub Form_Load()
Form1.Caption =
"App2"
With MSComm1
.CommPort = 2 'on utilise le port COM2: car on
utilise 1 PC avec 2 ports COM:
'si vous avez 2
PC, changez en .CommPort=1
!!!
.Handshaking = 2
.RThreshold =
1
.RTSEnable = True
.Settings =
"9600,n,8,1"
.SThreshold = 1
.PortOpen =
True
End With
Text1.Text = ""
End
Sub

Private Sub Form_Unload(Cancel As
Integer)
MSComm1.PortOpen = False 'on ferme le port quand l'appli
quitte
End Sub

Private Sub
MSComm1_OnComm()
Dim InBuff As
String

Select Case
MSComm1.CommEvent
' On
effectue la gestion des erreurs (cf. le modèle
ci-dessus)
' Ici, on gère en fait pas
grand-chose, mais c'est pour illustrer la démarche
;)

'liste des
erreurs possibles
Case comEventBreak
'On a reçu un signal
d’interruption (Break)
Case comEventCDTO
' Timeout de la
porteuse
Case comEventCTSTO ' Timeout du signal CTS (Clear To
Send)
Case comEventDSRTO ' Timeout du signal de
réception
Case comEventFrame ' Erreur de trame
Case
comEventOverrun ' Des données
ont été perdues
Case comEventRxOver
' Tampon de réception
saturé
Case comEventRxParity ' Erreur de parité
Case
comEventTxFull ' Tampon
d’envoi saturé
Case comEventDCB ' Erreur de réception DCB (jamais
vu)

'liste des
événements possibles qui sont, eux,
normaux
Case comEvCD 'Changement dans la broche CD
(porteuse)
Case comEvCTS 'Changement dans broche
CTS
Case comEvDSR 'Changement dans broche DSR
(réception)
Case comEvRing 'Changement dans broche RING
(sonnerie)

'Chouette!
on a reçu des données :)
Case
comEvReceive
     
tampon=MSComm1.Input
     
Call Traitement(tampon) 'traitement
données

Case comEvSend ' il y a des caractères à
envoyer

Case comEvEOF 'on a reçu le caractère
EOF
End Select
End Sub

text1.text =  tampon
text2.text = Rghit(text1.text,10)

mais sur la zone text1.text j'obtiens une série de valeurs envoyées par la balance, p.e:
1200G 1200G 1200G 1200G 1200G 1200G "si cette valeur change" on continue par cette même valeur changé p.e 1220G 1220G 1220G

Merci pour ton aide
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
4 avril 2007 à 19:07
Je te propose la fonction Traitement suivant :

Private Sub traitement(rcvstr As String)
Static buffer As String

' Remplissage du buffer avec les caractères reçus
buffer = buffer & rcvstr

' Recherche d'une donnée complete dans le buffer
' c-à-d recherche du caractère de fin de trame CR
Do While (InStr(1, buffer, vbCr) > 0)
   i = InStr(1, buffer, vbCr)
   ' i doit etre >= 9 pour avoir une donnée complete dans le buffer (8 octets + CR)
   If i >= 9 Then
       ' On affiche la partie donnée de la trame
       Text1.Text = Trim(Mid(buffer, i - 8, 8))
       
       ' On enleve de buffer, les octets déjà traités pour ne pas les traiter dans l'itération suivante
       buffer = Mid(buffer, i + 1)
   End If
Loop

End Sub<hr />, ----
[code.aspx?ID=41455 By Renfield]
Pense à décalrer tampon correctement dans MsComm1_OnComm, actuellement elle n'est pas déclarée

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
0

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

Posez votre question
basamir Messages postés 335 Date d'inscription vendredi 21 octobre 2005 Statut Membre Dernière intervention 8 mars 2008
5 avril 2007 à 00:55
merci
voila j'ai déclaré ceci:
dim tampon as string
dans MsComm1_OnComm

mais ta fonction ne renvoie rien au champ text1
0
basamir Messages postés 335 Date d'inscription vendredi 21 octobre 2005 Statut Membre Dernière intervention 8 mars 2008
5 avril 2007 à 01:44
En  fait voici ma fonction de traitement:

Sub traitement(tampon As String)
   Dim aData() As String
   Dim sDerniereData As String
   Text1.SelStart = Len(Text1.Text)
   Text1.SelText = CStr(tampon)
   aData = Split(tampon, " ")   ' Transforme le Tampon en tableau, séparateur "espace"
   sDerniereData = aData(UBound(aData))   ' Récupère le dernier élément
   If Right$(sDerniereData, 1) = "vbCrlf" Then   ' Vérifie la pertinence de la dernière donnée
      Text2.Text = Trim(sDerniereData)   ' Ok, on l'affiche
   Else
      ' Les 2 derniers caractères ne sont pas corrects (donnée tronquée)
      If UBound(aData) > 0 Then   ' S'il y a assez de données
         sDerniereData = aData(UBound(aData) - 1)   ' On prend la précédente
         Text2.Text = sDerniereData
      Else
         ' Sinon, on ne touche pas à Text1
      End If
   End If
End Sub

Mais ça donne des informations en continue dans la zone text1, genre:
22000G 22000G 22000G 22000G 22000G 22000G 22000G 22000G
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
5 avril 2007 à 10:11
Je l'ai testée chez moi avant de te la donner et elle marchait

Est-elle bien appelée au moins?

Met un point d'arret dedant et regarde avec une execution pas à pas ce que se passe exactement
Et vérifie qu'elle correspond au format de la trame que tu reçoit. Je me suis basé sur le format suivant : [STX][8 octets][CR]

<hr size="2" width="100%" />
Concernant ta propre fonction, il est normal que tu obtienne ça dans Text1 puisque tu rajoute systématiquement ce que tu reçoit à la fin du texte présent sans jamais vider la textbox. Les receptions s'accumulent.
En suite dans cette instruction,  , tu compare le dernier caractere de la chaine au texte "vbCrlf", ta comparaison ne sera positive que si le dernier caractère reçu est un "v". Il ne faut pas faire la comparaison par rapport au texte "vbCrlf" mais par rapport aux caractères vbCrLf (ATTENTION vbCrLf, c'est 2 caractères, le caractère <CR> suivie du caractère <LF>). Mais ce n'est toujours pas bon. Selon ton protocole, tu ne reçois que le caractère <CR> à la fin de la trame, tu ne reçois pas le caractère <LF>

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
0
basamir Messages postés 335 Date d'inscription vendredi 21 octobre 2005 Statut Membre Dernière intervention 8 mars 2008
6 avril 2007 à 16:35
tout a fait Cr, beh tu sais je connecte mon terminal à Aspycom et j'espionne ma trame en Hexa et en Ascci.

Crois moi j'ai pris ton code et je l'ai mis dans une fonction et je l'ai appelé au niveau de MsComm1_OnComm avec une déclaration de la variable tampon as string

je ne sais pas pourqoui il y a rien sur Text1

Merci
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
6 avril 2007 à 18:04
Oui il y a un petit bug possible dans ma source. Essaye de déplacer buffer = Mid(buffer, i + 1) après le End If

Sinon plusieurs possibilités, soit le CR n'est pas trouvé dans la trame, soit l'évènement comEvReceive n'est pas déclenché lors de la reception et donc la fonction traitement n'est pas appelée.
Pour ça, il n'y a que toi qui peut le voir. Il faut que tu te mette en deboguage et que tu mette un point d'arret sur l'appel de traitement, tu veras bien si tu passe par cette instruction.

---- Sevyc64  (alias Casy) ----<hr size ="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
0
basamir Messages postés 335 Date d'inscription vendredi 21 octobre 2005 Statut Membre Dernière intervention 8 mars 2008
6 avril 2007 à 21:06
ça marche tjrs pas
0
42wawa42 Messages postés 143 Date d'inscription dimanche 28 septembre 2003 Statut Membre Dernière intervention 6 septembre 2011
6 avril 2007 à 22:34
Voila basmir un code pour toi seulement.....


Option Explicit


Dim Buffer As String


Private Sub Form_Load()


MSComm1.CommPort = 1
MSComm1.Settings = "9600,N,8,1"
MSComm1.Handshaking = comNone
MSComm1.InputLen = 1
MSComm1.RThreshold = 1
MSComm1.RTSEnable = True
MSComm1.PortOpen = True
Buffer = ""
End Sub


Private Sub MSComm1_OnComm()


Dim xPos As Integer
    Buffer = Buffer & MSComm1.Input
    xPos = InStr(1, Buffer, Chr(2), vbBinaryCompare)
        If xPos = 1 Then
            Text2.Text = Mid(Buffer, 4, 5)
                If Len(Buffer) > 9 Then
                    Buffer = Right(Buffer, Len(Buffer) - 9)
                End If
        End If
    Text1.Text = Len(Buffer)
End Sub


A plus sur VBFrance
42wawa42


 
0
basamir Messages postés 335 Date d'inscription vendredi 21 octobre 2005 Statut Membre Dernière intervention 8 mars 2008
6 avril 2007 à 22:57
ok les gars toutes les solutions que vous me proposier ne sont pas celles qui me convient car peut etre j'ai mal exprimer mon problème.

Voici le code de mon programme:

Private Sub Form_Load()
With MSComm1
.CommPort = 5
.Handshaking = 2
.RThreshold = 1
.RTSEnable = True
.Settings = "9600,n,8,1"
.SThreshold = 1
.PortOpen = True
End With
Text1.Text = ""
End Sub

je travaille avec le port Com 5

voici comment je stocke dans tampon ce que je reçoit du port série:

Private Sub MSComm1_OnComm()
Dim tampon As String
Dim bit_de_trame() As Byte
Select Case MSComm1.CommEvent
' On effectue la gestion des erreurs (cf. le modèle ci-dessus)
' Ici, on gère en fait pas grand-chose, mais c'est pour illustrer la démarche ;)

'liste des erreurs possibles
Case comEventBreak 'On a reçu un signal d’interruption (Break)
Case comEventCDTO ' Timeout de la porteuse
Case comEventCTSTO ' Timeout du signal CTS (Clear To Send)
Case comEventDSRTO ' Timeout du signal de réception
Case comEventFrame ' Erreur de trame
Case comEventOverrun ' Des données ont été perdues
Case comEventRxOver ' Tampon de réception saturé
Case comEventRxParity ' Erreur de parité
Case comEventTxFull ' Tampon d’envoi saturé
Case comEventDCB ' Erreur de réception DCB (jamais vu)

'liste des événements possibles qui sont, eux, normaux
Case comEvCD 'Changement dans la broche CD (porteuse)
Case comEvCTS 'Changement dans broche CTS
Case comEvDSR 'Changement dans broche DSR (réception)
Case comEvRing 'Changement dans broche RING (sonnerie)
      
      tampon = MSComm1.Input
       
      Call traitement4(tampon) 'traitement données

Case comEvSend ' il y a des caractères à envoyer
Case comEvEOF 'on a reçu le caractère EOF
End Select
End Sub

voici la fonction qui renvoie une donnée numérique à mon champ text1 :
Sub traitement4(ByVal InString As String)
         Dim temp As String
         Dim x As Long
         Dim OutString As String

         For x = 1 To Len(InString)
            temp = Mid$(InString, x, 1)
            If temp = Chr$(Xoff) Then
               Label6.ForeColor = vbRed
               Label6.Caption = "Xoff received"
               temp = ""
            ElseIf temp = Chr$(Xon) Then
               Label6.ForeColor = vbGreen
               Label6.Caption = "Xon received"
               temp = ""
            End If
            OutString = OutString & temp
            temp = ""
         Next x
         Call HandleInput(OutString)
      End Sub
et la fonction HandleInput:
 Sub HandleInput(InBuff As String)
      Dim poids As String
        poids = Left(Text1.Text & InBuff, 8)
        Text1.Text = Right(poids, 5)
                     
      End Sub

Voici le problème:

Vue que je communique avec un terminal externe et que je ne suis pas synchronisé avec ce terminal, si j'ai une valeur de 20260 par exemple je peux ne pas avoir que 0260 ou 260 ou 60 ou 0 ou n'importe quelle série de numéro en fonction du moment ou je lis cette valeur et celui de l'envoie de cette meme valeur par le terminal.

ce que je devrait avoir dans mon champ text1 est exactement ce qui est affiché sur mon terminal.
je vous remercie tous
0
42wawa42 Messages postés 143 Date d'inscription dimanche 28 septembre 2003 Statut Membre Dernière intervention 6 septembre 2011
7 avril 2007 à 12:10
Hello Basmir,<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /??>






 







J’ai fait marché ton programme sur mon ordinateur la partie RS232 et bonne par contre les routine qui suive ne marche pas. J’ai ajouté un routine qui vas te donné les chiffres. Test et donne moi une réponse merci.






 









Private Sub Form_Load()
With MSComm1
.CommPort = 5     '5=================================================
.Handshaking = 2
.RThreshold = 1
.RTSEnable = True
.Settings = "9600,n,8,1"
.SThreshold = 0
.PortOpen = True
End With
Text1.Text = ""
End Sub


'je travaille avec le port Com 5


'voici comment je stocke dans tampon ce que je reçoit du port série:


Private Sub MSComm1_OnComm1()
Dim tampon As String
Dim bit_de_trame() As Byte
Select Case MSComm1.CommEvent
' On effectue la gestion des erreurs (cf. le modèle ci-dessus)
' Ici, on gère en fait pas grand-chose, mais c'est pour illustrer la démarche ;)


'liste des erreurs possibles
Case comEventBreak 'On a reçu un signal d'interruption (Break)
Case comEventCDTO ' Timeout de la porteuse
Case comEventCTSTO ' Timeout du signal CTS (Clear To Send)
Case comEventDSRTO ' Timeout du signal de réception
Case comEventFrame ' Erreur de trame
Case comEventOverrun ' Des données ont été perdues
Case comEventRxOver ' Tampon de réception saturé
Case comEventRxParity ' Erreur de parité
Case comEventTxFull ' Tampon d'envoi saturé
Case comEventDCB ' Erreur de réception DCB (jamais vu)


'liste des événements possibles qui sont, eux, normaux
Case comEvCD 'Changement dans la broche CD (porteuse)
Case comEvCTS 'Changement dans broche CTS
Case comEvDSR 'Changement dans broche DSR (réception)
Case comEvRing 'Changement dans broche RING (sonnerie)
      
      tampon = MSComm1.Input
       
      Call traitement4(tampon) 'traitement données


Case comEvSend ' il y a des caractères à envoyer
Case comEvEOF 'on a reçu le caractère EOF
End Select
End Sub


'voici la fonction qui renvoie une donnée numérique à mon champ text1 :
Sub traitement4(ByVal InString As String)
         Dim temp As String
         Dim x As Long
         Dim OutString As String


         For x = 1 To Len(InString)
            temp = Mid$(InString, x, 1)
            If temp = Chr$(Xoff) Then
               Label6.ForeColor = vbRed
               Label6.Caption = "Xoff received"
               temp = ""
            ElseIf temp = Chr$(Xon) Then
               Label6.ForeColor = vbGreen
               Label6.Caption = "Xon received"
               temp = ""
            End If
            OutString = OutString & temp
            temp = ""
         Next x
         Call HandleInput(OutString)
      End Sub
'et la fonction HandleInput:
 Sub HandleInput(InBuff As String)
      Dim poids As String
        poids = Left(Text1.Text & InBuff, 8)
        Text1.Text = Right(poids, 5)
                     
      End Sub


Private Sub MSComm1_OnComm()


Dim xPos As Integer
    Buffer = Buffer & MSComm1.Input
    xPos = InStr(1, Buffer, Chr(2), vbBinaryCompare)
        If xPos = 1 Then
            Text1.Text = Mid(Buffer, 4, 5)
                If Len(Buffer) > 9 Then
                    Buffer = Right(Buffer, Len(Buffer) - 9)
                End If
        End If
    'Text2.Text = Len(Buffer)
End Sub



A plus sur VBFrance.com





42wawa42
0
basamir Messages postés 335 Date d'inscription vendredi 21 octobre 2005 Statut Membre Dernière intervention 8 mars 2008
7 avril 2007 à 13:56
je compends pas ce que t'as fait, est ce que je dois remplacer ma procédure MsComm1_oncomm() par la tienne et je supprime ma fonction de traitement???

Merci de me préciser
0
basamir Messages postés 335 Date d'inscription vendredi 21 octobre 2005 Statut Membre Dernière intervention 8 mars 2008
7 avril 2007 à 14:00
beh écoute c'est ce que j'ai fait et ça ne marche pas rien ne s'affiche sur ma zone de text1.

c'est bizzare non?
0
42wawa42 Messages postés 143 Date d'inscription dimanche 28 septembre 2003 Statut Membre Dernière intervention 6 septembre 2011
8 avril 2007 à 00:09
Hello Basmir,<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /??>






 






Charge le programme comme sur le site et fais le marcher. Donnes moi une réponse merci.






 






PS as-tu Skype je n’ai pas MSN ?






 






A plus sur VBFrance.com





42wawa42
0
basamir Messages postés 335 Date d'inscription vendredi 21 octobre 2005 Statut Membre Dernière intervention 8 mars 2008
8 avril 2007 à 00:19
""lhlouidrissi"

je suis connecté

Merci
0
basamir Messages postés 335 Date d'inscription vendredi 21 octobre 2005 Statut Membre Dernière intervention 8 mars 2008
8 avril 2007 à 00:35
j'ai pas bien compris ce que tu veux dire par copier mon programme??

Mon psudo sur skype est : lhlouidrissi

Merci
0
42wawa42 Messages postés 143 Date d'inscription dimanche 28 septembre 2003 Statut Membre Dernière intervention 6 septembre 2011
8 avril 2007 à 12:05
Je suis sur Skype "hb9uqy"
0
Rejoignez-nous