Alimenter plusieurs textbox avec une variable et timer... [Résolu]

botbot1607 - 12 nov. 2012 à 12:20 - Dernière réponse :  botbot1607
- 23 nov. 2012 à 13:43
Bonjour à tous, :)

Débutant en VB, je me suis lancé sur un projet, et je bute à une étape de mon programme : :euh:

Le but de mon programme est, d'acquérir des données d'un dispositif (ex : multimètre) via le port COM de la machine.
J'ai réussi à émuler 2 ports COM en Nullmodem via un soft, pour faire mes tests de dialogue entre les COM, tout fonctionne très bien : j'arrive à envoyer une chaine sur un PORT 4 et le récupérer sur un PORT 5, et de l'afficher dans une textbox "TXT_EVENTS2"

Maintenant, ce que je voudrais faire, c'est alimenter 6 Textbox avec un timer d'une seconde entre chaque saisie, de la variable qu'à reçu le port COM.

Plus clair : :-°
Je fais une boucle jusqu'à ce que TXT_EVENTS6 contienne une valeur.
à T0 -> Saisir la data à T0 reçu du port COM dans textbox "TXT_EVENTS2"
à T+1ssec ->Saisir la data à T+1sec reçu du port COM dans textbox "TXT_EVENTS3"
à T+2ssec ->Saisir la data à T+2sec reçu du port COM dans textbox "TXT_EVENTS4 "
... Loop

J'ai essayé tout bêtement avec les boucles (je voudrais faire TXT_EVENTS[i]=donnee, et incrémenter a chaque fois), mais je n'y parviens pas :(

Voici la partie de mon code fonctionnel qui nous intéresse, pour la saisie d'une valeur uniquement, sans timer donc, là ou je bloque !

Public Event DataReceived As SerialDataReceivedEventHandler


    Public Sub Receiver(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) Handles COMPort.DataReceived
        Dim nb_octet As Integer = COMPort.BytesToRead ' on récupère le nombre d'octet présent dans le tampon
        Dim trame(nb_octet) As Byte ' Tableau acceuillant les données au format byte
        Dim donnee As String

        COMPort.Read(trame, 0, nb_octet) 'on lit le port
        donnee = System.Text.Encoding.ASCII.GetString(trame) ' on récupère les données au format ASCII
        TXT_EVENTS2.Invoke(New Action(Of String)(AddressOf ChangeValue), donnee)


    End Sub

    Private Sub ChangeValue(ByVal value As String)

        TXT_EVENTS2.Text = value

    End Sub


Quelqu'un sauait il une idée à la solution de mon problème ?

Merci beaucoup ! :)
Afficher la suite 

12 réponses

Répondre au sujet
Utilisateur anonyme - 12 nov. 2012 à 19:59
+3
Utile
Bonsoir,

Admettons que tu attribues des numéros dans les Tag des TextBox (de 0 à 6)

Tu peux faire ceci :
Option Strict On
Public Class Form1
    'numéro incrémenté
    Dim num As Integer
    'délagué invoqué
    Delegate Sub DelegateComPort(Numero As Integer, Donnees As String)

    Private Sub SerialPort1_DataReceived(sender As Object, e As System.IO.Ports.SerialDataReceivedEventArgs) Handles ComPort.DataReceived
        Dim nb_octet As Integer = ComPort.BytesToRead ' on récupère le nombre d'octet présent dans le tampon
        Dim trame(nb_octet) As Byte ' Tableau acceuillant les données au format byte
        Dim donnee As String
        ComPort.Read(trame, 0, nb_octet) 'on lit le port
        donnee = System.Text.Encoding.ASCII.GetString(trame) ' on récupère les données au format ASCII
        'invocation du délégué avec 2 paramètres
        Me.Invoke(New DelegateComPort(AddressOf ChangeValue), num, donnee)
        'incrémentation du numéro
        num += 1
        'délai de 1 seconde
        Threading.Thread.Sleep(1000)
    End Sub

    Private Sub ChangeValue(Numero As Integer, Donnees As String)
        'boucle sur chaque controle du formulaire
        For Each txtb As Control In Me.Controls
            'si le contrôle est un textbox
            If TypeOf txtb Is TextBox Then
                'et que son tag est égal au numéro
                If CType(txtb.Tag, Integer) = Numero Then
                    'on affiche les données
                    txtb.Text = Donnees
                End If
            End If
        Next
    End Sub
End Class
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Utilisateur anonyme
Utilisateur anonyme - 13 nov. 2012 à 18:22
+3
Utile
il y a t'il un moyen de transférer les données reçues sur un Usb vers un port COM virtuel

Regarde si sur ton cd d'installation vendu avec ton dispositif, il n'y a pas un driver qui permet d'émuler un port COM.
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Utilisateur anonyme
Utilisateur anonyme - 14 nov. 2012 à 12:24
+3
Utile
A mon avis, il y a un (ou plusieurs) caractère supplémentaire à la fin de ta chaîne. Peut-être un retour de ligne ou autre.
Tu devrais compter la longueur de la chaîne pour t'en assurer.
MessageBox.Show(donnee.length.tostring)

Ensuite, à toi d'adapter ton code en conséquence afin d'éliminer ces caractères indésirables.
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Utilisateur anonyme
cs_ShayW 3238 Messages postés jeudi 26 novembre 2009Date d'inscription 14 mars 2018 Dernière intervention - 14 nov. 2012 à 12:33
+3
Utile
Salut

Pourtant, quand je fais une msgbox(donnee), j'ai bien le texte


sers toi de l'espion possible que donnee a un caractère invisible
ajoutes la ligne pour tester

If donnee.length = "G0cr".length Then 
 COMPort5.WriteLine("Model HD2102-2") 
end if 
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de cs_ShayW
botbot1607 - 12 nov. 2012 à 21:54
0
Utile
Bonsoir banana32,

Merci pour ton aide, en revanche je pense que j'ai fait fausse route dans mon raisonnement (car dans notre code on met la même donnée reçue du port COM dans les textbox, mais il faut que chaque textbox contienne un relevé du port COM), j'ai du un peu remanier le fonctionnement de mon code :

J'ai fait une boucle qui met le focus sur les textbox de 1 à 6, avec une pause de 1 seconde entre chaque focus.
Lorsqu'une textbox à le focus, sur l'évènement il faut que je fasse appel à la fonction pour lire le port COM.

 Private Sub SéquenceTEST_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SéquenceTEST.Click
        
        Dim j As Integer = 1
        For j = 1 To 6
            Me.Controls("TextBox" & j).Focus()
            System.Threading.Thread.Sleep(1000)
            Me.Refresh()
        Next j
        
    End Sub


Mais je n'arrive pas a l'appeler, sais tu comment faire ?

Private Sub SerialPort1_DataReceived(sender As Object, e As System.IO.Ports.SerialDataReceivedEventArgs) Handles ComPort.DataReceived


La fonction prend deux paramètres, mais je ne sais pas comment les manier...

merci
Commenter la réponse de botbot1607
Utilisateur anonyme - 13 nov. 2012 à 00:23
0
Utile
Tu vas devoir faire intervenir un thread dans ton projet afin que Thread.Sleep ne bloque pas le thread principal.

Dans la procédure exécutée par ton thread secondaire, tu dois mettre en oeuvre une boucle do/loop avec une pause (sleep) ainsi qu'une invocation d'un délégué chargé de donner le focus à l'un des textbox de ton formulaire.

Dans une procédure commune à tous tes contrôles et abonnée aux événements GotFocus ( handles txt1.gotfocus, txt2.gotfocus...), il te suffira de lire les données sur ton serialport et d'afficher les données en récupérant l'objet sender par cast (directcast).

Je vais quitter mon poste maintenant mais te donnerai plus de précisions si besoin

Essaie déjà de ton côté.
Commenter la réponse de Utilisateur anonyme
cs_ShayW 3238 Messages postés jeudi 26 novembre 2009Date d'inscription 14 mars 2018 Dernière intervention - 13 nov. 2012 à 09:38
0
Utile
Salut

si cela peut t' aider

ici
Commenter la réponse de cs_ShayW
botbot1607 - 13 nov. 2012 à 16:32
0
Utile
Bonjour, merci pour vos réponses !

Enfet, j'ai revu encore une fois totalement le code, pour finalement y parvenir grâce au 1er principe de banana32 :)

Je fait une boucle jusqu'à ce que la dernière textbox soit remplie :

Je scanne le port COM
Je délègue le résultat a la textbox(i)
J'envoie COMPort.WriteLine("TX") -> Voir en dessous le but...
Je RAZ les données reçues du port COM
J'attends une seconde...
j'incrémente i
... Loop


le "COMPort.WriteLine("TX")" me sert à faire un test tant que je n'ai pas connecté mon dispositif au PC (attente du câble de transfert).
Via un 2ème soft programmé en VB (COM4 et COM5 ports virtuels reliés en câble virtuel Null Modem), lorsque ce soft reçoit des infos sue le portCOM5, il renvoie une info à COM4 dans mon 1er soft avec les textbox.
Enfet, il simule mon dispositif relié au PC...


Voici mon code :

Public Class Form1
    Shared donnee As String
    Shared j As Integer = 2
    Public Event DataReceived As SerialDataReceivedEventHandler
    Public Declare Sub Sleep Lib "kernel32" (ByVal SleepP1l0u As Long)
    'Private Declare Sub Sleep Lib "kernel32" (ByVal lngMilliSeconds As Long)
    'numéro incrémenté
    Dim num As Integer
    'délagué invoqué
    Delegate Sub DelegateComPort(ByVal Numero As Integer, ByVal Donnees As String)

    Private Sub SerialPort1_DataReceived(sender As Object, e As System.IO.Ports.SerialDataReceivedEventArgs) Handles ComPort.DataReceived
        Do While (TextBox29.Text = donnee)
            Dim nb_octet As Integer = COMPort.BytesToRead ' on récupère le nombre d'octet présent dans le tampon
            Dim trame(nb_octet) As Byte ' Tableau acceuillant les données au format byte
            Dim donnee As String
            COMPort.Read(trame, 0, nb_octet) 'on lit le port
            donnee = System.Text.Encoding.ASCII.GetString(trame) ' on récupère les données au format ASCII
            'invocation du délégué avec 2 paramètres
            Me.Invoke(New DelegateComPort(AddressOf ChangeValue), num, donnee)
            'incrémentation du numéro

            'délai de 1 seconde
            Threading.Thread.Sleep(1000)
            COMPort.WriteLine("TX")
            donnee = ""
            num = num + 1
        Loop
    End Sub

    Private Sub ChangeValue(ByVal Numero As Integer, ByVal Donnees As String)

        Dim i As Integer
        i = Numero + 2

        Me.Controls("TextBox" & i).Text = Donnees



    End Sub



J'ai juste un petit bug, de temps en temps j'ai une textbox qui prend 2 valeurs "donnee", et la suivante ne prend rien comme valeur, comme si le timer ne suivait pas, qu'il allait trop vite.
Pourtant, j'ai essayé de le mettre à 0.5s, 1s, 2s, même résultat... à suivre...

Tant que je vous tiens, mon câble de transfert sera en Usb (oups, j'aurais du prendre en port COM...), il y a t'il un moyen de transférer les données reçues sur un Usb vers un port COM virtuel ?

Merci à vous, bonne journée !
Commenter la réponse de botbot1607
botbot1607 - 14 nov. 2012 à 12:14
0
Utile
Exact, enfet, mieux que ça :

Le soft installe un pilote pour la connexion en usb. Ce pilote s'appelle "TUSB3410".
Après quelque recherche, il s'agit visiblement d'un chip de Texas instrument qui converti des données RS232 en USB. Ensuite, il crée un port COM virtuel sur le PC pour recevoir ces données... impeccable donc

J'ai aussi résolu mon bug de desynchro entre la réception de data et l'affichage dans les textbox, j'ai juste reculé en dernier la lige de commande pour la pause de 1 seconde dans mon code, et là plus aucun soucis !

Par contre une petite question :

J'ai poussé un peu les fonctionnalités de mon programme qui simule mon dispositif.
Je lui envoie une commande "G0cr", il doit me renvoyer le nom de l'appareil... J'essaye donc :

Programme Principal :



 Private Sub Button2_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
  COMPort.WriteLine("G0cr")
End sub



Private Sub SerialPort1_DataReceived(sender As Object, e As System.IO.Ports.SerialDataReceivedEventArgs) Handles ComPort.DataReceived
        Do While (TextBox29.Text = donnee)
            Dim nb_octet As Integer = COMPort.BytesToRead ' on récupère le nombre d'octet présent dans le tampon
            Dim trame(nb_octet) As Byte ' Tableau acceuillant les données au format byte
            Dim donnee As String
            COMPort.Read(trame, 0, nb_octet) 'on lit le port
            donnee = System.Text.Encoding.ASCII.GetString(trame) ' on récupère les données au format ASCII

            If donnee = "Model HD2102-2" Then
                MsgBox(donnee)
                Me.Label9.Text = donnee
            End If





Programme émulateur :

        Dim nb_octet As Integer = COMPort5.BytesToRead ' on récupère le nombre d'octet présent dans le tampon
        Dim trame(nb_octet) As Byte ' Tableau acceuillant les données au format byte
        Dim donnee As String

        COMPort5.Read(trame, 0, nb_octet) 'on lit le port
        donnee = System.Text.Encoding.ASCII.GetString(trame) ' on récupère les données au format ASCII
        If donnee = "G0cr" Then
            COMPort5.WriteLine("Model HD2102-2")
        End If


Avec un mode pas à pas détaillé, il s'avère qu'il ne remplit pas la condition suivante dans mon programme émulateur :

If donnee = "G0cr" Then
COMPort5.WriteLine("Model HD2102-2")

Pourtant, quand je fais une msgbox(donnee), j'ai bien le texte G0cr... !

Auriez-vous une idée ?

Merci beaucoup
Commenter la réponse de botbot1607
cs_ShayW 3238 Messages postés jeudi 26 novembre 2009Date d'inscription 14 mars 2018 Dernière intervention - 14 nov. 2012 à 12:35
0
Utile
bonjour banana32
les messages se sont croisés
bonne journée
Commenter la réponse de cs_ShayW
Utilisateur anonyme - 14 nov. 2012 à 13:39
0
Utile
Bonsoir ShayW,

Bonne journée à toi aussi
Commenter la réponse de Utilisateur anonyme
botbot1607 - 23 nov. 2012 à 13:43
0
Utile
Ok merci a vous deux et désolé pour le temps de réponse... !

C'était bien ça le problème, résolu donc :)
Commenter la réponse de botbot1607

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.