Operaciones aritméticas en automatización: del cálculo simple al algoritmo complejo

Las operaciones aritméticas dotan a los PLC de la capacidad de procesar señales, calcular variables de proceso, ejecutar algoritmos de control y tomar decisiones basadas en magnitudes numéricas. Desde la simple suma de contadores hasta la implementación de un PID o el cálculo de raíces cuadradas en sistemas de caudal, estas operaciones son esenciales en la ingeniería de automatización.

Según la norma IEC 61131-3, las operaciones aritméticas están disponibles en todos los lenguajes: en ST (Textos Estructurados) se escriben como expresiones matemáticas; en FBD y Ladder se usan bloques específicos (ADD, SUB, MUL, DIV, etc.). La elección depende de la complejidad y la claridad deseada.

Aplicación industrial: en una estación de mezclado, se leen caudales de dos componentes (señales analógicas), se suman, se compara el total con un setpoint, y se calcula la raíz cuadrada del caudal para linealizar la respuesta de una válvula. Todo ello se ejecuta en cada ciclo de scan.

Operaciones aritméticas básicas: ADD, SUB, MUL, DIV

Las operaciones fundamentales se implementan con instrucciones directas:

  • ADD (suma): resultado := A + B; en ST. En FBD, bloque con dos entradas y una salida.
  • SUB (resta): resultado := A - B;
  • MUL (multiplicación): resultado := A * B;
  • DIV (división): resultado := A / B; ¡Ojo con la división por cero! Siempre debe validarse que el divisor no sea cero antes de ejecutar la operación.

Ejemplo en ST:

// Suma de dos entradas analógicas escaladas
total := (analog_in_1 + analog_in_2) * 0.01;  // escalado simple

// Prevención de división por cero
IF divisor <> 0 THEN
    resultado := dividendo / divisor;
ELSE
    resultado := 0;
    error_div := TRUE;
END_IF

Datos técnicos: Los PLC trabajan con tipos de datos enteros (INT, DINT) y reales (REAL). Es crucial respetar los rangos para evitar desbordamientos. En Siemens S7-1500, un INT va de -32768 a 32767; un DINT de -2³¹ a 2³¹-1; un REAL tiene precisión de 6 dígitos decimales.

Operaciones avanzadas: potencias, raíces, trigonometría y logaritmos

Los PLC modernos incorporan funciones matemáticas complejas, accesibles generalmente en ST o como bloques en librerías:

  • POW (potencia): y := A ** B; o POW(A, B). Ejemplo: cálculo de energía en un motor (potencia = par * velocidad²).
  • SQRT (raíz cuadrada): y := SQRT(A);. Útil para linealizar señales de caudalímetros (caudal ∝ √ΔP).
  • SIN, COS, TAN: funciones trigonométricas (ángulos en radianes). Aplicaciones en robótica, mesas rotativas, cinemática.
  • LOG, LN, EXP: logaritmos y exponenciales. Usados en modelos de procesos químicos, control de pH, etc.
  • ABS (valor absoluto): y := ABS(A); para trabajar con magnitudes siempre positivas.

Ejemplo en ST (cálculo de caudal a partir de presión diferencial):

// Sensor de presión diferencial (0-1000 mbar)
dp_real := INT_TO_REAL(dp_raw) * 0.1;  // convertir a mbar
IF dp_real >= 0.0 THEN
    caudal := SQRT(dp_real) * K_factor;  // caudal en L/min
ELSE
    caudal := 0.0;
END_IF

Comparaciones: la base de las decisiones

Las instrucciones de comparación permiten evaluar condiciones numéricas y activar salidas lógicas:

  • EQ (equal, ==) : verdadero si A = B.
  • NE (not equal, <>) : verdadero si A ≠ B.
  • GT (greater than, >) : A > B.
  • LT (less than, <) : A < B.
  • GE (greater or equal, >=) : A ≥ B.
  • LE (less or equal, <=) : A ≤ B.

Aplicación típica: control de temperatura con histéresis:

IF temp > (setpoint + histeresis/2) THEN
    calefaccion := FALSE;
    refrigeracion := TRUE;
ELSIF temp < (setpoint - histeresis/2) THEN
    calefaccion := TRUE;
    refrigeracion := FALSE;
END_IF

Conversión de tipos de datos

Los PLC manejan diferentes formatos: BOOL, BYTE, WORD, INT, DINT, REAL, TIME, etc. Para operar entre ellos es necesario convertir explícitamente usando funciones como:

  • INT_TO_REAL : entero a real.
  • REAL_TO_INT : real a entero (trunca).
  • WORD_TO_DINT : palabra a doble entero.

Las conversiones implícitas pueden dar lugar a errores de compilación o comportamientos inesperados. Es buena práctica hacerlas explícitas.

Ejemplo:

velocidad_real := INT_TO_REAL(velocidad_raw) * 0.01;  // escalado
velocidad_entera := REAL_TO_INT(velocidad_real);      // truncamiento
Editor de texto estructurado SCL en TIA Portal mostrando variables: I_Start, Sys_Running, I_Stop, I_Sensor y Add_Tag. Código con instrucción IF-THEN con operadores lógicos (OR, AND, NOT) y comparación aritmética (I_Sensor > 30). En la rama THEN se asigna Add_Tag := Add_Tag + 1; en la rama ELSE se desactiva Sys_Running.
Figura 8: Ejemplo de código SCL/ST en TIA Portal con operaciones aritméticas y comparación condicional (IF-THEN-ELSE). Fuente: Inst Tools – Types of Expressions in the SCL Language / Licencia: © instrumentationtools.com — uso educativo (verificar permiso)
🐍 Simulación de operaciones aritméticas estilo PLC en Python (Raspberry Pi)
# plc_arithmetic.py - Simula operaciones aritméticas básicas y avanzadas
# Puede ejecutarse en Thonny y usarse con GPIO para leer sensores reales

import math

class PLCArithmetic:
    """Simula un PLC con memoria y operaciones aritméticas."""
    def __init__(self):
        # Áreas de memoria (simulan %I, %Q, %M, %DB)
        self.inputs = {'vel_raw': 0, 'caudal_raw': 0}   # enteros de sensores
        self.outputs = {'alarma': False, 'display_sum': 0.0, 'display_cuad': 0.0}
        self.marks = {'vel_real': 0.0, 'caudal_real': 0.0, 'suma': 0.0,
                      'vel_cuadrado': 0.0, 'caudal_limite': 50.0}

    def leer_sensores(self, vel, caudal):
        """Simula la lectura de entradas analógicas (raw values 0-27648)."""
        self.inputs['vel_raw'] = vel
        self.inputs['caudal_raw'] = caudal

    def escalar(self, raw, factor=0.01):
        """Convierte raw a real (simula INT_TO_REAL y escalado)."""
        return float(raw) * factor

    def ciclo_calculo(self):
        """Ejecuta las operaciones aritméticas en cada ciclo de scan."""
        # Conversiones
        self.marks['vel_real'] = self.escalar(self.inputs['vel_raw'])
        self.marks['caudal_real'] = self.escalar(self.inputs['caudal_raw'])

        # Suma
        self.marks['suma'] = self.marks['vel_real'] + self.marks['caudal_real']

        # Cuadrado de la velocidad
        self.marks['vel_cuadrado'] = self.marks['vel_real'] ** 2

        # Comparación: caudal > límite?
        if self.marks['caudal_real'] > self.marks['caudal_limite']:
            self.outputs['alarma'] = True
        else:
            self.outputs['alarma'] = False

        # Raíz cuadrada del caudal (solo si es positivo)
        if self.marks['caudal_real'] >= 0:
            self.outputs['display_cuad'] = math.sqrt(self.marks['caudal_real'])
        else:
            self.outputs['display_cuad'] = 0.0

        # Potencia (caudal^1.5) - ejemplo avanzado
        self.outputs['display_pot'] = math.pow(self.marks['caudal_real'], 1.5)

        # Salida a display (HMI simulado)
        self.outputs['display_sum'] = self.marks['suma']

    def mostrar_estado(self):
        print(f"vel={self.marks['vel_real']:.2f}  caudal={self.marks['caudal_real']:.2f}  "
              f"suma={self.marks['suma']:.2f}  vel²={self.marks['vel_cuadrado']:.2f}  "
              f"alarma={self.outputs['alarma']}  √caudal={self.outputs['display_cuad']:.2f}")

# --- Simulación de varios ciclos ---
plc = PLCArithmetic()
# Simulamos lecturas de sensores (valores raw)
for ciclo in range(1, 6):
    # Valores raw: 1000, 2000, . (representan 10.0, 20.0 .)
    plc.leer_sensores(vel=1000*ciclo, caudal=2000*ciclo)
    plc.ciclo_calculo()
    print(f"Ciclo {ciclo}: ", end="")
    plc.mostrar_estado()

# Salida esperada: alarma se activa cuando caudal_real > 50
# (caudal_raw 2000 → 20.0, 4000 → 40.0, 6000 → 60.0 → alarma True)

Este código simula las operaciones aritméticas básicas y avanzadas (suma, cuadrado, comparación, raíz cuadrada, potencia) sobre valores escalados. Se puede probar en Thonny y luego adaptar a Raspberry Pi con sensores reales usando GPIO o ADC.

Tendencias Actuales 2026

Los PLC actuales incorporan coprocesadores matemáticos que aceleran operaciones en coma flotante, permitiendo ejecutar algoritmos complejos (como filtros de Kalman o transformadas rápidas) en tiempo real. Además, la norma IEC 61131-3 edición 4 incluye nuevas funciones como raíces n-ésimas, logaritmos en cualquier base y operaciones con números complejos para aplicaciones de robótica avanzada.

Aplicaciones con Raspberry Pi

Con Python y librerías como math, podemos implementar todas las operaciones aritméticas vistas. Además, usando RPi.GPIO y convertidores ADC (MCP3008), podemos leer sensores analógicos, escalar, calcular raíces cuadradas y activar salidas. Es una excelente plataforma para prototipar algoritmos antes de pasarlos a un PLC.

Aplicaciones con Arduino

En Arduino, las operaciones aritméticas se escriben directamente en C++. Para raíces cuadradas se usa sqrt() (requiere math.h), para potencias pow(). El Arduino PLC IDE ofrece bloques gráficos para estas operaciones, facilitando la programación según IEC 61131-3.

💼 Caso Práctico Industrial: Celda robotizada

Contexto: En una celda robotizada se miden la velocidad de una cinta (en m/s) y el caudal de un líquido (en L/min) mediante sensores analógicos (valores raw 0-27648). Se necesita programar en FBD/ST:

  • Calcular la suma total de litros transportados en un ciclo (caudal * tiempo_ciclo).
  • Calcular el cuadrado de la velocidad media.
  • Comparar si el caudal supera los 50 L/min; si es así, activar una alarma.

Se dispone de un temporizador TON que genera un pulso de 1 segundo para medir tiempo.

Pregunta: ¿Qué secuencia de operaciones es la correcta para obtener la suma total de litros en un ciclo (caudal * tiempo)?

🍓 Raspberry Pi + Python

Contexto: En una Raspberry Pi, se ha escrito un script que lee un sensor analógico de temperatura (0-1023) a través de un ADC MCP3008. Se quiere convertir a grados Celsius (°C) usando la fórmula: temperatura = (raw * 3.3 / 1023 - 0.5) * 100. Luego se compara si supera los 30°C para activar un LED.

Pregunta: ¿Qué operaciones aritméticas intervienen en el escalado?

🐍 Conversión de tipos en Python

Contexto: En un PLC, se tiene una variable entera valor_raw (INT) que representa una lectura de sensor. Se desea calcular su raíz cuadrada y almacenarla en una variable real.

Pregunta: ¿Cuál de las siguientes opciones en Python sería equivalente a raiz := SQRT(INT_TO_REAL(valor_raw))?

Tabla 1: Operaciones aritméticas y funciones en IEC 61131-3 y Python
OperaciónST (PLC)PythonObservaciones
Sumaa + ba + b
Multiplicacióna * ba * b
Divisióna / ba / bEn ST, si a y b son enteros, resultado entero; en Python es float.
Potenciaa ** b o POW(a,b)a ** b o pow(a,b)
Raíz cuadradaSQRT(a)math.sqrt(a)
LogaritmoLN(a), LOG(a)math.log(a), math.log10(a)
Conversión INT->REALINT_TO_REAL(a)float(a)

📚 Recursos Técnicos y Normativos 2026

Normativas y Estándares

Recursos Raspberry Pi y Python