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

Delphi Discussion :

modbus rtu delphi


Sujet :

Delphi

  1. #1
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2019
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2019
    Messages : 51
    Par défaut modbus rtu delphi
    Bonjour

    je développe une application sur smartphone en utilisant Delphi et un module bluetooth ble . L'idée c'est de recevoir les données d'API (vitesse...) et de les traitées. Vu que je dois utiliser un modbus RTU (rs232), j'aimerai bien savoir si quelqu'un parmi vous à déjà un exemple de ce protocole modbus !!

    cordialement

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 982
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 982
    Par défaut
    Tu trouves des composants mais sache que le RS232 c'est un port PC, le bon vieux port COM, parfois connecté avec un adpateur pour bornier RS422 ou RS485


    Pour ma part, j'ai intégré du Modbus avec C++Builder


    Citation Envoyé par ShaiLeTroll Voir le message
    En C++Builder, j'ai utilisé uniquement un composant Modbus de PROCONX
    Tu dois pouvoir trouver des composants pour ces protocoles

    Surtout que profibus est remplacé par profinet ou Modbus/TCP

    CAN, tu peux tenter le codé à la main avec un TComport
    Citation Envoyé par ShaiLeTroll Voir le message
    Modbus n'est qu'un premier niveau, il faut savoir ensuite ce que ta carte met dans les registres

    Pour ma part, j'ai gagné de temps en passant par un composant payant chez ProconX mais tu n'auras pas le budget en tant qu'étudiant
    Par contre, j'étais en USB (en fait un port COM virtuel) en mode Serial physique en RS-232, voire même des borniers type RS485

    Commence déjà par jouer avec le TClientSocket et TServerSocket, tu as plien d'exemple, tu peux utiliser Telnet pour tester aussi
    Un fois la communication TCP maitrisée, il va te falloir bien gérer des trames binaires (et non du texte comme Telnet)

    As-tu une documentation sur la structure d'une Tram Modbus,
    je sais que sur le forum, certains se sont amuser à sniffer les trams échangées entre deux appareils pour comprendre les données.
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2019
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2019
    Messages : 51
    Par défaut
    en fait pour t'expliquer un petit peu, ma carte contient un module bluetooth ble HM-10 relié avec un adaptateur RS232 au variateur (API). Donc la je suis obligé de travailler avec le modbus RTU afin de recevoir les données sur mon smartphone.

  4. #4
    Membre émérite Avatar de sergio_is_back
    Homme Profil pro
    Consultant informatique industrielle, développeur tout-terrain
    Inscrit en
    Juin 2004
    Messages
    1 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Consultant informatique industrielle, développeur tout-terrain
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 180
    Par défaut
    La spécification du protocole modbus/RTU est publique, sur cette URL tu trouvera toute la description du protocole : https://ipc2u.com/articles/knowledge...-and-examples/

    Le protocole est un peu différent de modbus/TCP que j'utilise habituellement mais c'est pas problématique en soit

    Si tu connais les registres que tu veux lire et écrire tu peux facilement faire ta propre implémentation

    Et ici trouvera d'autres informations en particulier un exemple en C++ de calcul du CRC : https://www.modbustools.com/modbus.html

    Pour envoyer/recevoir sur le port série RS232 tu peux utiliser la librairie Comport ici : https://sourceforge.net/projects/comport/
    Je ne sais pas si elle compile pour Android mais ça peut servir pour un test sur PC

    Avec tout ça tu devrais facilement t'en sortir

  5. #5
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2019
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2019
    Messages : 51
    Par défaut
    je te remercie sergio, je crois que j'ai du mal à comprendre ce mode RTU. Supposant que je veux :

    lire cette trame 11 03 006B 0003 7687

    En réponse au périphérique esclave Modbus RTU, nous obtenons:

    11 03 06 AE41 5652 4340 49AD

    donc déja comment j'obtiens ca "06 AE41 5652 4340" ?? par contre je sais bien comment calculer le crc

  6. #6
    Membre émérite Avatar de sergio_is_back
    Homme Profil pro
    Consultant informatique industrielle, développeur tout-terrain
    Inscrit en
    Juin 2004
    Messages
    1 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Consultant informatique industrielle, développeur tout-terrain
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 180
    Par défaut
    Citation Envoyé par afriad Voir le message
    je te remercie sergio, je crois que j'ai du mal à comprendre ce mode RTU. Supposant que je veux :

    lire cette trame 11 03 006B 0003 7687

    En réponse au périphérique esclave Modbus RTU, nous obtenons:

    11 03 06 AE41 5652 4340 49AD

    donc déja comment j'obtiens ca "06 AE41 5652 4340" ?? par contre je sais bien comment calculer le crc
    11 03 006B 0003 7687 : c'est la trame que tu vas envoyer (dans l'exemple pour lire un ou plusieurs registres 16 bits)

    11 = Numéro du device, si tu n'a qu'un seul device connecté, tu peux essayer 00 ou $FF (broadcast)
    03 = C'est la commande de lecture pour les holding register
    006B = c'est l'adresse du premier registre que tu veux lire (sur 16 bits = 1 word)
    0003 = On veut lire trois registres
    7687 = Et là c'est le CRC

    Tu stockes tout ce beau monde dans un tableau de byte (array of byte), ou dans un TMemoryStream, ou dans une chaine de caractères AnsiString, c'est selon ton choix
    Après il faut que l'écrire sur le port série de ton périphérique connecté (là bien sur ça dépend de la façon dont tu est connecté)
    Ensuite il faut lire les caractères qui vont arriver sur ton port série (avec un timeout c'est mieux, ça évite de reste bloquer)
    Au fur et à mesure tu stocke et tu vérifie ce que tu reçois
    Lorsque ce que tu as reçu correspond au protocole (en gros à ce que tu as demandé), longueur de trame OK, CRC OK, etc...
    A ce moment tu peux exploiter les données

    par exemple :

    11 03 06 AE41 5652 4340 49AD

    11 = c'est bien le device requis qui a répondu
    03 = J'avais envoyé une commande 03 et c'est bien une réponse à la commande 03
    06 = Il y a 6 octets utiles qui suivent
    AE41 = 2 octets soit la données le premier registre (16 bits)
    5652 = 2 octets soit le seconds registre
    4340 = 2 octets soit le troisième registr
    49AD = le CRC de la trame (à recalculer et à vérifier bien sur)

    Et après tu exploite les infos :

    AE41 était la valeur dans le premier registre de ton périphérique et là... Ben c'est la documentation technique qu'il faut consulter...

    C'est clair ? ou pas...

  7. #7
    Membre émérite Avatar de sergio_is_back
    Homme Profil pro
    Consultant informatique industrielle, développeur tout-terrain
    Inscrit en
    Juin 2004
    Messages
    1 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Consultant informatique industrielle, développeur tout-terrain
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 180
    Par défaut
    Comme un petit exemple vaut mieux qu'un grand discours je te joint un code que j'ai déjà employé pour les protocoles Modbus/TCP et Modbus/UDP (qui sont un peu différents que le Modbus/RTU, y'a pas de CRC par exemple) mais c'est le principe qui compte :

    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
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
     
    // Note : Cette fonction lit un seul registre
    function TModbusClient.ReadRegister(Reg : TModbusRegister) : Boolean;
    var
        Data        :   TIdBytes;
        Transaction :   Word;
        Size        :   Integer;
    begin
        Result:=False;
        fError:='';
        SetLength(Data,12);
        ZeroMemory(@Data[0],12);
        Transaction:=NewTransaction;
        // Transaction
        Data[0]:=Lo(Transaction);
        Data[1]:=Hi(Transaction);
        // Protocole : 0 = MODBUS
        Data[2]:=0;
        Data[3]:=0;
        // Longueur des données : 6 ici
        Data[4]:=0;
        Data[5]:=6;
        // Unit identifier = $FF
        Data[6]:=1;
        // Command
        Data[7]:=mbReadInputRegisters;
        // Registre
        Data[8]:=Hi(Reg.Address-1);
        Data[9]:=Lo(Reg.Address-1);
        // 1 seul registre
        Data[10]:=0;
        Data[11]:=1;
     
        if Connected then
        begin
            try
                if fProtocol=mpTCP then
                begin
                    fTCP.IOHandler.WriteDirect(Data);
                end
                else
                begin
                    fUDP.SendBuffer(Data);
                end;
                SetLength(Data,1542);
                ZeroMemory(@Data[0],1542);
                Size:=0;
                if fProtocol=mpTCP then
                begin
                    fTCP.IOHandler.ReadTimeout:=fTimeout;
                    fTCP.IOHandler.CheckForDataOnSource(100);
                    if fTCP.IOHandler.InputBuffer.Size>5 then
                    begin
                        Size:=fTCP.IOHandler.InputBuffer.Size;
                        fTCP.IOHandler.ReadBytes(Data,Size,False);
                    end;
                end
                else
                begin
                    Size:=fUDP.ReceiveBuffer(Data,fTimeout)
                end;
                if Size>5 then
                begin
                    Transaction:=Data[0]+(Data[1] shl 8);
                    if Transaction=fTransaction then
                    begin
                        SetLength(Data,6+(Data[5]+(Data[4] shl 8)));
                        if Data[6]=1 then
                        begin
                            if Data[7]=mbReadInputRegisters then
                            begin
                                if Data[8]=2 then
                                begin
                                    Reg.Value:=Data[10]+(Data[9] shl 8);
                                    if Reg.Direction<>mdInput then Reg.fCache:=Reg.Value;
                                    Result:=True;
                                end;
                            end;
                        end;
                    end;
                end
                else
                begin
                    fError:='Communication timeout !';
                end;
            except on E:Exception do
                fError:=E.Message;
            end;
        end
        else
        begin
            fError:='Not connected !';
        end;
     
        if (not Result) and (fError='') then fError:='Modbus protocol error !';
     
    end;

  8. #8
    Membre émérite Avatar de sergio_is_back
    Homme Profil pro
    Consultant informatique industrielle, développeur tout-terrain
    Inscrit en
    Juin 2004
    Messages
    1 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Consultant informatique industrielle, développeur tout-terrain
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 180
    Par défaut
    Ici une petite explication sur la lecture et l'écriture avec périphérique BLE : http://docwiki.embarcadero.com/RADSt...oth_Low_Energy

  9. #9
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2019
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2019
    Messages : 51
    Par défaut
    en fait pour la partie bluetooth BLE je l'ai déjà fait et je l'ai testé par exemple j'envoie une chaîne de caractère à partir mon smartphone vers un terminal série du pc ca c'est bon!! maintenant c'est la partie modbus rtu qui manque pour recevoir les données du variateur vers mon smartphone tel que vitesse + ...

  10. #10
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2019
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2019
    Messages : 51
    Par défaut
    oui c'est clair

  11. #11
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2019
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2019
    Messages : 51
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    static private byte[] MakeRequest()
     {
     // request for reading Analog Input is always 8 bytes long.
     byte[] write = new byte[8];
     write[0] = _Id; // device id
     write[1] = 0x04; // Read A I
     byte[] start = BitConverter.GetBytes((ushort)_StartAddress); // ushort = 2 bytes
     write[2] = start[1]; // msb first
     write[3] = start[0];

  12. #12
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2019
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2019
    Messages : 51
    Par défaut
    quelqu'un peut m'aider à convertir ce bout de code en delphi

Discussions similaires

  1. Réponses: 10
    Dernier message: 09/04/2010, 09h24
  2. Supervision Cimplicity - Protocol MODBUS RTU
    Par IlyesBH dans le forum Automation
    Réponses: 5
    Dernier message: 21/11/2009, 21h41
  3. Réponses: 13
    Dernier message: 07/05/2009, 17h03
  4. RS232 - Modbus RTU
    Par jano44 dans le forum Automation
    Réponses: 6
    Dernier message: 13/12/2007, 15h11
  5. [Modbus RTU] Problème d'adresse
    Par virginoue dans le forum Autres langages
    Réponses: 1
    Dernier message: 16/05/2006, 08h33

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