How to use PZEM004T Energy Monitor with esphome

Nice setup, I am interested in the top 2 floors. Did you made them or can you buy them?

what type diodes you have bat45 or same?

I have used bat45

Hi,
I have Wemos D1 mini with PZEM-004T V3 connected as shown in the picture below. The problem I’m struggling with is “Unknown” sensor values.

Code:

esphome:
  name: power_consumption

esp8266:
  board: d1_mini

# Enable logging
logger:
 level: DEBUG
 baud_rate: 0

# Enable Home Assistant API
api:

ota:
  password: ######

wifi:
  ssid: ######
  password: ######

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: ######
    password: ######

captive_portal:

uart:
  rx_pin: GPIO3
  tx_pin: GPIO1
  baud_rate: 9600
  stop_bits: 1

modbus:

sensor:
  - platform: pzemac
    current:
      name: PZEM-004T V3 Current
    voltage:
      name: PZEM-004T V3 Voltage
    energy:
      name: PZEM-004T V3 Energy
    power:
      name: PZEM-004T V3 Power
    frequency:
      name: PZEM-004T V3 Frequency
    power_factor:
      name: PZEM-004T V3 Power Factor
    update_interval: 30s

I’ve also tried the following:

  • Switching to GPIO12/GPIO14 or GPIO4/GPIO5
  • Connecting 10k Ohm resistor between 3.3V - TX pin
  • Switching RX with TX pin
  • Connecting PZEM 5V with WEMOS 3.3V
  • Switching CT clamp on hot wire

The sensor was tested in ArduinoIDE giving measurments without any problem, but when connecting to HomeAssistnat I contantly get “unknown” values. I’m only trying to use Wemos with one PZEM so I don’t think I need to address the sensor.
Is level converter necessary to get this think work or there is something wrong with the code?
Any thoughts?
Thanks!

Just asking: Did you test this sensor (PZEM-004T V3) in the Arduino IDE with another device or with the same Wemos D1 mini?

I have a working connection with the combination Wemos D1 R2 / PZEM-004T V3 in ESPhome. In another combination I got a Wemos D1 mini V4 (with USB-C and Ic2 connection, save me to solder :grinning:), Both are recognized as:

esp8266:
  board: esp01_1m

The other difference with my PZEM-004T V3 / Wemos D1 R2 version is:

# Enable logging
logger:
  baud_rate: 0 # Due to TX/RX of Wemos D1 R2

uart:
  rx_pin: RX
  tx_pin: TX
  baud_rate: 9600

Not sure if this will fix your problem. Did not check if you made any typos. Is your log error-less?
I also would recommend to add the web-server:

# include a webserver because it is just very handy during your test phase :D
web_server:
  port: 80
  include_internal: true
  ota: false
  local: true
  log: false
  version: 2
  id: webserver

Good luck

good evening, I have a wemos d1 and a PZEM-004T V3 I parameterized it with esphome using vcc of 3.3v, tx, rx, gnd without any other component. the two devices are 2m apart. So far so good until 3 days ago I had to install a further 3 PZEM-004T V3 having modified the 3 addresses set thus 0x02 - 0x03 - 0x04 with the Arduino IDE with esp32. I reconnected everything to the wemos and set everything correctly and it tells me SENSOR UNKNOWN. info this distance is 8 meters without any components.

I have to add something

Ditch the arduino!!! use d1 with tasmota. 50/50 is long cable voltage 3.3V+1k resistor drop to pzem and dont work, or electrical interference on long rx,tx,5v cables.First wrap the rx/tx cable with tin foil,or run pzem with 5v and no 1k resistor

I have all in 3phase rat nest with shotky diodes on d1 rx side, 5v DC for D1 and pzem no 1k resistor and no Pzem adress. Works normal

1 Like

Pzem is power hungrey. I have problem with 3.3v and 1k resistor. Works on bench, when in use dont work. seperate 5v line from dc for d1 and pzem

2 Likes

after testing with 3 for 3phase 5v from DC for pzem and d1 and no resistor mode is a must.

Thanks to this thread. I am able to find lots of information and tips about PZEM004T. I managed to setup 3 phase energy monitoring using PZEM004T V3.0 successfully. I tried to change the address of a PZEM-004T using yaml available here. Peacefair PZEM-004T V3 Energy Monitor — ESPHome. Even after fixing all the yaml related validations and errors, I could not change the addresses at all.
By using the Windows software, it took really 5 minutes of efforts to modify the physical address of all the three modules. I am sharing the steps I have followed which may help anyone trying to set this up. I could not find detailed steps documented anywhere in my searches. Please note this is my first post here, so I might be missing few.

Connection: I have used FTDI to Serial Converter to change the addresses. When you are connecting the FTDI to your system, make a note of the com port it is connected to. The port details will be required at later step.
Also we have to connect Phase, Neutral, CT connections as shown in the left side of this diagram. Otherwise the parameter could not be modified in my case. YMMV.

The connections are as given below.

Software location: PZEM-004T V3 Module | Arduino & NodeMCU Code, Circuit, Pinout And Library
Scroll to the bottom of the page to find the windows software under the option “Windows Software for PZEM004T Module Testing”. This link is taking you to mediafire location to download. So follow the link and get the zip file downloaded.

Finding the executable: You will find so many folders similar to “PZEM-004Tsoftware New version” with different variants within the Zip. They will all look alike without version number or anything. I used the folder creation date as my choice. I was happy to see “the user manual of the software”, however it is written in some alien language so it is not very much useful. There will be 4 files namely “isAnalogLibrary.tlb”, “isAnalogLibrary.ocx”, “PZEM004T-Master.exe” and “run.bat”.

On your windows 10/11, Open command prompt with Admin privileges. Traverse to the location where you have extracted above mentioned files. Type run.bat and enter which will register the .tlb and .olx files in your system. Then run the application executable from command itself by typing PZEM004T-Master.exe. This will open the application as shown below.

Click on “Set COM Port” → Select the com port of FTDI/your device is connected to. Mine was connected at COM 7, so its shown here.

Click on Set Parameters option. This will show the options as given below.

PZEM004Tv3_Address_Change

You have to change the Address to desired one (at the highlighted section). After setting the value click Ok. This will take you to main window, click Cancel to exit from the Application. Proceed to your other PZEM modules as described above, use different address for each one. That’s all.

After changing all the 3 modules with different addresses, we are all set to go to esphome, call respective addresses in the yaml.

Additional Information:
You can also measure the readings using “Start Measure”, exit by selecting “Exit Measure” options to confirm the module is working fine before we connect to Home Assistant.

1 Like

My configuration with PZEM-004T-100A(V3.0) and a ESP32 was this one, and I need to add “address: 0xF8”

uart:
  rx_pin: GPIO16
  tx_pin: GPIO17
  baud_rate: 9600
  stop_bits: 1

modbus:

sensor:
  - platform: pzemac
    address: 0xF8
    current:
      name: "Current"
    voltage:
      name: "Voltage"
    energy:
      name: "Energy"
    power:
      name: "Power"
    frequency:
      name: "Frequency"
    power_factor:
      name: "Power Factor"
    update_interval: 15s

What are the dimensions of closed ct clamp ? Checked couple of Ali sellers, but none seem to provide that

The coil or the clamp? I would say both have at least 1cm of internal diameter - so plenty to measure typical wires down to 0 AWG (~8mm diameter) :muscle:

Just a little nugget of info for people trying to run more than two PZEM004t v3. I have never run more than 2 in the past and always powered them off 5v. After trying to put four together on the same uart, they all would stop reporting data, or just the last one 0x04 would continue to report data and all the others would quit. It was random, it seemed as to which it would do. I found several posts involving modding the pzem with resistors or diodes, but generally I try to avoid that. My 5v external PS was slightly adjustable, and I dropped it to 4.5v, suddenly the 3rd pzem started to report properly. Then I cut the 5v wire to the harness and supplied 3.3v from the mini board itself and all four came online reporting as 1s intervals with no issue. So the no mod answer for me it seems is, drop the voltage to 3.3v.

2 Likes

Good morning, can you help me in programming my pzem v3.0.
I did several tests and in the end I programmed them with the Windows program, that is, I have to change the address and then put them on esp32.

Only 1 device works for me while if I put more than 1 they don’t work, I don’t use any diodes or resistors, I haven’t made any changes to the pzem, I power the pzem with the 3.3v of the esp32.

I’m waiting for his help, here’s my code:

esphome:
  name: controll-home

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging toglere level e hardvare
logger:

# Enable Home Assistant API
api:
  encryption:
    key: !secret API_key

ota:
  password: !secret OTA_Password

wifi:   
  networks:  
    - ssid: !secret wifi_ssid_1
      password: !secret wifi_password_1
      priority: 2.0
    - ssid: !secret wifi_ssid_2
      password: !secret wifi_password_2  
      priority: 1.0
    - ssid: !secret wifi_ssid_3
      password: !secret wifi_password_3
      priority: 0.0

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "CONTROL HOME"
    password: !secret wifi_ap

web_server:
  port: 80

captive_portal:

# ___________________________________________________ DS18B20________________________________________________
#ESP32 (GPIO5)
dallas:
  pin: GPIO5
  update_interval: 5s



#_____________________________________________________PZEM-004T___________________________________________________
# ESP32 (TX-GPIO18 + RX-GPIO19)
uart:
  - id: ubus1
    tx_pin: GPIO18
    rx_pin: GPIO19
    baud_rate: 9600
    stop_bits: 1




sensor:
  - platform: pzemac
    id: pzemac
    address: 1
    current:
      name: "CORRENT"
      accuracy_decimals: 2
#    voltage:
#      name: "VOLTAGE"
#      accuracy_decimals: 2
    power:
      name: "POWER"
      unit_of_measurement: W
      accuracy_decimals: 2
      id: potenza_zia
#    frequency:
#      name: "FREQ"
#      unit_of_measurement: Hz
#      accuracy_decimals: 2
#    power_factor:
#      name: "POWER FACTOR"
#      accuracy_decimals: 2
    energy:
      name: "ENERGY"
      unit_of_measurement: Wh
      accuracy_decimals: 1
      id: energy
    update_interval: 5s #7s

  - platform: template
    name: "DAILY ENERGY"
    unit_of_measurement: "kWh"
    accuracy_decimals: 2
    update_interval: 15s #11s
    icon: mdi:counter
    lambda: return (( (id(energy).state)/1000.0));

  - platform: dallas
    name: "TEMP HOME"
    address: "0xcf041780cf3cff28"
    id: temp_home

button:
  - platform: template
    name: "RESET kWh"
    icon: "mdi:radiobox-marked"
    on_press:
      then:
        - delay: 1s
        - pzemac.reset_energy: pzemac

Here is my code for the pzems

sensor:
  - platform: pzemac
    id: pzemac_1
    modbus_id: mod_bus_pzem1
    address: 0x01
    current:
      name: 'Pumphouse Mains Current'
      accuracy_decimals: 3
      filters:
    voltage:
      name: 'Pumphouse Mains Voltage'
      accuracy_decimals: 1
    power:
      name: 'Pumphouse Mains Power'
      accuracy_decimals: 1
      unit_of_measurement: 'W'
      filters:
    energy:
      name: 'Pumphouse Mains Energy'
      filters:
        - multiply: 0.001 #converts to kwh
      unit_of_measurement: 'kWh'
      accuracy_decimals: 3
    frequency:
      name: 'Pumphouse Mains Frequency'
      accuracy_decimals: 1
    power_factor:
      name: 'Pumphouse Mains Power Factor'
      accuracy_decimals: 2
    update_interval: never
  
  - platform: pzemac
    id: pzemac_2
    modbus_id: mod_bus_pzem1
    address: 0x02
    
    current:
      name: 'Jet Pump Current'
      accuracy_decimals: 3
      filters:
#        - multiply: .5  
    voltage:
      name: 'Jet Pump Voltage'
      accuracy_decimals: 1
    power:
      name: 'Jet Pump Power'
      accuracy_decimals: 1
      unit_of_measurement: 'W'
      filters:
#        - multiply: .5  # Doubles the current reading
    energy:
      name: 'Jet Pump Energy'
      # convert to kWh
      filters:
#        - multiply: .5  # Doubles the current reading
        - multiply: 0.001
      unit_of_measurement: 'kWh'
      accuracy_decimals: 3
    frequency:
      name: 'Jet Pump Frequency'
      accuracy_decimals: 1
    power_factor:
      name: 'Jet Pump Power Factor'
      accuracy_decimals: 2
    update_interval: never

  - platform: pzemac
    id: pzemac_3
    modbus_id: mod_bus_pzem1
    address: 0x03
    
    current:
      name: 'Well Head Current'
      accuracy_decimals: 3
      filters:
#        - multiply: .5  
    voltage:
      name: 'Well Head Voltage'
      accuracy_decimals: 1
    power:
      name: 'Well Head Power'
      accuracy_decimals: 1
      unit_of_measurement: 'W'
      filters:
#        - multiply: .5  # Doubles the current reading
    energy:
      name: 'Well Head Energy'
      # convert to kWh
      filters:
#        - multiply: .5  # Doubles the current reading
        - multiply: 0.001
      unit_of_measurement: 'kWh'
      accuracy_decimals: 3
    frequency:
      name: 'Well Head Frequency'
      accuracy_decimals: 1
    power_factor:
      name: 'Well Head Power Factor'
      accuracy_decimals: 2
    update_interval: never

  - platform: pzemac
    id: pzemac_4
    modbus_id: mod_bus_pzem1
    address: 0x04
    current:
      name: 'Reverse Osmosis Current'
      accuracy_decimals: 3
      filters:
#        - multiply: .5  
    voltage:
      name: 'Reverse Osmosis Voltage'
      accuracy_decimals: 1
    power:
      name: 'Reverse Osmosis Power'
      accuracy_decimals: 1
      unit_of_measurement: 'W'
      filters:
#        - multiply: .5  # Doubles the current reading
    energy:
      name: 'Reverse Osmosis Energy'
      # convert to kWh
      filters:
#        - multiply: .5  # Doubles the current reading
        - multiply: 0.001
      unit_of_measurement: 'kWh'
      accuracy_decimals: 3
    frequency:
      name: 'Reverse Osmosis Frequency'
      accuracy_decimals: 1
    power_factor:
      name: 'Reverse Osmosis Power Factor'
      accuracy_decimals: 2
    update_interval: never

Good morning,

Excuse me but how did you connect them to the power supply and pins of resistors or diodes between esp32 and pzem? How did the pzem address change?

while the part that concerns uart?

I await your response

uart:
  - id: ubus1
    tx_pin: GPIO18
    rx_pin: GPIO19
    baud_rate: 9600
    stop_bits: 1

This is on an esp8266

uart:
  id: uart_1
  rx_pin: RX
  tx_pin: TX
  baud_rate: 9600
  data_bits: 8
  stop_bits: 1
  

modbus:
  - id: mod_bus_pzem1
    send_wait_time: 250ms
    uart_id: uart_1

RE: “For PZEM use 5V from D1 mini and Tx, Rx use 5V / 3.3V level converter”

and wiring Level Shifters/converters:

For Clarity:

  1. Connect the D1 Mini TX(@3v) pin directly to the PZEM Rx(@5v) pin. Lower voltage to higher is OK here.

Now the PZEM TX pin which is at 5v needs to be dropped to the lower voltage of 3.3v for the D1 mini’s RX pin which is at 3v. The “Logic Level Shifter” manages this.

  1. Connect the PZEM TX pin to the Logic Level Shifters High Side(5v) then connect the corresponding pin on the “shifters” LOW side(3v) to the D1 Mini’s RX, again at 3.3v.

Note: The “Shifters” High side needs to be connected to a 5v power source and GND and the Low side needs to be connect to a 3v power source and GND. Since the High and Low GND are connected, you “should” only need to connect to one of the two GND pads on the Shifter.

more simple way is tasmota way. I have D1 mini and ac/dc 5V direct to pzem no resistor mode,works 1 year no problems. Resistor mode 3.3V pzems dont like in my testing.
If you have 1 pzem no problem, If you have 3phase must have diodes BAT58 diode