-
-
Save bandaangosta/134c9d84ae9bd317297e96dcc0b9c860 to your computer and use it in GitHub Desktop.
# Reading PZEM-004t power sensor (new version v3.0) through Modbus-RTU protocol over TTL UART | |
# Run as: | |
# python3 pzem_004t.py | |
# To install dependencies: | |
# pip install modbus-tk | |
# pip install pyserial | |
import serial | |
import modbus_tk.defines as cst | |
from modbus_tk import modbus_rtu | |
# Connect to the sensor | |
sensor = serial.Serial( | |
port='/dev/PZEM_sensor', | |
baudrate=9600, | |
bytesize=8, | |
parity='N', | |
stopbits=1, | |
xonxoff=0 | |
) | |
master = modbus_rtu.RtuMaster(sensor) | |
master.set_timeout(2.0) | |
master.set_verbose(True) | |
data = master.execute(1, cst.READ_INPUT_REGISTERS, 0, 10) | |
voltage = data[0] / 10.0 # [V] | |
current = (data[1] + (data[2] << 16)) / 1000.0 # [A] | |
power = (data[3] + (data[4] << 16)) / 10.0 # [W] | |
energy = data[5] + (data[6] << 16) # [Wh] | |
frequency = data[7] / 10.0 # [Hz] | |
powerFactor = data[8] / 100.0 | |
alarm = data[9] # 0 = no alarm | |
print('Voltage [V]: ', voltage) | |
print('Current [A]: ', current) | |
print('Power [W]: ', power) # active power (V * I * power factor) | |
print('Energy [Wh]: ', energy) | |
print('Frequency [Hz]: ', frequency) | |
print('Power factor []: ', powerFactor) | |
print('Alarm : ', alarm) | |
# Changing power alarm value to 100 W | |
# master.execute(1, cst.WRITE_SINGLE_REGISTER, 1, output_value=100) | |
try: | |
master.close() | |
if sensor.is_open: | |
sensor.close() | |
except: | |
pass |
bandaangosta
commented
Oct 25, 2024
via email
Hi, @donemuhendislik. I'm happy to hear this code is useful. I remember reading (it's been a couple of years) that this version of the module does not allow for resetting the energy counter, although supposedly the function code 0x42 ("power zero clearing") does the trick. I have never tried it. In general, there is no need to clear the energy count. Just read the value at the beginning and end of a certain period. The difference is the energy consumption of the period.
Thank you so much @bandaangosta for your reply. In deed, i was meaning that 0x42 and i was afraid of trying that data to pzem-004t for may i could break it. So, your solution is best. Saving the initial energy value and saving last one and difference is consumption ππ» or calculating energy consumption with Wh formula that contains voltage and current. Again thank you so much for your helpful idea, i will use it ππ»
@bandaangosta Do you happen to have a TCP-version of this script? I'm now trying to access the data through a serial server running on an ESP-module. I can see from the log (of ESP Easy) that my script connects to the serial server, there's a single blink from a red LED on the PZEM-004t, but no data back :(
edit: Got as far as
import socket, sys
socket.setdefaulttimeout(5)
try:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print('Failed to create socket')
sys.exit()
print('Socket Created')
ESP_IP= "*.*.*.*"
ESP_PORT = *
client.connect((ESP_IP,ESP_PORT))
print('Socket Connected to ' + ESP_IP )
try:
print("Send command")
client.send(bytes("\x01\x04\x00\x00\x00\x0A\x70\x0D", 'ascii'))
print("Receive data")
data = client.recv(1024)
print(data)
except socket.error as e:
print(e)
The PZEM-module reacts to this (Rx LED goes on, followed by Tx-LED), but not receiving data back.