For a 12 V or 24 V solar system, an off-grid battery, or a DC distribution panel, watching the instantaneous voltage tells only part of the story. You may also want to know the current passing through a load, its electrical power, and how much energy it has consumed over several hours. The Peacefair PZEM-017 measures those quantities on a DC circuit and makes the results available over RS485. With an ESP32 running ESPHome, you can publish them to Home Assistant without using a cloud service.
The interesting part of this build is the interface: the PZEM-017 is not an I²C sensor and its RS485 wires must not be connected directly to ESP32 GPIOs. An appropriate RS485-to-UART transceiver or converter is needed between the meter and your ESP32. The meter also uses an external current shunt, unlike the INA260 with its integrated shunt. This guide concentrates on those two decisions, a working ESPHome configuration, and reliable Home Assistant energy statistics.
Safety: A low-voltage battery can deliver hundreds of amps into a wiring fault. Higher-voltage DC systems can sustain dangerous arcs and present a shock hazard. Fuse and isolate the circuit before installation; use terminals, wire, enclosures and a shunt rated for its worst-case fault and continuous current. Installation on high-energy battery strings, solar arrays, or distribution equipment should be designed and checked by a competent professional. The ESP32 monitoring device is not a protective disconnect, battery-management system, or revenue-grade meter.
What the PZEM-017 measures
The PZEM-017 is a DC voltage, current, power and energy monitor. It senses the voltage across its measurement terminals, and current through a separate calibrated resistive shunt placed in the monitored current path. The meter calculates power from its measurements and accumulates energy internally. Unlike a bare analog shunt amplifier, it exposes finished digital readings to the microcontroller through a serial protocol.
| Quantity | Meaning | How to use it |
|---|---|---|
| Voltage (V) | Voltage at the meter’s sense terminals | Check supply sag under load or battery voltage trends. |
| Current (A) | Current passing through the external shunt | Observe a load or one battery-current direction as wired. |
| Power (W) | Electrical power at the measurement point | Watch live DC demand and size wiring appropriately. |
| Energy (kWh) | Meter’s accumulated energy reading | Create daily/monthly consumption totals in Home Assistant. |
Think carefully about the measurement point. If the shunt is in a solar panel’s output path, the readings describe that panel output. If it is installed in the line feeding a DC load, the readings describe that load. Neither arrangement automatically tells you the total state of charge of a battery, the energy of every device in the system, or power entering and leaving a whole hybrid inverter.
PZEM-017 modules and bundles are sold with different shunt ranges. Seller photos and labels are not enough to establish a safe operating limit: inspect the actual supplied module, its matching shunt, marked ratings and instructions before designing the circuit. High current and high voltage are separate design constraints, and the rating of one component does not certify the whole installation.
PZEM-017 vs INA226, INA228 and INA260
The INA family discussed elsewhere on esp32.co.uk/ is useful on compact, lower-voltage DC electronics. The PZEM-017 serves a different wiring and communications use case: an external high-current shunt and a differential RS485 link that can be routed away from the measurement hardware when installed correctly. RS485 helps with communications over cable; it does not make an unsafe high-energy circuit safe or automatically provide galvanic isolation.
| Device | Current sensing | Host interface | Main design difference |
|---|---|---|---|
| INA226 | External shunt | I²C | Flexible shunt, short local logic-level bus. |
| INA228 | External shunt | I²C | Higher-resolution monitoring with hardware charge/energy accumulation. |
| INA260 | Integrated shunt | I²C | Simpler current path, but fixed on-chip shunt and its own limits. |
| PZEM-017 | External shunt | RS485/serial | Separate DC meter and differential serial communications. |
Do not substitute a PZEM-004T wiring tutorial here. That model measures AC and uses the ESPHome pzemac platform. The PZEM-017 is a DC model; ESPHome lists it under the pzemdc platform. Our earlier ESP32 PZEM-004T energy-monitoring guide covers the AC application rather than this RS485 shunt installation.
Parts and compatibility checklist
- A genuine or traceable PZEM-017 DC meter with the exact operating and communications specification for that revision.
- A correctly rated external shunt matched to the meter’s configured or supplied range, with manufacturer-specified sense connections.
- An ESP32 development board and its own suitable, protected power supply.
- A 3.3 V-compatible RS485-to-TTL/UART converter. An auto-direction converter is easier for this application; verify its IO voltage and isolation claims from its documentation.
- Appropriately rated measurement cables, fusing, insulation, enclosure, strain relief and terminal hardware.
- ESPHome installed via the Home Assistant add-on, ESPHome Device Builder, or command-line tools; a Home Assistant instance for the resulting entities.
A MAX485-labelled module is often powered at 5 V and may output 5 V logic; connecting such a board’s receiver output straight to an ESP32 RX pin is not safe merely because its RS485 side is differential. Prefer a verified 3.3 V logic converter, or use a correctly engineered level-translation solution. Where monitoring must be electrically isolated from the measured system, buy a converter with documented galvanic isolation, isolated power and adequate isolation rating; a generic transceiver is not equivalent.
Understand the two sides of the RS485 interface
RS485 uses a differential pair rather than single-ended logic-level TX and RX. The PZEM-017’s communication connector presents an RS485 pair, commonly marked A and B. On the ESP32 side, a converter presents logic-level TX and RX, and sometimes DE/RE direction-control pins. The interface is conceptually:
ESP32 GPIO17 (TX) ---> converter DI / UART RX input
ESP32 GPIO16 (RX) <--- converter RO / UART TX output
ESP32 logic GND <--> converter logic-side GND (unless isolated interface specifies otherwise)
RS485 converter A <==================> PZEM-017 RS485 A
RS485 converter B <==================> PZEM-017 RS485 B
DC measurement circuit ---> PZEM-017 voltage terminals and external shunt
ESP32 power supply ------> ESP32 power input (separate, correctly regulated)
Converter vendors do not always name the TTL pins from the same perspective. A pin labelled “TX” on a USB-style serial adapter may be an output, while “TX” on a transceiver board can be an input intended for the microcontroller. Follow the signal direction, not just matching text labels: ESP32 TX drives the converter’s transmit data input, and converter receive data output feeds ESP32 RX. Similarly, A/B labels have not been used consistently by all RS485 vendors; if the meter does not respond, verify the actual marked polarity and manufacturer pinout before considering a swap.
An ordinary auto-direction converter handles the transmit/receive turnaround itself. A manual-direction converter needs the correct direction control at the right time; the simple YAML below assumes an auto-direction 3.3 V UART-to-RS485 adapter. If you use a manually controlled half-duplex adapter, configure a supported ESPHome UART flow-control arrangement and check the converter’s DE/RE logic instead of assuming the same example will work unchanged.
If you use an isolated converter, its field-side and ESP32-side power and ground connections must follow its own installation instructions. Do not bridge an isolation barrier with an improvised ground wire. Check whether a line-reference conductor, end-of-line termination or bias network is specified for your cable length and topology. On a short point-to-point link, do not add arbitrary termination resistors to every board without inspecting what is already fitted.
Wire the measurement circuit and external shunt
The shunt is a precision resistor that develops a small voltage proportional to the load current. For example, a 100 A / 75 mV shunt develops 75 mV at 100 A; its nominal resistance is 0.00075 Ω, and its resistive heating is 7.5 W at that current. Those numbers are an illustrative calculation, not a claim that every PZEM-017 is designed for that shunt. Use the shunt value specified for your particular meter and selected current range.
The heavy load cable and the smaller sensing wires have different jobs. The high-current path goes through the shunt’s current terminals, while the sense leads connect to the points specified by its wiring drawing, ideally its separate Kelvin sense points if provided. Do not route load current through a thin sense lead. A loose bolted connection can introduce error and create substantial heat even at a moderate current.
PZEM-017 units can have different labelled measurement, communication and auxiliary-power connectors. Do not use a generic pin diagram to connect an unverified revision. Read the label on your module and its supplied wiring sheet. Verify shunt placement, sense-wire polarity, module power requirements, connector pin order, and whether measurement-side power and communications-side power are separate. Some variants require an independent supply when measured DC voltage is below their operating threshold; a reading of 0 V cannot be interpreted until the meter itself is confirmed to be powered. Never assume the RS485 converter powers the measurement circuit.
For batteries and solar systems, place overcurrent protection as close as practicable to the source according to the equipment design. Never connect or disconnect shunt and sense wiring while the circuit is live. After a qualified installation, compare the displayed current with a suitable DC clamp meter and voltage with a suitably rated meter under a known, stable load.
Complete ESPHome configuration for an ESP32
ESPHome’s built-in pzemdc integration supports the PZEM-017. The current documentation shows a UART speed of 9600 baud with two stop bits. Unlike the AC PZEM-004T V3 example, this configuration does not add a separate modbus: component: pzemdc handles the device protocol on the configured UART. Set GPIOs to the actual UART-capable pins on your ESP32 board and reserve any native USB, boot-strapping or other device pins as appropriate.
substitutions:
device_name: pzem017-dc-monitor
friendly_name: PZEM017 DC Monitor
esphome:
name: ${device_name}
friendly_name: ${friendly_name}
esp32:
board: esp32dev
framework:
type: esp-idf
logger:
level: INFO
api:
encryption:
key: !secret esphome_api_key
ota:
- platform: esphome
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "PZEM017 Recovery"
password: !secret fallback_ap_password
captive_portal:
uart:
id: pzem_uart
tx_pin: GPIO17
rx_pin: GPIO16
baud_rate: 9600
stop_bits: 2
sensor:
- platform: pzemdc
id: dc_meter
uart_id: pzem_uart
address: 1
voltage:
name: "DC Bus Voltage"
id: dc_bus_voltage
current:
name: "DC Load Current"
id: dc_load_current
power:
name: "DC Load Power"
id: dc_load_power
energy:
name: "DC Load Energy"
id: dc_load_energy
update_interval: 30s
Replace the sample secret names with keys in your ESPHome secrets.yaml. Generate and retain your api.encryption.key securely, rather than copying an example key from a published tutorial. The esp32dev board selection and GPIO16/GPIO17 are for a conventional ESP32 DevKit; a C3, S3 or other board needs its own pin choices. Your converter must be suitable for the chosen IO voltage, and the power-side wiring remains separate from the YAML.
The device address defaults to 1 in ESPHome. Keep that value for a single factory-configured meter unless your module’s actual address differs. With multiple meters on the same RS485 line, each meter must have a unique address before connecting them together. You cannot make two default-address units coexist merely by declaring two different names in YAML.
The meter’s accumulated energy reading is reported in kWh according to the pzemdc documentation. Do not blindly multiply it by 0.001: doing so would turn 1 kWh into 0.001 kWh and under-report use by a factor of one thousand. In Home Assistant, check the entity’s actual reported unit and statistics properties before using it in the Energy dashboard.
First power-up: test communications before trusting the numbers
Compile and flash the ESP32 using USB while the DC measurement circuit remains isolated. Validate Wi-Fi, the native API connection and ESPHome logging first. Confirm the RS485 adapter’s TTL power rails and IO voltage before connecting it to the GPIO pins. Only then commission the complete meter, following the verified measurement-side wiring procedure for your installation.
- Confirm the ESPHome node is online in Home Assistant and the four sensor entities exist. An entity that exists but says “unavailable” is not yet a working meter.
- Watch the ESPHome logs. Repeated UART request timeouts usually indicate meter power, wrong A/B polarity, wrong adapter direction, serial framing, address collision or an incorrect host-side pin.
- Check DC voltage first against an independent measurement. A plausible voltage but zero current can be perfectly normal if there is no load; introduce a known safe load before diagnosing the current channel.
- Compare power against voltage times current at a stable operating point. A large persistent mismatch, polarity anomaly or unexplained fluctuation warrants checking the meter setup and shunt wiring.
- Leave the circuit running long enough to observe an increase in accumulated energy. If you have 100 W of constant load for one hour, the expected energy change is approximately 0.1 kWh.
A displayed 0.00 A is not proof that a system is de-energised. Some meters round small loads to zero, communication might have stopped, and a failed shunt connection may give a misleading value. Use an approved verification procedure and an appropriate test instrument before touching conductors.
Home Assistant: live power versus cumulative energy
The power sensor is useful for live dashboards and load alerts: watts describe how quickly energy is being consumed at the present moment. The energy sensor is a cumulative total, expressed in kWh, and is the correct source for daily/monthly accounting once its units and statistics are confirmed. You do not need to integrate power a second time if a functioning cumulative energy sensor is already available.
In Home Assistant, open Developer Tools → States and inspect the DC Load Energy entity. For standard long-term energy statistics, Home Assistant expects the energy device class with an appropriate total or total_increasing state class and a supported energy unit. If the entity does not appear in an Energy dashboard picker, first inspect its attributes and the Developer Tools → Statistics page. Do not manufacture an energy entity by simply renaming a power entity from W to kWh.
A daily and monthly consumption graph can be made with Home Assistant’s Utility Meter helpers. Create a helper whose source is the cumulative PZEM energy entity and set its cycle to daily; repeat with a monthly cycle. The helpers track changes in the source reading and reset their own period counters. They do not reset the underlying PZEM hardware counter or change the reading returned by the meter.
For a stable DC load, configure a dashboard gauge showing power in watts, a history graph showing bus voltage and load current, and Utility Meter cards displaying energy for today and this month. Label the meter’s physical measurement point clearly: “battery inverter feed”, “DC pump circuit” or “solar controller output” is more useful than an ambiguous “total energy” when multiple sources exist.
Can the PZEM-017 measure battery charging and discharging?
A shunt is a perfectly reasonable way to measure battery current, but you must verify what this particular meter does with current polarity before treating it as a bidirectional battery monitor. A PZEM-017 installed with its prescribed polarity is primarily an energy-consumption meter. Its cumulative energy is not automatically split into energy charged and energy discharged, and it should not be assumed to calculate net battery amp-hours or state of charge.
If your objective is to account separately for import and export, select and test an instrument explicitly specified to report signed current and distinct charge/discharge accumulators, or install separate appropriate measurements on the relevant power paths. For state-of-charge estimation, combine a proper coulomb-counting strategy with capacity and full-charge calibration, or use a dedicated battery monitor/BMS with correctly exposed telemetry. The other DC monitoring guides on esp32.co.uk/ include devices designed around different shunt and battery-measurement requirements.
RS485 cable length, grounding and noise
RS485 is often chosen because a differential pair can tolerate common-mode noise better than a direct TTL UART connection, and its bus topology can support multiple addressed instruments. That does not justify running communication wires casually alongside high-current switching conductors. Keep the RS485 pair together, preferably as twisted-pair cable; follow the transceiver manufacturer’s instructions for shielding, grounding and cable routing. Very long cable runs, installations with separate earthing systems, and high-energy equipment may require a suitably rated galvanically isolated interface.
For a simple point-to-point experiment, use a short cable first and prove that one meter responds consistently. If you extend the link or add devices, consider termination only at the proper bus ends, correct fail-safe biasing, unique addresses and the meter’s supported Modbus serial framing. An ESP32 pin labelled “3.3 V” is not a general-purpose protective earth or reference for distant power systems.
Troubleshooting a PZEM-017 that will not report data
| Symptom | Likely checks |
|---|---|
| ESP32 online; every meter entity unavailable | Meter measurement-side power; transceiver IO supply; RX/TX directions; A/B marking; serial framing; module address. |
| Reading appears only when separate power is attached | Meter or isolated RS485 side lacks its required power. Verify both sides independently; do not assume one 5 V connection powers everything. |
| Voltage works; current stays at zero | No load; shunt omitted; sense leads reversed/open; wrong supplied shunt or range; reading below resolution. |
| Current or power wildly incorrect | Incorrect shunt rating, damaged/loose high-current connection, sense leads across wrong points, or mismatched module setting. |
| Readings drop out when inverter starts | Poor supply regulation, inadequate isolation/common-mode margin, poor cable routing, missing bus termination or excessive EMI. |
| Multiple meters respond unpredictably | Duplicate device addresses, unsuitable multi-drop converter configuration, line reflections or address/config mismatch. |
| Energy dashboard shows nothing | Check kWh units, energy device class, supported state class and statistics health; live W alone is not accumulated energy. |
| Sudden energy jump after reset | Review hardware energy-counter reset, entity recreation and recorder history before altering statistics. |
Avoid troubleshooting high-current wiring with the system energised. First establish that the ESP32 and RS485 converter work on the low-voltage side. Then power down and verify the module’s voltage input, correct shunt, sense-wire routing and fuse arrangement against the manufacturer’s instructions. Reconnect the energy source only using your installation’s safe commissioning procedure.
What happens when the ESP32 or Home Assistant restarts?
A properly functioning meter accumulates its own energy reading independently of Home Assistant polling, subject to its power, reset and counter-storage behaviour. If Home Assistant temporarily goes offline, its historical plot has a gap; it should not create invented intermediate measurements. When communication resumes, the next energy total provides the new cumulative counter value. A hardware reset or replacement may cause a genuine counter discontinuity that must be handled carefully in statistics.
Because Home Assistant’s long-term statistics can interpret counter decreases as a reset, expose the PZEM energy counter unchanged and avoid arbitrary transformations that make it jump up and down. Record the meter’s energy value before intentionally resetting or replacing it, and check Home Assistant’s statistics afterwards. Do not add a web-facing “reset energy” control to a production monitoring dashboard just because ESPHome supports the pzemdc.reset_energy action; clearing the device counter can complicate historical accounting.
Common questions
Does the PZEM-017 need a separate RS485 converter?
Yes. Its field-side communication is RS485; the ESP32 UART is logic-level serial. Use a verified, compatible converter between them. A generic USB-to-RS485 dongle is intended for a USB host such as a PC and is not a substitute for a UART-to-RS485 transceiver wired directly to the ESP32.
Should I add a modbus: block to the YAML?
Not for the pzemdc configuration shown here. ESPHome’s documented PZEM-00X DC platform communicates via its UART configuration and internally handles the meter protocol. Copying the pzemac example from the AC device and adding modbus: is a common way to end up with the wrong device platform.
Can it run with the measured battery at zero volts?
Only if your exact module design has the appropriate independent power available to its measurement electronics and the specified operational conditions are satisfied. Some PZEM-017 variants require an auxiliary supply below a minimum measured voltage. Confirm this from the actual meter’s datasheet and power diagram; do not equate an ESP32 that is powered up with a PZEM measurement circuit that is alive.
Is the reading suitable for billing or protection?
No, not without an appropriate certified metering installation for the intended purpose. This is a hobbyist/engineering telemetry build. Overcurrent protection, battery protection, isolation and emergency shutdown must remain independent of the ESP32 and of a Home Assistant automation.
Can multiple PZEM-017 meters share one ESP32?
The software exposes an address for the meter, so a multi-drop RS485 arrangement can be considered when modules support assigning unique addresses and the bus electronics and power supplies are designed for it. Start with one meter and demonstrate reliable operation; then change and verify additional addresses one device at a time, with only one meter attached while programming its address.
Further reading and source documentation
- ESPHome: PZEM-00X DC energy monitor (PZEM-017 support, UART settings and sensor fields).
- ESPHome: UART bus, pins, framing and debugging.
- Home Assistant: Energy dashboard requirements and missing-entity troubleshooting.
- Home Assistant: Utility Meter helpers for daily and monthly periods.
- esp32.co.uk/: PZEM-004T AC energy monitor, a different model and protocol.
Bottom line: The PZEM-017 is a useful way to bring a specified DC current path into Home Assistant, especially where an external shunt and an RS485 cable are preferable to a small local I²C breakout. Choose the correct shunt and rated installation hardware, interface RS485 to the ESP32 correctly, use ESPHome’s pzemdc platform, and treat the device’s energy counter as a measured source—not as a battery-percentage estimate or a substitute for electrical protection.