VB 2012 - Timer qui ne veut pas tourner [Résolu]

cs_Jack 14010 Messages postés samedi 29 décembre 2001Date d'inscriptionModérateurStatut 28 août 2015 Dernière intervention - 16 août 2014 à 18:48 - Dernière réponse : cs_Jack 14010 Messages postés samedi 29 décembre 2001Date d'inscriptionModérateurStatut 28 août 2015 Dernière intervention
- 17 août 2014 à 03:47
Bonjour à tou(te)s

J'ai une bizarrerie que je ne m'explique pas :
Mon application dialogue avec un port série avec un automate qui m'envoie des données toutes les 5 secondes à 9600 bauds - on n'est pas pressé.
La comm fonctionne correctement.

Au lancement de mon appli, j'envoie un signe de vie à mon automate.
A la réception de la réponse, je lance un Timer qui aura pour tâche une sorte de 'ping' pour surveiller la comm (bit de vie).

Seulement voilà : Le timer que je rends ".Enabled" au moment opportun ne s'exécute pas; le Timer_Tick ne se lance pas (Intervale 1000 mS), alors que le "_DataReceived" de mon port série continue à recevoir et traiter mes données.

Par acquit de conscience, j'ai recréé une appli toute propre en copiant/collant le code, procédure par procédure, et le résultat est le même.
J'avoue, je sèche là.

Mon code n'est pas compliqué :
- Ouverture de port COM
- Envoi d'un mot clé pour provoquer une réponse de l'automate.
- Dans le DataReceived, des tests sur les débuts de chaine pour identifier ce qu'on m'envoie.
Parmi les choses qu'on m'envoie, la réponse attendue.
Une fois que j'ai lu cette réponse, je démarre un timer qui va, cycliquement, envoyer un Byte qu'il faut que l'automate me renvoie dans les 10 secondes, en guise de témoin de communication Ok.
--> Et c'est là que ça merdouille : Je rends le Timer Enabled et sa procédure ne se déclenche pas.

Pire que ça, si je ne lance pas la comm série et que je démarre le Timer dans un bouton, il fonctionne !
J'en perds mon latin.
Afficher la suite 

Votre réponse

6 réponses

cs_ShayW 3238 Messages postés jeudi 26 novembre 2009Date d'inscription 14 mars 2018 Dernière intervention - 17 août 2014 à 02:07
+1
Utile
Bonjour
peut etre ici
http://www.vbforums.com/showthread.php?635713-You-can-t-enable-a-timer-from-a-SerialPort-DataReceived-Event

If you want to make it work, do what the documentation says: post the change requests to the appropriate thread. Control.Invoke() does the trick, you just need a delegate to give it:
Code:
Private Sub EnableTimer()
Timer1.Enabled = True
End Sub

Private Sub SerialPort1_DataReceived(...) Handles ...
Timer1.Invoke(New Action(AddressOf EnableTimer))
End Sub

Salut ucfoutu
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de cs_ShayW
Whismeril 11547 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 24 mai 2018 Dernière intervention - 16 août 2014 à 21:05
0
Utile
T'as le bout de code?
Commenter la réponse de Whismeril
ucfoutu 18039 Messages postés lundi 7 décembre 2009Date d'inscriptionModérateurStatut 11 avril 2018 Dernière intervention - Modifié par ucfoutu le 16/08/2014 à 22:14
0
Utile
Bonsoir,
Mon premier réflexe : ton port COM est mobilisé par l'automate qui l'a ouvert et ne saurait recevoir de signaux autres que ceux de ton automate, sauf à le fermer, le rouvrir, et envoyer un byte.
Que se passerait-il (essaye) si, au lieu de tenter d'envoyer un byte depuis le timer, tu affichais un truc (n'importe quoi d'autre s'incrémentant) dans un label ? Si, comme je le pense, le label voyait son affichage se modifier, ce ne serait pas un défaut du timer, mais bel et bien une mobilisation de ton port COM.


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviend
Commenter la réponse de ucfoutu
cs_Jack 14010 Messages postés samedi 29 décembre 2001Date d'inscriptionModérateurStatut 28 août 2015 Dernière intervention - 16 août 2014 à 23:31
0
Utile
Salut ucfoutu.
Bien longtemps que l'on n'a conversé !

Côté communication, tout se passe bien :
mon automate reçoit mon byte; je reçois sa réponse; je passe sur mon instruction
tmrTimeOut.Enabled = True
mais, hélas, la procédure _Tick associée ne se lance pas, alors que si je lance le timer sans avoir démarré ma comm, elle se lance bien.
Mon programme, tout comme ma comm, ne sont pas surmenés; comm lente, des échanges toutes les 5 sec, des timers toutes les secondes; vraiment rien qui expliquerait une éventuelle surcharge.

C'est assez dingue.
Je crois que je vais désinstallé / réinstaller mon Visual Studio; doit y avoir une coquille sans q.
Commenter la réponse de cs_Jack
cs_Jack 14010 Messages postés samedi 29 décembre 2001Date d'inscriptionModérateurStatut 28 août 2015 Dernière intervention - Modifié par cs_Jack le 17/08/2014 à 03:50
0
Utile
Bon, je viens de finir de désinstaller / réinstaller VS sans changement.

Le code; oui, pourquoi pas, mais ça va faire du volume pour pas grand chose.
Juste une interrogation sur la méthode d'utilisation du port COM :
Au début :
Imports System.IO.Ports
Public Class Form1
Private WithEvents PortSerie As System.IO.Ports.SerialPort
Dans le Form1_Load, un saut dans une Sub "InitPortSerie" dans lequel je fais :
        If Not PortSerie Is Nothing Then PortSerie = Nothing
PortSerie = New System.IO.Ports.SerialPort
With PortSerie
.PortName = "COM7" ...
Après avoir ouvert mon port, j'envoie un code à mon automate pour qu'il commence à faire les envois.
Une fois que j'ai reçu la première trame, je lance un Timer qui envoie cycliquement un Byte de valeur aléatoire et que l'automate doit me renvoyer.
Dans le "PortSerie_DataReceived", à la réception de cette première trame, je fais donc un
        tmrTimeOut.Enabled = True

Et là, bah ... rien.
En fait, si je démarre le timer au démarrage (Enabled à True dans la conf du composant), il fonctionne au lancement de l'appli, mais si on le stoppe puis le relance, rien à faire : il ne redémarre pas.
Commenter la réponse de cs_Jack
cs_Jack 14010 Messages postés samedi 29 décembre 2001Date d'inscriptionModérateurStatut 28 août 2015 Dernière intervention - 17 août 2014 à 03:47
0
Utile
Oups;
J'ai déposé un commentaire à mon premier post.
Pas grave, il n'apportait rien.

Par contre, ShayW m'a apporté la solution : le delegate
En détail, ce que j'ai écrit :
En partie déclarative :
Friend Delegate Sub SimpleDelegate()
Puis, la petite Sub d'action :
    Private Sub tmrTimeOut_Enable()
tmrTimeOut.Enabled = True
End Sub
Et dans le PortSerie_DataReceived, j'ai remplacé le fameux
tmrTimeOut.Enabled = True
par
Me.BeginInvoke(New SimpleDelegate(AddressOf tmrTimeOut_Enable))

Ca marche à nouveau et le lien du forum correspondant au même problème.
Je n'y ai pas pensé, grr.
Ce qui est étrange, c'est que l'IDE / Debugger ne m'ait pas averti, au moment d'exécuter la ligne incriminée de ce problème de Delegate.
Sous VS 2010, il me le signalait à chaque fois.
Cette version 2012, en plus d'être esthétiquement moche, semble être plus confuse (encore) que 2010.

En tous les cas, ShayW, un grand grand merci pour cette bonne idée qui apporte la solution.
Commenter la réponse de cs_Jack

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.