Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB 6 et antérieur Discussion :

VB6 MSCOmm réception données binaires


Sujet :

VB 6 et antérieur

  1. #1
    Membre du Club
    VB6 MSCOmm réception données binaires
    Bonjour,

    Je cherche depuis 2 jours mais je cale complètement, aucun exemple trouvé sur le net ne correspond ou ne fonctionne

    Voilà, je suis en train de faire une appli permettant de paramétrer un appareil via port com et liaison infra rouge (un petit module USB - IRDA qui est vu comme un port COM) afin de remplacer une "pocket" (un Palm, avec appli constructeur intégré, et port infra rouge) .
    J'ai pu récupérer les codes envoyés par le Palm via 232Analyzer.
    En décimal, ils se présentent sont cette forme, par exemple :
    016 002 002 002 016 003

    Pour l'envoi, je fais comme ceci :
    Commande = Chr(16) & Chr(2) & Chr(2) & Chr(2) & Chr(16) & Chr(3)
    MSComm1.Output = Commande
    Cela fonctionne, l'appareil reçoit bien l'ordre et exécute la fonction correspondante.

    En revanche, pour récupérer ce que l'appareil renvoi comme code (sous la même forme, toujours visualisé avec 232Analyzer), par exemple, si je relis la config de l'appareil, j'ai ceci, si les valeurs de ses paramètres sont bons :
    016 002 067 032 003 002 196 009 196 009 020 000 118 016 003 (aussi, elle est répétée plusieurs fois lors de la lecture)

    L'idée étant de lire par exemple la config et de comparer avec une valeur définie et dire si elle est conforme ou non.
    De même pour les accusés de réceptions des différents ordres de test.
    Toutes les communications commencent par 016 002 et finissent par 016 003.

    Je pense dans un premier m'inspirer d'un code comme celui ci pour visualiser le code recu (on vera après pour le stocker sous forme de valeur d'une variable, ca risque d'etre marrant aussi ça) :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    Private Sub MSComm1_OnComm()
     
     
    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 <img src="images/smilies/icon_wink.gif" border="0" alt="" title=";)" class="inlineimg" />
     
    '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 <img src="images/smilies/icon_smile.gif" border="0" alt="" title=":)" class="inlineimg" />
    Case comEvReceive
          tampon = MSComm1.Input
          tampon = Asc(tampon)
         Text1.SelText = (tampon) & "," 'ici, on affiche le résultat dans un champ de texte
     
    Case comEvSend ' il y a des caractères à envoyer
     
    Case comEvEOF 'on a reçu le caractère EOF
    End Select
     
    End Sub

    Evidement, ca m'affiche des valeurs farfelues.

    Je pense qu'il faudrait récupérer chaque octet, donc sur l'exemple de la lecture de config :
    00010000 00000010 01000011 00100000 00000011 00000010 11000100 00001001 11000100 00001001 00010100 00000000 01110110 00010000 00000011

    Je pense qu'il faut utiliser "InputMode = comInputModeBinary" (d’ailleurs, est-ce que cela change aussi le mode output ou je peux garder mes Chr(016) etc etc ?) , mais plus je fais d'essais plus j'ai entre rien et n'importe quoi

    Je patauge complètement (en temps normal, c'est bien pour un canard , mais là nan ).

    Un petit coup de palme serait bienvenu

    Merci et à bientôt
    Couin
    Retrouvez-moi tous les dimanches à 22H pour une heure de mix en live tout au vinyle sur eurodance90.fr

  2. #2
    Rédacteur/Modérateur

    Salut

    J'avais un programme qui nécessitait une conversion binaire vers décimale et inversement, du coup je te propose un une version simplifié.
    Dans un projet, un module.BAS et un Form avec 4 CommandButtons et 3 TextBoxs,
    Code du Module1.BAS
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    Option Explicit
     
    Dim Binnaire(16) As Long
    Dim T As Double, U As Integer
     
    Public Sub Main()
    For T = 1 To 16: Binnaire(T) = 2 ^ (T - 1): Next T
    Form1.Show
    End Sub
     
    Public Function Bin8_Dec(ValBin As String) As Integer
        'exemple: 11100011 = 227
        Dim StrDonn As String
        StrDonn = CStr(ValBin)
        U = Len(StrDonn)
        For T = 1 To U
            If Mid$(StrDonn, T, 1) = 1 Then Bin8_Dec = Bin8_Dec + Binnaire(U - (T - 1))
        Next T
    End Function
     
    Public Function Dec_Bin8(ValDec As Integer) As String
        'exemple: 227 = 11100011
        U = 8
        For T = 1 To 8
            If ValDec >= Binnaire(U - (T - 1)) And ValDec <> 0 Then
                Dec_Bin8 = Dec_Bin8 & "1": ValDec = ValDec - Binnaire(U - (T - 1))
                Else
                Dec_Bin8 = Dec_Bin8 & "0"
            End If
        Next T
    End Function

    Code du Form1.frm
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    Option Explicit
    Dim TT As Integer
    Dim TextRecupe As String
     
    Private Sub Form_Load()
        Me.Height = 3645: Me.Width = 5205: Me.Caption = "Convertisseur"
     
        Text1.FontName = "Courier New"
        Text1.FontSize = 8
        Text1.Move 120, 60, 4740, 795
        Text1.BorderStyle = 1
        Text1.Appearance = 0
        'Text1.MultiLine = True <------------ A faire en desing -------------
        Text1.Text = "00010000 00000010 01000011 00100000 00000011 00000010 11000100 00001001 11000100 00001001 00010100 00000000 01110110 00010000 00000011"
     
        Command1.Move 120, 900, 2355, 435: Command1.Caption = "^-- Binnaire ---> Décimale --v"
        Command2.Move 2555, 900, 2295, 435: Command2.Caption = "v-- Décimale ---> Binnaire --^"
     
        Text2.FontName = "Courier New"
        Text2.FontSize = 8
        Text2.Move 120, 1380, 4740, 555
        Text2.BorderStyle = 1
        Text2.Appearance = 0
        'Text2.MultiLine = True <------------ A faire en desing -------------
        Text2.Text = ""
     
        Command3.Move 120, 1980, 2355, 435: Command3.Caption = "^-- Ascii ---> caractère --v"
        Command4.Move 2555, 1980, 2295, 435: Command4.Caption = "v-- caractére ---> Ascii --^"
     
        Text3.FontName = "Courier New"
        Text3.FontSize = 8
        Text3.Move 120, 2460, 4740, 555
        Text3.BorderStyle = 1
        Text3.Appearance = 0
        'Text3.MultiLine = True <------------ A faire en desing -------------
        Text3.Text = ""
     
    End Sub
     
    Private Sub Command1_Click()
        If Trim(Text1.Text) = "" Then Exit Sub
        Dim ArrayDataBin() As String
        ArrayDataBin = Split(Trim(Text1.Text), " ")
        TextRecupe = "": Text2.Text = ""
        For TT = 0 To UBound(ArrayDataBin)
            TextRecupe = TextRecupe & CStr(Bin8_Dec(ArrayDataBin(TT))) & " "
        Next TT
        TextRecupe = Left(TextRecupe, Len(TextRecupe) - 1)
        Text2.Text = TextRecupe
    End Sub
     
    Private Sub Command2_Click()
        If Trim(Text2.Text) = "" Then Exit Sub
        Dim ArrayDataDec() As String
        ArrayDataDec = Split(Trim(Text2.Text), " ")
        TextRecupe = "": Text1.Text = ""
        For TT = 0 To UBound(ArrayDataDec)
            TextRecupe = TextRecupe & CStr(Dec_Bin8(CInt(ArrayDataDec(TT)))) & " "
        Next TT
        TextRecupe = Left(TextRecupe, Len(TextRecupe) - 1)
        Text1.Text = TextRecupe
    End Sub
     
    Private Sub Command3_Click()
        If Trim(Text2.Text) = "" Then Exit Sub
        Dim ArrayDataCaract() As String
        ArrayDataCaract = Split(Trim(Text2.Text), " ")
        TextRecupe = ""
        For TT = 0 To UBound(ArrayDataCaract)
            If CInt(ArrayDataCaract(TT)) = 0 Then
                TextRecupe = TextRecupe & "NULL"
                Else
                TextRecupe = TextRecupe & Chr(CInt(ArrayDataCaract(TT)))
            End If
        Next TT
        Text3.Text = TextRecupe
    End Sub
     
    Private Sub Command4_Click()
        If Trim(Text3.Text) = "" Then Exit Sub
        Dim StrSoumis As String
        StrSoumis = Trim(Text3.Text)
        TextRecupe = "": Text2.Text = ""
        For TT = 1 To Len(StrSoumis)
            If (TT - 4) <= Len(StrSoumis) Then
                If Mid(StrSoumis, TT, 4) = "NULL" Then
                    TextRecupe = TextRecupe & "0 ": TT = TT + 3
                    Else
                    TextRecupe = TextRecupe & AscW(Mid(StrSoumis, TT, 1)) & " "
                End If
                Else
                TextRecupe = TextRecupe & AscW(Mid(StrSoumis, TT, 1)) & " "
            End If
        Next TT
        TextRecupe = Left(TextRecupe, Len(TextRecupe) - 1)
        Text2.Text = TextRecupe8
    End Sub
    Dans le TextBox du haut tu peux y mettre différent octets sur 8 bits en les séparent par un caractère espace (" ") , en cliquant sur le premier CommandButton tu obtiens la conversion en décimale, puis en cliquant sur le bouton ^-- Ascii ---> caractère --v tu obtiens la conversion en caratères.
    Inversement, tu peux partir du TextBox le plus bas pour écrire du texte pour le convertir en code ascii puis en équivalence octets sur 8bits.
    A savoir, un octet égal à null (00000000) sera converti en un mot égal à NULL, inversement si tu veux obtenir un octet 00000000 tu écris NULL dans le TextBox le plus bas, ce qui donne 0 (zéro) en décimale et 00000000 en octet 8bits.

    Si tu entre: 016 002 067 032 003 002 196 009 196 009 020 000 118 016 003 dans le TextBox du milieu, tu obtiens 00010000 00000010 01000011 00100000 00000011 00000010 11000100 00001001 11000100 00001001 00010100 00000000 01110110 00010000 00000011 pour la conversion octets et voir l'image pour la conversion en caractères.
    Soyez sympa, pensez -y
    Balises[CODE]...[/CODE]
    Balises[CODE=NomDuLangage]...[/CODE] quand vous mettez du code d'un autre langage que celui du forum ou vous postez.
    Balises[C]...[/C] code intégré dans une phrase.
    Balises[C=NomDuLangage]...[/C] code intégré dans une phrase quand vous mettez du code d'un autre langage que celui du forum ou vous postez.
    Le bouton en fin de discussion, quand vous avez obtenu l'aide attendue.
    ......... et pourquoi pas, pour remercier, un pour celui/ceux qui vous ont dépannés.

  3. #3
    Membre du Club
    Hello,

    Désolé pour mon passage tardif, merci pour ta réponse Je garde ça sous l'aile

    Je suis entretemps parvenu à réceptionner les données voulues et les exploiter en décimal (encore mieux pour l'écriture du programme ).

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    Private Sub Form_Load()
    MSComm1.CommPort = 3
    MSComm1.Settings = "115200,n,8,1"     'port settings
    MSComm1.RTSEnable = True            'makes pin 4 high (12V)
    MSComm1.RThreshold = 1
    MSComm1.InputMode = comInputModeBinary
    cmdClose.Enabled = False
    End Sub
     
     
    Private Sub GetDataTimer_Timer()
        If MSComm1.InBufferCount > 0 Then
            ReadDataBits
        End If
    End Sub
     
    '----------------------------------------------------------END----------------------------------------------------------
    'Read The Data From The Com Port And Display As A Binary String per Byte Received
    '---------------------------------------------------------START---------------------------------------------------------
    Private Sub ReadDataBits()
            Dim bytInput() As Byte
            Dim bytElement As Byte
            Dim sLead As String
            Dim sDisplay As String
            Dim sToget As String
            Dim iX As Long
            Dim iY As Long
     
            If MSComm1.InBufferCount = 0 Then            'Check The Buffer For Data
            Exit Sub                                        'Exit If The Buffer Is Empty
            End If
     
            bytInput = MSComm1.Input
            iX = UBound(bytInput)                               'Get the number of byte elements in the input
     
            For iY = 0 To iX
                bytElement = bytInput(iY)                       'Get the next byte element from the input
                sLead = bytElement & " "                       'Create display lead
                sDisplay = sDisplay & sLead
            Next
            lstData.AddItem sDisplay
        Exit Sub
     
    End Sub


    Toutefois, je cale sur un point donc je vais ouvrir un nouveau sujet pour éviter les mélanges de réponses

    A bientôt
    Retrouvez-moi tous les dimanches à 22H pour une heure de mix en live tout au vinyle sur eurodance90.fr

  4. #4
    Futur Membre du Club
    Salut Couin,

    Avant de dépiauter les trames, il faudrait connaitre le protocole de communication utilisé par le Palm.
    IR étant le mode de transport, ModBus pourrait être par exemple le protocole ?
    (Je dis ca car le 16 est le code fonction d'écriture multiple d'entier en ModBus mais ca n'a pas l'air d'être ca.)

    Il est difficile de trouver la structure des trames échangées avec l'exemple fourni :
    016 002 067 032 003 002 196 009 196 009 020 000 118 016 003

    Les données seraient : 067 032 003 002 196 009 196 009 020 000 118
    Mais a quoi correspondent elles ? Est-ce de l'hexa ou du décimal envoyé par le palm ? y a il un CRC ? Une adresse du Palm ? un code fonction ? (lecture, écriture etc...) C'est chaud !

    D'autre part, utilise plutôt l’événement OnComm du composant MSCOM pour la réception de données.
    a+

  5. #5
    Membre du Club
    Hello,

    Merci pour ta réponse

    Je suis parvenu à pas mal de chose entre temps .

    Tous les messages envoyés par la pocket ou répondus par l'appareil commencent par 16 2 et finissent par 16 3 .
    Je ne connais pas le protocole utilisé et je ne pourrais jamais le savoir.
    Pour l'exemple du read config :
    016 002 067 032 003 002 196 009 196 009 020 000 118 016 003
    (J'ai constaté que récemment que le read config répondait différemment si la carte de l'appareil est de première ou de deuxièmement génération).
    Certains paramètres sont cryptés d'une drôle de manière (que je n'ai pas trouvée lol) mais à la limite, ce n’est pas très grave dans le sens où je compare le code lu avec un code de bonne config connue.
    032 003 est le pitch (valeur 800 donc crypté), 002 est le paramètre numéro 18, valeur 2 (donc non crypté, si je mets une autre valeur le code retourne directement la valeur), 196 009 correspondent à une valeur de 2500 pour 2 paramètres (c’est pour ce qu'il y est 2 fois car les deux params sont à 2500) , 020 est là aussi directement lisible (paramètre 5, valeur 20), 000 est un autre paramètre , là aussi directement lisible. 118 doit être un CRC car quelque soit le paramètre que je change, il est toujours différent.
    De ce fait en splittant le code je peux isoler chaque paramètre lu et dire lequel n’est pas bon quand il y a une erreur de conf.

    Je pense que le protocole est totalement propriétaire (le constructeur de la machine fabrique la carte électronique et le logiciel pour communiquer avec donc il a pu mettre ce qu'il voulait lol).

    Je vais étudier la méthode OnComm, l'idée étant de virer le timer, c'est bien ca ?
    Retrouvez-moi tous les dimanches à 22H pour une heure de mix en live tout au vinyle sur eurodance90.fr

  6. #6
    Futur Membre du Club
    Salut Couin,

    Effectivement tu n'es pas obligé de comprendre les trames (ouf! ) si ton objectif est de comparer ce que tu reçois par rapport à une config correcte.
    Oui pour le OnComm(), tu pourras virer le Timer.
    Grace à un
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    MSCom_OnComm()
    Select Case MSCom.CommEvent
      case comEvReceive



    Tu pourras gérer ton buffer de com MSCom.Input de manière événementielle, au moins tu es sur de ne rien rater.

    Idem pour les autres constantes (comEvCTS, comEvCD, etc...) , ca te permettra de savoir vraiment ce qu'il se passe sur le port de com.

    Et pour info, c'est quoi le modèle de ton convertisseur USB-IRDA ?

    Bon courage !

  7. #7
    Membre du Club
    En ce qui concerne le buffer du port COM, actuellement le timer check si il y a quelque chose dedans et si il y a quelque chose, j'envoie le contenu dans une variable string que j'analyse ensuite. A priori ca a l'air de fonctionner aussi.

    Pour le convertisseur IrDA-USB je te redirais lundi soir
    Retrouvez-moi tous les dimanches à 22H pour une heure de mix en live tout au vinyle sur eurodance90.fr

  8. #8
    Membre du Club
    Reu !

    Le module USB - IRDA est un actisys act-ir224un-ln115 http://www.actisys.com/IrDAProd.html#IR224UN
    Retrouvez-moi tous les dimanches à 22H pour une heure de mix en live tout au vinyle sur eurodance90.fr

  9. #9
    Futur Membre du Club
    Merci Couin ^^

  10. #10
    Membre du Club
    De rien

    Au passage, j'ai tenté la migration vers l’événement OnComm, mais ça me ramassait pas les trames que par petits bouts et du coup la comparaison ne pouvait se faire.
    Ou alors il faudrait un truc du genre "Si rien reçu depuis x millisecondes, on exécute telle fonction".
    Retrouvez-moi tous les dimanches à 22H pour une heure de mix en live tout au vinyle sur eurodance90.fr

  11. #11
    Futur Membre du Club
    C'est que le Palm doit envoyer plusieurs trames car l’événement OnComm() ne se déclenche que lorsque ton buffer reçoit quelque chose.

  12. #12
    Membre du Club
    En l’occurrence le Palm n'est pas en cause car l'appli reçoit ce que l'équipement (sur lequel on travaille avec le Palm pour le moment) répond. En gros le logiciel que je ponds remplace le Palm.
    Mais comme ils communiquent les trames sont les mêmes.

    Je pense que le traitement de ce que ramasse l'évent OnComm, est trop rapide et du coup au lieu d'avoir un code du genre 16 2 67 32 3 2 196 9 196 9 20 0 118 16 3 on a
    16 2
    67 32 3
    2 196
    9 196 9
    20 0
    118 16
    3
    Par exemple.
    Comme le traitement des données reçue se fait une fois le buffer vide, bah il n'y a que des petits bouts à traiter.
    Retrouvez-moi tous les dimanches à 22H pour une heure de mix en live tout au vinyle sur eurodance90.fr

###raw>template_hook.ano_emploi###