fantasio36
Messages postés21Date d'inscriptionmercredi 30 juillet 2008StatutMembreDernière intervention 3 octobre 2011
-
30 sept. 2008 à 06:20
masbaby
Messages postés2Date d'inscriptionvendredi 10 juillet 2009StatutMembreDernière intervention22 août 2009
-
22 août 2009 à 23:41
Re-Bonjour a tous, je suis mega bloque depuis une bonne semaine........A l'aide!!
J'attends dans une routine une lecture de 1024 bytes sur le port COM que je dois lire par paquet de 64 bytes. Mon probleme est que je n'arrive pas a lire l'event de reception qui a lieu dans la routine dediee dans une autre partie du soft. Du coup je me retrouve bloque et il me faudrait sortir de cette routine de lecture pour que l'event de reception puisse etre leve, puis retour dans ma routine de lecture....bref, comment est-il possible par exemple de mettre un flag a 1 dans ma routine de reception, sachant que cette routine de reception doit pouvoir venir interrompre l'execution de ma routine d'attente de mise a 1 de ce flag? Ou bien est-il possible de faire autrement??? Si c'est pas clair, je peux donner plus de details!!
leprov
Messages postés1160Date d'inscriptionvendredi 23 juillet 2004StatutMembreDernière intervention21 octobre 201017 30 sept. 2008 à 09:33
Non cest carrément pas clair. Pour lire dans un port COM, en général on a deux solutions :
1 - s'abonner a l'event datareceived de l'objet serialport et lire dans la méthode handler de l'event
2 - créer un thread, puis lire en boucle dans ce thread. A priori dans ton cas, le mieux est d'utiliser cette solution. tu lis les données en boucle jusqu'a ce que ta trame soit complète, et une fois que cest le cas, tu la traite, puis tu te remet en attente de lecture (le mieux étant de fournir cette trame à un autre thread qui s'occupera de gérer tout ca, pour ne pas interrompre la lecture au cas ou quelque chose d'autre arriverait)
maitredede
Messages postés153Date d'inscriptionvendredi 9 août 2002StatutMembreDernière intervention18 septembre 2009 30 sept. 2008 à 09:39
Sinon, tu peux aussi utiliser la propriété BaseStream de ton SerialPort, et là tu peux mettre ce que tu veux comme Stream avec. De plus, tu peux l'utiliser en asynchrone, ce qui ne nécessitera pas de gérer un autre thread (comme gérer l'arret de ce thread à l'arret du programme).
Je commence a croire qu'il me faut faire du multi threading, mais pour le moment rien ne fonctionne du tout!!
En fait sur un microcontrolleur on a une interruption de generee lorsque je recois une trame sur le COM, mais je n'arrive pas a faire qqchose de similaire sur le visual C#. Je reste desesperement bloque sur le test du flag de reception....
Ton aide/suggestions sont grandement les bienvenus!! Et si c'est tjrs pas clair, n'hesite pas a me le faire savoir!
Merci,
Florent
Vous n’avez pas trouvé la réponse que vous recherchez ?
maitredede
Messages postés153Date d'inscriptionvendredi 9 août 2002StatutMembreDernière intervention18 septembre 2009 30 sept. 2008 à 09:54
Essaie ce code :
byte[] requette;
//requete pour 64 bytes
COMPort.Write(requette, 0, 19);
List trame = new List();
byte[] buffer = new byte[64];
while (trame.Count < 1024)
{
//Réception de 64bits
COMPort.BaseStream.Read(buffer, 0, buffer.Length);
//stocke le buffer dans la trame
trame.AddRange(buffer);
}
//Récupère le buffer complet
buffer = trame.ToArray();
Pas besoin de gérer l'évènement "DataReveived"
Si ça ne marche pas, je t'en mettrait un autre avec de l'asynchrone...
fantasio36
Messages postés21Date d'inscriptionmercredi 30 juillet 2008StatutMembreDernière intervention 3 octobre 2011 30 sept. 2008 à 10:35
Merci pour ta reponse super rapide, je vais essayer cela de suite! Serais-t-il possible que tu me mette l'autre version aussi, asynchrone?? J'ai essaye gras de chose a ce sujet, avec des begininvoke et autres trucs tordus, ca n'a jamais marche!!!
fantasio36
Messages postés21Date d'inscriptionmercredi 30 juillet 2008StatutMembreDernière intervention 3 octobre 2011 30 sept. 2008 à 11:10
Re-salut,
Je viens d'essayer mais les valeurs retournees dans le buffer sont tres bizarres, je me prends pas mal de 0x1f au debut de la trame et le reste des data semblent erronées...Lors de mes precedents essais, j'avais remarque que ca marchait tjrs si j'attendais l'event data_received. Par contre lors de mes essais precedents je faisais un while (COMPort.BytesToRead <= 64); mais ca me donnait aussi au final des data erronees...Est-il possible d'implementer la methode asynchrone dont tu m'as parle?
maitredede
Messages postés153Date d'inscriptionvendredi 9 août 2002StatutMembreDernière intervention18 septembre 2009 30 sept. 2008 à 11:16
Essaie avec celui-là :
byte[] requette;
//requete pour 64 bytes
COMPort.Write(requette, 0, 19);
List trame = new List();
byte[] buffer = new byte[64];
while (trame.Count < 1024)
{
//Réception de 64bits
int read = COMPort.BaseStream.Read(buffer, 0, buffer.Length);
//stocke le buffer dans la trame
for (int i = 0; i < read; i++)
{
trame.Add(buffer[i]);
}
}
//Récupère le buffer complet
buffer = trame.ToArray();
Tes données erronées en début, je ne sais pas... C'est peut-être un résidu de ce qu'il y a dans le buffer de ton port.
Avant d'envoyer ta requête, essaie d'ajouter :
COMPort.DiscardInBuffer();
masbaby
Messages postés2Date d'inscriptionvendredi 10 juillet 2009StatutMembreDernière intervention22 août 2009 30 juil. 2009 à 18:20
Bonjours à tous,
J'ai exactement le meme type de soucis avec le event handler "data_received".
Avec cette methode étant donné que j'envoi des requetes de message avec un thread toute les 80ms (pourtant avec une pause de 80 ms entre chaque envoi) ne permet pas de récupérer les messages arrivé proprement(Ils sont tronqués).
J'ai regardé attentivement vos solutions proposé pour la reception de message mais celle ci ne propose pas de traiter ça dans un autre thread paralléle à l'envoi ou y à t'il une solution plus viable et stable.
maitredede
Messages postés153Date d'inscriptionvendredi 9 août 2002StatutMembreDernière intervention18 septembre 2009 4 août 2009 à 10:44
Bonjour,
Si tes messages sont tronqués, tu dois d'abord les mettre dans un buffer (un MemoryStream ou un tableau de byte) et ne traiter ton message que si il est complet.
fantasio36
Messages postés21Date d'inscriptionmercredi 30 juillet 2008StatutMembreDernière intervention 3 octobre 2011 5 août 2009 à 04:35
Salut,
De memoire je me rappelle ne jamais avoir trouve l'explication a mon probleme de message tronque. Je pense juste qu'il y a un truc louche du cote de l'outil microsoft plutot que du cote de mon code (qui en passant reste une simple application COM port, rien d'extraordinaire...). J'ai du rajoute des flag (volatile bool) avec une tempo de plusieurs centaines de ms qui attend que le bool passe a true dans la routine de reception du com port. Si c'est pas le cas on relance la requete. Une fois que le flag passe a true, la je verifie a l'aide d'un checksum que les data ne sont pas corrompues. Voila, c'est la seule solution qui marche pour moi, je me suis casse les dents sur ce probleme des semaines!!
maitredede
Messages postés153Date d'inscriptionvendredi 9 août 2002StatutMembreDernière intervention18 septembre 2009 5 août 2009 à 09:23
Salut,
Plutôt que d'utiliser une boucle avec une tempo, essaie avec un System.Threading.ManualResetEvent
En gros, ça bloque le thread appelant tant qu'un autre n'a pas dit "T'as le droit de continuer", ou bien que tu aie atteint un timeout. C'est plus propre que les boucles à temporisation.
masbaby
Messages postés2Date d'inscriptionvendredi 10 juillet 2009StatutMembreDernière intervention22 août 2009 22 août 2009 à 23:41
Salut tout le monde,
Desolé de reagir si tardivement j'etais en vacance...
Donc il y a du nouveau quand meme!!
Je ne peux pas metre le thread d'nvoi en attente car ce thraed doit resté constament periodique de 80 ou 100ms (connection avec un peripherique exterieur sera perdu! J'ai testé).
Néanmoins j'arrive maintenant à récupéré des messages si il ne sont pas trop long... dans l'ordre de 10 ou 12 octet environ...
Si le message reçu est plus je recois soit le debut ou soit la fin et ceci peridiquement... l'affichage me l'informe!
Tanto les 8 ou 10 premiers tant les 6,8, 4 derniers et vice versa... J'utilise la dll IO.Port de Visual studio 2005