IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

Port COM -> Envoie données Hexadecimale


Sujet :

Langage Delphi

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 37
    Points : 12
    Points
    12
    Par défaut Port COM -> Envoie données Hexadecimale
    Salut a tous,
    Actuellement j'essait de configurer une petite centrale de mesure
    Qui me retourne des valeur comme la tension, intensité ...
    Mais la docs me demande de transmettre mes demandes a la centrale
    en Hexadecimal.
    " Modbus RTU protocol "
    Ex : 01 03 00 00 00 01 84 0A

    Alors j'ai creer un petit programme pour essayer tous sa.
    Mais lorsque j'utilise un programme pour sniffer les commande envoyer,
    Aucune n'est en Hexa, toute sont convertie car ce que j'envoit
    est un String.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    WriteFile(g_hCOM, edit1.text[1], Length(edit1.text[1]), BytesWritten, nil);
    J'ai bien essayer sa :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     
    var
      BytesWritten: DWORD;
      mBuffer:array[0..100] of Byte;
      i:integer;
    begin
      for i:=1 to length(edit2.text) do
      begin
         mBuffer[i]:=ORD(edit2.text[i]);
      end;
     
         WriteFile(g_hCOM, mBuffer, Length(mBuffer), BytesWritten, nil);
    Mais identique, pas de changement.

    Quelqu'un a t-il une idee ?

    Merciiii

  2. #2
    Membre actif

    Homme Profil pro
    Inscrit en
    Mars 2009
    Messages
    128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2009
    Messages : 128
    Points : 203
    Points
    203
    Par défaut
    Heu... Excuse-moi, Benda, mais ça veut dire quoi ça :

    Mais lorsque j'utilise un programme pour sniffer les commande envoyer,
    Aucune n'est en Hexa, toute sont convertie car ce que j'envoit
    est un String.
    ???

  3. #3
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    et le string contient quoi ?
    une representation de données en hexadécimale ?


    si tu envois une commande exemple : 09 AF 6D 6D 80

    et que tu ecris cette commande dans un Edit, il faut convertir la representation en hexa :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    type
      PBinBuffer = ^TBinBuffer;
      TBinBuffer = packed array[0..0] of byte;
      TBuffer = record
        bbSize  : LongWord;
        bbPBuff : PBinBuffer;
      end;
     
     
    procedure BinBufferToStr(aBuffer: TBuffer; var hxStr: ansiString);
    var N  : integer;
        pB : ^Word;
    const
      BTC : array[$0..$F] of byte = ($30, $31, $32, $33, $34, $35, $36, $37, $38, $39,
                                     $61, $62, $63, $64, $65, $66);
    begin
      SetLength(hxStr, aBuffer.bbSize shl 1);
      pB := @hxStr[1];
      for N := 0 to aBuffer.bbSize-1 do
      begin
        pB^ := BTC[aBuffer.bbPBuff[N] shr 4] or (BTC[aBuffer.bbPBuff[N] and $F] shl 8);
        inc(pB);
      end;
    end;
     
    procedure StrToBinBuffer(hxStr: ansiString; var aBuffer: TBuffer);
    var N, L, B, P : integer;
        HC : ansiString;
        pB : PBinBuffer;
    begin
      L  := Length(hxStr);
      pB := PBinBuffer(hxStr);
      aBuffer.bbSize  := 0;
      aBuffer.bbPBuff := AllocMem(L shr 1);
      P  := 1;
      for N := 0 to L-1 do
      begin
        B := -1;
        case pB[N] of
          48..57  : B := (pB[N] - 48);
          65..70  : B := (pB[N] - 55);
          97..102 : B := (pB[N] - 87);
        end;
        if B in [$0..$F] then
        begin
          if P = 0 then
          begin
            aBuffer.bbPBuff[aBuffer.bbSize] := aBuffer.bbPBuff[aBuffer.bbSize] or B;
            inc(aBuffer.bbSize);
            P := 1;
          end
          else
          begin
            aBuffer.bbPBuff[aBuffer.bbSize] := B shl 4;
            P := 0;
          end;
        end;
      end;
      if P = 0 then
        inc(aBuffer.bbSize);
      ReAllocMem(aBuffer.bbPBuff, aBuffer.bbSize);
    end;

    exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    procedure TForm14.FormCreate(Sender: TObject);
    var S : AnsiString;
        B : Tbuffer;
    begin
      try
        S := '0123456789ABCDEF';
        StrToBinBuffer(S, B); // B = 01 23 45 67 89 AB CD EF
     
        S := '';
     
        BinBufferToStr(B, S); // S = 0123456789abcdef
        caption := string(S);
      finally
        // important : toujours libérer le pointeur bbPBuff
        FreeMem(B.bbPBuff, B.bbSize);
      end;
    end;
    et avec ton code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    var
      B : TBuffer;
    begin
      StrToBinBuffer(Edit1.Text, B);
      try
        if B.bbSize > 0 then
          WriteFile(g_hCOM, B.bbPBuff^, B.bbSize, BytesWritten, nil);
      finally
        FreeMem(B.bbPBuff, B.bbSize);
    end;
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 37
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par Rekin85 Voir le message
    Heu... Excuse-moi, Benda, mais ça veut dire quoi ça :



    ???
    Que j'ai un logiciel ( au boulot, j'ai pas le nom sous la main ) Qui m'affiche
    tout ce qui se passe sur le port COM
    Ex: Baud, envoie, reception, ...

    @Dr.Who : Merci je regarde sa ce soir
    Le string contient une chaine comme celle que tu a ecrites.
    ' 01 03 00 00 00 01 84 0A '

  5. #5
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    Citation Envoyé par benda95280 Voir le message

    @Dr.Who : Merci je regarde sa ce soir
    Le string contient une chaine comme celle que tu a ecrites.
    ' 01 03 00 00 00 01 84 0A '
    alors ça devrais fonctionner comme cela, la fonction "saute" les caractères non valide dans une chaine hexa, les espaces également.
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  6. #6
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 771
    Points
    2 771
    Par défaut
    Citation Envoyé par Rekin85 Voir le message
    Heu... Excuse-moi, Benda, mais ça veut dire quoi ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Mais lorsque j'utilise un programme pour sniffer les commande envoyer,
    Aucune n'est en Hexa, toute sont convertie car ce que j'envoit
    est un String.
    ???
    +1 , c'est normal, votre programme sniffer te donne simplement le code ascii des caractére envoyer par example 0>$30, ou j'ai mal compris
    PAS DE DESTIN, C'EST CE QUE NOUS FAISONS

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 37
    Points : 12
    Points
    12
    Par défaut
    Le programme que j'utilise est : AspyCom
    Il y a une partie En Ascii, et une partie en Hexadecimal.

    Aparament sa a l'air de bien fonctionner, test en reel avec la machine aujourd'hui.
    Encore merci Mais Bizard que j'ai jamais vu sur google un seul moyen
    de passer des commande en Hexa ...


    News de 9:19 :

    La centrale recois bien la commande
    Mais, lorsque je la lis: je me retrouve avec un " 7 "
    Alors qu'elle me retourne une chaine en Hexa ...
    Decidement, je detesete l'Hexa c'est sur ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    procedure TForm4.Button2Click(Sender: TObject);
    var
    s: string;
    d: array[1..80] of Char;
    BytesRead, i: Integer;
    begin
     
    ReadFile(g_hCOM,
                      d,
                      SizeOf(d),
                      cardinal(BytesRead),
                      nil);
     
    s := '';
    for i := 1 to BytesRead do s := s + d[I];
    memo1.Text := s;
    memo2.Text := inttostr(bytesRead);
     
    end;
    Dois-je utiliser : ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    BinBufferToStr(aBuffer: TBuffer; var hxStr: ansiString);

  8. #8
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 771
    Points
    2 771
    Par défaut
    Dois-je utiliser : ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    BinBufferToStr(aBuffer: TBuffer; var hxStr: ansiString);
    normalement
    autre solution:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    procedure TForm4.Button2Click(Sender: TObject);
    var
    s: string;
    BytesRead: Integer;
    begin
    setlength(s,80);
    ReadFile(g_hCOM,
                      @s[1], // ou s[1] a tester car normalement readfile attend un pointeur
                      80,
                      cardinal(BytesRead),
                      nil);
    memo1.Text := s;
    end;
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    procedure TForm4.Button2Click(Sender: TObject);
    var
    s: array[1..80] of char;
    BytesRead: Integer;
    begin
    fillchar(s,sizeof(s),0);
    ReadFile(g_hCOM,
                     s,
                      sizeof(s),
                      cardinal(BytesRead),
                      nil);
    memo1.Text := s;
    end;
    PAS DE DESTIN, C'EST CE QUE NOUS FAISONS

  9. #9
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    oui, utilise

    StrToBinBuffer pour envoyer une commande :
    texte = (string) 01030000000807 (representation hexadecimale)
    en ascii = (hexa) 3031303330303030303030383037
    buffer aprés convertion = (hexa) 01 03 00 00 00 08 07

    et
    BinBufferToStr pour recevoir une commande :
    Commande = (hexa) 00 01 02 00 60 70
    Buffer = (hexa) 00 01 02 00 60 70
    en ascii = (hexa) 303030313032303036303730
    texte = (string) 000102006070



    donc pour l'envois :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var
      B : TBuffer;
    begin
      StrToBinBuffer(Edit1.Text, B);
      try
        if B.bbSize > 0 then
          WriteFile(g_hCOM, B.bbPBuff^, B.bbSize, BytesWritten, nil);
      finally
        FreeMem(B.bbPBuff, B.bbSize);
      end;
    end;

    pour la récéption :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var
      B : TBuffer;
    const
      MaxBuffer = 256;
    begin
      B.bbPBuff := AllocMem(MaxBuffer);
      try
        ReadFile(g_hCOM, B.bbPBuff^, MaxBuffer, B.bbSize, nil);
        ReAllocMem(B.bbPBuff, B.bbSize);
        BinBufferToStr(B, Edit1.Text);
      finally
        FreeMem(B.bbPBuff, B.bbSize);
      end;
    end;
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 37
    Points : 12
    Points
    12
    Par défaut
    Merci, Cela fonctionne parfairement
    Mais il reside un petit probleme, le temps de latence:
    L'application se fige pendant environ 3-4s, lors de la lecture
    alors que l'ecriture est immediate
    Je ne comprend vraiment pas pourquoi ...
    ( L'appareil me rend bien une reponse imediatement ... )

Discussions similaires

  1. [Lazarus] Envoi de données port com pour modbus
    Par Jon Shannow dans le forum Lazarus
    Réponses: 3
    Dernier message: 13/09/2012, 14h35
  2. Transfert de données d'un port com vers une base de données
    Par turbo_chess dans le forum Développement
    Réponses: 3
    Dernier message: 15/05/2007, 20h05
  3. [vb6] Evénement de réception/envoi sur port COM
    Par Original Prankster dans le forum VB 6 et antérieur
    Réponses: 31
    Dernier message: 13/12/2006, 00h05
  4. test d'envoi sur le port com
    Par sylviek dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 15/10/2006, 13h08
  5. [socket] envoyer des données vers un port com
    Par Slimer dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 20/07/2004, 17h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo