Raspberry Pi

Monitor de Energia com Raspberry Pi e MQTT: Meça Tensão, Corrente e Consumo

Meça tensão, corrente, potência e energia acumulada com um Raspberry Pi e um INA219, publique as leituras como JSON via MQTT e saiba quando usar um HAT com alicate CT para circuitos de corrente alternada.

Raspberry Pi ligado a um sensor de corrente INA219 medindo um circuito de bateria solar, um monitor de energia com Raspberry Pi publicando dados na nuvem
Rode isso no seu próprio broker MQTTTenha um broker MQTT privado e gerenciado no plano Free e comece com exemplos de código prontos.
Teste grátis Exemplos de código Sem cartão de crédito

Um monitor de energia com Raspberry Pi mostra exatamente quanto um circuito consome, quanto uma bateria está carregando e quanta energia um equipamento gasta ao longo do dia. Neste tutorial você vai medir tensão, corrente e potência em corrente contínua com um INA219, integrar esses valores em watt-hora e publicar tudo como JSON via MQTT para que um dashboard ou uma automação possa usar. Você também vai ver como HATs com alicate CT levam a mesma ideia para circuitos de corrente alternada da rede elétrica.

Escolhendo o sensor: INA219 ou alicate CT

Breakout INA219 HAT com alicate CT
Mede Tensão CC (até 26 V), corrente, potência Corrente CA por um alicate; algumas placas também medem tensão CA
Conexão Em série com a carga, por um resistor shunt Não invasiva, o alicate abraça um condutor
Uso típico Painéis solares, baterias de 12 V, fitas de LED, robôs, o próprio Pi Circuitos residenciais, eletrodomésticos, máquinas
Interface I2C Normalmente um ADC SPI ou I2C no HAT
Segurança Apenas baixa tensão O alicate é isolado, mas a instalação perto da rede elétrica exige um profissional qualificado

Este tutorial monta a versão com INA219 de ponta a ponta porque ela é barata, precisa para CC de baixa tensão e segura para experimentar. Se você precisa medir CA, um HAT com alicate CT vem com sua própria biblioteca Python; leia os valores dele e reutilize a parte MQTT do script sem alterações. O equivalente com ESP32 para a rede elétrica está no guia do sensor de corrente SCT-013 com ESP32.

Como o INA219 funciona

O INA219 mede a pequena queda de tensão em um resistor shunt de 0,1 ohm em série com a carga e a tensão do barramento do lado da carga. A partir desses dois valores, ele calcula internamente a corrente e a potência. O breakout padrão suporta até 26 V no barramento e, com a calibração padrão, cerca de 3,2 A. Como o shunt fica em série, toda a corrente da carga passa pelo breakout, então respeite os limites dele e use fios grossos o suficiente para a corrente.

Ligação

Pino do INA219 Ligar em
VCC 3,3 V do Pi (pino físico 1)
GND GND do Pi (pino físico 6) e o terra da fonte da carga
SDA GPIO2 (pino físico 3)
SCL GPIO3 (pino físico 5)
VIN+ Terminal positivo da fonte de energia
VIN- Entrada positiva da carga

O terra do circuito medido precisa ser compartilhado com o terra do Pi; caso contrário, a leitura da tensão do barramento não faz sentido. Ative o I2C com sudo raspi-config nonint do_i2c 0 e confirme que o sensor aparece no endereço 0x40 com i2cdetect -y 1.

Instalando o software

sudo apt update
sudo apt install -y python3-venv i2c-tools
mkdir -p ~/power-monitor && cd ~/power-monitor
python3 -m venv .venv
source .venv/bin/activate
pip install "paho-mqtt>=2.0" adafruit-circuitpython-ina219

Topics e payload

Topic Conteúdo Retained
connectmq/demo/8d20f6/solar/power Tensão, corrente, potência a cada 5 s Não
connectmq/demo/8d20f6/solar/energy Wh acumulados, a cada minuto Sim
connectmq/demo/8d20f6/solar/status online / offline Sim

Uma mensagem de potência tem esta cara:

{"voltage": 12.84, "current_ma": 412.6, "power_w": 5.3, "ts": 1792161000}

O topic de energia é retained, então um dashboard aberto mais tarde vê na hora o total do dia.

O script do monitor de energia com Raspberry Pi

O script faz uma amostragem por segundo, tira a média ao longo do intervalo de publicação para suavizar o ruído e integra a potência no tempo em watt-hora. Ele salva o contador de energia em disco a cada dez minutos, para que um reinício não o zere, sem gravar no cartão SD a cada amostra. Salve como power_monitor.py:

#!/usr/bin/env python3
"""INA219 power monitor publishing to MQTT."""
import json
import os
import time
import uuid
from pathlib import Path

import board
import paho.mqtt.client as mqtt
from adafruit_ina219 import INA219

BROKER = os.getenv("MQTT_HOST", "broker.connectmq.com")
PORT = int(os.getenv("MQTT_PORT", "1883"))
USERNAME = os.getenv("MQTT_USERNAME")
PASSWORD = os.getenv("MQTT_PASSWORD")
CLIENT_ID = os.getenv("MQTT_CLIENT_ID", f"power-{uuid.uuid4().hex[:8]}")
PREFIX = os.getenv("MQTT_PREFIX", "connectmq/demo/8d20f6/solar")
PUBLISH_EVERY = 5      # segundos
ENERGY_EVERY = 60      # segundos
SAVE_EVERY = 600       # segundos
STATE_FILE = Path(os.getenv("STATE_FILE", "energy_wh.txt"))

ina = INA219(board.I2C())  # calibração padrão: faixa de 32 V, 2 A


def load_energy():
    try:
        return float(STATE_FILE.read_text())
    except (OSError, ValueError):
        return 0.0


def save_energy(wh):
    tmp = STATE_FILE.with_suffix(".tmp")
    tmp.write_text(f"{wh:.4f}")
    tmp.replace(STATE_FILE)  # renomeação atômica evita arquivos gravados pela metade


def on_connect(client, userdata, flags, reason_code, properties):
    if reason_code.is_failure:
        print(f"Connection refused: {reason_code}")
        return
    print(f"Connected as {CLIENT_ID}")
    client.publish(f"{PREFIX}/status", "online", qos=1, retain=True)


client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=CLIENT_ID)
client.on_connect = on_connect
client.will_set(f"{PREFIX}/status", "offline", qos=1, retain=True)
client.reconnect_delay_set(min_delay=1, max_delay=60)
if USERNAME:
    client.username_pw_set(USERNAME, PASSWORD)
if PORT == 8883:
    client.tls_set()
client.connect(BROKER, PORT, keepalive=30)
client.loop_start()

energy_wh = load_energy()
samples = []
last_sample = time.monotonic()
last_publish = last_energy = last_save = last_sample

try:
    while True:
        time.sleep(1)
        now = time.monotonic()
        voltage = ina.bus_voltage + ina.shunt_voltage  # tensão do lado da fonte
        current_ma = ina.current
        power_w = ina.power
        if ina.overflow:
            print("Warning: INA219 overflow, current exceeds calibrated range")

        energy_wh += power_w * (now - last_sample) / 3600.0
        last_sample = now
        samples.append((voltage, current_ma, power_w))

        if now - last_publish >= PUBLISH_EVERY:
            n = len(samples)
            payload = {
                "voltage": round(sum(s[0] for s in samples) / n, 2),
                "current_ma": round(sum(s[1] for s in samples) / n, 1),
                "power_w": round(sum(s[2] for s in samples) / n, 2),
                "ts": int(time.time()),
            }
            client.publish(f"{PREFIX}/power", json.dumps(payload), qos=0)
            samples.clear()
            last_publish = now

        if now - last_energy >= ENERGY_EVERY:
            energy = {"energy_wh": round(energy_wh, 3), "ts": int(time.time())}
            client.publish(f"{PREFIX}/energy", json.dumps(energy), qos=1, retain=True)
            last_energy = now

        if now - last_save >= SAVE_EVERY:
            save_energy(energy_wh)
            last_save = now
except KeyboardInterrupt:
    pass
finally:
    save_energy(energy_wh)
    client.publish(f"{PREFIX}/status", "offline", qos=1, retain=True).wait_for_publish(2)
    client.loop_stop()
    client.disconnect()

Rode com python power_monitor.py e assine a partir de outra máquina:

mosquitto_sub -h broker.connectmq.com -p 1883 -i watch-8d20f6 \
  -t 'connectmq/demo/8d20f6/solar/#' -v

Ligue e desligue a carga e veja current_ma e power_w responderem em até cinco segundos.

Calibração e precisão

A calibração padrão cobre 32 V e 2 A com resolução razoável. Se a sua carga for pequena, como um microcontrolador consumindo dezenas de miliampères, chame ina.set_calibration_16V_400mA() depois de criar o sensor para obter uma resolução mais fina. Se precisar de mais do que a faixa do breakout, troque o shunt por um de valor menor e escreva sua própria calibração, ou passe para um sensor projetado para correntes maiores.

Confira com um multímetro em série com a carga. Pequenos desvios são normais; um erro percentual constante geralmente indica a tolerância do shunt, que você pode corrigir com um fator de escala no software. Corrente negativa significa que VIN+ e VIN- estão invertidos, o que pode até ser útil: um monitor de bateria pode usar o sinal para mostrar carga versus descarga.

Casos de uso

O mesmo script serve para muitos projetos, mudando apenas o prefixo de topic e a calibração. Como os assinantes só veem JSON com campos de tensão, corrente, potência e energia, você pode trocar o sensor depois, ou adicionar um segundo INA219 no endereço 0x41 para outro circuito, sem mexer no dashboard ou na automação que consome os dados.

  1. Sistemas solares e de baterias: acompanhe a geração dos painéis e a tensão da bateria e publique um alerta quando a bateria cair abaixo de um nível seguro, por exemplo em um sistema fotovoltaico isolado em uma fazenda.
  2. Medir seus próprios projetos com Pi ou ESP32: coloque o INA219 entre a fonte e um dispositivo para ver o consumo real durante picos de Wi-Fi e durante o sleep.
  3. Robôs e veículos: monitore a corrente do motor para detectar travamentos.
  4. Iluminação e bombas de 12 V: confirme que uma carga realmente ligou, e não apenas que um relé estalou.

Para monitorar uma casa inteira com alicates CT e gráficos de longo prazo, nosso artigo sobre monitor de energia residencial com MQTT mostra o lado do assinante, e o guia Raspberry Pi com Grafana e InfluxDB armazena as leituras por meses. Esses mesmos dados de energia também podem alimentar um gêmeo digital da instalação. Com orçamento de energia apertado, o mesmo script roda bem em um nó MQTT com Raspberry Pi Zero 2 W.

Da bancada à instalação permanente

No servidor MQTT público em broker.connectmq.com qualquer pessoa pode ler os seus topics, o que é aceitável para um teste de bancada, mas revela padrões de uso em uma casa ou oficina de verdade. Migre para um broker privado com TLS antes de instalar o monitor de forma permanente. Com o ConnectMQ, um broker MQTT gerenciado, você recebe credenciais geradas por dispositivo; defina MQTT_PORT=8883 mais MQTT_USERNAME=YOUR_USERNAME, MQTT_PASSWORD=YOUR_PASSWORD e MQTT_CLIENT_ID=YOUR_CLIENT_ID em um arquivo de ambiente do systemd e reinicie. Depois adicione uma regra de alerta por limite no portal ConnectMQ, por exemplo tensão abaixo de 11,8 V no topic de potência, para ser avisado antes que uma bateria seja danificada.

Se você ainda está conhecendo o que faz um broker MQTT ou como rodar um script como serviço, comece pelo tutorial MQTT com Raspberry Pi e volte a este projeto.

Solução de problemas

  • ValueError: No I2C device at address: 0x40: confira SDA e SCL, ative o I2C e rode i2cdetect -y 1.
  • A tensão aparece perto de zero: VIN+ ou VIN- não está ligado ao circuito medido, ou os terras não estão compartilhados.
  • As leituras de corrente estão ruidosas: tire a média ao longo do intervalo de publicação, como o script faz, e mantenha curtos os fios do shunt.
  • O total de energia zera após o reboot: o arquivo de estado não tem permissão de escrita ou o script foi encerrado antes de salvar; verifique as permissões do diretório de trabalho.

Comece com o ConnectMQ

Envie seus dados de energia para um broker MQTT na nuvem que dashboards e alertas possam acessar de qualquer lugar. Crie seu broker ConnectMQ gratuito no plano Serverless, sem cartão de crédito, e conecte via TLS com MQTT 3.1.1 ou 5.0. O explorador de topics ao vivo mostra cada leitura assim que ela chega.

Perguntas frequentes

Um INA219 consegue medir a potência da rede elétrica CA?

Não. O INA219 é um sensor de CC para até 26 V. Use um HAT com alicate CT ou um medidor de energia certificado para circuitos CA, e deixe o trabalho na rede elétrica com um profissional qualificado.

Qual a precisão de um monitor de energia com Raspberry Pi e INA219?

Precisão suficiente para a maioria dos trabalhos de hobby e monitoramento, depois de conferida com um multímetro. A tolerância do shunt é a principal fonte de erro e pode ser corrigida com um fator de escala.

Por que publicar a energia como retained message?

Para que qualquer dashboard ou assinante que se conecte mais tarde receba na hora o total atual, em vez de esperar até um minuto pela próxima atualização.

Com que frequência devo publicar as leituras de potência?

A cada poucos segundos é suficiente para dashboards. Faça a amostragem mais rápido localmente, tire a média e publique a média para manter o tráfego baixo.

Artigos relacionados

Registro de Acessos Raspberry Pi RFID MQTT com o Leitor RC522

Ligue um leitor RFID RC522 a um Raspberry Pi, leia tags em Python, confira-as em uma lista de permissões local e publique cada tentativa de acesso como um evento MQTT que loggers, dashboards e ferramentas de alerta podem consumir.

8 min de leitura

Confiabilidade do Raspberry Pi: Rodando um Pi 24/7 como Gateway IoT

Um guia prático para manter um gateway MQTT com Raspberry Pi rodando por meses: desgaste do armazenamento, sistemas de arquivos somente leitura, alimentação, refrigeração, watchdogs de hardware e software e monitoramento remoto de saúde.

9 min de leitura

Pico W vs Pico 2 W para MQTT: Desempenho, Memória e TLS do RP2040 vs RP2350

O Pico 2 W mantém o formato e o chip Wi-Fi do Pico W, mas troca o RP2040 pelo RP2350, mais rápido. Esta comparação mostra o que isso significa para dispositivos MQTT: CPU, memória, TLS, recursos de segurança, suporte de software e qual placa comprar para cada projeto.

9 min de leitura

Todos os artigos →

Seu broker MQTT privado está a poucos cliques de distância

Crie uma conta, receba as credenciais do seu broker e conecte seu primeiro dispositivo — sem servidores para instalar, atualizar ou escalar.