As instruções a seguir servem tanto para Modbus RTU (classe TModBusRTUDriver) quanto para Modbus TCP (classe TModBusTCPDriver). Para configurar um tag+protocolo Modbus você deve:

  1. Inserir uma porta de comunicação apropriada para o protocolo Modbus escolhido:
  2. Inserir o componente de protocolo escolhido.
  3. Conectar o protocolo com a porta, através da propriedade CommunicationPort;
  4. Inserir os tags manualmente ou através da ferramenta “Tag builder”
  5. Caso inserir os tags manualmente, configurar as propriedades conforme descrito a seguir;
  6. Conectar o tag ao driver de protocolo através da propriedade ProtocolDriver presente em cada tag.

 

Ambas classes suportam os seguinte tipos de tags:

  • TPLCTagNumberplctagnumber
  • TPLCBlockplcblock
  • TPLCStructplcstruct
  • TPLCStringplcstring

 

Para configurar um tag para usar o ModBus, é necessário configurar as seguintes propriedades do tag:

  • PLCStation: Endereço do equipamento modbus. Para Modbus TCP, esta propriedade tem seu valor fixado em 1, geralmente, depende da implementação do Modbus Server.
  • MemAddress: Endereço da entrada/saida/registrador que se deseja lêr/escrever. Os endereços começam de zero, sempre. Não use a notaçao de endereço 1xxxxx, 2xxxxx, 3xxxxx, 4xxxxx, pois ela não é suportada.
  • MemReadFuntion: Função que será usada para ler o tag. Veja tabela abaixo.
  • MemWriteFuntion: Função que será usada para escrever valores do tag. Veja tabela abaixo.

Para as propriedades MemReadFunction e MemWriteFunction são aceitos os seguintes valores de acordo com a área de memória desejada:

Área desejada MemReadFunction MemWriteFunction
Entradas digitais 2 0
Saidas digitais 1

5 (TPLCTagNumberplctagnumber)

15 (TPLCTagNumberplctagnumber TPLCBlockplcblock TPLCStructplcstruct TPLCStringplcstring)

Registradores 3

6 (TPLCTagNumberplctagnumber)

16 (TPLCTagNumberplctagnumber TPLCBlockplcblock TPLCStructplcstruct TPLCStringplcstring)

Entradas analógicas 4 0
Status equipamento 7 0

É necessário que você conheça as funções ModBus que seu equipamento suporta.

31 comentários em “Modbus RTU e TCP

  1. Popescu Dragos Responder

    Hi,
    I need to read digital inputs from an ICPDAS modbus module, M-7054, using standard 02 function “(0x02) Read discrete inputs”.
    The string to send into module is “adr_byte 0x02 start_input (2bytes) count (2bytes) CRC (2bytes)”. The response will be according to the standard.

    Please tell me how do I do this, using PascalScada Tags?
    I’m using 0.7.3 version.

    • Fabio Luis Girardi Autor do postResponder

      Hi!

      Few steps:

      1) Insert a TSerialPortDriver into your app and set up it with the same serial settings of your device and activate it.
      2) Insert a TModbusRTUDriver and set CommunicationPort Property to point to Serial Port created on the previous step.
      3) Insert a TPLCTagNumber and set:
      3.1) MemAddress to point to your Digital Input (address starts from zero – 0)
      3.2) MemReadFunction to 2 “(0x02) Read discrete inputs”
      3.3) PLCStation to point to your Modbus slave address;
      3.4) Set property ProtocolDriver to point to ModbusDriver created in step 2.
      3.5) Assure that TagType is pttDefault or pttBit;

      4) Put a THMILabel into your app/form and link it with the tag created at step 3.

      5) If everything is set accordingly, you will see the label showing values 0 or 1, depending on the state of your digital input. The digital input can vary depending on your Modbus device.

  2. jayakrishnan Responder

    Hi fabio

    i have installed the software and done some basic works like configuring modbus device etc, after that i was trying to display the datas in the chart but i was unable to bind the tags to the chart. Could you pls instruct me how to do this and following features like alarming and reporting or pls provide me a deatiled documentation of those above mentioned .

  3. jayakrishnan Responder

    Hi fabio,

    i have installed pascal scada and done some stuff like creating tags and configured a modbus tcp device. when i try to get data of the device to be displayed in the charts provided in the package i was not able to bind the tags to chart. Could you pls tell me how to bind the tags and also an explanation about some features like alarms, reporting etc. Pls provide me a deatiled documentation .

  4. Fabio Luis Girardi Autor do postResponder

    Hi Mr. JAYAKRISHNAN!

    There are missing features on PascalSCADA, due to I have tried to keep it working with Lazarus and Delphi:

    ** Alarm historic
    ** Historic
    ** Recipes
    ** User management stored in file/database;
    ** Tag chart connection.

    Since I cutted off the Delphi support, some things have better progress, since I don’t need anymore to think multiple IDE support. I have two things started, but not finished:

    ** Lazarus TAChart series datasource linked with PLC Tags (started, near to be finished)
    ** Database abstraction (I’m researching the better way to achieve this)

    So, for now, I’ll have to do your chartings using the components of TAChart with few lines of code, to add new values and delete old values.

  5. Konrad Responder

    Hi, Does PascalSCADA supports MODBUS ASCII protocol?
    I see WEST ASCII there, but I think it is quite different from MODBUS ASCII.
    Thanks
    Konrad

    • Fabio Luis Girardi Autor do postResponder

      Hi Konrad!

      Modbus ASCII isn’t supported yet. At least, I don’t reserved time to do that and anybody else…

      Also, you are the first that had requested this.

  6. Boban Spasic Responder

    Hi Fabio,

    I have a Project with 1xModBusRTU and 4xModBusTCP drivers (I want to read from 4 IP addresses).
    The problems start when I want to close Lazarus and the Project is open in Lazarus – Lazarus locks my Windows10 with 100% CPU usage.
    The compiled project does the same – 100% CPU usage.
    OS: Windows 10 64bit, Lazarus versions tested 2.0.10 and 2.2.0RC1
    I would send you my code if you want to take a look at it.

    With just one ModBusRTU and one ModBusTCP drivers it works fine.

    • Fabio Luis Girardi Autor do postResponder

      Can you test the same application on Windows 7 environment? I don’t have any Windows 10 environment configured.

    • Fabio Luis Girardi Autor do postResponder

      Or if you have time and can share your environment with me, I can investigate using anydesk/teamviewer… If you agree, please send e-mail to fabio at pascalscada dot com

      • Boban Spasic Responder

        I apologize for late answer. I think I solved the problem.
        I have 4x TTCP_UDPPort and if I set the events for all the error handling (OnCommErrorReading … OnCommPortOpenError) for every port – here is the problem with 100% CPU usage.

        Here is my code for the events (all 4 ports are using the same procedures, no extra procedures for Port2-Port4):

        procedure TfrmMain.TCPPort1CommPortClosed(Sender: TObject);
        var
        portName: String;
        begin
        portName := TTCP_UDPPort(Sender).Name;
        mmLog.Lines.Add(portName + ‘ Port closed’);
        end;

        procedure TfrmMain.TCPPort1CommPortCloseError(Sender: TObject);
        var
        portName: String;
        begin
        portName := TTCP_UDPPort(Sender).Name;
        mmLog.Lines.Add(portName + ‘ Port close error’);
        end;

        procedure TfrmMain.TCPPort1CommPortDisconnected(Sender: TObject);
        var
        portName: String;
        begin
        portName := TTCP_UDPPort(Sender).Name;
        mmLog.Lines.Add(portName + ‘ Port disconnected’);
        end;

        procedure TfrmMain.TCPPort1CommPortOpened(Sender: TObject);
        var
        portName: String;
        begin
        portName := TTCP_UDPPort(Sender).Name;
        mmLog.Lines.Add(portName + ‘ Port opened’);
        end;

        procedure TfrmMain.TCPPort1CommPortOpenError(Sender: TObject);
        var
        portName: String;
        begin
        portName := TTCP_UDPPort(Sender).Name;
        if TTCP_UDPPort(Sender).LastOSErrorNumber 0 then
        mmLog.Lines.Add(portName + ‘ Port open error: ‘ + IntToStr(TTCP_UDPPort(Sender).LastOSErrorNumber) +
        ‘: ‘ + TTCP_UDPPort(Sender).LastOSErrorMessage);
        tbRun.Down := False;
        isRunning := False;
        tbRunClick(self);
        end;

        After removing these events, it looks it runs fine, although I didn’t do some extensive testing.

  7. Laurent Belanger Responder

    Hi Fabio,

    Is it possible to implement Modbus TCP master / slave communication between two freepascal app using PascalSCADA?

    Thanks!
    Laurent

    • Fabio Luis Girardi Autor do postResponder

      Hi Mr. Belanger

      PascalSCADA has only master/client implementation of Modbus RTU/TCP protocol stack. PascalSCADA can’t communicate with other PascalSCADA implementation because it doesn’t have slave/server implementation of these protocols. I don’t have free time to do that, but it’s possible to do. I finished the move from SVN to Github. So, now is more easy receive these cool features

  8. Reid Simonsen Responder

    I am kind of new on Modbus. I have installed pascalscada on Lazarus. Now I would like to use it with Arduino. I need some sample code on pascalscada and Arduino. Where can I find some sample code for it?

    • Fabio Luis Girardi Autor do postResponder

      Hi Mr. Simonsen!

      Well, I’m not a arduino enthusiast, so I can’t help you on the arduino side. The unique thing that I know is that if arduino supports the standart modbus funcitons (0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x0f and 0x10) PascalSCADA will communicate with it. The unique thing that maybe causes some difficulties, is a setting to avoid pascalscada send packets when it’s in idle state that will make your arduino cpu usage high. But this settings is just a property that should be set to false.

      I helped some people in the past, with the promise of when the prototype is done, they will send-me a full arduino example. For now, I received nothing.

      • reidsim Responder

        Fabio,

        I use Simply Modbus Master program that I was able to turn on some LEDs from Arduino. I am not sure how to do this from PascalScada. Here is what I have done so far on PascalScada. Add SerialPortDriver1 (setbaudrate as 9600 and ComPort as Com3). Then add ModbusRTUDriver1 (CommunicationPort as SerialPortDriver1). I am not sure which tag do we use to write code to Arduino. Here is the code which I need to send Arduino to turn on LEDs. To turn on first LEDs is 01 06 00 00 00 01 48 0A. To turn off the first LEDs is 01 06 00 00 00 00 89 CA. All I know is the first code for which slave and the sixth is turn off or on LEDs – 00 for off and 01 for on. For the Second LED to turn on is 01 10 00 00 00 02 04 00 01 00 00 A2 6F To turn off the second LED is 01 10 00 00 00 02 04 00 00 00 00 F3 AF.
        I’m not sure how to do this. Do we use PLCTaqgNumber1?

        • Fabio Luis Girardi Autor do postResponder

          Sorry for taking too much time to reply. I have problems with old email address. Today I updated the site to use the new one.

          Put a TPLCTagNumber and set

          MemAddress = 0
          MemReadFunciton = 3 //maybe this is unnecessary.
          MemWriteFunction = 6
          PLCStation = 1
          ProtocolDriver = ModbusRTUDriver1
          TagType = pttDefault or pttWord (both unsigned 16 bit)

          Then in your source do:

          yourPLCTagNumber.Value := 1; //turn on

          yourPLCTagNumber.Value := 0; //turn off

          Then

  9. Reid Simonsen Responder

    Hi Fabio,

    I could not find instruction how to send out this code from PascalScada. The code which I need to send out is 01 06 00 00 00 01 48 0A to turn on one LED. To turn off LED is 01 06 00 00 00 00 89 CA. For second LED to turn on is 01 10 00 00 00 02 04 00 00 00 00 A2 6F. Second LED to turn off is 01 10 00 00 00 02 04 00 00 00 00 F3 AF. I have more LED but I want to stat with this LED for now.

    What I have on form
    SerialPortDriver1
    set BaudRate as br9600
    ComPort as COM3
    ModBusRTUDriver1
    set CommunicationPort as SerialPortDriver1
    I am not sure what is next or which Tags Should we use?

    • Fabio Luis Girardi Autor do postResponder

      Hi Mr. Reed!

      I replied you on a previous message. Again sorry by this mistake due my lack of attention on my e-mail address.

    • Fabio Luis Girardi Autor do postResponder

      Sorry for taking too much time to reply. I have problems with old email address. Today I updated the site to use the new one.

      Just change change yourTag.TagType to pttSmallInt (signed 16 bit integer)

        • Fabio Luis Girardi Autor do postResponder

          Strange. Can you show the properties of your tag? Your variable has some kind of scale?

          • Rudi Santoso Responder

            This from .lfm file :

            object PLCTagNumber1: TPLCTagNumber
            TagGUID = ‘{60AB3B0D-66D9-4E16-9542-7300FEA456BC}’
            OnAsyncValueChange = PLCTagNumber1AsyncValueChange
            PLCRack = 0
            PLCSlot = 0
            PLCStation = 1
            MemFile_DB = 0
            MemAddress = 1803
            MemSubElement = 0
            MemReadFunction = 3
            MemWriteFunction = 0
            ProtocolDriver = modbustcp
            LongAddress = ”
            TagType = pttSmallInt
            EnableMaxValue = False
            EnableMinValue = False
            MaxValue = 1
            Left = 440
            Top = 256
            end

    • Fabio Luis Girardi Autor do postResponder

      Yes, you can . Just do

      YourTag.tagType := pttDword; // if you want change it to dword data type

      On your source code

      • Tamás Fehér Responder

        Thanks!

        I would like to save it to an ini file and reload it from there when the program starts. This way, you don’t need a new program for the different sensors. How can I do this?

        • Fabio Luis Girardi Autor do postResponder

          You have to do this manually in your source code. I don’t have anything related to save/load tag parameters. You can also create tags at runtime

  10. Rodrigo Hernandes Responder

    Ola Fabio boa noite.
    tem alguma dica de como utilizar o LogFile em um Memo.

    O que queria era receber os bytes de (leitura) brutos em um memo para efetuar debugs de outros equipamentos, para saber o que está chegando igualmente o LogFile porem em um memo (somente o bytes recebidos).

    • Fabio Luis Girardi Autor do postResponder

      Boa pergunta. Nao há como na implementacao atual. Nao com uma implementacao fácil. O maneira que existe é ficar recarregando o arquivo de tempo em tempo, ou adicionar algum tipo de watcher neste arquivo e recarregar quando o arquivo for atualizado.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *