{"id":442,"date":"2016-08-30T00:18:15","date_gmt":"2016-08-30T03:18:15","guid":{"rendered":"http:\/\/www.pascalscada.com\/?page_id=442"},"modified":"2026-09-17T09:36:46","modified_gmt":"2026-09-17T12:36:46","slug":"scale-processors","status":"publish","type":"page","link":"https:\/\/www.pascalscada.com\/pb\/scale-processors\/","title":{"rendered":"Processadores de escala"},"content":{"rendered":"<h5>Introdu\u00e7\u00e3o<\/h5>\n<p>Em primeiro lugar, sinta-se livre para enviar corre\u00e7\u00f5es de qualquer tipo, incluindo reformula\u00e7\u00f5es de texto.<\/p>\n<p>Este artigo tem como objetivo principal entender para que servem as classes de processamento de escala e os cen\u00e1rios onde estas classes devem ser usadas. Um resumo das propriedades de cada uma ser\u00e1 abordado a seguir.<\/p>\n<h5>O que s\u00e3o as classes processadoras de escalas<\/h5>\n<p>As classes processadoras de escalas (que s\u00e3o derivadas da classe <code>TScaleProcessor<\/code>) servem para fazer uma transforma\u00e7\u00e3o num\u00e9rica do valor que vem do seu equipamento (valor puro) para um valor que ser\u00e1 exibido para o usu\u00e1rio do sistema de supervis\u00e3o (engenharia), fazendo o caminho reverso quando o usu\u00e1rio altera um valor no sistema de supervis\u00e3o que est\u00e1 na escala de engenharia, entregando um valor puro para o seu equipamento.<\/p>\n<p>O equipamento raramente entrega o valor na unidade que o operador quer ver: uma entrada anal\u00f3gica de um S7 chega como um inteiro de 0 a 27648; um inversor manda a frequ\u00eancia em d\u00e9cimos de hertz; um transmissor de n\u00edvel d\u00e1 4\u201320 mA convertidos em 0\u20134095. \u00c9 esse o trabalho das escalas.<\/p>\n<p>Elas se ligam aos tags num\u00e9ricos pela propriedade <strong><code>ScaleProcessor<\/code><\/strong> (veja <a href=\"\/pb\/tags\/\">Tags<\/a>). A partir da\u00ed:<\/p>\n<ul>\n<li><code>ValueRaw<\/code> \u00e9 o valor puro, como veio do equipamento;<\/li>\n<li><code>Value<\/code> \u00e9 <code>ValueRaw<\/code> depois da escala \u2014 o que os controles da <a href=\"\/pb\/hmi-control-library-hcl\/\">HCl<\/a> mostram e o que voc\u00ea usa em c\u00f3digo;<\/li>\n<li>escrever em <code>Value<\/code> aplica a escala inversa e grava o valor puro no equipamento.<\/li>\n<\/ul>\n<h5>Escalas implementadas no PascalSCADA atualmente<\/h5>\n<p>O processamento de escala mais utilizado \u00e9 o processamento linear, que j\u00e1 est\u00e1 implementado no PascalSCADA na classe <code>TLinearScaleProcessor<\/code>. Mas caso necessite de uma escala que n\u00e3o est\u00e1 implementada ainda, voc\u00ea pode usar a classe <code>TUserScale<\/code>, que permite, atrav\u00e9s da implementa\u00e7\u00e3o de dois eventos da inst\u00e2ncia, a sua pr\u00f3pria escala. E para compor v\u00e1rias escalas em sequ\u00eancia existe a <code>TScalesQueue<\/code>. Todas ficam na paleta <strong>PascalSCADA Utils<\/strong>.<\/p>\n<table>\n<thead>\n<tr>\n<th>Componente<\/th>\n<th>Faz<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/TLinearScaleProcessor.png\"> <code>TLinearScaleProcessor<\/code><\/td>\n<td>Convers\u00e3o linear entre duas faixas (a regra de tr\u00eas). Cobre 90% dos casos.<\/td>\n<\/tr>\n<tr>\n<td><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/TUserScale.png\"> <code>TUserScale<\/code><\/td>\n<td>Convers\u00e3o que voc\u00ea escreve em dois eventos \u2014 para qualquer f\u00f3rmula.<\/td>\n<\/tr>\n<tr>\n<td><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/TScalesQueue.png\"> <code>TScalesQueue<\/code><\/td>\n<td>Encadeia v\u00e1rios processadores em sequ\u00eancia.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h5>Preciso criar um objeto de escala para cada tag da minha aplica\u00e7\u00e3o?<\/h5>\n<p>N\u00e3o. O sistema de escalas do PascalSCADA foi desenhado para que um objeto de escala possa ser compartilhado com quantos tags existirem na sua aplica\u00e7\u00e3o. Ou seja, se todos os meus tags usam a mesma escala e se num determinado momento for necess\u00e1rio realizar uma altera\u00e7\u00e3o desta escala, basta mudar as propriedades de um \u00fanico objeto para alterar a escala de todos os tags de sua aplica\u00e7\u00e3o. O processador n\u00e3o guarda estado por tag.<\/p>\n<h5 id=\"TLinearScaleProcessor\">A classe TLinearScaleProcessor<\/h5>\n<p>A classe <code>TLinearScaleProcessor<\/code> faz o que o nome dela prop\u00f5e: a convers\u00e3o de valores atrav\u00e9s de uma fun\u00e7\u00e3o linear de primeiro grau. A imagem abaixo ilustra seu funcionamento: <a href=\"http:\/\/www.pascalscada.com\/wp-content\/uploads\/2016\/08\/TLinearScaleProcessor.png\"><img decoding=\"async\" alt=\"TLinearScaleProcessor\" src=\"http:\/\/www.pascalscada.com\/wp-content\/uploads\/2016\/08\/TLinearScaleProcessor.png\"><\/a><\/p>\n<p>As propriedades <code>PLCMin<\/code> e <code>PLCMax<\/code> representam o intervalo de valores puros, que vem do seu equipamento. J\u00e1 as propriedades <code>SysMin<\/code> e <code>SysMax<\/code> representam a faixa de valores na unidade de engenharia, ou seja, que ser\u00e3o exibidas ao usu\u00e1rio do sistema de supervis\u00e3o. A convers\u00e3o \u00e9 feita em ambos os sentidos, do equipamento para o usu\u00e1rio e do usu\u00e1rio para o equipamento:<\/p>\n<pre><code>Value    = (ValueRaw - PLCMin) * (SysMax - SysMin) \/ (PLCMax - PLCMin) + SysMin\nValueRaw = (Value    - SysMin) * (PLCMax - PLCMin) \/ (SysMax - SysMin) + PLCMin\n<\/code><\/pre>\n<p><img decoding=\"async\" alt=\"Warning32\" src=\"http:\/\/www.pascalscada.com\/wp-content\/uploads\/2016\/08\/Warning32.png\">Vale lembrar que os processadores de escala n\u00e3o fazem a restri\u00e7\u00e3o para valores na escala de engenharia fora da faixa: um valor puro fora de <code>PLCMin<\/code>..<code>PLCMax<\/code> produz um valor de engenharia fora de <code>SysMin<\/code>..<code>SysMax<\/code> \u2014 o que geralmente \u00e9 o desejado, para que uma sobrefaixa apare\u00e7a como tal. Para restringir a entrada de dados use as propriedades <code>EnableMinValue<\/code>, <code>EnableMaxValue<\/code>, <code>MinValue<\/code> e <code>MaxValue<\/code> de seus tags.<\/p>\n<p>Basta configurar as propriedades <code>PLCMin<\/code>, <code>PLCMax<\/code>, <code>SysMin<\/code> e <code>SysMax<\/code> com os dados da sua escala. Para testar n\u00e3o \u00e9 necess\u00e1rio rodar a aplica\u00e7\u00e3o: basta usar a propriedade <code>Input<\/code> para simular o valor vindo de seu CLP e a propriedade <code>Output<\/code> para simular os valores vindos da aplica\u00e7\u00e3o. Sete o valor na propriedade <code>Input<\/code> e veja o valor convertido na escala de engenharia na propriedade <code>Output<\/code>, e vice-versa. (<code>PLCMax = PLCMin<\/code> ou <code>SysMax = SysMin<\/code> n\u00e3o divide por zero: o divisor \u00e9 tratado como 1.)<\/p>\n<p>Abaixo est\u00e1 uma lista de alguns exemplos de convers\u00f5es usando a classe <code>TLinearScaleProcessor<\/code>:<\/p>\n<table>\n<thead>\n<tr>\n<th>Nome<\/th>\n<th>PLCMin<\/th>\n<th>PLCMax<\/th>\n<th>SysMin<\/th>\n<th>SysMax<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Milissegundos (CLP) \u2192 segundos (Supervis\u00e3o)<\/td>\n<td>0<\/td>\n<td>1000<\/td>\n<td>0<\/td>\n<td>1<\/td>\n<\/tr>\n<tr>\n<td>Segundos (CLP) \u2192 minutos (Supervis\u00e3o)<\/td>\n<td>0<\/td>\n<td>60<\/td>\n<td>0<\/td>\n<td>1<\/td>\n<\/tr>\n<tr>\n<td>Temperatura RTD em d\u00e9cimos de grau (CLP) \u2192 graus (Supervis\u00e3o)<\/td>\n<td>0<\/td>\n<td>10<\/td>\n<td>0<\/td>\n<td>1<\/td>\n<\/tr>\n<tr>\n<td>Anal\u00f3gica 4 a 20 mA Siemens (CLP) \u2192 0 a 100 % (Supervis\u00e3o)<\/td>\n<td>4096<\/td>\n<td>27648<\/td>\n<td>0<\/td>\n<td>100<\/td>\n<\/tr>\n<tr>\n<td>Anal\u00f3gica 0 a 10 V Siemens (0\u201327648) \u2192 0 a 100 %<\/td>\n<td>0<\/td>\n<td>27648<\/td>\n<td>0<\/td>\n<td>100<\/td>\n<\/tr>\n<tr>\n<td>Entrada 4\u201320 mA em cart\u00e3o 0\u20134095 (4 mA = 819) \u2192 0 a 10 bar<\/td>\n<td>819<\/td>\n<td>4095<\/td>\n<td>0<\/td>\n<td>10<\/td>\n<\/tr>\n<tr>\n<td>Temperatura em d\u00e9cimos de grau, com offset (\u2212400 = \u221240,0 \u00b0C)<\/td>\n<td>\u2212400<\/td>\n<td>1500<\/td>\n<td>\u221240<\/td>\n<td>150<\/td>\n<\/tr>\n<tr>\n<td>Inverter o sentido (0 = cheio, 1000 = vazio) \u2192 100 a 0 %<\/td>\n<td>0<\/td>\n<td>1000<\/td>\n<td>100<\/td>\n<td>0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h5 id=\"TUserScale\">A classe TUserScale<\/h5>\n<p><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/TUserScale.png\"> Para convers\u00f5es n\u00e3o lineares \u2014 raiz quadrada de um transmissor de vaz\u00e3o por press\u00e3o diferencial, tabela de lineariza\u00e7\u00e3o de um termopar, polin\u00f4mio de calibra\u00e7\u00e3o \u2014 implemente os dois eventos:<\/p>\n<pre class=\"brush: delphi; tab-size: 2; title: ; notranslate\" title=\"\">\/\/ Equipamento -&gt; usu\u00e1rio\nprocedure TForm1.UserScale1PLCToUser(Sender: TObject; const Input: Double;\n  var Output: Double);\nbegin\n  Output := Sqrt(Input \/ 4095) * 500;      \/\/ vaz\u00e3o em m\u00b3\/h\nend;\n\n\/\/ Usu\u00e1rio -&gt; equipamento (inversa da anterior)\nprocedure TForm1.UserScale1UserToPLC(Sender: TObject; const Input: Double;\n  var Output: Double);\nbegin\n  Output := Sqr(Input \/ 500) * 4095;\nend;<\/pre>\n<p><code>Sender<\/code> \u00e9 o tag que pediu a convers\u00e3o, ent\u00e3o um \u00fanico <code>TUserScale<\/code> pode aplicar f\u00f3rmulas diferentes conforme o tag (<code>if Sender = Tag_Vazao1 then \u2026<\/code>). Se um evento n\u00e3o estiver atribu\u00eddo, o valor passa sem altera\u00e7\u00e3o naquele sentido.<\/p>\n<p>Os eventos rodam na thread principal, sempre que o tag \u00e9 atualizado \u2014 mantenha-os r\u00e1pidos e sem acesso a banco ou rede.<\/p>\n<h5 id=\"TScalesQueue\">A classe TScalesQueue<\/h5>\n<p><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.pascalscada.com\/wp-content\/uploads\/2026\/09\/TScalesQueue.png\"> Uma fila de processadores. A cole\u00e7\u00e3o <code>ScalesQueue<\/code> tem itens com a propriedade <code>ScaleProcessor<\/code>; o valor puro passa pelo primeiro item, o resultado pelo segundo, e assim por diante. No sentido usu\u00e1rio \u2192 equipamento a ordem \u00e9 invertida automaticamente, do \u00faltimo para o primeiro.<\/p>\n<p>Serve para compor convers\u00f5es reutiliz\u00e1veis: um <code>TLinearScaleProcessor<\/code> &#8220;0\u201327648 \u2192 0\u2013100 %&#8221; seguido de outro &#8220;0\u2013100 % \u2192 0\u2013500 m\u00b3\/h&#8221;, ou uma escala linear seguida de um <code>TUserScale<\/code> de lineariza\u00e7\u00e3o. Um <code>TScalesQueue<\/code> tamb\u00e9m \u00e9 um processador de escala e pode entrar na fila de outro <code>TScalesQueue<\/code> (s\u00f3 n\u00e3o pode conter a si mesmo).<\/p>\n<h5>Onde mais as escalas aparecem<\/h5>\n<ul>\n<li><strong><a href=\"\/pb\/tags\/#TNumericExprTag\"><code>TNumericExprTag<\/code><\/a><\/strong> tamb\u00e9m tem <code>ScaleProcessor<\/code>, aplicado ao resultado da express\u00e3o.<\/li>\n<li><strong><code>TTagBit<\/code><\/strong> com <code>UseRawValue = False<\/code> mapeia os bits de <code>Value<\/code> (escalado) do tag origem; com <code>True<\/code>, de <code>ValueRaw<\/code>. Para palavras de status ligue <code>True<\/code>.<\/li>\n<li>Os controles <strong><code>THMITrackBar<\/code><\/strong>\/<strong><code>THMIScrollBar<\/code><\/strong> trabalham com inteiros da LCL: para um setpoint de 0,0 a 10,0 bar, ponha a escala no tag (<code>SysMin = 0<\/code>, <code>SysMax = 100<\/code>) e o controle de 0 a 100 \u2014 ou use <code>THMIEdit<\/code>\/<code>THMIUpDown<\/code>, que aceitam <code>Double<\/code>.<\/li>\n<li>Os <strong><code>THMIControlDislocatorAnimation<\/code><\/strong> usam internamente uma escala linear entre <code>ValueP0<\/code>\/<code>ValueP1<\/code> e as posi\u00e7\u00f5es P0\/P1.<\/li>\n<\/ul>\n<h5>Exemplos relacionados<\/h5>\n<ul>\n<li><a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/laz_linear_scalling\"><code>examples\/laz_linear_scalling<\/code><\/a> \u2014 um <code>TScalesQueue<\/code> com um <code>TLinearScaleProcessor<\/code> (&#8220;1 no sistema = 100 no CLP&#8221;) aplicado a elementos de um bloco Modbus TCP, com <code>THMIScrollBar<\/code> e <code>THMILabel<\/code> mostrando puro e escalado lado a lado.<\/li>\n<li><a href=\"https:\/\/github.com\/fluisgirardi\/pascalscada_v0\/tree\/master\/examples\/laz_numericexpr\"><code>examples\/laz_numericexpr<\/code><\/a> \u2014 c\u00e1lculo entre tags com <code>TNumericExprTag<\/code>, alternativa \u00e0s escalas quando o resultado depende de mais de um tag.<\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>Introdu\u00e7\u00e3o Em primeiro lugar, sinta-se livre para enviar corre\u00e7\u00f5es de qualquer tipo, incluindo reformula\u00e7\u00f5es de texto. Este artigo tem como objetivo principal entender para que servem as classes de processamento &#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"template-fullwidth.php","meta":{"footnotes":""},"class_list":["post-442","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.pascalscada.com\/pb\/wp-json\/wp\/v2\/pages\/442","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=442"}],"version-history":[{"count":34,"href":"https:\/\/www.pascalscada.com\/pb\/wp-json\/wp\/v2\/pages\/442\/revisions"}],"predecessor-version":[{"id":1236,"href":"https:\/\/www.pascalscada.com\/pb\/wp-json\/wp\/v2\/pages\/442\/revisions\/1236"}],"wp:attachment":[{"href":"https:\/\/www.pascalscada.com\/pb\/wp-json\/wp\/v2\/media?parent=442"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}