Introdução
Em primeiro lugar, sinta-se livre para enviar correções de qualquer tipo, incluindo reformulações de texto.
Este artigo tem como objetivo principal entender para que servem as classes de processamento de escala e os cenários onde estas classes devem ser usadas. Um resumo das propriedades de cada uma será abordado a seguir.
O que são as classes processadoras de escalas
As classes processadoras de escalas (que são derivadas da classe TScaleProcessor) servem para fazer uma transformação numérica do valor que vem do seu equipamento (valor puro) para um valor que será exibido para o usuário do sistema de supervisão (engenharia), fazendo o caminho reverso quando o usuário altera um valor no sistema de supervisão que está na escala de engenharia, entregando um valor puro para o seu equipamento.
O equipamento raramente entrega o valor na unidade que o operador quer ver: uma entrada analógica de um S7 chega como um inteiro de 0 a 27648; um inversor manda a frequência em décimos de hertz; um transmissor de nível dá 4–20 mA convertidos em 0–4095. É esse o trabalho das escalas.
Elas se ligam aos tags numéricos pela propriedade ScaleProcessor (veja Tags). A partir daí:
ValueRawé o valor puro, como veio do equipamento;ValueéValueRawdepois da escala — o que os controles da HCl mostram e o que você usa em código;- escrever em
Valueaplica a escala inversa e grava o valor puro no equipamento.
Escalas implementadas no PascalSCADA atualmente
O processamento de escala mais utilizado é o processamento linear, que já está implementado no PascalSCADA na classe TLinearScaleProcessor. Mas caso necessite de uma escala que não está implementada ainda, você pode usar a classe TUserScale, que permite, através da implementação de dois eventos da instância, a sua própria escala. E para compor várias escalas em sequência existe a TScalesQueue. Todas ficam na paleta PascalSCADA Utils.
| Componente | Faz |
|---|---|
TLinearScaleProcessor |
Conversão linear entre duas faixas (a regra de três). Cobre 90% dos casos. |
TUserScale |
Conversão que você escreve em dois eventos — para qualquer fórmula. |
TScalesQueue |
Encadeia vários processadores em sequência. |
Preciso criar um objeto de escala para cada tag da minha aplicação?
Não. O sistema de escalas do PascalSCADA foi desenhado para que um objeto de escala possa ser compartilhado com quantos tags existirem na sua aplicação. Ou seja, se todos os meus tags usam a mesma escala e se num determinado momento for necessário realizar uma alteração desta escala, basta mudar as propriedades de um único objeto para alterar a escala de todos os tags de sua aplicação. O processador não guarda estado por tag.
A classe TLinearScaleProcessor
A classe TLinearScaleProcessor faz o que o nome dela propõe: a conversão de valores através de uma função linear de primeiro grau. A imagem abaixo ilustra seu funcionamento: 
As propriedades PLCMin e PLCMax representam o intervalo de valores puros, que vem do seu equipamento. Já as propriedades SysMin e SysMax representam a faixa de valores na unidade de engenharia, ou seja, que serão exibidas ao usuário do sistema de supervisão. A conversão é feita em ambos os sentidos, do equipamento para o usuário e do usuário para o equipamento:
Value = (ValueRaw - PLCMin) * (SysMax - SysMin) / (PLCMax - PLCMin) + SysMin
ValueRaw = (Value - SysMin) * (PLCMax - PLCMin) / (SysMax - SysMin) + PLCMin
Vale lembrar que os processadores de escala não fazem a restrição para valores na escala de engenharia fora da faixa: um valor puro fora de PLCMin..PLCMax produz um valor de engenharia fora de SysMin..SysMax — o que geralmente é o desejado, para que uma sobrefaixa apareça como tal. Para restringir a entrada de dados use as propriedades EnableMinValue, EnableMaxValue, MinValue e MaxValue de seus tags.
Basta configurar as propriedades PLCMin, PLCMax, SysMin e SysMax com os dados da sua escala. Para testar não é necessário rodar a aplicação: basta usar a propriedade Input para simular o valor vindo de seu CLP e a propriedade Output para simular os valores vindos da aplicação. Sete o valor na propriedade Input e veja o valor convertido na escala de engenharia na propriedade Output, e vice-versa. (PLCMax = PLCMin ou SysMax = SysMin não divide por zero: o divisor é tratado como 1.)
Abaixo está uma lista de alguns exemplos de conversões usando a classe TLinearScaleProcessor:
| Nome | PLCMin | PLCMax | SysMin | SysMax |
|---|---|---|---|---|
| Milissegundos (CLP) → segundos (Supervisão) | 0 | 1000 | 0 | 1 |
| Segundos (CLP) → minutos (Supervisão) | 0 | 60 | 0 | 1 |
| Temperatura RTD em décimos de grau (CLP) → graus (Supervisão) | 0 | 10 | 0 | 1 |
| Analógica 4 a 20 mA Siemens (CLP) → 0 a 100 % (Supervisão) | 4096 | 27648 | 0 | 100 |
| Analógica 0 a 10 V Siemens (0–27648) → 0 a 100 % | 0 | 27648 | 0 | 100 |
| Entrada 4–20 mA em cartão 0–4095 (4 mA = 819) → 0 a 10 bar | 819 | 4095 | 0 | 10 |
| Temperatura em décimos de grau, com offset (−400 = −40,0 °C) | −400 | 1500 | −40 | 150 |
| Inverter o sentido (0 = cheio, 1000 = vazio) → 100 a 0 % | 0 | 1000 | 100 | 0 |
A classe TUserScale
Para conversões não lineares — raiz quadrada de um transmissor de vazão por pressão diferencial, tabela de linearização de um termopar, polinômio de calibração — implemente os dois eventos:
// Equipamento -> usuário procedure TForm1.UserScale1PLCToUser(Sender: TObject; const Input: Double; var Output: Double); begin Output := Sqrt(Input / 4095) * 500; // vazão em m³/h end; // Usuário -> equipamento (inversa da anterior) procedure TForm1.UserScale1UserToPLC(Sender: TObject; const Input: Double; var Output: Double); begin Output := Sqr(Input / 500) * 4095; end;
Sender é o tag que pediu a conversão, então um único TUserScale pode aplicar fórmulas diferentes conforme o tag (if Sender = Tag_Vazao1 then …). Se um evento não estiver atribuído, o valor passa sem alteração naquele sentido.
Os eventos rodam na thread principal, sempre que o tag é atualizado — mantenha-os rápidos e sem acesso a banco ou rede.
A classe TScalesQueue
Uma fila de processadores. A coleção ScalesQueue tem itens com a propriedade ScaleProcessor; o valor puro passa pelo primeiro item, o resultado pelo segundo, e assim por diante. No sentido usuário → equipamento a ordem é invertida automaticamente, do último para o primeiro.
Serve para compor conversões reutilizáveis: um TLinearScaleProcessor “0–27648 → 0–100 %” seguido de outro “0–100 % → 0–500 m³/h”, ou uma escala linear seguida de um TUserScale de linearização. Um TScalesQueue também é um processador de escala e pode entrar na fila de outro TScalesQueue (só não pode conter a si mesmo).
Onde mais as escalas aparecem
TNumericExprTagtambém temScaleProcessor, aplicado ao resultado da expressão.TTagBitcomUseRawValue = Falsemapeia os bits deValue(escalado) do tag origem; comTrue, deValueRaw. Para palavras de status ligueTrue.- Os controles
THMITrackBar/THMIScrollBartrabalham com inteiros da LCL: para um setpoint de 0,0 a 10,0 bar, ponha a escala no tag (SysMin = 0,SysMax = 100) e o controle de 0 a 100 — ou useTHMIEdit/THMIUpDown, que aceitamDouble. - Os
THMIControlDislocatorAnimationusam internamente uma escala linear entreValueP0/ValueP1e as posições P0/P1.
Exemplos relacionados
examples/laz_linear_scalling— umTScalesQueuecom umTLinearScaleProcessor(“1 no sistema = 100 no CLP”) aplicado a elementos de um bloco Modbus TCP, comTHMIScrollBareTHMILabelmostrando puro e escalado lado a lado.examples/laz_numericexpr— cálculo entre tags comTNumericExprTag, alternativa às escalas quando o resultado depende de mais de um tag.
