jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201413 29 oct. 2005 à 21:21
salut,
plusieurs choses dans ton code risque de provoquer un plantage:
utilise plutot la methode readstr que read
quand tu reçois une trame il ne faut jamais considéré qu'un seul caractere à été reçu;
utilise la fonction InputCount pour recuperer le nobre de carcteres reçus;
L:= form2.Comport3.InputCount.;
form2.Comport3.ReadStr(octet,L);
Si le premier octet de la chaine est toujours $ tu peux utiliser la
propiete eventchar:= $ et placer la reception de la chaine dans
OnRxChar.
quand tu fais form2.comport3.read(octet[1],1); il n'est pas sur
que octet soit initialiser (erreur indice hors limites) de même pour
form2.comport3.read(octet[k],1);
pour lire une chaine de 80 octets la meilleure methode est:
while form2.Comport3.InputCount.<(80-L) do begin end ;// attendre que la chaine soit complete tenir compte du nombre de caracteres lus
L: = form2.Comport3.InputCount.;
octet:=octet+form2.Comport3.ReadStr(buffer,L);// on conserve le resultat precedent et onutilise un buffer intermediaire pour le complement
j'ai encore un petit soucis, car je veux stocker chaque nombre de ma
trame dans un tableau, ceci doit etre un tableau d'integer car je
manipule des nombres.
j'ai fait:
for k:6 to 80 do
form2.comport3.read(octet[K],1) // me permet de stocker dans un tableau tout les nombres y compris les virgules, point et lettre.
Ceci marche bien, mais certaine fois ceci m'envoi un message d'erreur
et la fonction saute des nombres de temps en temps. je n'ai pas
très bien compris comment faire avec la solution que tu m'a donnée car
je ne veux pas l'afficher directement mais la décomposer pour
l'afficher dans des "Edittext".
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201413 31 oct. 2005 à 16:07
salut,
quel message d'erreur te renvoie-t-il?
note pour info que 4000.1021 n'est pas un integer mais un reel. Il faut
que tu declares un Array [0...XXXX]of real; sinon tu planteras à la
conversion.
pour lire le port Com il vaut lire la trame en 1 seule fois:
var recept:string;
Long:integer= 0;
while Long<80 do Long:= form2.Comport3.InputCount.; // attendre la totalite de la trame
form2.Comport3.ReadStr(Recept,Long);// la recevoir en 1 fois ça ne prend pas plus de temps
pour afficher ou stoker les valeurs dans un
tableau il faut les extraire de la trame en utilisant la fonction copy
( copier dans une variable chaine temporaire ce qui est compris entre 2
séparateurs de champ : "," ) ensuite tu peux soit afficher
cette variable dans un TEdit soit la convertir avec la fonction
StrToFloat .... ou les deux
cela pourrai donner quelque chose comme cela:
procedure TForm1.Button2Click(Sender: TObject);
var temp,temp1:string;
valeur:real;
i:integer;
begin
temp: =edit1.Text;
i:= posEx(',',temp,1);delete(temp,1,i);
while i<>0 do
begin
temp1:= copy(temp,1,i-1);//extraction de la chaine
delete(temp,1,i);// suppression de la chaine
temp1:=Ansireplacetext(temp1,'.',','); // met le decimalseparator correct
// valeur: = strtofloat(temp1);
edit1.Text:= temp1;
i:=pos(',',temp);
end;
temp1:=temp; // recuperer la derniere valeur
temp1: =Ansireplacetext(temp1,'.',',');
edit1.Text:=temp1;
end;
bon ici j'ai mis une boucle while pour tester à toi d'adapter le code à tes besoins ( en partciulier si tu fais valeur:= strtofloat(temp1); sur une variable non numérique tu auras une erreur d'exécution
bonne prog
Vous n’avez pas trouvé la réponse que vous recherchez ?
bibidimu
Messages postés13Date d'inscriptionmercredi 26 octobre 2005StatutMembreDernière intervention27 septembre 2010 31 oct. 2005 à 16:55
Je n'ai pas la possibilité de recevoir un par un ma trame pour pouvoir stocker dans un tableau d'integer?
Moi je pensais faire un comport3.read pour chaque morceaux reçus car
j'utilise un prog développé sous delphi1 et ceci était fait de cette
manière seulement ce n'était pas comport qui était utilisé.
octet: array[1..80] of integer;
comport3.read(0ctet [1],1);
comport3.read(0ctet [2],1);
comport3.read(0ctet [3],1);
ceci fonctionne mais il y a des rater de temps en temps, il ne lit pas
bien tous les données reçu, il doit en sauter. On ne peut pas remedier
en gardant cette même structure.
for k:6 to 80 do
form2.comport3.read(octet[K],1)
pourquoi ceci ne fonctionne pas, car ceci serai possible
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201413 31 oct. 2005 à 17:35
salut,
dans la trame que tu donne comme les valeurs sont envoyées comme des
chaines de caracteres tu ne peux donc pas les affecter directement à
des variables integer tu dois convertir en valeur numerique. verifie le
format de la trame en l'affichant dans un edit (si le nombres sont
transmis sous un format numerique ils seront illisible) si tu la lis
comme tu l'indique alors ils sont transmis sous forme de chaine (en
principe c'est le cas c'est le seul format qui puisse être interpreté
par tous les langages).
si le format est numerique la ça se complique le coordonnée GPS étant
des reels il faut connaitre le format de codage ('C' et DELPHI ne
codent pas les valeurs numeriques de la même façon)
les valeurs transmises comme 4000.1021 ne sont pas des integer mais des reels.
la syntaxe de read est : read(var buffer:non typé,count:integer);
ce qui veut dire que tu dois renseigner comport de la longueur de
la variable transmise donc si la variable est un integer count =
4 . Quand tu fais : comport3.read(0ctet [1],1); read transmet UN
caractere (8bits) à la cellule indicée or pour un integer il faut 4 octets (32 bits)
si la trame est constituée de chaines utilises la procedure que je t'ai donnée; elle pose moins de problémes.
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201413 31 oct. 2005 à 18:09
si ta trame est parfaitement definie tu peux aussi utiliser le
composant TCompDataPacket il te permet d'automatiser la réception en
detectant les débuts et fins de trame.
bibidimu
Messages postés13Date d'inscriptionmercredi 26 octobre 2005StatutMembreDernière intervention27 septembre 2010 1 nov. 2005 à 10:07
Je pars sur un autre sujet, j'aimerais savoir comment faire pour
recevoir et transmettre des données par ethernet. J'ai vu que l'on
pouvait utiliser TCPclient mais je ne sais pas comment l'utiliser. De
plus connait tu un livre qui pourrait m'aider à programmer en delphi
car je commence tout juste et je ne connais pas grand chose.Je dois
transformer un programme fait sous delphi1 en delphi 2005 et j'ai plein
de pb comme tu as pu le voir.
Sous delphi1 lorsque l'on veut transformer en string on fait:
str(toto :3:2,chaine)
edit2.text: = chaine.
Ceci permet de limiter à 2 chiffres après la virgule, comment faire en delphi 2005 car ceci ne fonctionne pas.
Lorsque je fais
str(toto,chaine)
edit2.text = chaine j'obtient dans l'edit2: 1.200000000000E+01 et moi je veux 12.00
bibidimu
Messages postés13Date d'inscriptionmercredi 26 octobre 2005StatutMembreDernière intervention27 septembre 2010 3 nov. 2005 à 14:04
Salut c encore moi, j'aimerais avoir un renseignement sur le composant Port Com.
Lorsque je met une condition "eventschar" dans les propriété ($), normalement la procedure On RXchar ne devrait pas commencer si je n'ai pas le $. Je n'ai laisser activé que le evRxchar dans "events", pourquoi ce pb.
Sinon pour ma trame GPS j'ai pensé utiliser le composant packet car ma trame contient toujours 80 caractères. J'ai activé le début de ma reception par la reception du "$" mais une fois qu'il à enregistrer mon packet comment le lire. Peux tu me donner un exemple pour lire la trame que j'ai reçu.
J'ai commencer par:
procedure TForm2.ComDataPacket1CustomStart(Sender: TObject; const Str: string;
var Pos: Integer);
begin
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201413 3 nov. 2005 à 14:20
pour la reception sur event effectivement la reception ne commence
qu'apres reception du caractere '$' . Je teste çà avec la carte
microcontroleur.
pour la reception de packet je pense que ton probleme vient de la
declaration de ta variable octet comme pour l'évent je le teste et je
te tiens au courant.
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201413 3 nov. 2005 à 17:09
je n'arrive plus à faire fonctionner le datapacket (il y a longtemps que je ne l'ai pas utilisé)
le onRxchar me pose également quelques soucis de blocage intempestif de windows.
j'en suis donc revenu à ma méthode habituelle (on ne change pas une équipe qui gagne!!)
2 solutions:
la plus simple si c'est toi qui demande l'envoie des coordonnées:
procedure TForm1.Button1Click(Sender: TObject);
var str:string;
i:integer;
begin
edit1.Text:= '';
if not Com1.Connected then Com1.Open; // on ouvre le port
Com1.ClearBuffer(true,true);//on vide les buffer E/S
Com1.WriteStr('v');//on envoie la commande (le 'v' est propre à ma carte en fait j'ai mis la trame dans le nom de version!!
while Com1.InputCount<80 do begin end;// on attend la totalisté de la trame
i: =Com1.InputCount;//on va chercher le nombre de caracteres
Com1.Readstr(str,i);// on lit la totalité de la trame
edit1.Text:= str;
Com1.Close; //on ferme le port
end;
la seconde dans le cas d'un flux continu:
procedure TForm1.Button2Click(Sender: TObject);
var str,str1:string;
i:integer;
begin
edit1.Text: ='';
if not Com1.Connected then Com1.Open;//pour l'essai
Com1.ClearBuffer(true,true); // ""
Com1.WriteStr('v');
// ""
while ( pos('$',str)= 0) do // on attend le debur de trame
begin
i: =Com1.InputCount; //on lit tout ce qu'il y a dans le buffer
Com1.Readstr(str1,i);
str:= str+str1;str1:='';
end;
if pos('$',str)<>1 then delete(str,pos('$',str)-1,pos('$',str)) ;//on normalise le buffer
while length(str)<80 do //on attend le reste de la chaine
begin
i: =Com1.InputCount; //on lit tout ce qu'il y a dans le buffer
Com1.Readstr(str1,i);
str:= str+str1;str1:='';
end;
delete(str,81,length(str)); //on reduit la chaine à 80
// Com1.Close;
edit1.Text: =str;
end;
Attention dans la lecture en continu la maintient du port ouvert
peut engendrer de dysfonctionnement ( emulation d'un com par un usb
--> plantage par un plug and play d'un autre usb : ça m'est arrivé)
En conclusion il vaut mieux passer par le routines de lecture de
chaines : elles sont plus fiables et plus simples à mettre en oeuvre.
ensuite il ne te reste plus qu'à extraire les valeurs en utilisant les separateurs de champs et à le convertir en nombre reels.
utlise:
function PosEx(const SubStr, S: string; Offset: Cardinal = 1): Integer;
et copy(); pour extraire et strtofloat pour convertir.
bibidimu
Messages postés13Date d'inscriptionmercredi 26 octobre 2005StatutMembreDernière intervention27 septembre 2010 4 nov. 2005 à 16:02
J'ai enfin réussi à séparer tout les éléments qui constitue ma trame GPS grâce à ta méthode mais il me reste un autre problème car je veux convertir certain de ces éléments en real et là j'ai un message d'erreur lorsque je veux convertir l'octet[3] qui est pourtant égale à "500.222":
Message:EconvertError avec le message"' n'est pas une valeur en virgule flottante correcte'
procedure TForm2.ComDataPacket1CustomStart(Sender: TObject; const Str: string;
var Pos: Integer);
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201413 5 nov. 2005 à 10:29
salut,
c'est pas normal.Je pense que cela peut venir du decimalseparator (bizarre)
force le à ',' en faisant decimalseprator:=',';
essaie aussi si tu as bien affiché edit6.Text:= 500,222 de faire:
octetA[3]:= strtofloat(edit6.Text);
sinon verfie que ta chaine ne contient pas de caracteres indesirables
et non visibles en controlant sa longueur avec
length(octet[3]) dans ton cas tu dois avoir 7;