Conteúdo

Introdução

Portas de comunicação são o meio utilizado pelos drivers de protocolo para enviar e receber dados. Uma porta de comunicação pode ser usada por um  ou mais drivers de protocolo, simultaneamente.

As portas de comunicação são separadas da implementação dos protocolos para permitir uma maior flexibilidade do sistema. Uma aplicação dessa real que pode ser feita com essa arquitetura, é associar uma porta TTCP_UDPPort com um COMServer (equipamento que nada mais é que um gateway RS-232/485/422 para TCP/IP), para por exemplo, comunicar com algum equipamento Modbus RTU a muitos quilômetros de distância sobre internet. Outra vantagem deste design é colocar dois ou mais protocolos usando a mesma porta de comunicação simultaneamente na mesma aplicação. Isto é possível pelo fato de todas portas contar com um mecanismo que só permite que um protocolo use a porta durante a operação de comunicação.  Ou seja, uma aplicação pode comunicar com vários equipamentos,  estes equipamentos com diferentes protocolos de comunicação e todos conectados na mesma rede RS-485. É possível, apesar de não ser recomendado.

Todas as portas existentes no PascalSCADA descendem da classe TCommPort, que implementa os métodos base para abrir e fechar a porta, ler e escrever dados e limpar os buffers de leitura e escrita em caso de falha de comunicação. Mas lógico que estes métodos precisam ser especializados caso uma nova porta de comunicação esteja sendo implementada.

Seleção_090TSerialPort

A classe TSerialPort, derivada da classe TCommPort, foi criada para permitir os protocolos trocar dados sobre portas seriais, independente do meio físico utilizado pela porta.

Em sistemas operacionais Windows, esta classe necessita uma porta serial com o nome entre COM1 e COM255.

Rodando sobre Linux, qualquer dispositivo que o nome comece com tty<número>, ttyUSB<número> ou ttyACM<número> é válida.

On FreeBSD, any device qualquer dispositivo cujo o nome comece com cuad<número> é aceita pela classe.

Tanto em Linux como FreeBSD (ou outro Unix) deverá ser tomado o cuidado de adicionar o usuário que irá rodar a aplicação no grupo dono da porta serial, alem de dar permissão de leitura/escrita para o grupo sobre a porta serial desejada. O nome deste grupo varia conforme o sistema.

Independente de sistema operacional, a classe de porta Serial conta com as seguintes propriedades que configuram o funcionamento da porta serial:

  • COMPort: define a porta serial a ser utilizada. Caso a aplicação seja configurada com uma porta e esta porta seja desconectada do sistema (por exemplo, um conversor USB <-> Serial) e a aplicação seja iniciada, uma exceção será gerada. Se esta exceção for gerada durante a carga (inicialização) da aplicação, sua aplicação não iniciará, mesmo com a propriedade Active = FALSE.
  • Baudrate: velocidade em bits por segundo que esta porta irá utilizar durante a comunicação. Velocidades entre 110 bps e 115200 bps são aceitas.
  • DataBits: Define o tamanho da palavra de dados que será trocada durante a comunicação serial, em bits. Os tamanhos aceitos são 7 ou 8 bits, sendo o padrão 8 bits. Alguns protocolos pedem 7 bits, como por exemplo o Modbus ASCII. Outros como o Modbus RTU, definem o tamanho da palavra de dados de 8 bits.
  •  StopBits: Configura a quantidade de bits que será usada para marcar o início e o final de cada palavra transmitida na comunicação serial. O padrão é 1 stop bits.
  • Paridade: configura se a palavra irá contar com checagem de erros, e se em caso dela existir, se a checagem vai ser par ou impar.
  • Timeout: Define o tempo máximo que a porta serial irá aguardar pela leitura de uma certa quantia de dados. Este tempo é definido em milissegundos. Em casos de estouro do timeout, uma limpeza dos buffers de leitura e escrita é realizada.
  • AcceptAnyPortName: Esta propriedade, quando habilitada em um sistema Unix (Linux, FreeBSD,  etc), faz com que qualquer nome de dispositivo seja aceito na propriedade COMPort. Muito útil quando alguns drivers criam nomes de dispositivos que não são aceitos pelo padrão descrito acima. No Windows ela não tem efeito.
  • WriteReadDelay: Atraso em milissegundos entre um comando de escrita e em seguida um leitura.
  • Active: Esta propriedade controla a abertura e fechamento da porta. A porta serial não deverá estar aberta por nenhum outro processo quando esta propriedade vai para true, caso contrário a propriedade Active irá votar para false. Em tempo de desenvolvimento, Active = true só realiza as verificações para abertura da porta mas não efetua a abertura da porta.
Seleção_091TTCP_UDPPort

A classe TTCP_UDPPort, derivada da classe TCommPort, foi criada para permitir os protocolos trocar dados sobre portas TCP (testado) ou UDP (necessita testes) sobre IPv4. independente do meio físico utilizado pela porta.

Esta classe de porta, não tem propriedades que dependentes de sistema operacional, sendo que as seguintes propriedades configuram seu funcionamento:

  • Host: Endereço IPv4 que a porta irá conectar. Nomes de host não são aceitos, somente endereços IP.
  • Port: Número da porta no host destino que a porta irá conectar. são aceitos qualquer número entre 1 e 65535.
  • PortType: Define se o socket que irá ser estabelecido irá ser sobre TCP ou UDP.
  • ExclusiveDevice: Caso true, evita que a porta seja aberta durante o tempo de desenvolvimento. Util quando o host destino tem um limite muito baixo de conexões disponíveis.
  • EnableAutoReconnect: Caso true e caso o socket for desconectado (problema no meio físico ou com o host) habilita o temporizador que irá ficar tentando reconectar o socket. Neste caso o socket com problemas é fechado e a propriedade Active permanece true.
  • ReconnectRetryInterval: Esta propriedade define o intervalo de tempo em milissegundos em que a porta tentará reconectar conexões perdidas. Esta propriedade só é valida caso EnableAutoReconnect e Active sejam true.
  • Timeout: Define o tempo máximo que a porta irá aguardar pela confirmação de escrita ou leitura de uma certa quantia de dados. Este tempo é definido em milissegundos. Caso alguma operação exceda este tempo, os buffers são limpos, a porta é verificada e em caso de alguma anormalidade, o socket será descartado e se EnableAutoReconnect é true uma tentativa de reconectar o socket será feito.
  • Active: Esta propriedade controla a abertura e fechamento do socket. Em tempo de desenvolvimento, Active = true irá abrir o socket e realizar comunicações com seu dispositivo, exceto se ExclusiveDevice for setado para true.
Exemplos

Abaixo estão listados exemplos de como trocar dados usando as portas de comunicação do PascalSCADA diretamente via código, ou seja sem usar, sem usar um driver de protocolo. Como todas as portas são descendentes da classe TCommPort, o exemplo abaixo também vale se quiser implementar algo usando uma porta TTCP_UDPPort.

70 comentários em “Portas de comunicação

  1. Sergey Responder

    Hi! My name is Sergey, I from Russia. Wanted to install the latest version of Pascalscada, but failed , installed for Delphi 7. Now using version 0.7.2

  2. Maks Responder

    I can’t send or recieve data with SerialPortDriver in Win64 and Win32. I see examples, but i can’t to repaet them. Maybe there is some solution. Lazarus 1.8.0 scada 0.7.4.

  3. Maks Responder

    I did not find any examples, but I figured out the system’s work. But still, I did not have a definite mistake. When I add a few tags and connect to the HMI component, it displays some kind of nonsense if I do not use the built-in method of auto-reading, and I use the timer then it works.

    • Fabio Luis Girardi Autor do postResponder

      Hi @Marks!

      What are you trying to do? Please give some details about your hardware, protocols and network of your application.

  4. AJAY KUMAR Responder

    hi sir good afternoon, am ajay kumar from india. i started learning of HMI’s . my question is ” HMI having two ports COM0, COM1. while COM0 in connected with PLC to pass Modbus commands over TCP . While that is happening I want to read HMI registers from another COM port on the same HMI. How can we do that?

  5. AJAY KUMAR Responder

    hi , my name is AJAY from INDIA. i need some answer regarding below question. please review on this question
    basically HMI having 2 ports vise COM0 & COM1. now am connected COM0 to passed Modbus commands over TCP to PLC while HMI was master.
    While that is happening I want to read HMI registers from another COM port on the same HMI. How can we do that? Can you implement and show?

    • Fabio Luis Girardi Autor do postResponder

      Hi Mr. Ajay!

      Why not read and write using the same port (COM0)?

      I don’t understand if your slave is Modbus RTU or TCP. If your slave is Modbus RTU you can’t put your application using COM0 and COM1 communicating with the same PLC port, because Modbus RTU don’t alloos two masters on the same bus.

      But if:
      you are using Modbus RTU AND have two ports on your PLC

      OR

      you are using Modbus TCP

      You should put two:

      ** Two serial ports and two Modbus RTU protocolo driver, one for read other writing operations

      ** Two TCP_Udpport and two Modbus TCP driver, one for read other writing operations.

      For both cases:

      ** tags linked with with port dedicated for read, should autowrite set to false

      ** tags linked with port dedicated to write should autoread set to false

      ** Modbus driver linked with the port dedicated for read should have ReadOnly property set to true.

      I don’t what you want to do, but I hope this helps.

      The best regards from Brazil,

      Fabio

      • AJAY KUMAR Responder

        thnaks Fabio for valuable information . may i use this information to solve my problem , but still i confused.
        if any issues made during my working process i will ask questions , please give some guidance for me. i want to learn good HMI knowledge. i needed this . thank you sir.
        best regards AJAY KUMAR
        INDIA

  6. Rafael Responder

    Boa tarde!
    Fábio, é possível utilizando o pascalsacada trocar dados entres aplicações diferentes, tipo uma aplicação ser mestre e a outra escravo?

  7. Rafael Responder

    Fabio,
    Gostaria de comunicar com Logo v8, poderia me dar um exemplo de configuração do pascalscada e se possível mostrar como configuro o logo.

  8. fozkan Responder

    Hello from Turkey. First of all thank you for this perfect project.
    I would like some update about baudrate list. As you know nowadays it is common to use upper baudrates. Could you add the following rates to TSerialPort.
    128000, 153600, 230400, 256000, 460800, 921600.

    P.S. : I am not sure if this is a right place for such kind of request.

    Thanks in advance.

    Fatih

    • Fabio Luis Girardi Autor do postResponder

      Hi Fatih!

      I’ll find the baudrates common to all supported OSes and keep you updated. If I’m right, these low baudrates are a Windows limitations. I will keep you updated.

      • fozkan Responder

        Hi Fabio,

        I have already tested in lab for modbus rtu protocol by adding extra baudrates above. Of course mentioned limits depend on the capability of hardware, our adapter works up to 2 Mbits.
        As I said I can make the modifications on code but in order to use up-to-date code without editing, it would be better, it also helps other people as well. I have just test it in Windows, but in next week, I can test in Linux .

        Thanks.
        Fatih

        • Fabio Luis Girardi Autor do postResponder

          Hi Fatih!

          Can you check if these baud rates are available on Windows, installing your hardware on that? I’m reading into docs, and Windows appears to support only 128kbps baud rate… sad!

          Can you send me your modifications to merge into current code base?

    • sadik acar Responder

      fatih kardes benim pascalscada ile ilgili bir problemim var yardimci olabilirmisin
      sadikacar60@gmail.com

      iki ayri delphi programi ile plc ye baglaniyorum. birinciyi baglayinca sorun yok ama ikinciyi bagladigimda prg kitleniyor. diger tcp kompenantlarda denedim sorun yok
      saygilar

  9. Rafael B. Pimentel Responder

    Bom dia!
    Estou montando uma rede de PLCs via ethernet TcpIP e gostaria de saber se o PascalScada pode se comunicar com mais de um equipamento com uma unica porta.

    • Fabio Luis Girardi Autor do postResponder

      Bom dia Rafael!

      Não. E não é uma limitação do PascalSCADA e sim do design das conexões (UDP,TCP)/IP que são 1:1, ou seja, em qualquer sistema de supervisão vc terá esta limitação. A única excessão é se na outra ponta, você tem um equipamento que desempenha a função de gateway, como um gateway ModbusTCP => Modbus RTU. Ai neste caso sim, um unica conexão TCP pode ser usada para “conectar-se” com vários equipamentos Modbus RTU, mantendo a conexão TCP 1:1.

      Para solucionar seu problema no PascalSCADA, será necessário uma porta TCP/IP para cada equipamento que vc precisa comunicar.

      • Rafael B. Piementel Responder

        Certo… Quando você fala uma porta para cada equipamento você esta se referindo a uma porta física ou uma porta componente do Pascalscada, se for a componente, você teria algum exemplo de como gerenciar essa portas? Sei que a pergunta é simples, mas acontece que só havia tido experiencias com portas seriais.
        Ahhh… outra coisa, eu gostaria também de parabeniza-lo Fabio, com certeza sei q não se lembra de mim, mas a uns 7 ou 8 anos eu fiz meu primeiro contato contigo, eu ainda morava em Vitória ES, agora estou em Petrolina PE e fico muito feliz de ver que seu trabalho permanece em desenvolvimento e ajudando dessa maneira. Desenvolvi algumas soluções usando o PascalScada, como prensas, sistemas de pesagem e o maior foi desenvolvido a uns 3 anos, um sistema de gerenciamento de 60 medidores de grandezas elétricas da Schneider Electric, PM1200, usando a serial RS232->RS485 direto nos equipamentos de shopping aqui da região.

        • Fabio Luis Girardi Autor do postResponder

          Boa tarde Rafael!

          Lembro de ti sim, você me enviou screenshots de algumas de suas aplicações a alguns anos (que estão publicados na pagina de screenshots). Se quiser mandar mais alguns screenshots das suas aplicações, me ajuda bastante.

          Bom respondendo sua pergunta, são necessário vários componentes TCP_UDPPort do PascalSCADA inseridos na sua aplicação. Este componente representa um socket tcp/ip (que é uma das várias conexões lógicas que um equipamento pode ter) que correm sobre uma porta física, que geralmente é ethernet. Então sua solução terá um PC com uma porta ethernet ligada a um switch, e deste sairá a conexão física (leia cabos) para todos os seus equipamentos. Neste PC seu PC com uma porta ethernet (porta fisica) estará rodando uma aplicação feita no PascalSCADA com vários componentes TCP_UDPPort representando várias conexões lógicas, cada uma endereçada para um equipamento, todas saindo pela mesma porta ethernet do seu PC.

          Espero ter conseguido explicar a lógica de funcionamento de uma aplicação com multiplas conexões TCP/IP.

  10. Rafael B. Pimentel Responder

    Boa noite Fabio,

    Olha eu aqui de novo… quando desabilitamos o AutoRead e o AutoWrite, o comando para ler é simples de usar… mas na hr de usar o de escrita ele pede algumas informações que eu não soube decifra. Quanto ao prints… vou organizar e mandar tudo já com essa nova aplicação!!!

          • Fabio Luis Girardi Autor do postResponder

            TPLCTagNumber voce pode utilizar:
            PLCTagNumber1.Write(valor);

            TPLCBlock vc tem que fazer:
            var
            values:TArrayOfDouble;
            begin
            setLength(values,2); //2 é o tamanho do bloco
            values[0]:=valor1;
            values[1]:=valor2;
            Block1.Write(values,0,0);
            SetLength(values,0);

  11. alk859 Responder

    Hi, Fabio! Thanks for your great work!
    I am trying to use SerialPortDriver to connect Modbus RTU via MOXA 5110 tcp NPort (Win32). Everything works fine, but after the program is completed, the process remains in memory, and the virtual COM port remains blocked. How to complete the process and release the port? My code OnFormClose:
    SerialPortDriver1.Active:=False;
    SerialPortDriver1.COMPort:=”;
    SerialPortDriver1.Free;
    Thank you in advance!

  12. Rodrigo Responder

    Bom dia a todos , alguem sabe como fazer uma listagem de portas disponiveis com o combobox usando o serial do pascalscada

    atualmente utilizo uma “gambiarra” com o ” comcombobox” do modulo ” tcomport” no qual ele já vem programado para listagem das portas

    simplesmente faço o seguinte

    serialPortDriver1.COMport := comcombobox.Caption;

    como ele ja faz a listagem automatica da porta com ( com1, com2 com…) apenas comolo para ler o que está escrito nele.

    ele está funcionado perfeitamente essa “gambiarra” porem o Tcomport só funciona no windows , e futuramente pretendo migrar algumas coisas para ser utilizado no linux tambem .

    • Fabio Luis Girardi Autor do postResponder

      Bom dia Rodrigo!

      Você pode usar o editor da propriedade TSerialPortDriver.COMPort. A classe responsável por fazer a edição desta propriedade tem o seguinte nome: TPortPropertyEditor e está definida na unit scadapropeditor.pas, do pacote pascalscada.lpk (pascalscada_dsng.lpk se você estiver usando a versão trunk). É só criar um instancia desta classe chamar o metodo TPortPropertyEditor.GetValues(@ProcedimentoQueIraAdicionarAPortaEncontradaNoSeuCombobox); Depois de usá-lo, basta destruir.

  13. Сергей Александрович Responder

    Good day Fabio! How can pascalscada connect to a controller that is located on a different network?

  14. bill kang Responder

    Hello. I’m from China, bill.kang. I want to ask. Can I modify the code of SCADA according to my functional requirements through code modification?

  15. Paulo Portugal Responder

    Hi Fábio,

    I have a question about how asynchronous read requests can be sent on ModbusTCP.

    My problem is the following: I have a TPLCBLOCK_1 that is using function 16 (WriteMultiple registers) to update some Modbus registers on the server. I use the following TPLCBLOCK_1 method to do this. TPLCBLOCK_1.Write (…). Right after that I want to read another TPLCBLOCK_2 that is using function 3 (Read input registers) to read other set of Modbus registers. This function works cyclically. However, I intend to read immediately after TPLCBLOCK_1. Write (…). That is, I want to make an asynchronous reading (i.e. at that moment) of TPLCBLOCK_2. For this I used the method TPLCBLOCK_2.Read ().

    Things are working, but it was kind of a trial-error-trial because there is no documentation abut it and I had to analyze the source code to try to found the methods. I ask if this is the correct procedure?

    Thanks
    Paulo Portugal

    • Fabio Luis Girardi Autor do postResponder

      Hi Paulo!

      Sorry for taking too much time to reply. I’m having e-mail issues on this website, that doesn’t notify me about new comment messages.

      Tag.Read and Tag.Write are synchronous functions. They will stop the protocol scanner to do their job, and depending of your application, they can freeze it by a small time to complete the operation. To “do” asynchronous read after write your values, you have some options:

      1) watch the value of ValuesTimestamp and/or CommReadsOK, together with LastAsyncReadStatus, something like this:

      lastValueTimestamp := Tag.ValuesTimestamp;
      lastCommReadsOK := Tag.CommReadsOK;
      repeat
      application.processMessages; //don’t remove this line.
      until (lastValueTimestamp < Tag.ValuesTimestamp) and (lastCommReadsOK < Tag.CommReadsOK) and (tag.LastAsyncReadStatus=ioOk); 2) use TPLCBLOCK_2.OnUpdate to know when the tag was updated by the protocol scanner, and check if the last update was successful. If successful, set a flag to allow your process to continue. 3) After write, use application.QueueAsyncCall to queue procedure to check your TPLCBLOCK_2 status. If the tag TPLCBLOCK_2 wasn't updated, queue the procedure, again, again and again. Similar to approach number 1, but without repeat ... until loop.

    • Fabio Luis Girardi Autor do postResponder

      I’m replying your comment again, to see if you are notified about my reply.

  16. Peter Responder

    Hi Fabio,

    i am trying to read holding registers from my Kostal Plenticore Inverter by using the laz_modbus_tcp_example from sourceforge but without success.
    I have double checked the IP Adress, Port Number and can open the port without error, but requesting a register from the inverter ends up with no result.

    There do i adjust the slave id of the inverter ?

    Thanks for your help in advance

  17. Miguel Responder

    Hi Fabio.

    I’m trying to send a command to a control board for a emergency generator.
    I’m success reading operation parameters. Not same story in write or send command.

    Board documentation indicate to write (in single command) to register 4104 and 4105 the values 35701 and 29835, respectively.
    This should set the board to AUTO Mode.

    On the side of the programming. Did you see this correct?

    PLCTagNumber2.TagType:=pttWord;
    PLCTagNumber2.MemReadFunction:=16;
    PLCTagNumber2.MemAddress:=4104;
    PLCTagNumber2.Write([35700,29836],2,0);

    Feb-16 08:42:32.107, iocWriteRead, Result=iorOK, Written: 00 00 00 00 00 09 00 10 10 08 00 01 02 00 00
    Feb-16 08:42:32.107, iocWriteRead, Result=iorOK, Received: 00 00 00 00 00 03 00 90 02
    Feb-16 08:42:35.200, iocRead , Result=iorTimeOut, Received: 00

    The registers are:
    – Write only.
    – Min. Value = 0
    – Max Value = 65535

    Environment:
    – Windows 10 (64bits).
    – Lazarus 2.0.10 (32bits)

    Thank you.
    M.Caro

    • Miguel Responder

      Update.
      Problems were in my side:
      1. Change from TPLCTagNumber.Write to TPLCBlock.ScanWrite. This change was made after better understanding of PascalSCADA by reading from documentation. Also reading from users questions and author answers (Fabio).
      2. Others issues not related to PascalSCADA.

      Works like a charm!

      • Fabio Luis Girardi Autor do postResponder

        The difference between that ScanWrite and Write, is that ScanWrite will queue the write command to be executed after other possible write commands queued before, while write command stops the read/write queue to execute your command. So if you need to do a emergency stop tag.write should be your choice.

  18. Rodrigo Hernandes Responder

    Olá bom dia.
    Aceita sugestões de novas funções em versões futuras ?

    Eu sei que minha parte é a mais fácil ( o pedir é fácil ). E sei também que é possível fazer , porem começa a exigir um pouco mais de conhecimento da linguagem.

    Mas são funções que para quem não programa comumente (delphi / Lazarus) ajudaria essa pessoa.

    Geralmente quem chega aqui pode ser a pessoa ( como eu ) que não conhece profundamente programação em pascal , e o seu software ajuda muito neste sentido.

    Tem alguns itens que fizeram falta por não está na lista de componentes , pessoalmente consegui fazer com outros meios para chegar no resultado, porem para quem está a muito pouco tempo vai encontrar muita dificuldade.

    A primeira coisa que senti muita falta foi um “Seletor de Porta COMM” “no estilo combobox” no qual seleciona as portas existentes , antigamente nos Pcs as portas com era bem fixas raramente mudava o numero , e poderiam deixar fixadas no programa , porem com o advento das USB/Serial , dependendo do modelo do adaptador, da porta USB e de quantas portas já existem a porta COM muda seu numero. fora que quando você tira o numero some.
    Atualmente estou usando um recurso do Tcomport ( um combobox já preparado para buscar as portas COMM existentes) para fazer essa seleção.

    Aproveitando este item poderia também fazer uns seletores dos outros itens de porta de comunicação (data bit,paridade,stopbit) apesar destes serem muito mais fácil adaptar um combobox, pois sempre vão ter disponível e fixo estas opções e são poucas.

    Como recentemente estava testando os CRC , outro item que seria interessante colocar seria uma informação em formato de texto(string) dos erros que está acontecendo , eu vi que já tem isso no “LastAsyncReadStatus” e existe vários erros , porem por exemplo o erro de CRC está como “IOCOMMERROR”
    ( não testei ainda só vi visualizando o código). fica muito genérico e não ajuda a quem está procurando o erro que está acontecendo.

  19. Rodrigo Hernandes Responder

    Um outro item que esqueci de mencionar que também ajudaria seria um visualizador de bytes recebidos/enviados , eu vi que no texto de log ele mostra os bits recebidos e enviados ….
    Seria legal ter isso em um MEMO para poder visualizar em nível de bytes ( EX: 01 03 05 00 00 …..CRC) isso tambem ajudaria a pessoa fazer um debug do seu sistema ……

  20. Reid Responder

    I am new on Pascalscada with Lazarus. I got Pascalscada on Lazarus. I have two buttons and two texts and set them as “OFF” on the Lazarus form. I want to be able to click the first button from Lazarus form to turn on the LED from the first slave Arduino. Click the second button from Lazarus form to turn on the LED from the second slave Arduino. Also, the first slave Arduino has a button, push the button which makes the first text from Lazarus Form to set as “ON”. Push the button again to change from “ON” to “OFF” Same with the button on the second slave Arduino. I just want a simple to get two Arduino working. They are connected with RS485. I just need to code for Lazarus, first slave Arduino, and second slave Arduino. Do you know where I can find the example code?

  21. Koen Responder

    Hello,
    I have a timeout problem using rtu in a simple test project connected via a virtual serial port (ST-LINK)) to a STM32 Nucleo board.
    Using ModScan64.exe I get this correct communication:
    XMT: [02][04][75][30][00][02][6b][fb]
    RCV: [02][04][07][88][00][88][00][c1][24]

    Using PascalScada (SerialPortDriver with Timeout=1000, ModBusRTUDriver, PLCTagNumber with refreshTime=2000 and TagType pttDWord ) I get this result:
    Jan-03 16:27:08.831, iocWriteRead, Result=iorOK, Written: 02 04 75 31 00 02 3A 3B
    Jan-03 16:27:08.831, iocWriteRead, Result=iorOK, Received: 02 04 07
    Jan-03 16:27:14.199, iocRead , Result=iorTimeOut, Received: 88 00 88 00 C1 24 00 00 00
    Jan-03 16:27:14.231, iocWriteRead, Result=iorOK, Written: 02 04 75 31 00 02 3A 3B
    Jan-03 16:27:14.231, iocWriteRead, Result=iorOK, Received: 02 04 07
    Jan-03 16:27:19.517, iocRead , Result=iorTimeOut, Received: 88 00 88 00 C1 24 00 00 00
    Jan-03 16:27:19.541, iocWriteRead, Result=iorOK, Written: 02 04 75 31 00 02 3A 3B
    Jan-03 16:27:19.541, iocWriteRead, Result=iorOK, Received: 02 04 07

    Any hint as where this 5 to 6 seconds “delay” comes from?
    Windows 10, Lazarus 2.2.6
    Thanks in advance for any help!

    • Fabio Luis Girardi Autor do postResponder

      I never used the Modbus function $04. I’m looking at the sources and to communication packets to understand what’s happening.

    • Fabio Luis Girardi Autor do postResponder

      In the Modbus RTU documentation, is wrote that the reply of function 0x04 is similar to the function 0x03.

      So, looking to exchanged Modbus RTU Packets, I saw

      Jan-03 16:27:08.831, iocWriteRead, Result=iorOK, Received: 02 04 07

      So, the Modbus RTU driver expects 7 more data bytes plus 2 bytes of CRC to be read on next request. But only 6 bytes are available. The missing 3 bytes are zero filled. Timeout happens and CRC checks fails.

      I’ll try to simulate this function soon as possible.

  22. Koen Responder

    Hello Fabio. thank you!
    We should have noticed that ourself.
    But I have another issue.
    I noticed that setting the ProtocolDriver in a PLCTagNumber during design results in a high (25%) CPU-load for Lazarus.
    Without setting the ProtocolDriver it is near 0%.
    My workaround is setting the ProtocolDriver in FormCreate. No problem for me.
    Is this a wanted behavior?
    Thanks again!

  23. Koen Responder

    Set the property ReadSomethingAlways of your modbus rtu driver to false.
    I tried. It makes no difference in CPU usage.

  24. Koen Responder

    “In the other hand send this application that reproduces this to be analyzed.”
    ==> send by answering your mail

Deixe uma resposta

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