Port com

bibidimu Messages postés 13 Date d'inscription mercredi 26 octobre 2005 Statut Membre Dernière intervention 27 septembre 2010 - 29 oct. 2005 à 19:11
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 - 12 nov. 2005 à 13:10
Je veux recevoir une trame GPS sur le port com et tester si elle est correcte.
Lorsque je tape l'expression suivante cela plante


while (octet[1] <> 36) do
begin {recherche du $}
form2.comport3.read(octet[1],1);
end

Ceci me permet de commencer correctement la reception de ma trame et continuer l'enregistrement de ma trame.

for k:=6 to 80 do
form2.comport3.read(octet[k],1);

20 réponses

jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
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

bonne prog
0
bibidimu Messages postés 13 Date d'inscription mercredi 26 octobre 2005 Statut Membre Dernière intervention 27 septembre 2010
30 oct. 2005 à 09:40
merci pour ses infos, si j'ai d'autres pb je t'enverrai una utres messages
0
bibidimu Messages postés 13 Date d'inscription mercredi 26 octobre 2005 Statut Membre Dernière intervention 27 septembre 2010
31 oct. 2005 à 14:44
Salut c encore moi



trame; $GPGGA,112888,4000.1021,N,05000.0058,W,1,04,44.2,00025.45,M,00047.88,M,,0000



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".
0
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
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
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
bibidimu Messages postés 13 Date d'inscription mercredi 26 octobre 2005 Statut Membre Dernière intervention 27 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
0
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
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.
0
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
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.
0
bibidimu Messages postés 13 Date d'inscription mercredi 26 octobre 2005 Statut Membre Dernière intervention 27 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
0
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
1 nov. 2005 à 11:05
pour l'uilisation de TCPclient je ne pourrais pas t'aider (j'utilise les liaisons serie pour piloter de cartes d'extension).

pour debuter en DELPHI utilises les tutoriaux. Vas voir le site http://fbeaulieu.free.fr/guide/

et Delphi documentation

utilise aussi l'aide delphi (quoique je prefere celle de la version 7 à la version 2005);

pour les livres difficiles de te conseiller (ceux que j'utilise ne s'adressent pas vraiment à des débutants)p

pour convertir un reel ou un float en chaine utilise la fonction:

function FloatToStrF(Value: Extended; Format: TFloatFormat; Precision,
Digits: Integer): ce qui te donne: Edit2.text:=floattostrF(Toto,ffFixed
,15,2 )

ffFixed : format a virgule fixe

precision:15

digits: 2 decimales

pour les differentes valeurs de TFloatFormat vas voir dans l'aide

bonne prog
0
bibidimu Messages postés 13 Date d'inscription mercredi 26 octobre 2005 Statut Membre Dernière intervention 27 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


ComPort.Readstr(octet[2],1);
//form2.comport1.ReadStr(octet[2],1);


Form2.edit1.Text:=octet[2];
end;

Ceci ne fonctionne pas, ou est stocker le paquet????????? et comment le lire.

Merci beaucoup pour ton aide tres précieuse.
0
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
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.

jlen
0
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
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.

jlen.
0
bibidimu Messages postés 13 Date d'inscription mercredi 26 octobre 2005 Statut Membre Dernière intervention 27 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);

begin


Form2.edit1.Text:=str;
edit2.Text:=inttostr(pos);


k:=1;
temp:=edit1.Text; / /"$GPGGA,12222,200.3333,N,222222,W,2222.22222......."
i:=posEX(',',temp,1);


while(i<>0) do
begin
i:=posEX(',',temp,1);
octet[K]:= copy(temp,1,i-1); //partie enlevée "GPGGA"
octet[k]:=Ansireplacetext(octet[k],'.',',');
delete(temp,1,i);
k:=K+1;
end;


edit2.Text:=octet[1]; //GPGGA
edit4.Text:=octet[2]; //15555
edit6.Text:=octet[3]; //500,222
edit8.Text:=octet[4]; //N
edit10.Text:=octet[5]; //0000,9999
edit3.Text:=octet[6];
edit5.Text:=octet[7];
edit7.Text:=octet[8];
edit9.Text:=octet[9];
edit11.Text:=octet[10];
edit12.Text:=octet[11];
edit13.Text:=octet[12];
edit14.Text:=octet[13];


if(octet[1]='GPGGA') then
begin


octetA[3]:= strtofloat(octet[3]); // c'est ici le probleme, comment faire
edit15.Text:=floattostr(octetA[3]);
end;


Merci d'avance si tu as le temps de me repondre.Bon week end
0
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
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;

bon WE et bonne prog.
0
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
5 nov. 2005 à 10:50
pour verifier du decimalseparator remplace: octet[3]:=Ansireplacetext(octet[3],'.',',');

par octet[3]:=Ansireplacetext(octet[3],'.',decimalseparator);
0
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
7 nov. 2005 à 09:50
pour l'uilisation de TCPclient vas voir:

http://delphi.developpez.com/cours/?dom=COMPOSANT

il semble intéressant

jlen
0
bibidimu Messages postés 13 Date d'inscription mercredi 26 octobre 2005 Statut Membre Dernière intervention 27 septembre 2010
11 nov. 2005 à 19:12
J'ai un petit soucis car je voudrais séparer la partie entière de la partie décimale. Comment faire??????????

Exemple:

5000,2222

je voudrais séparer en deux:

5000 et 0,2222 pour pouvoir faire des divisions séparement sur ses deux parties.

une fois avoir fait mes divisions je rassemble les deux morceaux en les ajoutants

Merci d'avance
0
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
11 nov. 2005 à 19:41
est ce que tu veux le faire sur la chaine ou sur le nombre?

@+

jlen
0
bibidimu Messages postés 13 Date d'inscription mercredi 26 octobre 2005 Statut Membre Dernière intervention 27 septembre 2010
12 nov. 2005 à 10:07
Je veux le faire sur le nombre puis je le retransformerais en chaine de caractère par la suite.



Merci,@+
0
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
12 nov. 2005 à 13:10
var

valeur,partie_entiere,partie_decimale:extended;

si valeur= 5000,2222

partie_entiere:=int(valeur) //partie_entiere:=5000

partie_decimale: =frac(valeur)//
partie_decimale:=0.2222

@+

jlen
0
Rejoignez-nous