IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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.NET Discussion :

Communication avec un port série


Sujet :

VB.NET

  1. #1
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Australie

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2011
    Messages : 6
    Points : 4
    Points
    4
    Par défaut Communication avec un port série
    Bonjour,

    Voila j'ai établie ce programme avec VB.net, pour lire une valeur de variation d'un débit d'un gaz sur un capteur qui est un débitmètre.
    Pour communiquer avec ce débitmètre, il faut envoyer une requête, une adresse qui est du genre "!11,f" ,elle dépend du protocole au fait, bref....
    Quand j'utiliser les instruction simple sur vb ,write et read, j'avais un problème, qui était que mon interface se figeait,et les auutre fonctionnalité sur l'interfae ne répondait pas tel un button ,textbox,.....c'est pour cela j'ai utiliser une autre solution qui est "backgroundworker" ,qui permet d'executer mes lecture et écriture du port en arrière plan quoi,....sans que l'interface se fige

    Donc voila le programme, aprés je mettrai mes autres questions si vous le permettrez :

    ça c'est la déclaration d'un chemin qui relie le label du premier thread à l'instruction de lecture de donnée du 2éme thread
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Private Delegate Sub SetTextBoxTextDelegate(ByVal text As String)
    ça c'est l'affichage de ma valeur sur un label
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Private Sub SetTextBoxText(ByVal text As String)
    Me.Label13.Text = text.Substring(4)
    End Sub
    ça c'est l'execution de mon code sous l'instruction backgroundworker
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
     
     
    Do
    com1.Write("!11,f" & ControlChars.CrLf)
    Me.Invoke(New SetTextBoxTextDelegate(AddressOf SetTextBoxText), com1.ReadLine())
    Loop
    End Sub
    'Normalement l'arrêt du programme ?! mais ça ne marche pas
    Private Sub terminus(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    BackgroundWorker1.CancelAsync()
    End Sub
    Voila jusqu'à là,je reçois le plus normalement les données affichées sur mon label13

    Les questions sont :
    1.Pourquoi je peux pas tout simplement arrêter mon backgroundworker ,même en utilisant la portion du code citer précédemment?
    2.j'ai ajouter d'autres instructions write et read, dans le même backgroundworker, mais ça répond pas en même temps que les précédant ? normalement ça peut se faire ?
    3.comment utiliser l'instruction "System.Threading.Thread.Sleep",pour mettre en pause le backgroundworker?

    Voila merci de vos réponses.

  2. #2
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 493
    Points
    5 493
    Par défaut
    Bonsoir.

    1./ Parce que l'événement RunWorkerCompleted n'est jamais appelé, pour la simple raison que la boucle ne se finit jamais. RunWorkerCompleted n'est invoqué que si la méthode du backgroundworker atteinte ton terme. CancelAsync est fait pour être appelé en réacton à un clic sur un bouton "annuler" par exemple, ou la fermeture du formulaire.

    2./ Comment ça ? Les instructions s'exécutent les unes à suite des autres, comme sur ton thread principal, pas toutes en même temps. Qui plus est, tous les threads du système d'exploitation se partagent le CPU et chacun d'entre eux peut être mis en attente pour plusieurs millisecondes.

    3./ Sleep(500) ordonne au thread de dormir 500 ms. Par exemple : Thread.Current.Sleep(500); En-dessous de 15ms le temps spécifié n'est pas significatif avec les réglages par défaut de l'OS (tu auras 15ms même si tu as mis 1ms).
    Si tu cherches un moyen d'endormir et réveiller le thread à volonté, en réaction à un événement extérieur, regarde plutôt du côté des WaitEventHandle.
    Thread à endormir : waitHandle.WaitOne(); // met le thread en sommeil, on peut aussi spécifier une durée max
    Thread UI : waitHandle.Set(); // réveille le thread endormi

  3. #3
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 177
    Points : 25 125
    Points
    25 125
    Par défaut
    merci d'utiliser la balise code pour que ca soit lisible

    si tu as plusieurs capteurs, il est alors préférable de séparer tout ca, à savoir un thread qui lit les données et rempli des objets capteur, et un timer simple qui va lire les données de ces objets pour afficher les infos sur l'interface (et donc pas besoin de délégué au passage ^^)

    NB : CancelAsync ne fait rien , il flag seulement un booléen, et c'est à toi de le tester, idéalement dans une boucle, pour arreter le thread

  4. #4
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 442
    Points
    4 442
    Par défaut backgroundworker & serialport com
    bonjour Artist
    Utiliser un backgroundwork (2eme thread) avec un serialport qui lui-meme s'execute deja sur un 2eme thread different de celui de l'UI,me semble bien complique .
    (au passage beaucoup d'users tente d'utiliser un serialport directement sur l'ui d'ou leurs deboires lorsqu'ils tente de mettre à jour l'UI).
    La solution du serialport a ete deja evoque dans le forum .
    C'est d'utiliser plus simplement l'evenenement DataReceived du serialport et BeginInvoke dans le thread du serialport comme dit dans la doc msdn .
    un exemple code:
    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
     
     
    Imports System
    Imports System.IO.Ports
    Public Class frmDataReceveid
        Private Delegate Sub SetLabelDelegate(ByVal text As String)
        Private objDelegate As SetLabelDelegate
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            objDelegate = New SetLabelDelegate(AddressOf setLabel)
     
            SerialPortCOM1.BaudRate = 9600
            SerialPortCOM1.Parity = Parity.None
            SerialPortCOM1.StopBits = StopBits.One
            SerialPortCOM1.DataBits = 8
            SerialPortCOM1.Handshake = Handshake.None
            SerialPortCOM1.Open()
        End Sub
        'Il faut passer par Control.BeginInvoke car le thread du serial port
        'n'est pas le meme que celui de l'interface(thread principal)
        Private Sub SerialPortCOM1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPortCOM1.DataReceived
            Dim sp As SerialPort = CType(sender, SerialPort)
            sp.Write("!11,f" & ControlChars.CrLf)
            's'il y a des data à lire 
            If sp.BytesToRead > 0 Then
                Dim InData As String = sp.ReadExisting()
     
                Me.BeginInvoke(objDelegate, New Object() {InData})
                'ou delai d'attente depasse 
            ElseIf sp.ReadTimeout > 1000 Then
                Dim InData As String = "pas de donnees...."
                Me.BeginInvoke(objDelegate, New Object() {InData})
            End If
        End Sub
        Private Sub setLabel(ByVal text As String)
            Me.Label13.Text = text.Substring(4)
        End Sub
     
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            SerialPortCOM1.Close()
        End Sub
    End Class
    bon code.....

Discussions similaires

  1. Communication avec un port série
    Par Cacophrene dans le forum Caml
    Réponses: 1
    Dernier message: 13/08/2014, 10h53
  2. Communication avec un port série
    Par Yann_69 dans le forum Android
    Réponses: 0
    Dernier message: 03/04/2013, 17h27
  3. Communication avec le port série
    Par Jackyzgood dans le forum C
    Réponses: 2
    Dernier message: 12/02/2011, 21h38
  4. Problème de communication avec un port série
    Par hélène2 dans le forum C#
    Réponses: 8
    Dernier message: 22/04/2009, 09h26
  5. Code VBA pour communication avec un port série dans EXCEL
    Par Fbroom dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 30/05/2008, 10h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo