cs_CHARLI78
Messages postés8Date d'inscriptiondimanche 9 avril 2006StatutMembreDernière intervention14 avril 2006
-
11 avril 2006 à 09:13
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 2014
-
14 avril 2006 à 15:06
Bonjour à tous,
Je suis nouveau sur le forum, et novice en POO... J'utilise Delphi 4.
Je souhaite utiliser Tcomport pour recevoir des trames de données binaires à 9600 bauds. Elles sont émises par un microcontroleur. La trame fait toujours 10 octets, mais la cadence à laquelle elles sont émises par le UC change (de 2 trames secondes à 10 trames secondes). Il n'y a pas de contrôle de flux, donc le UC envoie autoritairement ces trames de données binaires.
J'ai essayé de les récupérer à l'aide de OnRxChar, avec Comport.read(data,1). Je lis donc mes octets un par un puis les visualise à l'aide de Memo.text.
Ca marche à peu près, mais j'ai rencontré les problèmes suivants:
- Si l'émission des trames s'interrompt, mon affichage de données s'interrompt aussi alors que le buffer contient encore une cinquantaine de data. Je m'en suis apperçu en reprenant l'émission avec des trames de tests (donc différentes au niveau des datas), et les 50 (environ) premières datas affichées correspondaient à des anciennes données stockées dans le buffer.
- Si la trame est composé de la valeur 0 (en binaire et non pas le caractère), cette valeur ne semble pas vu par comport.Read. J'ai vu sur le forum qu'un autre développeur a rencontré exactement le même problème. Il n'y a pas eu de solution proposé, et il a contourné le problème en générant des trames ASCII et non pas binaire. Dans mon application je ne peux pas modifier le format des trames de données reçues. Je suis donc condamné à trouver une solution.
Mes questions: - Le composant TCOMPORT est il conçu pour recevoir des données binaires? Si oui, y a-t-il un paramétrage à effectuer pour l'informer d'interpréter correctement une donnée reçue?
- Comment résoudre le traitement de la valeur 0 lors d'une réception?
- Comment utiliser Tcomport pour que les datas reçues soient instantannément lues au lieu d'être stockée plus ou moins longtemps dans le buffer?
- Quelqu'un peut il me faire parvenir un programme fonctionnel complet pour Delphi 4 utilisant Tcomport pour recevoir des trames binaires sans contrôle de flux afin que je comprenne bien toutes les subtilités afin de ne pas perdre des données en cours de route, ou bloquer le programme à cause d'une absence de Time-out? (Je le redis, je suis totalement novice POO).
cs_shining
Messages postés304Date d'inscriptionlundi 30 décembre 2002StatutMembreDernière intervention10 mars 2012 14 avril 2006 à 11:31
la fonction Sleep est effectivement bloquante, mais fort heureusement ce sont uniquement les messages window qui sont bloqué en attendant le retour de la "main", car si ça bloquait le CPU dans son intregalité il ne serait jamais apte à rendre la main un jour !!! car il ne pourra plus compter l'interval ect.., maintenant explique moi pourquoi dans mon Application de carte à puce, lorsque je fait Sleep(25 ms) et que par la suite j'envoi un reset à la carte, j'ai correctement l'ATR, avec un Sleep(5ms) j'en ai que la moitié ??? hum ?, on oubli peut être que l'UART est un micro processeur(presque independant), car effectivement le cpu se charge de la config, néanmoins en cas de reception l'UART place dans le buffer les octets reçus http://perso.wanadoo.fr/michel.hubin/physique/microp/chap_mp3.htm
"FillChar(Buffer , SizeOf(Buffer) , 0);// on vide le buffer" <== concernant le vidage du buffer : lorsqu'on fait une lecture les 1er octets seront écrasés mais si count est inférieur à la taille du tableau il restera des dechets donc autant travaillé convenablement !!! mais bon chacun fait ce qui lui plaît :)
au fait ya une erreur dans mon exemple
if ComPort.InputCount = 2 then il faut mettre à la place
if ComPort.InputCount >= 2 then car si jamais le buffer dépasse 2 Octets la condition précédante ne fonctionnera pas !!!
voilà
PS : Soyez indulgent je suis qu'un simple amateur avec très peu de connaissance en Delphi & en Elecronique :]
proverbe de Lao Tseu:
La vitesse de la lumière étant supérieure à la vitesse du son, bien des gens ont l'air brillants jusqu'à ce qu'ils ouvrent la bouche !!!
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201413 14 avril 2006 à 15:06
pour fillchar Tcomport ne te rendra la main que quand READ(buffer,8)
aura effectivement lu les 8 octets (cette procédure est bloquante) donc
quand tu relist les octets 0 à 7 ont obligatoirement été
surchargés par
TComport maintenant si dans ton programme tu traites les octets situés
après c'est que ton prog a la mémoire courte et que de toute façon tu
traites une valeur non significative que tu l'ais initialisée à 0 ou
pas --->l'initialisation est donc tout à fait inutile et ne fait qu'
alourdir le programme et de consommer du temps CPU (ATTENTION ceci
n'est plus vrai avec readasyncr() qui rend la main quand son buffer
interne est vide )
pour la gestion du port série sous windows (et sur XP en particulier)
on ne lit pas directement les registre de l'UART qui travaille sous
interruption et en fait on lit ce que l'interruption placé dans
un buffer
en gros quand l'UART détecte le bit de stop il déclenche une interruption CPU
cette intrruption vérifie que la mémoire est acceesible pui elle bloque l'accés des thread à la zone mémoire du buffer
il écrit la donnée et met à jour les pointeurs et enfin elle libère l'accès au buffer
En fait une getion de la liaison série bien faite commence par vérifier
si elle à accès à la zone mémoire si oui elle protège cet accès puis
elle lit le nombre de caractères présent dans le buffer puis elle lit
les caractères dont elle à besoin met à jour les pointeurs et rend
l'accès
avec cette procédure il 'y a pas de perte de données c'est la raison
pour laquelle dans un autre post j'ai déconseillè l'utilisation d'une
DLL permettant de lire directement les registre de l'UART d' autant que
dans ce cas on ne mets pas à jour les pointeurs et que l'on fini par
saturer le buffer. Note que même sur les microprocesseurs on met en
place des procédures similaires et qu'un programme bien fait même en
assembleur travaillera sous interruption c'est la meilleure méthode
pour garantir une lecture fiable des données et quand on veut
simplifier cette procédure en lisant directement le registre de données
on est sur que tôt ou tard on aura des erreurs de lecture.
pour ton problème de lecteur de carte à puces ne connaissnt ni ton
programme ni les procédures d'accès à celles là je peux difficillement
te répondre. Plusieurs piste toutefois:
1) buffer du PC non vider aavntde lancer la procédure
2)délai de reconnaissance et d'ouverture longue (par exemple pour un port virtuel d'USB c'est plusieur secondes)
3) quand on passe par un thead comme le fait TCOMPORT le délais moyen
entre la fin de l'envoi et le début de réception est d'environ 16
ms là ce n'est pas l'UART mais lea gestion de Windows qui est en
cause..(si tu attends un thread un sleep<16 ne sert à rien)
4) Temps de rpésonce de la carte trop long par rapport au sleep
vitesse de transmission inappropriée
il y a certainement d'autres causes posibles mais il faudrait se plonger dans les données techniques des cartes pour les trouver
Enfin à l'époque ou on travaillait sous DOS (le vrai pas l'émulation de
XP) il était possible de travailler avec des vitesses de plus de 250kB
avec des temps de latence < 50µs sans perdre un seul octet
maintenant on peut travailler à près de 1Mb mais les temps de matence
ont explosés ce qui fait qu'un PC à 3GHz sous XP est moins performant
qu'un vieux P1 à 100MHz voir qu'un microcontroleur à 20MHz
maintenant pour faire la même routine que l'on faisait avec un inline c'est une vrai galère.
j'ai été voir dans les API de windows le sleep ne bloque que l'application en laissant la main à windows