How to use PZEM004T Energy Monitor with esphome

ESP Pins logic is indeed 3.3V but they are 5V tolerant.

I typically use all sensors/actors that support 5V directly with esp’s since years without any problems. I also use pzem004t’s without any level shifter and they work a treat.

Search for JST-XH 2.54

3 Likes

Would there be any issue with extending the wires on the split core ct clamp?

Hello there, do i need to do for each PZEM at start-up and then do the normal configuration?

I don’t think so.

Here is how I made my devices.

So far I made 10 of these. I’m using a generic bar soap case as an enclosure. Soap cases are less than 1 USD.

I’m using a cheap bidirectional 5V-3V digital converter module to power the ESP01 with 5V and also to allow bidirectional communication with 5V serial TTL with PZEM. Also I’m using a simple USB TTL converter for ESP01 for programming. I’ve added a switch to put it into programming mode and a button to reset.

Power supplies are 5V USB chargers. I bought 25 of them from Amazon at 1 USD each when they were on sale. They are about 5 USD each now which is still a bit cheaper than they can go for.

I’m using computer power cables with IEC connectors. I cut the IEC connector and add a female mains connector. I using cable ties to keep the power cables from moving.

The way I wired the PZEM module allows me to measure its own consumption as well as the 5V power supply in addition to the load.

Here is the ESPHome code.

substitutions:
  device_description: "Fridge"

esphome:
  name: powermeter-10
  comment: '${device_description}'

esp8266:
  board: esp01_1m

# Enable logging
logger:
  baud_rate: 0

# Enable Home Assistant API
api:

ota:
  password: "*****"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Powermeter-10 Fallback Hotspot"
    password: "*****"

captive_portal:

uart:
  tx_pin: GPIO1
  rx_pin: GPIO3
  baud_rate: 9600

modbus:

sensor:
  - platform: pzemac
    current:
      name: "PM-${device_description} Current"
    voltage:
      name: "PM-${device_description} Voltage"
    power:
      name: "PM-${device_description} Power"
    energy:
      name: "PM-${device_description} Energy"
    frequency:
      name: "PM-${device_description} Frequency"
    power_factor:
      name: "PM-${device_description} Power Factor"
    update_interval: 2s   

Here are the pictures:

4 Likes

Hi, I assembled the circuit as shown in the previous messages and once mounted in the electrical panel it ran smoothly for 2 days. This morning I realized that the data was no longer available and even restarting it did not solve the problem. I disassembled the meter and I did not notice any hardware problems, so I reconnected it but after some time the led of the nodemcu started flashing very quickly and then it went out. It hasn’t given any signs of life since and I can’t even flash the firmware again. What may have happened? My configuration is this:

esphome:
  name: "pmeter"

esp8266:
  board: nodemcuv2

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "*********"

ota:
  password: "*****"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Power-Meter Fallback Hotspot"
    password: "*****"

captive_portal:


uart:
  - id: ubus1
    tx_pin: GPIO1
    rx_pin: GPIO3
    baud_rate: 9600
    stop_bits: 1   
    

time:
  platform: sntp
  id: my_time
  
  on_time:
      - seconds: 57
        minutes: 59
        hours: 23
        then:  
          - sensor.template.publish:
              id: template_pMeter_veille
              state: !lambda return id(pMeter_power_of_day).state;
  
sensor:
   
     #### PZEM-004T V3 ####
    
  - platform: pzemac
    address: 1
    current:
      name: "Power Meter - Corrente"
      accuracy_decimals: 2
    voltage:
      name: "Power Meter - Tensione"
      accuracy_decimals: 2
    power:
      name: "Power Meter - Potenza Attiva"
      unit_of_measurement: W
      accuracy_decimals: 2
      id: pMeter_power
    frequency:
      name: "Power Meter - Frequenza"
      unit_of_measurement: Hz
      accuracy_decimals: 2
    power_factor:
      name: "Power Meter - Fattore di potenza"
      accuracy_decimals: 2
      id: pMeter_power_factor
    energy:
      name: "Power Meter - Energia"
      unit_of_measurement: Wh
      accuracy_decimals: 1
      id: pMeter_energy
    update_interval: 5s


  - platform: template
    name: "Power Meter - Potenza cumulativa"
    unit_of_measurement: "kWh"
    accuracy_decimals: 1
    update_interval: 5s
    icon: mdi:power
    lambda: return (( (id(pMeter_energy).state)/1000.0));
    
  - platform: total_daily_energy
    name: "Power Meter - Energia giornaliera"
    power_id: pMeter_power 
    unit_of_measurement: "kWh"
    accuracy_decimals: 2
    id: pMeter_power_of_day
    filters:
        # Multiplication factor from W to kW is 0.001
        - multiply: 0.001
    icon: mdi:counter
    
  - platform: template
    name: "pMeter_veille"
    id: template_pMeter_veille
    unit_of_measurement: "kwh"
    accuracy_decimals: 2
    icon: mdi:power
    update_interval: 10s
    
  - platform: template
    name: "Power Meter - Potenza Apparente"
    id: pMeter_power_apparente
    unit_of_measurement: "VA"
    accuracy_decimals: 2
    update_interval: 5s
    icon: mdi:power
    lambda: return ((id(pMeter_power).state/id(pMeter_power_factor).state));
  
  - platform: template
    name: "Power Meter - Potenza Reattiva"
    id: pMeter_power_reactive
    unit_of_measurement: "VAr"
    accuracy_decimals: 2
    update_interval: 5s
    icon: mdi:power
    lambda: return (( sqrt( (id(pMeter_power_apparente).state)*(id(pMeter_power_apparente).state)   -  (id(pMeter_power).state)*(id(pMeter_power).state) ) ));
    
  - platform: wifi_signal
    name: "WiFi Power Meter - Potenza segnale wifi"
    update_interval: 10s
    
  - platform: uptime
    name: "up"
    id: uptime_sec    
 
switch:
  - platform: restart
    name: "Power Meter - Riavvio"
    
    
binary_sensor:
  - platform: status
    name: "Power Meter - Stato"    
    
    
text_sensor:
  - platform: template
    name: Power Meter - Uptime
    lambda: |-
      int seconds = (id(uptime_sec).state);
      int days = seconds / (24 * 3600);
      seconds = seconds % (24 * 3600); 
      int hours = seconds / 3600;
      seconds = seconds % 3600;
      int minutes = seconds /  60;
      seconds = seconds % 60;
      return { (String(days) +"d " + String(hours) +"h " + String(minutes) +"m "+ String(seconds) +"s").c_str() };
    icon: mdi:clock-start
    update_interval: 113s

How are you converting 3.3V - 5V serial communication?

I would like to replicate your project, however, I didn’t find the diagram. Is there any? What module has been used? thanks

I have used this module https://www.aliexpress.com/item/4000527585052.html?spm=a2g0o.order_list.order_list_main.10.1a3c18024bW1q8
I think I had used this diode: bat45
68074678-0dd16e80-fd9e-11e9-8d80-5650e9e18fb8

2 Likes

‘’’
Hi,

Since the last update I have this problem.
Any idea ?

Thx

[09:56:17][W][modbus:105]: Modbus CRC Check failed! 3300!=00
[09:56:18][W][modbus:105]: Modbus CRC Check failed! EECB!=2100
[09:56:18][W][modbus:105]: Modbus CRC Check failed! 3300!=00
[09:56:19][W][modbus:105]: Modbus CRC Check failed! 7EC6!=2100
[09:56:19][W][modbus:105]: Modbus CRC Check failed! 3300!=00
[09:56:20][W][modbus:105]: Modbus CRC Check failed! 7EC6!=2100
[09:56:20][W][modbus:105]: Modbus CRC Check failed! 3300!=00
[09:56:21][W][modbus:105]: Modbus CRC Check failed! 7EC6!=2100
[09:56:21][W][modbus:105]: Modbus CRC Check failed! 3300!=00
[09:56:22][W][modbus:105]: Modbus CRC Check failed! EECB!=2100
[09:56:22][W][modbus:105]: Modbus CRC Check failed! 3300!=00
[09:56:23][W][modbus:105]: Modbus CRC Check failed! EECB!=2100
[09:56:23][W][modbus:105]: Modbus CRC Check failed! 3300!=00
[09:56:24][W][modbus:105]: Modbus CRC Check failed! EE61!=2100
[09:56:24][W][modbus:105]: Modbus CRC Check failed! 3300!=00
[09:56:25][W][modbus:105]: Modbus CRC Check failed! EE61!=2100
[09:56:25][W][modbus:105]: Modbus CRC Check failed! 3300!=00
[09:56:26][W][modbus:105]: Modbus CRC Check failed! 7E6C!=2100
[09:56:26][W][modbus:105]: Modbus CRC Check failed! F141!=00
[09:56:27][W][modbus:105]: Modbus CRC Check failed! 1E75!=2100
[09:56:27][W][modbus:105]: Modbus CRC Check failed! 3300!=00
[09:56:28][W][modbus:105]: Modbus CRC Check failed! 7EC6!=2100
[09:56:28][W][modbus:105]: Modbus CRC Check failed! 3300!=00
[09:56:29][W][modbus:105]: Modbus CRC Check failed! 7EC6!=2100
[09:56:29][W][modbus:105]: Modbus CRC Check failed! 3300!=00
‘’’

I think the difference is that it talks to all of them at the same time.
I have change the “update_interval:” on one to be 1s, the other to be 1.02s
I get periodic CRCs when they align, but overall 95% of reads are good.
I used to have a delay in the code for the second one, but since an update that shows as a yaml error, so I can’t have it in the code now.
Hope this helps.
Steve

And they can be wired in parallel, since on Tx, each is just an LED and resistor on the PZEM board, and on the Rx, any one of them that is replying (- assuming you only addressed one!) can pull the input to the ESP down to ground.
If you want to talk to many, you’d need to change the drive strength of the ESP (ESP32 only feature), or the current it can output will be too low, when divided between all the PZEM bards, to drive the optocouplers and be able to signal to the PZEM electronics.
Otherwise 1 transistor could buffer the current if needed.
Drop me an Email if you want a diagram etc. [email protected] remove the 1’s

I have the same issue with the
Modbus CRC Check failed!

Have you found a solution?

Steeve wrote about reporting issue of several devices. But I have one only to test it.

Appears there was a bug introduced around 2022.11.3 that causes issues with modbus.

Some are having success with changing the arduino framework version as below.

esp32:
  board: nodemcu-32s
  framework:
    type: arduino
    version: 2.0.6

Here are a couple related GitHub issues

In my case, I had an issue at about the same version that caused the Quinled-ESP32 ABE boards to not boot and switching to esp-idf resolved it.

I try to change address my PZEM004T to 0x003 to this code:

but it always has the old address: 0x01 what am I doing wrong?

esphome:

  name: ac-mero-01

  on_boot:

    ## configure controller settings at setup

    ## make sure priority is lower than setup_priority of modbus_controller

    priority: -100

    then:

      - lambda: |-

          auto new_address = 0x03;

          if(new_address < 0x01 || new_address > 0xF7) // sanity check

          {

            ESP_LOGE("ModbusLambda", "Address needs to be between 0x01 and 0xF7");

            return;

          }

          esphome::modbus_controller::ModbusController *controller = id(pzem);

          auto set_addr_cmd = esphome::modbus_controller::ModbusCommandItem::create_write_single_command(

            controller, 0x0003, new_address);

          delay(200) ;

          controller->queue_command(set_addr_cmd);

          ESP_LOGI("ModbusLambda", "PZEM Addr set");

modbus:

  send_wait_time: 200ms

  id: mod_bus_pzem

modbus_controller:

  - id: pzem

    # The current device address.

    address: 0x01

    # The special address 0xF8 is a broadcast address accepted by any pzem device,

    # so if you use this address, make sure there is only one pzem device connected

    # to the uart bus.

    # address: 0xF8

    modbus_id: mod_bus_pzem

    command_throttle: 0ms

    setup_priority: -10

    update_interval: 30s

Not providing any logs?

I think you wrongly changed this part

auto set_addr_cmd = esphome::modbus_controller::ModbusCommandItem::create_write_single_command(

            controller, 0x0003, new_address)

the 0x0003 should be left as 0x0002, it’s register number for the address, not the address itself.

I made and emulator for pzem-004t v3 module. See here. Could be used to troubleshoot issues

1 Like

I got wrong low power incoming value, and also very low power factor. Trying to count my main AC power, energy consumption that connected to AC in of solar inverter.
I hope that some one can help to resolve issue with incorrect values? Much appreciated