A submedição de energia com medidores IoT atribui a eletricidade da planta a máquinas, linhas e utilidades individuais, em vez de depender de um único medidor geral. Neste tutorial você vai conectar medidores de energia Modbus em trilho DIN de um barramento RS-485 a um pequeno gateway, ler tensão, corrente, potência e contadores de energia com Python e publicar tudo via MQTT, para que cada máquina tenha seu próprio número de energia ao vivo e histórico.
Por que submedir no nível da máquina
O medidor geral responde "quanto"; os submedidores respondem "onde" e "quando". Quando cada máquina grande tem seu próprio medidor, você enxerga o consumo ocioso entre ordens, compara máquinas idênticas, verifica o efeito de um novo inversor ou de um setpoint alterado e informa a energia por peça. A submedição também é a espinha dorsal de medição do monitoramento de energia na fábrica em toda a planta e de um plano de coleta de dados para a ISO 50001.
Escolhendo medidores e gateway
| Componente | Escolha comum | Observações |
|---|---|---|
| Medidor trifásico | Multimedidor em trilho DIN com Modbus RTU via RS-485 e entradas para TC (por exemplo, Eastron SDM630 MCT, ou modelos semelhantes de outros fabricantes) | Verifique se o mapa de registradores é publicado |
| Transformadores de corrente | TCs de núcleo dividido dimensionados para o alimentador, ou bobinas de Rogowski | O núcleo dividido permite retrofit sem desconectar cabos |
| Barramento | RS-485 em par trançado, em cadeia (daisy chain), com terminação de 120 ohms nas duas pontas | Até 32 cargas unitárias por segmento sem repetidores |
| Gateway | Raspberry Pi com adaptador USB-RS485, PC industrial de borda ou conversor Modbus TCP para RTU | Precisa de um caminho de rede confiável até o broker |
| Software | Python com pymodbus e paho-mqtt, ou Node-RED | Python mostrado abaixo |
Dê a cada medidor um endereço Modbus único (1, 2, 3 e assim por diante) e a mesma taxa de transmissão e paridade, configuradas no painel frontal do medidor. Os exemplos usam 9600 baud, 8 bits de dados, sem paridade e 1 bit de parada.
A instalação elétrica de medidores e TCs deve ser feita por um eletricista qualificado, seguindo as normas locais. TCs com saída secundária nunca devem ficar com o secundário aberto enquanto o primário conduz corrente, a menos que sejam do tipo seguro, com saída em tensão.
Mapa de registradores
Os multimedidores expõem as leituras como floats IEEE 754 de 32 bits distribuídos em dois registradores de entrada de 16 bits. Na família SDM630, alguns registradores de entrada úteis (código de função 04) são:
| Valor | Registrador (decimal) | Unidade |
|---|---|---|
| Tensão da fase 1 | 0 | V |
| Corrente da fase 1 | 6 | A |
| Potência total do sistema | 52 | W |
| Fator de potência total do sistema | 62 | - |
| Frequência | 70 | Hz |
| Energia ativa importada total | 72 | kWh |
Outros medidores usam endereços, códigos de função ou ordens de palavras diferentes. Trabalhe sempre com o documento de registradores do fabricante; uma ordem de palavras errada produz números que parecem plausíveis, mas estão completamente fora.
Ligando o gateway
- Conecte os terminais A e B (às vezes D+ e D-) do adaptador USB-RS485 aos terminais A e B do primeiro medidor e siga em cadeia para os demais. Evite topologias em estrela.
- Instale resistores de terminação de 120 ohms nas duas pontas físicas do barramento, caso os medidores ou o adaptador não os tenham embutidos.
- Conecte o terra de referência se o adaptador tiver um, especialmente em trechos mais longos.
- Conecte o adaptador ao Raspberry Pi e confirme que o dispositivo aparece:
ls -l /dev/ttyUSB*
sudo usermod -aG dialout $USER # depois, saia e entre novamente na sessão
python3 -m venv ~/meter-env
source ~/meter-env/bin/activate
pip install "pymodbus>=3.10" paho-mqtt pyserial
O script do gateway de submedição de energia IoT
O script consulta cada medidor em sequência, decodifica os floats e publica uma mensagem JSON por medidor em um topic que identifica a máquina que ele alimenta. Para a demonstração, ele usa o servidor MQTT público gratuito; a variante de produção aparece logo depois.
#!/usr/bin/env python3
"""Electrical sub-metering gateway: Modbus RTU meters -> MQTT."""
import json
import struct
import time
import paho.mqtt.client as mqtt
from pymodbus.client import ModbusSerialClient
BROKER = "broker.connectmq.com"
PREFIX = "connectmq/demo/subm-4q9z/plant1"
POLL_SECONDS = 10
# Endereço Modbus -> caminho de topic da máquina que ele mede
METERS = {
1: "molding/imm-01",
2: "molding/imm-02",
3: "utilities/comp-1",
}
REGISTERS = { # nome: endereço do registrador de entrada (float32, 2 palavras)
"v_l1": 0,
"i_l1": 6,
"kw": 52,
"pf": 62,
"hz": 70,
"kwh_total": 72,
}
def read_float(modbus, address, unit):
rr = modbus.read_input_registers(address, count=2, device_id=unit)
if rr.isError():
raise IOError(f"Modbus error unit {unit} reg {address}: {rr}")
return struct.unpack(">f", struct.pack(">HH", *rr.registers))[0]
def read_meter(modbus, unit):
values = {name: read_float(modbus, reg, unit) for name, reg in REGISTERS.items()}
values["kw"] = values["kw"] / 1000.0 # o medidor informa watts
return {k: round(v, 3) for k, v in values.items()}
def on_connect(client, userdata, flags, reason_code, properties):
print("MQTT connected:", reason_code)
client.publish(f"{PREFIX}/gateway/status", "online", qos=1, retain=True)
def main():
modbus = ModbusSerialClient(
port="/dev/ttyUSB0", baudrate=9600, bytesize=8, parity="N", stopbits=1, timeout=1
)
if not modbus.connect():
raise SystemExit("Cannot open serial port")
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="subm-gw-4q9z")
mqttc.will_set(f"{PREFIX}/gateway/status", "offline", qos=1, retain=True)
mqttc.on_connect = on_connect
mqttc.connect(BROKER, 1883, keepalive=60)
mqttc.loop_start()
while True:
cycle_start = time.time()
for unit, path in METERS.items():
topic = f"{PREFIX}/{path}/energy"
try:
payload = {"ts": int(time.time()), "meter": unit, **read_meter(modbus, unit)}
mqttc.publish(topic, json.dumps(payload), qos=1)
print(topic, payload)
except IOError as err:
mqttc.publish(f"{topic}/error", str(err), qos=1)
print(err)
time.sleep(0.05) # pequeno intervalo entre medidores no barramento
time.sleep(max(0, POLL_SECONDS - (time.time() - cycle_start)))
if __name__ == "__main__":
main()
Acompanhe a saída a partir de qualquer máquina com o cliente Mosquitto:
mosquitto_sub -h broker.connectmq.com -p 1883 -i subm-viewer-$RANDOM \
-t "connectmq/demo/subm-4q9z/plant1/#" -v
O servidor MQTT público é ideal para este primeiro teste, mas qualquer pessoa pode ler o que passa por ele; por isso, mude para um broker privado antes de conectar equipamentos reais de produção.
Indo para produção
Passe o gateway para TLS autenticado substituindo as linhas de conexão:
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="YOUR_CLIENT_ID")
mqttc.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
mqttc.tls_set()
mqttc.will_set(f"{PREFIX}/gateway/status", "offline", qos=1, retain=True)
mqttc.connect("broker.connectmq.com", 8883, keepalive=60)
Troque PREFIX pelo seu próprio namespace, por exemplo connectmq/plant1, seguindo a hierarquia ISA-95. A ConnectMQ reconhece esse tipo de estrutura e lista os dispositivos por site, área e linha no portal, o que torna fácil navegar por algumas dezenas de medidores. Execute o script como serviço systemd para que ele reinicie em caso de falha e na inicialização.
Atribuindo energia às máquinas
Com um topic por máquina, a atribuição é direta:
- Energia por período: subtraia o contador
kwh_totalno início do turno ou do dia do valor no final. - Energia ociosa: combine a potência com o estado da máquina. A energia consumida enquanto a máquina está ociosa ou parada, usando os estados do monitoramento de status de máquinas, é o número mais acionável para muitas plantas.
- Remanescente não medido: medidor geral menos a soma dos submedidores. Um remanescente grande ou crescente indica cargas não medidas ou um erro de configuração de medidor.
- Energia por peça: divida o kWh da máquina pelas peças boas do mesmo período.
Armazene o fluxo em um banco de séries temporais com o Telegraf ou com um pequeno assinante e calcule esses números lá; o broker transporta dados ao vivo e últimos valores retidos, não histórico.
Planejando a implantação da submedição
Meça primeiro os maiores consumidores. Uma rápida volta com um alicate amperímetro, ou uma olhada nas placas de motores e resistências, geralmente mostra que um punhado de máquinas e utilidades responde por grande parte da carga. Coloque esses no primeiro barramento, comprove o caminho dos dados de ponta a ponta e só então estenda para cargas menores.
Mantenha um cadastro de medidores desde o início: endereço Modbus, localização física, alimentador, relação do TC, data de instalação e o topic em que ele publica. É essa lista que permite que outra pessoa mantenha o sistema, e é exatamente o tipo de informação documentada que uma auditoria energética solicita. Quando um medidor for substituído, registre o contador final do antigo e o contador inicial do novo, para que os cálculos por período continuem corretos.
Por fim, defina os intervalos de leitura por finalidade. Dez segundos bastam para dashboards ao vivo e detecção de energia ociosa; relatórios no estilo de faturamento precisam apenas dos contadores, então um intervalo mais lento em um barramento longo é aceitável.
Solução de problemas em submedidores
| Sintoma | Causa provável | Correção |
|---|---|---|
| Timeouts em todos os medidores | A e B invertidos, taxa de transmissão ou paridade erradas | Inverta A/B e iguale as configurações seriais em todos os dispositivos |
| Um medidor dá timeout | Endereço Modbus duplicado ou errado | Confira o endereço no display do medidor |
| Valores como 1.4e-38 ou números enormes | Ordem de palavras ou deslocamento de registrador errado | Verifique o mapa de registradores; tente inverter os dois registradores |
| Potência negativa | TC montado ao contrário ou fases trocadas | Inverta o TC ou corrija a atribuição de fases |
| Potência alta demais por um fator constante | Relação de TC errada configurada no medidor | Configure a relação primário/secundário correta |
| Erros intermitentes em barramentos longos | Falta de terminação ou de terra de referência | Termine as duas pontas e conecte o terra de referência |
Além do kWh
Muitos multimedidores também expõem distorção harmônica total, valores por fase e registradores de demanda. Esses dados alimentam diretamente o monitoramento da qualidade de energia, que ajuda a explicar desarmes indevidos e transformadores superaquecidos. Para uma visão genérica de como fazer a ponte de qualquer dispositivo Modbus RTU, veja Modbus RTU para MQTT. O guia de manufatura inteligente situa a submedição no roteiro mais amplo da produção conectada, que inclui do monitoramento de energia ao gêmeo digital da planta.
Conecte seus medidores à ConnectMQ
A ConnectMQ é um broker MQTT gerenciado com TLS, MQTT 5, explorador de topics ao vivo, visão de dispositivos ISA-95 e alertas por limite em campos como kw ou pf. Crie um broker Serverless gratuito sem cartão de crédito, cole as credenciais geradas e seus submedidores estarão online.
Perguntas frequentes
Quantos medidores de energia podem compartilhar um barramento RS-485?
Um segmento RS-485 padrão suporta até 32 cargas unitárias, e muitos transceptores modernos representam cargas fracionárias, permitindo mais dispositivos. Na prática, o tempo de leitura define o limite: mais medidores por barramento significa um ciclo mais longo para cada medidor.
Posso usar medidores Modbus TCP?
Sim. Substitua ModbusSerialClient por ModbusTcpClient e pelo endereço IP do medidor; a decodificação dos registradores e a publicação MQTT continuam as mesmas.
O gateway deve calcular o kWh a partir das leituras de potência?
Não. Publique o registrador de energia acumulada do próprio medidor. Ele é preciso entre as leituras e sobrevive a reinicializações do gateway e a mensagens perdidas.
Os dados de submedição de energia IoT ficam seguros pela internet?
Use TLS na porta 8883 com credenciais emitidas para cada gateway. Na ConnectMQ, os client IDs ficam vinculados às suas credenciais, e tentativas repetidas de login com falha levam ao bloqueio do IP.



