{"id":425,"date":"2016-08-30T00:02:30","date_gmt":"2016-08-30T03:02:30","guid":{"rendered":"http:\/\/www.pascalscada.com\/?page_id=425"},"modified":"2026-09-17T09:36:38","modified_gmt":"2026-09-17T12:36:38","slug":"s7-protocol-over-isotcp","status":"publish","type":"page","link":"https:\/\/www.pascalscada.com\/pb\/s7-protocol-over-isotcp\/","title":{"rendered":"Protocolo S7 sobre ISOTCP"},"content":{"rendered":"<h5>Introdu\u00e7\u00e3o<\/h5>\n<p>O <code>TISOTCPDriver<\/code> fala o protocolo <strong>S7comm sobre ISO-on-TCP<\/strong> (RFC 1006, porta TCP 102) \u2014 o mesmo que o STEP 7, o TIA Portal e a LibNodave usam para ler e escrever mem\u00f3rias de um CLP Siemens. O driver \u00e9 uma reescrita em Pascal do ISOTCP da LibNodave de Thomas Hergenhahn: n\u00e3o depende de nenhuma DLL ou biblioteca externa.<\/p>\n<p>Ele conversa com:<\/p>\n<ul>\n<li><strong>S7-300, S7-400, ET200S\/ET200SP<\/strong> com CPU ou CP Ethernet;<\/li>\n<li><strong>S7-1200 e S7-1500<\/strong> \u2014 depois de liberar o acesso PUT\/GET e desligar o acesso otimizado dos DBs (veja <em>Preparando o CLP<\/em>);<\/li>\n<li><strong>S7-200<\/strong> atrav\u00e9s de um CP 243-1 (<code>ConnectionWay = ISOTCP_VIA_CP243<\/code>);<\/li>\n<li><strong>LOGO! 0BA7\/0BA8<\/strong> (LOGO! 7 e 8), que exp\u00f5e a \u00e1rea V como DB1;<\/li>\n<li>qualquer simulador ou gateway compat\u00edvel com S7comm (PLCSIM com NetToPLCSim, Snap7 server, etc.).<\/li>\n<\/ul>\n<p>Ele <strong>n\u00e3o<\/strong> conversa com o S7-1200\/1500 pelo protocolo nativo deles (S7CommPlus, que \u00e9 o que o TIA Portal usa para acesso simb\u00f3lico) \u2014 para isso existe o <a href=\"\/pb\/s7commplus\/\"><code>TS7CommPlusDriver<\/code><\/a>. O ISOTCP continua sendo a op\u00e7\u00e3o mais simples para esses CLPs quando voc\u00ea controla o projeto no TIA e pode desligar o acesso otimizado.<\/p>\n<h5>Componentes necess\u00e1rios<\/h5>\n<ol>\n<li>Uma <img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/TTCP_UDPPort.png\"> <strong><code>TTCP_UDPPort<\/code><\/strong> com <code>Host<\/code> = IP do CLP, <code>Port = 102<\/code> (padr\u00e3o) e <code>PortType = ptTCP<\/code>. Veja <a href=\"\/pb\/communication-ports\/\">Portas de comunica\u00e7\u00e3o<\/a>.<\/li>\n<li>Um <img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/TISOTCPDriver.png\"> <strong><code>TISOTCPDriver<\/code><\/strong> com <code>CommunicationPort<\/code> apontando para a porta.<\/li>\n<li>Os tags (<code>TPLCTagNumber<\/code>, <code>TPLCBlock<\/code>, <code>TPLCStruct<\/code>, <code>TPLCString<\/code>) com <code>ProtocolDriver<\/code> apontando para o driver.<\/li>\n<\/ol>\n<p>O jeito mais r\u00e1pido de chegar ao passo 3 \u00e9 clicar com o bot\u00e3o direito no <code>TISOTCPDriver<\/code> e escolher <strong>Tag Builder<\/strong> (veja abaixo).<\/p>\n<h5>Propriedades do driver<\/h5>\n<table>\n<thead>\n<tr>\n<th>Propriedade<\/th>\n<th>Padr\u00e3o<\/th>\n<th>Descri\u00e7\u00e3o<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>CommunicationPort<\/code><\/td>\n<td>\u2013<\/td>\n<td>A porta <code>TTCP_UDPPort<\/code> usada pelo driver.<\/td>\n<\/tr>\n<tr>\n<td><code>PLCRack<\/code><\/td>\n<td>0<\/td>\n<td>Rack da CPU.<\/td>\n<\/tr>\n<tr>\n<td><code>PLCSlot<\/code><\/td>\n<td>0<\/td>\n<td>Slot da CPU.<\/td>\n<\/tr>\n<tr>\n<td><code>PLCStation<\/code><\/td>\n<td>2<\/td>\n<td>Endere\u00e7o da esta\u00e7\u00e3o. S\u00f3 tem significado em redes MPI\/PROFIBUS atr\u00e1s de um gateway; em Ethernet deixe o padr\u00e3o.<\/td>\n<\/tr>\n<tr>\n<td><code>ConnectionWay<\/code><\/td>\n<td><code>ISOTCP<\/code><\/td>\n<td><code>ISOTCP<\/code> para conex\u00e3o direta \u00e0 CPU\/CP Ethernet; <code>ISOTCP_VIA_CP243<\/code> para S7-200 atr\u00e1s de um CP 243-1.<\/td>\n<\/tr>\n<tr>\n<td><code>ISOTCPConnType<\/code><\/td>\n<td><code>ctOP<\/code><\/td>\n<td>Tipo de conex\u00e3o que o driver se identifica ao CLP: <code>ctPG<\/code> (programadora), <code>ctOP<\/code> (painel de opera\u00e7\u00e3o) ou <code>ctBasic<\/code> (outra). O CLP reserva recursos por tipo; se todas as conex\u00f5es OP estiverem em uso, troque para <code>ctBasic<\/code>.<\/td>\n<\/tr>\n<tr>\n<td><code>ForcePDUSize<\/code><\/td>\n<td><code>pduAuto<\/code><\/td>\n<td>Tamanho de PDU negociado. <code>pduAuto<\/code> pede o maior que o CLP aceita; force <code>pdu240<\/code> para CLPs antigos ou LOGO!, que n\u00e3o negociam corretamente.<\/td>\n<\/tr>\n<tr>\n<td><code>ReadOnly<\/code><\/td>\n<td><code>False<\/code><\/td>\n<td>Se <code>True<\/code>, o driver recusa qualquer escrita (<code>ioReadOnlyProtocol<\/code>). \u00datil para uma tela de supervis\u00e3o que nunca deve alterar o processo.<\/td>\n<\/tr>\n<tr>\n<td><code>ReadSomethingAlways<\/code><\/td>\n<td><code>True<\/code><\/td>\n<td>Mant\u00e9m a conex\u00e3o viva lendo algum tag a cada ciclo mesmo que nenhum precise ser atualizado.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<blockquote>\n<p><strong>Uma conex\u00e3o ISOTCP fala com um \u00fanico CLP.<\/strong> Por isso, as propriedades <code>PLCRack<\/code>, <code>PLCSlot<\/code> e <code>PLCStation<\/code> <strong>dos tags s\u00e3o ignoradas<\/strong>: o que vale \u00e9 o que est\u00e1 configurado no driver. Para falar com dois CLPs, use duas portas e dois drivers.<\/p>\n<\/blockquote>\n<p>Valores de rack\/slot que funcionam na maioria dos casos:<\/p>\n<table>\n<thead>\n<tr>\n<th>CPU<\/th>\n<th>PLCRack<\/th>\n<th>PLCSlot<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>S7-300 (CPU com PN integrada ou CP 343-1)<\/td>\n<td>0<\/td>\n<td>2<\/td>\n<\/tr>\n<tr>\n<td>S7-400<\/td>\n<td>0<\/td>\n<td>slot f\u00edsico da CPU (normalmente 2 ou 3)<\/td>\n<\/tr>\n<tr>\n<td>S7-1200 \/ S7-1500<\/td>\n<td>0<\/td>\n<td>0 (1 tamb\u00e9m funciona no 1200)<\/td>\n<\/tr>\n<tr>\n<td>ET200S \/ ET200SP CPU<\/td>\n<td>0<\/td>\n<td>2 (ET200S) \/ 0 (ET200SP)<\/td>\n<\/tr>\n<tr>\n<td>S7-200 via CP 243-1<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>LOGO! 7 \/ 8<\/td>\n<td>0<\/td>\n<td>0 (ver <em>Preparando o CLP<\/em>)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Em c\u00f3digo, <code>UpdatePLCAddress(Rack, Slot, Station)<\/code> troca os tr\u00eas de uma vez sem reiniciar a conex\u00e3o tr\u00eas vezes.<\/p>\n<h5>Preparando o CLP<\/h5>\n<p><strong>S7-300 \/ S7-400<\/strong>: nada a fazer al\u00e9m de ter o IP configurado. Se a CPU tiver senha de prote\u00e7\u00e3o contra escrita, o driver l\u00ea mas n\u00e3o escreve.<\/p>\n<p><strong>S7-1200 \/ S7-1500<\/strong> (no TIA Portal):<\/p>\n<ol>\n<li>Nas propriedades da CPU \u2192 <em>Protection &amp; Security<\/em> \u2192 <em>Connection mechanisms<\/em>: marque <strong>Permit access with PUT\/GET communication from remote partner<\/strong>.<\/li>\n<li>Em cada DB que o PascalSCADA vai acessar, desmarque <strong>Optimized block access<\/strong> (propriedades do DB \u2192 <em>Attributes<\/em>) e recompile. Um DB otimizado n\u00e3o tem endere\u00e7os absolutos, e o ISOTCP s\u00f3 endere\u00e7a por byte.<\/li>\n<li>Se o n\u00edvel de prote\u00e7\u00e3o da CPU for <em>Full access<\/em>, nada mais. Com <em>Read access<\/em> o driver s\u00f3 l\u00ea; com <em>HMI access<\/em> ou <em>No access<\/em> a conex\u00e3o \u00e9 recusada.<\/li>\n<\/ol>\n<p><strong>LOGO! 7 \/ 8<\/strong> (no LOGO!Soft Comfort): em <em>Tools \u2192 Ethernet connections<\/em>, adicione uma <strong>conex\u00e3o de servidor<\/strong> com TSAP local <code>20.00<\/code> e TSAP remoto <code>10.00<\/code>, ou marque <em>Allow all connections<\/em>. A \u00e1rea V (VB\/VW\/VD) aparece para o PascalSCADA como <strong>DB1<\/strong> (<code>MemReadFunction = 4<\/code>, <code>MemFile_DB = 1<\/code>); as mem\u00f3rias M como \u00e1rea M (<code>MemReadFunction = 3<\/code>). O exemplo <a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/demo_logo8\"><code>examples\/demo_logo8<\/code><\/a> mostra isso, com <code>ForcePDUSize = pdu240<\/code> e <code>PLCStation = 0<\/code>.<\/p>\n<p><strong>S7-200<\/strong>: use <code>ConnectionWay = ISOTCP_VIA_CP243<\/code> e configure uma conex\u00e3o no CP 243-1 pelo assistente do STEP 7-Micro\/WIN. A \u00e1rea V \u00e9 <code>MemReadFunction = 4<\/code> com <code>MemFile_DB = 1<\/code>.<\/p>\n<h5>Endere\u00e7ando mem\u00f3rias<\/h5>\n<p>Todo endere\u00e7o S7 \u00e9 composto de uma <strong>\u00e1rea<\/strong>, um <strong>n\u00famero de DB<\/strong> (s\u00f3 para a \u00e1rea DB), um <strong>endere\u00e7o em bytes<\/strong> e o <strong>tipo<\/strong> da vari\u00e1vel. No tag isso vira:<\/p>\n<table>\n<thead>\n<tr>\n<th>Propriedade do tag<\/th>\n<th>Preencha com<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>MemReadFunction<\/code><\/td>\n<td>C\u00f3digo da \u00e1rea (tabela abaixo).<\/td>\n<\/tr>\n<tr>\n<td><code>MemFile_DB<\/code><\/td>\n<td>N\u00famero do DB, quando a \u00e1rea for 4. Ignorado nas outras.<\/td>\n<\/tr>\n<tr>\n<td><code>MemAddress<\/code><\/td>\n<td>Endere\u00e7o do <strong>byte<\/strong> inicial (o n\u00famero depois de <code>IB<\/code>, <code>MW<\/code>, <code>DBD<\/code>\u2026).<\/td>\n<\/tr>\n<tr>\n<td><code>TagType<\/code><\/td>\n<td>Tipo da vari\u00e1vel (tabela mais abaixo).<\/td>\n<\/tr>\n<tr>\n<td><code>MemWriteFunction<\/code>, <code>MemSubElement<\/code>, <code>PLCRack\/Slot\/Station<\/code><\/td>\n<td>N\u00e3o usados. Deixe em zero.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>C\u00f3digos de \u00e1rea para <code>MemReadFunction<\/code>:<\/p>\n<table>\n<thead>\n<tr>\n<th>C\u00f3digo<\/th>\n<th>\u00c1rea<\/th>\n<th>CPUs<\/th>\n<th>Observa\u00e7\u00e3o<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>1<\/td>\n<td><code>I<\/code> \u2014 entradas digitais (imagem de processo)<\/td>\n<td>todas<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td><code>Q<\/code> \u2014 sa\u00eddas digitais (imagem de processo)<\/td>\n<td>todas<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td>3<\/td>\n<td><code>M<\/code> \u2014 mem\u00f3rias\/flags<\/td>\n<td>todas<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td>4<\/td>\n<td><code>DB<\/code> \u2014 bloco de dados<\/td>\n<td>300\/400\/1200\/1500; V no S7-200 e LOGO!<\/td>\n<td>Preencha <code>MemFile_DB<\/code>.<\/td>\n<\/tr>\n<tr>\n<td>5<\/td>\n<td><code>C<\/code> \u2014 contadores<\/td>\n<td>300\/400<\/td>\n<td><code>TagType = pttWord<\/code>.<\/td>\n<\/tr>\n<tr>\n<td>6<\/td>\n<td><code>T<\/code> \u2014 temporizadores<\/td>\n<td>300\/400<\/td>\n<td><code>TagType = pttWord<\/code>.<\/td>\n<\/tr>\n<tr>\n<td>7<\/td>\n<td><code>SM<\/code> \u2014 mem\u00f3ria especial<\/td>\n<td>S7-200<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td>8<\/td>\n<td><code>AI<\/code> \u2014 entradas anal\u00f3gicas<\/td>\n<td>S7-200<\/td>\n<td><code>TagType = pttWord<\/code>.<\/td>\n<\/tr>\n<tr>\n<td>9<\/td>\n<td><code>AQ<\/code> \u2014 sa\u00eddas anal\u00f3gicas<\/td>\n<td>S7-200<\/td>\n<td><code>TagType = pttWord<\/code>.<\/td>\n<\/tr>\n<tr>\n<td>10<\/td>\n<td><code>C<\/code> \u2014 contadores<\/td>\n<td>S7-200<\/td>\n<td><code>TagType = pttWord<\/code>.<\/td>\n<\/tr>\n<tr>\n<td>11<\/td>\n<td><code>T<\/code> \u2014 temporizadores<\/td>\n<td>S7-200<\/td>\n<td><code>TagType = pttWord<\/code>.<\/td>\n<\/tr>\n<tr>\n<td>12<\/td>\n<td><code>PIW<\/code> \u2014 periferia de entrada<\/td>\n<td>300\/400<\/td>\n<td><code>TagType = pttWord<\/code>. L\u00ea o valor direto do cart\u00e3o, sem passar pela imagem de processo.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Tipos de dados S7 e o <code>TagType<\/code> correspondente:<\/p>\n<table>\n<thead>\n<tr>\n<th>Tipo no CLP<\/th>\n<th>Bytes<\/th>\n<th>TagType<\/th>\n<th>SwapBytes<\/th>\n<th>SwapWords<\/th>\n<th>SwapDWords<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>BOOL<\/code><\/td>\n<td>\u2013<\/td>\n<td><code>pttByte<\/code> no tag + um <a href=\"\/pb\/tags\/#TTagBit\"><code>TTagBit<\/code><\/a> por bit<\/td>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><code>BYTE<\/code>, <code>CHAR<\/code>, <code>USINT<\/code><\/td>\n<td>1<\/td>\n<td><code>pttByte<\/code><\/td>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><code>SINT<\/code><\/td>\n<td>1<\/td>\n<td><code>pttShortInt<\/code><\/td>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><code>WORD<\/code>, <code>UINT<\/code>, <code>S5TIME<\/code>, <code>DATE<\/code><\/td>\n<td>2<\/td>\n<td><code>pttWord<\/code><\/td>\n<td>&#x2714;<\/td>\n<td><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><code>INT<\/code><\/td>\n<td>2<\/td>\n<td><code>pttSmallInt<\/code><\/td>\n<td>&#x2714;<\/td>\n<td><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><code>DWORD<\/code>, <code>UDINT<\/code>, <code>TIME_OF_DAY<\/code><\/td>\n<td>4<\/td>\n<td><code>pttDWord<\/code><\/td>\n<td>&#x2714;<\/td>\n<td>&#x2714;<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><code>DINT<\/code>, <code>TIME<\/code><\/td>\n<td>4<\/td>\n<td><code>pttLongInt<\/code><\/td>\n<td>&#x2714;<\/td>\n<td>&#x2714;<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><code>REAL<\/code><\/td>\n<td>4<\/td>\n<td><code>pttFloat<\/code><\/td>\n<td>&#x2714;<\/td>\n<td>&#x2714;<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><code>LINT<\/code>, <code>LTIME<\/code><\/td>\n<td>8<\/td>\n<td><code>pttInt64<\/code><\/td>\n<td>&#x2714;<\/td>\n<td>&#x2714;<\/td>\n<td>&#x2714;<\/td>\n<\/tr>\n<tr>\n<td><code>ULINT<\/code>, <code>LWORD<\/code><\/td>\n<td>8<\/td>\n<td><code>pttQWord<\/code><\/td>\n<td>&#x2714;<\/td>\n<td>&#x2714;<\/td>\n<td>&#x2714;<\/td>\n<\/tr>\n<tr>\n<td><code>LREAL<\/code><\/td>\n<td>8<\/td>\n<td><code>pttDouble<\/code><\/td>\n<td>&#x2714;<\/td>\n<td>&#x2714;<\/td>\n<td>&#x2714;<\/td>\n<\/tr>\n<tr>\n<td><code>STRING[n]<\/code><\/td>\n<td>n + 2<\/td>\n<td><code>TPLCString<\/code> com <code>StringType = stSIEMENS<\/code><\/td>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Os CLPs Siemens guardam os valores em <strong>big-endian<\/strong> e o PascalSCADA monta os bytes na ordem da m\u00e1quina (little-endian). Por isso tudo que tem mais de um byte precisa dos <code>Swap*<\/code> marcados como na tabela \u2014 sem eles, um <code>INT<\/code> = 1 aparece como 256 e um <code>REAL<\/code> vira um n\u00famero absurdo. O Tag Builder j\u00e1 marca os swaps corretos.<\/p>\n<p>Exemplos:<\/p>\n<table>\n<thead>\n<tr>\n<th>Endere\u00e7o S7<\/th>\n<th>MemReadFunction<\/th>\n<th>MemFile_DB<\/th>\n<th>MemAddress<\/th>\n<th>TagType<\/th>\n<th>Swaps<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>IB3<\/code><\/td>\n<td>1<\/td>\n<td>0<\/td>\n<td>3<\/td>\n<td><code>pttByte<\/code><\/td>\n<td>\u2013<\/td>\n<\/tr>\n<tr>\n<td><code>Q0.5<\/code><\/td>\n<td>2<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td><code>pttByte<\/code> + <code>TTagBit<\/code> com <code>StartBit = EndBit = 5<\/code><\/td>\n<td>\u2013<\/td>\n<\/tr>\n<tr>\n<td><code>MW10<\/code><\/td>\n<td>3<\/td>\n<td>0<\/td>\n<td>10<\/td>\n<td><code>pttWord<\/code><\/td>\n<td>B<\/td>\n<\/tr>\n<tr>\n<td><code>MD100<\/code> (como <code>REAL<\/code>)<\/td>\n<td>3<\/td>\n<td>0<\/td>\n<td>100<\/td>\n<td><code>pttFloat<\/code><\/td>\n<td>B + W<\/td>\n<\/tr>\n<tr>\n<td><code>DB5.DBW20<\/code><\/td>\n<td>4<\/td>\n<td>5<\/td>\n<td>20<\/td>\n<td><code>pttSmallInt<\/code><\/td>\n<td>B<\/td>\n<\/tr>\n<tr>\n<td><code>DB5.DBD24<\/code> (como <code>DINT<\/code>)<\/td>\n<td>4<\/td>\n<td>5<\/td>\n<td>24<\/td>\n<td><code>pttLongInt<\/code><\/td>\n<td>B + W<\/td>\n<\/tr>\n<tr>\n<td><code>DB10.DBB0<\/code> at\u00e9 <code>DBB49<\/code><\/td>\n<td>4<\/td>\n<td>10<\/td>\n<td>0<\/td>\n<td><code>TPLCBlock<\/code> <code>pttByte<\/code>, <code>Size = 50<\/code><\/td>\n<td>\u2013<\/td>\n<\/tr>\n<tr>\n<td><code>DB12<\/code> <code>STRING[30]<\/code> em <code>DBB8<\/code><\/td>\n<td>4<\/td>\n<td>12<\/td>\n<td>8<\/td>\n<td><code>TPLCString<\/code>, <code>StringSize = 30<\/code>, <code>stSIEMENS<\/code><\/td>\n<td>\u2013<\/td>\n<\/tr>\n<tr>\n<td><code>VW6<\/code> (LOGO!\/S7-200)<\/td>\n<td>4<\/td>\n<td>1<\/td>\n<td>6<\/td>\n<td><code>pttSmallInt<\/code><\/td>\n<td>B<\/td>\n<\/tr>\n<tr>\n<td><code>T5<\/code> (S7-300)<\/td>\n<td>6<\/td>\n<td>0<\/td>\n<td>5<\/td>\n<td><code>pttWord<\/code><\/td>\n<td>B<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h5>Bits<\/h5>\n<p>O ISOTCP do PascalSCADA l\u00ea e escreve <strong>por byte<\/strong>. Para um <code>BOOL<\/code> (uma entrada, uma sa\u00edda, um bit de um DB), crie um <code>TPLCTagNumber<\/code> com <code>TagType = pttByte<\/code> apontando para o byte que cont\u00e9m o bit e um <a href=\"\/pb\/tags\/#TTagBit\"><code>TTagBit<\/code><\/a> para cada bit de interesse (<code>StartBit = EndBit = n\u00famero do bit<\/code>). A escrita no <code>TTagBit<\/code> l\u00ea o byte atual, altera s\u00f3 aquele bit e grava o byte de volta.<\/p>\n<p>Para muitos bits no mesmo byte, clique com o bot\u00e3o direito no tag e escolha <strong>Map bits<\/strong>: ele cria os oito <code>TTagBit<\/code> de uma vez. O exemplo <a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/laz_isotcp_mapping_bits_from_other_tag\"><code>examples\/laz_isotcp_mapping_bits_from_other_tag<\/code><\/a> faz isso com <code>DB1.DBB0<\/code>.<\/p>\n<h5>Blocos, estruturas e strings<\/h5>\n<ul>\n<li>Um <strong><code>TPLCBlock<\/code><\/strong> l\u00ea <code>Size<\/code> vari\u00e1veis consecutivas do mesmo tipo em uma requisi\u00e7\u00e3o \u2014 um array de <code>REAL<\/code> num DB, por exemplo (<code>TagType = pttFloat<\/code>, <code>Size<\/code> = n\u00famero de elementos, <code>MemAddress<\/code> = byte inicial). Os swaps valem para o bloco inteiro.<\/li>\n<li>Um <strong><code>TPLCStruct<\/code><\/strong> l\u00ea <code>Size<\/code> bytes consecutivos, e cada <code>TPLCStructItem<\/code>\/<code>TPLCStructString<\/code> interpreta um trecho com seu pr\u00f3prio tipo e swap. \u00c9 a forma natural de mapear um DB com campos mistos ou uma UDT \u2014 veja o exemplo em <a href=\"\/pb\/tags\/#TPLCStruct\">Tags<\/a>.<\/li>\n<li>Um <strong><code>TPLCString<\/code><\/strong> com <code>StringType = stSIEMENS<\/code> l\u00ea uma <code>STRING[n]<\/code>: os dois bytes de cabe\u00e7alho (tamanho m\u00e1ximo e tamanho atual) s\u00e3o tratados pelo driver. Use <code>stC<\/code> s\u00f3 para arrays de <code>CHAR<\/code> terminados em zero.<\/li>\n<\/ul>\n<p>O driver junta automaticamente tags vizinhos da mesma \u00e1rea e do mesmo <code>RefreshTime<\/code> em uma requisi\u00e7\u00e3o s\u00f3, respeitando o tamanho da PDU negociado. Com <code>pduAuto<\/code> numa CPU moderna cabem at\u00e9 1920 bytes de dados por mensagem; num S7-300 antigo ou LOGO!, 240. Se o <code>AvgUpdateRate<\/code> dos tags ficar muito acima do <code>RefreshTime<\/code>, o CLP n\u00e3o est\u00e1 dando conta \u2014 aumente o <code>RefreshTime<\/code> dos tags menos cr\u00edticos ou agrupe-os em blocos.<\/p>\n<h5>Tag Builder<\/h5>\n<p>Bot\u00e3o direito no <code>TISOTCPDriver<\/code> \u2192 <strong>Tag Builder<\/strong> abre o assistente <em>Siemens S7 Tag builder<\/em>:<\/p>\n<ol>\n<li>Escolha a <strong>\u00e1rea<\/strong> (entradas, sa\u00eddas, flags, DB, contadores, timers, \u00e1reas do S7-200\u2026), o <strong>tipo de tag<\/strong> a criar (<code>TPLCTagNumber<\/code> separados, um <code>TPLCBlock<\/code>, ou <code>TPLCStruct<\/code>) e o tempo de varredura.<\/li>\n<li>Para tags separados ou bloco: informe o tipo de dado, o endere\u00e7o inicial, a quantidade e o DB. O assistente j\u00e1 marca <code>SwapBytes<\/code>\/<code>SwapWords<\/code> conforme o tipo.<\/li>\n<li>Para estruturas: monte a lista de itens (nome, tipo, swap, scan) na aba <em>Items declaration<\/em>; o assistente calcula os offsets e pode gerar N estruturas iguais em sequ\u00eancia (\u00fatil para arrays de UDT).<\/li>\n<\/ol>\n<p>Os componentes criados aparecem no form\/datamodule com <code>ProtocolDriver<\/code> j\u00e1 ligado.<\/p>\n<h5>Exemplo passo a passo<\/h5>\n<p>Ler a temperatura <code>DB1.DBD0<\/code> (<code>REAL<\/code>) e escrever o setpoint <code>DB1.DBW4<\/code> (<code>INT<\/code>) de um S7-1200 em 192.168.0.10:<\/p>\n<ol>\n<li>No TIA Portal: libere PUT\/GET, desmarque <em>Optimized block access<\/em> no DB1, compile e carregue.<\/li>\n<li>Solte um <code>TTCP_UDPPort<\/code>: <code>Host = 192.168.0.10<\/code>, <code>Port = 102<\/code>, <code>Active = True<\/code>.<\/li>\n<li>Solte um <code>TISOTCPDriver<\/code>: <code>CommunicationPort = TCP_UDPPort1<\/code>, <code>PLCRack = 0<\/code>, <code>PLCSlot = 0<\/code>.<\/li>\n<li>Solte um <code>TPLCTagNumber<\/code> chamado <code>Temperatura<\/code>: <code>ProtocolDriver = ISOTCPDriver1<\/code>, <code>MemReadFunction = 4<\/code>, <code>MemFile_DB = 1<\/code>, <code>MemAddress = 0<\/code>, <code>TagType = pttFloat<\/code>, <code>SwapBytes = True<\/code>, <code>SwapWords = True<\/code>.<\/li>\n<li>Solte outro chamado <code>Setpoint<\/code>: idem, com <code>MemAddress = 4<\/code>, <code>TagType = pttSmallInt<\/code>, <code>SwapBytes = True<\/code>.<\/li>\n<li>Ligue um <code>THMILabel<\/code> em <code>Temperatura<\/code> e um <code>THMIEdit<\/code> em <code>Setpoint<\/code>. Rode.<\/li>\n<\/ol>\n<p>O mesmo em c\u00f3digo, para quem cria os componentes em tempo de execu\u00e7\u00e3o:<\/p>\n<pre class=\"brush: delphi; tab-size: 2; title: ; notranslate\" title=\"\">uses tcp_udpport, ISOTCPDriver, PLCTagNumber, ProtocolTypes;\n\nvar\n  Port: TTCP_UDPPort;\n  Drv: TISOTCPDriver;\n  Temp: TPLCTagNumber;\nbegin\n  Port := TTCP_UDPPort.Create(Self);\n  Port.Host := &#039;192.168.0.10&#039;;\n  Port.Port := 102;\n\n  Drv := TISOTCPDriver.Create(Self);\n  Drv.CommunicationPort := Port;\n  Drv.PLCRack := 0;\n  Drv.PLCSlot := 0;\n\n  Temp := TPLCTagNumber.Create(Self);\n  Temp.MemReadFunction := 4;   \/\/ DB\n  Temp.MemFile_DB := 1;\n  Temp.MemAddress := 0;\n  Temp.TagType := pttFloat;\n  Temp.SwapBytes := True;\n  Temp.SwapWords := True;\n  Temp.RefreshTime := 500;\n  Temp.ProtocolDriver := Drv;  \/\/ por \u00faltimo\n\n  Port.Active := True;\nend;<\/pre>\n<p>Outros exemplos no reposit\u00f3rio: <a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/laz_isotcp_demonstration\"><code>examples\/laz_isotcp_demonstration<\/code><\/a> (DB com bloco, string e bits), <a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/laz_isotcp_hourmeter\"><code>examples\/laz_isotcp_hourmeter<\/code><\/a> (hor\u00edmetro com escrita), <a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/laz_isotcp_performance\"><code>examples\/laz_isotcp_performance<\/code><\/a> (medi\u00e7\u00e3o de taxa de atualiza\u00e7\u00e3o) e <a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/demo_logo8\"><code>examples\/demo_logo8<\/code><\/a>.<\/p>\n<h5>Problemas comuns<\/h5>\n<table>\n<thead>\n<tr>\n<th>Sintoma<\/th>\n<th>Causa prov\u00e1vel<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Porta abre (<code>Active = True<\/code>) mas nenhum tag atualiza; <code>LastSyncReadStatus = ioConnectPLCFailed<\/code><\/td>\n<td>Rack\/slot errados, ou S7-1200\/1500 sem PUT\/GET liberado, ou n\u00edvel de prote\u00e7\u00e3o <em>No access<\/em>.<\/td>\n<\/tr>\n<tr>\n<td>Porta n\u00e3o abre (<code>OnCommPortOpenError<\/code>)<\/td>\n<td>IP errado, porta 102 bloqueada por firewall, ou o CLP j\u00e1 atingiu o limite de conex\u00f5es (troque <code>ISOTCPConnType<\/code>).<\/td>\n<\/tr>\n<tr>\n<td>Tags de um DB espec\u00edfico d\u00e3o <code>ioIllegalMemoryAddress<\/code> \/ <code>ioObjectNotExists<\/code><\/td>\n<td>DB n\u00e3o existe, \u00e9 menor que o endere\u00e7o pedido, ou (1200\/1500) ainda est\u00e1 com <em>Optimized block access<\/em>.<\/td>\n<\/tr>\n<tr>\n<td>Valores de 16\/32 bits absurdos (<code>1<\/code> vira <code>256<\/code>, <code>REAL<\/code> vira <code>1E-40<\/code>)<\/td>\n<td>Falta <code>SwapBytes<\/code>\/<code>SwapWords<\/code>.<\/td>\n<\/tr>\n<tr>\n<td>Escritas falham com <code>ioReadOnlyProtocol<\/code> ou <code>ioObjectAccessNotAllowed<\/code><\/td>\n<td><code>ReadOnly = True<\/code> no driver, ou a CPU est\u00e1 com prote\u00e7\u00e3o de escrita\/senha.<\/td>\n<\/tr>\n<tr>\n<td>Funciona no S7-300 e n\u00e3o no LOGO!<\/td>\n<td>Force <code>ForcePDUSize = pdu240<\/code> e confira o TSAP da conex\u00e3o de servidor no LOGO!Soft.<\/td>\n<\/tr>\n<tr>\n<td>Timers\/contadores lidos como zero<\/td>\n<td><code>TagType<\/code> precisa ser <code>pttWord<\/code> nessas \u00e1reas.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h5>Exemplos relacionados<\/h5>\n<ul>\n<li><a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/laz_isotcp_demonstration\"><code>examples\/laz_isotcp_demonstration<\/code><\/a> \u2014 DB com <code>TPLCBlock<\/code>, elementos, <code>TPLCString<\/code> e bits, com <code>THMIEdit<\/code>\/<code>THMIText<\/code> (h\u00e1 uma vers\u00e3o Delphi em <a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/delphi_isotcp_demonstration\"><code>examples\/delphi_isotcp_demonstration<\/code><\/a>).<\/li>\n<li><a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/laz_isotcp_hourmeter\"><code>examples\/laz_isotcp_hourmeter<\/code><\/a> \u2014 hor\u00edmetros lidos de blocos com dezenas de <code>TTagBit<\/code> e <code>THMIAnimation<\/code>, com escrita.<\/li>\n<li><a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/laz_isotcp_mapping_bits_from_other_tag\"><code>examples\/laz_isotcp_mapping_bits_from_other_tag<\/code><\/a> \u2014 <code>DB1.DBB0<\/code> com um <code>TTagBit<\/code> por bit.<\/li>\n<li><a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/laz_isotcp_performance\"><code>examples\/laz_isotcp_performance<\/code><\/a> \u2014 milhares de elementos de bloco para medir a taxa de atualiza\u00e7\u00e3o e o efeito do tamanho da PDU.<\/li>\n<li><a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/demo_logo8\"><code>examples\/demo_logo8<\/code><\/a> \u2014 LOGO! 8: \u00e1rea V como DB1, <code>ForcePDUSize = pdu240<\/code>.<\/li>\n<li><a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/hmi_bandeja\"><code>examples\/hmi_bandeja<\/code><\/a> \u2014 <code>TPLCStruct<\/code> sobre um DB, com <code>THMIBandeja<\/code>.<\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>Introdu\u00e7\u00e3o O TISOTCPDriver fala o protocolo S7comm sobre ISO-on-TCP (RFC 1006, porta TCP 102) \u2014 o mesmo que o STEP 7, o TIA Portal e a LibNodave usam para ler &#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"closed","template":"template-fullwidth.php","meta":{"footnotes":""},"class_list":["post-425","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.pascalscada.com\/pb\/wp-json\/wp\/v2\/pages\/425","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pascalscada.com\/pb\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.pascalscada.com\/pb\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.pascalscada.com\/pb\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pascalscada.com\/pb\/wp-json\/wp\/v2\/comments?post=425"}],"version-history":[{"count":31,"href":"https:\/\/www.pascalscada.com\/pb\/wp-json\/wp\/v2\/pages\/425\/revisions"}],"predecessor-version":[{"id":1232,"href":"https:\/\/www.pascalscada.com\/pb\/wp-json\/wp\/v2\/pages\/425\/revisions\/1232"}],"wp:attachment":[{"href":"https:\/\/www.pascalscada.com\/pb\/wp-json\/wp\/v2\/media?parent=425"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}