Code Monkey home page Code Monkey logo

pzem-004t-v30's Issues

Create Wiki for the PZEM-004T v3.0

The information about this module exists, but it is sparsely distributed on the internet. It would be useful to collect all the available information in one place that could act as a reference for further development.

The Wiki feature of Github could be used for that. Would be great to include the datasheet info, perform some actual measurements. However this is a long term endeavor. Anyone willing to invest their time would be welcome to take over.

Configure Current probe

At the moment, the library assumes the 100A current probe. There should be a way to set the current probe version to the 10A version.

Add calibration function to the library

The chip supports this.
This seems to be in the documentation. It would be great.

The format of the master command for calibrating a slave (6 bytes in total):

0xF8 + 0x41 + 0x37 + 0x21 + CRC check high byte + CRC check low byte.

Correct answer: 0xF8 + 0x41 + 0x37 + 0x21 + CRC check high byte + CRC check low byte.

Error response: 0xF8 + 0xC1 + anomalous code + CRC check high byte + CRC check low byte.

It should be noted that the calibration takes from 3 to 4 seconds, after the master sends a command, if the calibration is successful, it takes 3-4 seconds to get a response from the slave.

Add ESP32 Support

Please add ESP32 support.

I changed line #25 in PZEM004Tv30.h file to:

#if (not defined(PZEM004_NO_SWSERIAL)) && (defined(__AVR__) || defined(ESP8266)) || defined(ESP32)
which makes it works with hardwareserial e.g. serial2

But softwareserial still makes problems and didn't work with the EspSoftwareSerial.

Compatibility with Nodemcu ESP32 board?

I have used the library to work with Arduino UNO and it works fine.
With my Nodemcu-32S board, I am not able to get anything on the serial monitor when I run "PZEMHardSerial" example with "&Serial" instead of "&Serial3".
Is your library compatible with Nodemcu-32S module?
If not, is there a way to make it compatible?

Thanks.

problems with wemos d1 and PZEM-004T

My connections:

  • Wemos D5 to PZEM Tx
  • Wemos D6 to PZEM Rx
  • Wemos 5V to PZEM 5V
  • Wemos GND to PZEM GND
    After running a few minutes the system will crush. Error messages:

Exception 0: Illegal instruction

PC: 0x402021e4: circular_queue ::push(unsigned int&&) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/xtensa-lx106-elf/include/c++/10.1.0/bits/atomic_base.h line 420
EXCVADDR: 0x00000000

Decoding stack results
0x4010079c: interrupt_handler(void*, void*) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_digital.cpp line 166
0x40100e2c: check_poison_block(umm_block*) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/umm_malloc/umm_poison.c line 95
0x40100cd1: umm_free_core(void*) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/umm_malloc/umm_malloc.cpp line 351
0x401006d8: interrupt_handler(void*, void*) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_digital.cpp line 137
0x401006d8: interrupt_handler(void*, void*) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_digital.cpp line 137
0x401006d8: interrupt_handler(void*, void*) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_digital.cpp line 137
0x401006d8: interrupt_handler(void*, void*) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_digital.cpp line 137
0x40204768: loop_task(ETSEvent*) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_features.h line 92
0x4020dee4: sys_timeout_LWIP2 at core/timeouts.c line 304
0x4020df57: tcpip_tcp_timer at core/timeouts.c line 153
0x40204784: loop_task(ETSEvent*) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp line 208
0x401004fc: ets_post(uint8, ETSSignal, ETSParam) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp line 177
0x401004fc: ets_post(uint8, ETSSignal, ETSParam) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp line 177
0x401004fc: ets_post(uint8, ETSSignal, ETSParam) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp line 177
0x401004fc: ets_post(uint8, ETSSignal, ETSParam) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp line 177
0x4020d6b2: glue2esp_linkoutput at glue-esp/lwip-esp.c line 241
0x401004fc: ets_post(uint8, ETSSignal, ETSParam) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp line 177
0x401004fc: ets_post(uint8, ETSSignal, ETSParam) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp line 177
0x401003b0: SoftwareSerial::rxBitISR(SoftwareSerial*) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/xtensa-lx106-elf/include/c++/10.1.0/bits/unique_ptr.h line 420
0x401004fc: ets_post(uint8, ETSSignal, ETSParam) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp line 177
0x401007b8: interrupt_handler(void*, void*) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_digital.cpp line 174
0x4010079c: interrupt_handler(void*, void*) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_digital.cpp line 166
0x401003b0: SoftwareSerial::rxBitISR(SoftwareSerial*) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/xtensa-lx106-elf/include/c++/10.1.0/bits/unique_ptr.h line 420
0x401004fc: ets_post(uint8, ETSSignal, ETSParam) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp line 177
0x401006d8: interrupt_handler(void*, void*) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_digital.cpp line 137
0x40100569: millis() at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring.cpp line 193
0x4010054c: millis() at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring.cpp line 175
0x402021dc: std::_Function_handler >::_M_invoke(const std::_Any_data &, unsigned int &&) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/libraries/SoftwareSerial/src/SoftwareSerial.cpp line 423
0x40201ca8: circular_queue ::for_each(Delegate const&) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/xtensa-lx106-elf/include/c++/10.1.0/bits/atomic_base.h line 122
0x401001ce: SoftwareSerial::writePeriod(unsigned int, unsigned int, bool) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/libraries/SoftwareSerial/src/SoftwareSerial.cpp line 263
0x40201f88: SoftwareSerial::rxBits() at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/xtensa-lx106-elf/include/c++/10.1.0/bits/std_function.h line 303
0x401004fc: ets_post(uint8, ETSSignal, ETSParam) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp line 177
0x402021d0: std::_Function_handler >::_M_invoke(const std::_Any_data &, unsigned int &&) at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/libraries/SoftwareSerial/src/SoftwareSerial.cpp line 423
0x4020483b: __yield() at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_features.h line 92
0x402015fa: PZEM004Tv30::recieve(unsigned char*, unsigned short) at /home/willieyu/Arduino/libraries/PZEM-004T-v30-master/PZEM004Tv30.cpp line 469
0x402016aa: PZEM004Tv30::sendCmd8(unsigned char, unsigned short, unsigned short, bool, unsigned short) at /home/willieyu/Arduino/libraries/PZEM-004T-v30-master/PZEM004Tv30.cpp line 246
0x40201752: PZEM004Tv30::updateValues() at /home/willieyu/Arduino/libraries/PZEM-004T-v30-master/PZEM004Tv30.cpp line 377
0x402018dd: PZEM004Tv30::voltage() at /home/willieyu/Arduino/libraries/PZEM-004T-v30-master/PZEM004Tv30.cpp line 130
0x40201077: getPzem() at /home/willieyu/Arduino/PZEMSoftwareSerial/PZEMSoftwareSerial.ino line 119
0x40201374: loop() at /home/willieyu/Arduino/PZEMSoftwareSerial/PZEMSoftwareSerial.ino line 78
0x40204928: loop_wrapper() at /home/willieyu/arduino/arduino-1.8.13/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp line

197

Sketch:

#include <PZEM004Tv30.h>
#include <ESP8266WiFi.h>

/* Use software serial for the PZEM

  • Pin 11 Rx (Connects to the Tx pin on the PZEM)
  • Pin 12 Tx (Connects to the Rx pin on the PZEM)
    */
    PZEM004Tv30 pzem(D5, D6);

#ifndef APSSID
#define APSSID ""
#define APPSK "
"
#endif

const char* ssid = APSSID;
const char* password = APPSK;

const char* host = "192.168.0.103";
const int port = 3000;

int i = 0;

WiFiClient client;

void prinScanResult(int networksFound)
{
Serial.printf("%d network(s) found\n", networksFound);
for (int i = 0; i < networksFound; i++)
{
Serial.printf("%d: %s, Ch:%d (%ddBm) %s\n", i + 1, WiFi.SSID(i).c_str(), WiFi.channel(i), WiFi.RSSI(i), WiFi.encryptionType(i) == ENC_TYPE_NONE ? "open" : "");
}
}

void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("trying to connected WIFI...");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());

// Use WiFiClient class to create TCP connections
if (!client.connected()) {
Serial.println("connected to server");
if (!client.connect(host, port)) {
Serial.println("connection failed");
delay(5000);
return;
}
Serial.println("connected sucess ");
}

}

void loop() {

if (!client.connected()) {
  Serial.println("reconnected to server");
  if (!client.connect(host, port)) {
    Serial.println("reconnection failed");
    delay(5000);
    return;
  }
  Serial.println("reconnected sucess");
}

getPzem(); 

     // This will send a string to the server
Serial.println("sending data to server");
if (client.connected()) {
  client.print("{name:'test'}");
}

// delay(2000);
// wait for data to be available
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println(">>> Client Timeout !");
client.stop();
if((WiFi.status() != WL_CONNECTED)){
Serial.println(">>> WiFi disconnected!");
}else{
Serial.println(">>> WiFi connected!");
}
delay(60000);
return;
}
}

  // Read all the lines of the reply from server and print them to Serial
  Serial.println("receiving from remote server");
  // not testing 'client.connected()' since we do not need to send data here
  while (client.available()) {
    char ch = static_cast<char>(client.read());
    Serial.print(ch);
  }

   Serial.println();


Serial.println();
delay(2000);

}

void getPzem(){

// String result = "";
// result += "[";
float voltage = pzem.voltage();
if( !isnan(voltage) ){
Serial.print("Voltage: "); Serial.print(voltage); Serial.println("V");
// result += "{name:'voltage', value:"+String(voltage)+", unit:'V'},";
} else {
Serial.println("Error reading voltage");
}

float current = pzem.current();
if( !isnan(current) ){
    Serial.print("Current: "); Serial.print(current); Serial.println("A");

// result += "{name:'current', value:"+String(current)+", unit:'A'},";
} else {
Serial.println("Error reading current");
}

float power = pzem.power();
if( !isnan(power) ){
    Serial.print("Power: "); Serial.print(power); Serial.println("W");

// result += "{name:'power', value:"+String(power)+", unit:'W'},";
} else {
Serial.println("Error reading power");
}

float energy = pzem.energy();
if( !isnan(energy) ){
    Serial.print("Energy: "); Serial.print(energy,3); Serial.println("kWh");

// result += "{name:'energy', value:"+String(energy)+", unit:'kWh'},";
} else {
Serial.println("Error reading energy");
}

float frequency = pzem.frequency();
if( !isnan(frequency) ){
    Serial.print("Frequency: "); Serial.print(frequency, 1); Serial.println("Hz");

// result += "{name:'frequency', value:"+String(frequency)+", unit:'Hz'},";
} else {
Serial.println("Error reading frequency");
}

float pf = pzem.pf();
if( !isnan(pf) ){
    Serial.print("PF: "); Serial.println(pf);

// result += "{name:'pf', value:"+String(pf)+", unit:''},";
} else {
Serial.println("Error reading power factor");
}

// result += "]";
// return result;
}`

always getting error reading message with default example

Hi I am using an Arduino Uno and tried to connect the PZEM-004-v30 RX -->D11 and TX --> D12.
when I compiled and uploaded the default example I gets always the following message in the serial monitor.
Error reading voltage
Error reading current
Error reading power
Error reading energy
Error reading frequency
Error reading power factor

code which i have used:
#include <PZEM004Tv30.h>

/* Use software serial for the PZEM

  • Pin 11 Rx (Connects to the Tx pin on the PZEM)
  • Pin 12 Tx (Connects to the Rx pin on the PZEM)
    */
    PZEM004Tv30 pzem(11, 12);

void setup() {
Serial.begin(115200);
}

void loop() {
float voltage = pzem.voltage();
if( !isnan(voltage) ){
Serial.print("Voltage: "); Serial.print(voltage); Serial.println("V");
} else {
Serial.println("Error reading voltage");
}

float current = pzem.current();
if( !isnan(current) ){
    Serial.print("Current: "); Serial.print(current); Serial.println("A");
} else {
    Serial.println("Error reading current");
}

float power = pzem.power();
if( !isnan(power) ){
    Serial.print("Power: "); Serial.print(power); Serial.println("W");
} else {
    Serial.println("Error reading power");
}

float energy = pzem.energy();
if( !isnan(energy) ){
    Serial.print("Energy: "); Serial.print(energy,3); Serial.println("kWh");
} else {
    Serial.println("Error reading energy");
}

float frequency = pzem.frequency();
if( !isnan(frequency) ){
    Serial.print("Frequency: "); Serial.print(frequency, 1); Serial.println("Hz");
} else {
    Serial.println("Error reading frequency");
}

float pf = pzem.pf();
if( !isnan(pf) ){
    Serial.print("PF: "); Serial.println(pf);
} else {
    Serial.println("Error reading power factor");
}

Serial.println();
delay(2000);

}

any Idea what I am doing wrong?

pzem.setAddress() function doesn't work?

Firstly, thank you very much for creating this library. It works great! Recently, I tried the ChangeAddress example with Arduino Mega and Particle's Argon board but couldn't change the address. It prints out 248 always. If I initialize the meter with say PZEM004Tv30 pzem(10, 11, 0x07);, it does work and getAddress() gives me the same.

Anything I'm doing wrong?

How to enable multiple slave in an same Serial Interface ?

Hi, I'd like do understand how can I use more than one PZEM using the same Serial Interface as described in README. I've tested some ways but none worked.
PS: I'm starting to use Github these days, sorry if it isn't the correct space. Thanks!

Read 2 pzem04 with wemos d1 with 2 serial

Good morning,

I have a problem with wemos d1 and 2 pzem04T

When wemos d1 turns on it does not read the pzem04,
I must first connect 1 pzem and after the other pzem, then it starts to read them

the code is attached

thank you very much

`//

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <PubSubClient.h>
#include <PZEM004Tv30.h>

//PZEM004Tv30 pzem(&Serial3);
PZEM004Tv30 pzem (D5, D6);
PZEM004Tv30 pzem2 (D7, D8);

const char* ssid = "+++++++";
const char* password = "++++++++";
const char* mqtt_server = "192.168.1.1";
long previousMillis = 0;
long interval = 60000;

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

const char* inTopic = "home/enel";
const char* outTopic = "home/enel";
const char* outTopic_enel_gen_v = "home/enel/generale/v";
const char* outTopic_enel_gen_a = "home/enel/generale/a";
const char* outTopic_enel_gen_w = "home/enel/generale/w";
const char* outTopic_enel_gen_kwh = "home/enel/generale/kwh";
const char* outTopic_enel_gen_hz = "home/enel/generale/hz";
const char* outTopic_enel_gen_pf = "home/enel/generale/pf";
const char* outTopic_enel_ap_v = "home/enel/appartamento/v";
const char* outTopic_enel_ap_a = "home/enel/appartamento/a";
const char* outTopic_enel_ap_w = "home/enel/appartamento/w";
const char* outTopic_enel_ap_kwh = "home/enel/appartamento/kwh";
const char* outTopic_enel_ap_hz = "home/enel/appartamento/hz";
const char* outTopic_enel_ap_pf = "home/enel/appartamento/pf";
const char* outIP = "home/enel/ip";

void setup_wifi() {

delay(5);
WiFi.begin(ssid);

while (WiFi.status() != WL_CONNECTED) {
for(int i = 0; i<500; i++){
delay(1);
}
Serial.print(".");
}
}

void callback(char* topic, byte* payload, unsigned int length) {
if ((char)payload[0] == '1') {
pzem.resetEnergy();
pzem2.resetEnergy();

}
}

void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("Enel")) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish(outTopic, "enel booted");
client.subscribe(inTopic);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
for(int i = 0; i<5000; i++){
delay(1);
}
}
}
}

void send_ip(){
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
client.publish(outIP, WiFi.localIP().toString().c_str());
}
}

void read_enel_gen(){

float volt = pzem.voltage();
Serial.print("Voltage: ");
Serial.print(volt);
Serial.println("V");

float cur = pzem.current();
Serial.print("Current: ");
Serial.print(cur);
Serial.println("A");

float powe = pzem.power();
Serial.print("Power: ");
Serial.print(powe);
Serial.println("W");

float ener = pzem.energy();
Serial.print("Energy: ");
Serial.print(ener,3);
Serial.println("kWh");

float freq = pzem.frequency();
Serial.print("Frequency: ");
Serial.print(freq);
Serial.println("Hz");

float pf = pzem.pf();
Serial.print("PF: ");
Serial.println(pf);

char buffer[10];
dtostrf(volt,2,2, buffer);
client.publish(outTopic_enel_gen_v,buffer);
dtostrf(cur,2,2, buffer);
client.publish(outTopic_enel_gen_a,buffer);
dtostrf(powe,2,2, buffer);
client.publish(outTopic_enel_gen_w,buffer);
dtostrf(ener,2,2, buffer);
client.publish(outTopic_enel_gen_kwh,buffer);
dtostrf(freq,2,2, buffer);
client.publish(outTopic_enel_gen_hz,buffer);
dtostrf(pf,2,2, buffer);
client.publish(outTopic_enel_gen_pf,buffer);

}

void read_enel_ap(){

float volt = pzem2.voltage();
Serial.print("Voltage2: ");
Serial.print(volt);
Serial.println("V");

float cur = pzem2.current();
Serial.print("Current: ");
Serial.print(cur);
Serial.println("A");

float powe = pzem2.power();
Serial.print("Power: ");
Serial.print(powe);
Serial.println("W");

float ener = pzem2.energy();
Serial.print("Energy: ");
Serial.print(ener,3);
Serial.println("kWh");

float freq = pzem2.frequency();
Serial.print("Frequency: ");
Serial.print(freq);
Serial.println("Hz");

float pf = pzem2.pf();
Serial.print("PF: ");
Serial.println(pf);

char buffer[10];
dtostrf(volt,2,2, buffer);
client.publish(outTopic_enel_ap_v,buffer);
dtostrf(cur,2,2, buffer);
client.publish(outTopic_enel_ap_a,buffer);
dtostrf(powe,2,2, buffer);
client.publish(outTopic_enel_ap_w,buffer);
dtostrf(ener,2,2, buffer);
client.publish(outTopic_enel_ap_kwh,buffer);
dtostrf(freq,2,2, buffer);
client.publish(outTopic_enel_ap_hz,buffer);
dtostrf(pf,2,2, buffer);
client.publish(outTopic_enel_ap_pf,buffer);

}

void setup() {

Serial.begin(115200);
setup_wifi(); // Connect to wifi
client.setServer(mqtt_server, 1883);
// client.setCallback(callback);

Serial.print("Reset Energy");
// pzem.resetEnergy();
// pzem2.resetEnergy();

// Serial.print("Set address to 0x42");
// pzem.setAddress(0x42);

// Hostname defaults to esp8266-[ChipID]
ArduinoOTA.setHostname("enel");
// START OTA
ArduinoOTA.onStart( {
String type;
if (ArduinoOTA.getCommand() == U_FLASH) {
type = "sketch";
} else { // U_FS
type = "filesystem";
}

// NOTE: if updating FS this would be the place to unmount FS using FS.end()
Serial.println("Start updating " + type);

});
ArduinoOTA.onEnd( {
Serial.println("\nEnd");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) {
Serial.println("Auth Failed");
} else if (error == OTA_BEGIN_ERROR) {
Serial.println("Begin Failed");
} else if (error == OTA_CONNECT_ERROR) {
Serial.println("Connect Failed");
} else if (error == OTA_RECEIVE_ERROR) {
Serial.println("Receive Failed");
} else if (error == OTA_END_ERROR) {
Serial.println("End Failed");
}
});
ArduinoOTA.begin();
//END OTA
}

void loop() {
if (!client.connected()) {
reconnect();
}
ArduinoOTA.handle();
client.loop();
read_enel_gen();
delay(2000);
read_enel_ap();
delay(2000);
send_ip();
}`

Rewrite the example code to be more readable

At the moment, the example code is written in a very verbose way that does not look very appealing. We should aim for examples that are around 20 lines of compact, elegant code.

Most of the code centers around error handling. Perhaps, this should be somehow compressed and made more readable.

Multiple pzem

Hi, can we put multiple pzem in to 1 uart serial? any recommendation method? thank you

not an issue, nor a pull request as it's a change the API, but got a working samd21 and pzem.

Hi,

So as I have wrote in that long title after some hours I got a working SAMD21 with pzem-004t-v30 using Uart/Sercom.
First thank @mandulaj for your work :-D
ie: I got inspiration from the TinyGSM library and a post on stackoverflow, and the knx from thelsing, and many bug report :-D

Instead of using traditional hardwareSerial or softwareserial, as neither work well with new microcontroller like the samd21/51 (DUE, Feather M0, sparkfun SAMD21 ....), I have used the Stream class with reference instead of pointer...

in the .ino file:

PZEM004Tv30 pzem(Serial1, PZEM_DEFAULT_ADDR);
Setup call add:
Serial1.begin(9600);

In .h

Change :
PZEM004Tv30(HardwareSerial* port, uint8_t addr=PZEM_DEFAULT_ADDR);
to
PZEM004Tv30(HardwareSerial& serialPZEM, uint8_t addr=PZEM_DEFAULT_ADDR);

And
Stream* _serial; // Serial interface
to
Stream& _serial; // Serial interface

And in .cpp
comment:
//extern HardwareSerial Serial;

Replace:

PZEM004Tv30::PZEM004Tv30(HardwareSerial* port, uint8_t addr) {

port->begin(PZEM_BAUD_RATE);
this->_serial = port;
this->_isSoft = false;
init(addr);
}

with:
PZEM004Tv30::PZEM004Tv30(HardwareSerial& serialPZEM, uint8_t addr) :
_serial(serialPZEM)
{
this->_serial = serialPZEM;
init(addr);
}

Remove: // Need to find cleaner way that completely removing :-D

if(_isSoft)
delete this->_serial;

And line around line 244
change _serial->write(sendBuffer, 8); to _serial.write(sendBuffer, 8);

same for 431/432 change the => with .
same for 463-466

This solution could remove many DEFINE and condition in the .h and .cpp and just need something like:
for softwareSerial:
SoftwareSerial SerialPZEM(2, 3);

HardwareSerial \ Uart and sercom should be the same.
ie for an another sercom on a samd21
Uart Serial2(&sercom1, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX); //TX D10, RX D12
The "extern HardwareSerial serial" could be define here....?!?!

@mandulaj : what do you think about changing a little bit the API? to be more future proof and use direct Stream class ?

Direction of energy

Hello all, in PZEM-004Tv3.0 version, how do we can see the direction of energy? In the older version the IC have a output that indicate the direction of energy ... like this article [https://github.com/apreb/eNode ].... it's possible in the new V3.0 version?

Library

Thanks a lot for your library. It works really well.
What does not work is the usage of "NAN" in the SoftwareSerial example. I replaced it with "isnan" and then it works really well so far. I created a 3-phase circuit with an esp8266 with 3 SoftwareSerial interfaces and mqtt readout. Thanks a lot for your work.

Wemos D1 Mini / Software Serial compile error

Hello,

First, thanks U for this library ! 👍

I want to use her with a "Wemos D1 Mini" board. When i compile the exemple program named "PZEMSoftwareSerial" i have the following error code :
C:\Users\ADN\Documents\Arduino\libraries\PZEM-004T-v30-master\PZEM004Tv30.cpp:456:42: error: 'class SoftwareSerial' has no member named 'listen'.

I have been looking for a solution on internet for several days but without success...

For additionnal information, this program work very well on a "Arduino Uno" board.

Thanks U in advance

Compatibility with Arduino nano 33 IoT

I was trying to connect PZEM004 to Arduino nano 33 IoT board, and this library is using SofwareSerial.h,
I tried to dig deeper, and Nano 33 IoT does not use SoftwareSerial anymore, so I'm not sure how to make
PZEM004 compatible with Nano 33 IoT board, could not find anything in the internet about this issue.
Maybe someone has an idea how to solve this?

This is from arduino official site:

Serial ports on the Arduino NANO 33 IoT

The USB connector of the board is directly connected to the USB host pins of the SAMD21. This routing enables you to use the Arduino NANO 33 IoT as a client USB peripheral (acting as a mouse or a keyboard connected to the computer) or as a USB host device so that devices like a mouse, keyboard, or an Android phone can be connected to the Arduino NANO 33 IoT. This port can also be used as a virtual serial port using the Serial object in the Arduino programming language. The RX0 and TX1 pins are a second serial port available as Serial1

So I've tried to simply write the code like this:

#include <PZEM004Tv30.h>

PZEM004Tv30 pzem(Serial1);

void setup() {
  Serial.begin(115200);

  Serial.print("Reset Energy");
  pzem.resetEnergy();


  Serial.print("Set address to 0x42");
  pzem.setAddress(0x42);
}

void loop() {
  float volt = pzem.voltage();
  float cur = pzem.current();
  float powe = pzem.power();
  float ener = pzem.energy();
  float freq = pzem.frequency();
  float pf = pzem.pf();
  

  Serial.print(volt);
  Serial.print(" ");
  Serial.print(cur);
  Serial.print(" ");
  Serial.print(powe);
  Serial.print(" ");
  Serial.print(ener,3);
  Serial.print(" ");
  Serial.print(freq);
  Serial.print(" ");
  Serial.println(pf);

  delay(1000);
}

But getting error output in aruino IDE:

error: no matching function for call to 'PZEM004Tv30::PZEM004Tv30(Uart&)'

PZEM004Tv30 pzem(Serial1);

Documents\Arduino\libraries\PZEM-004T-v30/PZEM004Tv30.h:65:5: note: candidate: PZEM004Tv30::PZEM004Tv30(arduino::HardwareSerial*, uint8_t)

PZEM004Tv30(HardwareSerial* port, uint8_t addr=PZEM_DEFAULT_ADDR);

^~~~~~~~~~~

Documents\Arduino\libraries\PZEM-004T-v30/PZEM004Tv30.h:59:7: note: candidate: constexpr PZEM004Tv30::PZEM004Tv30(const PZEM004Tv30&)

class PZEM004Tv30

^~~~~~~~~~~

exit status 1
no matching function for call to 'PZEM004Tv30::PZEM004Tv30(Uart&)'

[Arduino Uno] PZEMSoftwareSerial example

Hey guys

Im running PZEMSoftwareSerial example in my arduino uno using 115200 serial baud rate.

Heres my serial output every 2s:

Error reading voltage
Error reading current
Error reading power
Error reading energy
Error reading frequency
Error reading power factor

Error reading voltage
Error reading current
Error reading power
Error reading energy
Error reading frequency
Error reading power factor

I got my D11 and D12 setup according to example although I got only RX blinking at arduino side and TX blinking at PZEM side.

How can I diagnose this?

Issue with multiple pzems - solved

Hi there,
i worked on a project to monitor multiple breakers using this library + wemos d1 mini, but came into some issues. First it was powering them via internal voltage regulator which was solved by using max 6 pzem on one gpio pair, so only 6 pzems having load at the same time. Other issue was memory limit, with more than 16 devices i get into system crash - heap was full. This was solved by great help of a guy @mzero on adafruit discord channel. You need to modify

PZEM004Tv30.h
####################################
#if defined(PZEM004_SOFTSERIAL)
PZEM004Tv30(uint8_t receivePin, uint8_t transmitPin, uint8_t addr=PZEM_DEFAULT_ADDR);
PZEM004Tv30(SoftwareSerial &port, uint8_t addr=PZEM_DEFAULT_ADDR);
#endif
####################################

PZEM004T.cpp
####################################
#if defined(PZEM004_SOFTSERIAL)
PZEM004Tv30::PZEM004Tv30(uint8_t receivePin, uint8_t transmitPin, uint8_t addr)
{
SoftwareSerial *port = new SoftwareSerial(receivePin, transmitPin);
port->begin(PZEM_BAUD_RATE);
this->_serial = port;
this->_isSoft = true;
init(addr);
}
PZEM004Tv30::PZEM004Tv30(SoftwareSerial &port, uint8_t addr)
{
port.begin(PZEM_BAUD_RATE);
this->_serial = &port;
this->_isSoft = false;
init(addr);
}
####################################

then you can use this example:
####################################
SoftwareSerial serial56(D5, D6);
SoftwareSerial serial34(D3, D4);
SoftwareSerial serial12(D1, D2);

PZEM004Tv30 pzem1(serial56, 0x01);
PZEM004Tv30 pzem2(serial56, 0x02);
PZEM004Tv30 pzem3(serial34, 0x03);
PZEM004Tv30 pzem4(serial34, 0x04);
PZEM004Tv30 pzem5(serial12, 0x05);
PZEM004Tv30 pzem6(serial12, 0x06);
PZEM004Tv30 pzem7(serial56, 0x07);
PZEM004Tv30 pzem8(serial56, 0x08);
PZEM004Tv30 pzem9(serial34, 0x09);
PZEM004Tv30 pzem10(serial34, 0x0a);
PZEM004Tv30 pzem11(serial12, 0x0b);
PZEM004Tv30 pzem12(serial12, 0x0c);
PZEM004Tv30 pzem13(serial56, 0x0d);
PZEM004Tv30 pzem14(serial56, 0x0e);
PZEM004Tv30 pzem15(serial34, 0x0f);
PZEM004Tv30 pzem16(serial34, 0x10);
PZEM004Tv30 pzem17(serial12, 0x11);
PZEM004Tv30 pzem18(serial12, 0x12);
####################################

and memory stays low because heap isnt being used at all because nothing is being dynamically allocated. Once again, big thanx to mzero.

Pzem reads 2-way?

Other electronic meters often distinguish the current direction.
Is there any way pzem can distinguish the current direction?
Because I want to have kWh import and kWh export
please help!

Cannot use the library on Platformio

I've tried to import it to the project and complied with platformio core there's an error that seems to come out from SoftwareSerial library. Does anyone have any solution

Screen Shot

here is the error log:
`Processing megaatmega2560 (platform: atmelavr; board: megaatmega2560; framework: arduino)

Verbose mode can be enabled via -v, --verbose option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/megaatmega2560.html
PLATFORM: Atmel AVR 1.15.0 > Arduino Mega or Mega 2560 ATmega2560 (Mega 2560)
HARDWARE: ATMEGA2560 16MHz, 8KB RAM, 248KB Flash
PACKAGES: toolchain-atmelavr 1.50400.190710 (5.4.0), framework-arduinoavr 4.1.1
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 15 compatible libraries
Scanning dependencies...
Dependency Graph
|-- 1.0.0
| |-- 6.6.4
Building in release mode
Compiling .pio/build/megaatmega2560/src/main.cpp.o
Compiling .pio/build/megaatmega2560/lib2c4/EspSoftwareSerial_ID168/SoftwareSerial.cpp.o
Compiling .pio/build/megaatmega2560/libad6/PZEM-004T-v30_ID6551/PZEM004Tv30.cpp.o
Archiving .pio/build/megaatmega2560/libFrameworkArduinoVariant.a
Compiling .pio/build/megaatmega2560/FrameworkArduino/CDC.cpp.o
Indexing .pio/build/megaatmega2560/libFrameworkArduinoVariant.a
Compiling .pio/build/megaatmega2560/FrameworkArduino/HardwareSerial.cpp.o
Compiling .pio/build/megaatmega2560/FrameworkArduino/HardwareSerial0.cpp.o
Compiling .pio/build/megaatmega2560/FrameworkArduino/HardwareSerial1.cpp.o
Compiling .pio/build/megaatmega2560/FrameworkArduino/HardwareSerial2.cpp.o
In file included from /Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.h:27:0,
from /Users/wit03/.platformio/lib/PZEM-004T-v30_ID6551/PZEM004Tv30.h:30,
from /Users/wit03/.platformio/lib/PZEM-004T-v30_ID6551/PZEM004Tv30.cpp:1:
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:210:19: error: 'Delegate' has not been declared
void for_each(Delegate<void(T&&), ForEachArg> fun);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:210:27: error: expected ',' or '...' before '<' token
void for_each(Delegate<void(T&&), ForEachArg> fun);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:222:31: error: 'Delegate' has not been declared
bool for_each_rev_requeue(Delegate<bool(T&), ForEachArg> fun);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:222:39: error: expected ',' or '...' before '<' token
bool for_each_rev_requeue(Delegate<bool(T&), ForEachArg> fun);
^
In file included from /Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.h:27:0,
from /Users/wit03/.platformio/lib/PZEM-004T-v30_ID6551/PZEM004Tv30.h:30,
from src/main.cpp:2:
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:210:19: error: 'Delegate' has not been declared
void for_each(Delegate<void(T&&), ForEachArg> fun);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:210:27: error: expected ',' or '...' before '<' token
void for_each(Delegate<void(T&&), ForEachArg> fun);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:222:31: error: 'Delegate' has not been declared
bool for_each_rev_requeue(Delegate<bool(T&), ForEachArg> fun);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:222:39: error: expected ',' or '...' before '<' token
bool for_each_rev_requeue(Delegate<bool(T&), ForEachArg> fun);
^
In file included from /Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.h:27:0,
from /Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:23:
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:210:19: error: 'Delegate' has not been declared
void for_each(Delegate<void(T&&), ForEachArg> fun);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:210:27: error: expected ',' or '...' before '<' token
void for_each(Delegate<void(T&&), ForEachArg> fun);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:222:31: error: 'Delegate' has not been declared
bool for_each_rev_requeue(Delegate<bool(T&), ForEachArg> fun);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:222:39: error: expected ',' or '...' before '<' token
bool for_each_rev_requeue(Delegate<bool(T&), ForEachArg> fun);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:357:46: error: variable or field 'for_each' declared void
void circular_queue<T, ForEachArg>::for_each(Delegate<void(T&&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:357:46: error: 'Delegate' was not declared in this scope
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:357:55: error: expected primary-expression before 'void'
void circular_queue<T, ForEachArg>::for_each(Delegate<void(T&&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:357:76: error: expected primary-expression before '>' token
void circular_queue<T, ForEachArg>::for_each(Delegate<void(T&&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:357:78: error: 'fun' was not declared in this scope
void circular_queue<T, ForEachArg>::for_each(Delegate<void(T&&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:376:58: error: 'bool circular_queue<T, ForEachArg>::for_each_rev_requeue' is not a static data member of 'class circular_queue<T, ForEachArg>'
bool circular_queue<T, ForEachArg>::for_each_rev_requeue(Delegate<bool(T&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:357:46: error: variable or field 'for_each' declared void
void circular_queue<T, ForEachArg>::for_each(Delegate<void(T&&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:357:46: error: 'Delegate' was not declared in this scope
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:357:55: error: expected primary-expression before 'void'
void circular_queue<T, ForEachArg>::for_each(Delegate<void(T&&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:357:76: error: expected primary-expression before '>' token
void circular_queue<T, ForEachArg>::for_each(Delegate<void(T&&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:357:78: error: 'fun' was not declared in this scope
void circular_queue<T, ForEachArg>::for_each(Delegate<void(T&&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:376:58: error: 'bool circular_queue<T, ForEachArg>::for_each_rev_requeue' is not a static data member of 'class circular_queue<T, ForEachArg>'
bool circular_queue<T, ForEachArg>::for_each_rev_requeue(Delegate<bool(T&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:376:58: error: template definition of non-template 'bool circular_queue<T, ForEachArg>::for_each_rev_requeue'
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:376:58: error: 'Delegate' was not declared in this scope
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:376:67: error: expected primary-expression before 'bool'
bool circular_queue<T, ForEachArg>::for_each_rev_requeue(Delegate<bool(T&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:376:87: error: expected primary-expression before '>' token
bool circular_queue<T, ForEachArg>::for_each_rev_requeue(Delegate<bool(T&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:376:89: error: 'fun' was not declared in this scope
bool circular_queue<T, ForEachArg>::for_each_rev_requeue(Delegate<bool(T&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:376:58: error: template definition of non-template 'bool circular_queue<T, ForEachArg>::for_each_rev_requeue'
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:376:58: error: 'Delegate' was not declared in this scope
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:376:67: error: expected primary-expression before 'bool'
bool circular_queue<T, ForEachArg>::for_each_rev_requeue(Delegate<bool(T&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:376:87: error: expected primary-expression before '>' token
bool circular_queue<T, ForEachArg>::for_each_rev_requeue(Delegate<bool(T&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:376:89: error: 'fun' was not declared in this scope
bool circular_queue<T, ForEachArg>::for_each_rev_requeue(Delegate<bool(T&), ForEachArg> fun)
^
In file included from /Users/wit03/.platformio/lib/PZEM-004T-v30_ID6551/PZEM004Tv30.h:30:0,
from /Users/wit03/.platformio/lib/PZEM-004T-v30_ID6551/PZEM004Tv30.cpp:1:
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.h:193:20: error: 'Delegate' has not been declared
void onReceive(Delegate<void(int available), void*> handler);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.h:193:28: error: expected ',' or '...' before '<' token
void onReceive(Delegate<void(int available), void*> handler);
^
In file included from /Users/wit03/.platformio/lib/PZEM-004T-v30_ID6551/PZEM004Tv30.h:30:0,
from /Users/wit03/.platformio/lib/PZEM-004T-v30_ID6551/PZEM004Tv30.cpp:1:
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.h:252:5: error: 'Delegate' does not name a type
Delegate<void(int available), void*> receiveHandler;
^
In file included from /Users/wit03/.platformio/lib/PZEM-004T-v30_ID6551/PZEM004Tv30.h:30:0,
from /Users/wit03/.platformio/lib/PZEM-004T-v30_ID6551/PZEM004Tv30.cpp:1:
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.h:162:12: error: 'size_t SoftwareSerial::readBytes(uint8_t*, size_t)' marked 'override', but does not override
size_t readBytes(uint8_t* buffer, size_t size) override;
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.h:165:12: error: 'size_t SoftwareSerial::readBytes(char*, size_t)' marked 'override', but does not override
size_t readBytes(char* buffer, size_t size) override {
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:357:46: error: variable or field 'for_each' declared void
void circular_queue<T, ForEachArg>::for_each(Delegate<void(T&&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:357:46: error: 'Delegate' was not declared in this scope
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:357:55: error: expected primary-expression before 'void'
void circular_queue<T, ForEachArg>::for_each(Delegate<void(T&&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:357:76: error: expected primary-expression before '>' token
void circular_queue<T, ForEachArg>::for_each(Delegate<void(T&&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:357:78: error: 'fun' was not declared in this scope
void circular_queue<T, ForEachArg>::for_each(Delegate<void(T&&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:376:58: error: 'bool circular_queue<T, ForEachArg>::for_each_rev_requeue' is not a static data member of 'class circular_queue<T, ForEachArg>'
bool circular_queue<T, ForEachArg>::for_each_rev_requeue(Delegate<bool(T&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:376:58: error: template definition of non-template 'bool circular_queue<T, ForEachArg>::for_each_rev_requeue'
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:376:58: error: 'Delegate' was not declared in this scope
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:376:67: error: expected primary-expression before 'bool'
bool circular_queue<T, ForEachArg>::for_each_rev_requeue(Delegate<bool(T&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:376:87: error: expected primary-expression before '>' token
bool circular_queue<T, ForEachArg>::for_each_rev_requeue(Delegate<bool(T&), ForEachArg> fun)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:376:89: error: 'fun' was not declared in this scope
bool circular_queue<T, ForEachArg>::for_each_rev_requeue(Delegate<bool(T&), ForEachArg> fun)
^
In file included from /Users/wit03/.platformio/lib/PZEM-004T-v30_ID6551/PZEM004Tv30.h:30:0,
from src/main.cpp:2:
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.h:193:20: error: 'Delegate' has not been declared
void onReceive(Delegate<void(int available), void*> handler);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.h:193:28: error: expected ',' or '...' before '<' token
void onReceive(Delegate<void(int available), void*> handler);
^
In file included from /Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:23:0:
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.h:193:20: error: 'Delegate' has not been declared
void onReceive(Delegate<void(int available), void*> handler);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.h:193:28: error: expected ',' or '...' before '<' token
void onReceive(Delegate<void(int available), void*> handler);
^
In file included from /Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:23:0:
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.h:252:5: error: 'Delegate' does not name a type
Delegate<void(int available), void*> receiveHandler;
^
In file included from /Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:23:0:
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.h:162:12: error: 'size_t SoftwareSerial::readBytes(uint8_t*, size_t)' marked 'override', but does not override
size_t readBytes(uint8_t* buffer, size_t size) override;
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.h:165:12: error: 'size_t SoftwareSerial::readBytes(char*, size_t)' marked 'override', but does not override
size_t readBytes(char* buffer, size_t size) override {
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp: In member function 'void SoftwareSerial::begin(uint32_t, SoftwareSerialConfig, int8_t, int8_t, bool, int, int)':
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:71:20: error: 'ESP' was not declared in this scope
m_bitCycles = (ESP.getCpuFreqMHz() * 1000000UL + baud / 2) / baud;
^
In file included from /Users/wit03/.platformio/lib/PZEM-004T-v30_ID6551/PZEM004Tv30.h:30:0,
from src/main.cpp:2:
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.h:252:5: error: 'Delegate' does not name a type
Delegate<void(int available), void*> receiveHandler;
^
In file included from /Users/wit03/.platformio/lib/PZEM-004T-v30_ID6551/PZEM004Tv30.h:30:0,
from src/main.cpp:2:
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.h:162:12: error: 'size_t SoftwareSerial::readBytes(uint8_t*, size_t)' marked 'override', but does not override
size_t readBytes(uint8_t* buffer, size_t size) override;
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.h:165:12: error: 'size_t SoftwareSerial::readBytes(char*, size_t)' marked 'override', but does not override
size_t readBytes(char* buffer, size_t size) override {
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:84:40: error: no match for 'operator||' (operand types are 'bool' and 'std::unique_ptr<circular_queue >')
if (m_buffer && (!m_parityMode || m_parityBuffer) && m_isrBuffer) {
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:84:40: note: candidate: operator||(bool, bool)
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:84:40: note: no known conversion for argument 2 from 'std::unique_ptr<circular_queue >' to 'bool'
/Users/wit03/.platformio/lib/PZEM-004T-v30_ID6551/PZEM004Tv30.cpp: In destructor 'PZEM004Tv30::~PZEM004Tv30()':
/Users/wit03/.platformio/lib/PZEM-004T-v30_ID6551/PZEM004Tv30.cpp:94:22: warning: deleting object of abstract class type 'Stream' which has non-virtual destructor will cause undefined behaviour [-Wdelete-non-virtual-dtor]
delete this->_serial;
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp: In member function 'void SoftwareSerial::end()':
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:108:9: error: could not convert '((SoftwareSerial*)this)->SoftwareSerial::m_buffer' from 'std::unique_ptr<circular_queue >' to 'bool'
if (m_buffer) {
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:112:9: error: could not convert '((SoftwareSerial*)this)->SoftwareSerial::m_isrBuffer' from 'std::unique_ptr<circular_queue >' to 'bool'
if (m_isrBuffer) {
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp: In member function 'uint32_t SoftwareSerial::baudRate()':
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:118:12: error: 'ESP' was not declared in this scope
return ESP.getCpuFreqMHz() * 1000000UL / m_bitCycles;
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp: In member function 'void SoftwareSerial::enableRx(bool)':
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:156:31: error: 'ESP' was not declared in this scope
m_isrLastCycle = (ESP.getCycleCount() | 1) ^ m_invert;
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:158:125: error: 'attachInterruptArg' was not declared in this scope
attachInterruptArg(digitalPinToInterrupt(m_rxPin), reinterpret_cast<void ()(void)>(rxBitISR), this, CHANGE);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:160:150: error: 'attachInterruptArg' was not declared in this scope
attachInterruptArg(digitalPinToInterrupt(m_rxPin), reinterpret_cast<void ()(void)>(rxBitSyncISR), this, m_invert ? RISING : FALLING);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp: In member function 'virtual int SoftwareSerial::read()':
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:176:9: error: could not convert '((SoftwareSerial*)this)->SoftwareSerial::m_parityBuffer' from 'std::unique_ptr<circular_queue >' to 'bool'
if (m_parityBuffer)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp: In member function 'size_t SoftwareSerial::read(uint8_t*, size_t)':
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:192:33: error: 'class circular_queue' has no member named 'pop_n'
if (0 == (avail = m_buffer->pop_n(buffer, size))) {
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:194:27: error: 'class circular_queue' has no member named 'pop_n'
avail = m_buffer->pop_n(buffer, size);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:197:9: error: could not convert '((SoftwareSerial*)this)->SoftwareSerial::m_parityBuffer' from 'std::unique_ptr<circular_queue >' to 'bool'
if (m_parityBuffer) {
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:201:25: error: 'class circular_queue' has no member named 'pop_n'
m_parityBuffer->pop_n(nullptr, parityBits / 8);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp: In member function 'virtual int SoftwareSerial::available()':
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:223:33: error: 'optimistic_yield' was not declared in this scope
optimistic_yield(10000UL);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp: In member function 'void SoftwareSerial::preciseDelay(bool)':
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:232:51: error: 'xt_wsr_ps' was not declared in this scope
if (!m_intTxEnabled) { xt_wsr_ps(m_savedPS); }
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:233:24: error: 'ESP' was not declared in this scope
auto expired = ESP.getCycleCount() - m_periodStart;
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:239:98: error: 'optimistic_yield' was not declared in this scope
while ((ESP.getCycleCount() - m_periodStart) < m_periodDuration) { optimistic_yield(10000); }
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:241:54: error: 'xt_rsil' was not declared in this scope
if (!m_intTxEnabled) { m_savedPS = xt_rsil(15); }
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:245:17: error: 'ESP' was not declared in this scope
while ((ESP.getCycleCount() - m_periodStart) < m_periodDuration) {}
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:248:21: error: 'ESP' was not declared in this scope
m_periodStart = ESP.getCycleCount();
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp: In member function 'size_t SoftwareSerial::write(const uint8_t*, size_t, SoftwareSerialParity)':
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:293:31: error: 'xt_rsil' was not declared in this scope
m_savedPS = xt_rsil(15);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:298:21: error: 'ESP' was not declared in this scope
m_periodStart = ESP.getCycleCount();
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:359:28: error: 'xt_wsr_ps' was not declared in this scope
xt_wsr_ps(m_savedPS);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp: In member function 'virtual void SoftwareSerial::flush()':
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:370:9: error: could not convert '((SoftwareSerial*)this)->SoftwareSerial::m_parityBuffer' from 'std::unique_ptr<circular_queue >' to 'bool'
if (m_parityBuffer)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp: In member function 'virtual int SoftwareSerial::peek()':
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:390:9: error: could not convert '((SoftwareSerial*)this)->SoftwareSerial::m_parityBuffer' from 'std::unique_ptr<circular_queue >' to 'bool'
if (m_parityBuffer) m_lastReadParity = m_parityBuffer->peek() & m_parityOutPos;
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp: In member function 'void SoftwareSerial::rxBits()':
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:402:23: error: 'class std::atomic' has no member named 'exchange'
if (m_isrOverflow.exchange(false)) {
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:412:13: error: 'ESP' was not declared in this scope
if (ESP.getCycleCount() - m_isrLastCycle > detectionCycles) {
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:419:81: error: no matching function for call to 'circular_queue::for_each(SoftwareSerial::rxBits()::<lambda(const uint32_t&)>)'
m_isrBuffer->for_each([this](const uint32_t& isrCycle) { rxBits(isrCycle); });
^
In file included from /Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.h:27:0,
from /Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:23:
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:210:10: note: candidate: void circular_queue<T, ForEachArg>::for_each(int) [with T = long unsigned int; ForEachArg = void]
void for_each(Delegate<void(T&&), ForEachArg> fun);
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/circular_queue/circular_queue.h:210:10: note: no known conversion for argument 1 from 'SoftwareSerial::rxBits()::<lambda(const uint32_t&)>' to 'int'
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp: In member function 'void SoftwareSerial::rxBits(const uint32_t&)':
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:472:25: error: could not convert '((SoftwareSerial*)this)->SoftwareSerial::m_parityBuffer' from 'std::unique_ptr<circular_queue >' to 'bool'
if (m_parityBuffer)
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp: In static member function 'static void SoftwareSerial::rxBitISR(SoftwareSerial*)':
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:500:25: error: 'ESP' was not declared in this scope
uint32_t curCycle = ESP.getCycleCount();
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp: In static member function 'static void SoftwareSerial::rxBitSyncISR(SoftwareSerial*)':
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:509:22: error: 'ESP' was not declared in this scope
uint32_t start = ESP.getCycleCount();
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp: At global scope:
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:531:32: error: variable or field 'onReceive' declared void
void SoftwareSerial::onReceive(Delegate<void(int available), void*> handler) {
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:531:32: error: 'Delegate' was not declared in this scope
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:531:41: error: expected primary-expression before 'void'
void SoftwareSerial::onReceive(Delegate<void(int available), void*> handler) {
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:531:62: error: expected primary-expression before 'void'
void SoftwareSerial::onReceive(Delegate<void(int available), void*> handler) {
^
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp: In member function 'void SoftwareSerial::perform_work()':
/Users/wit03/.platformio/lib/EspSoftwareSerial_ID168/src/SoftwareSerial.cpp:538:9: error: 'receiveHandler' was not declared in this scope
if (receiveHandler) {
^
*** [.pio/build/megaatmega2560/src/main.cpp.o] Error 1
*** [.pio/build/megaatmega2560/libad6/PZEM-004T-v30_ID6551/PZEM004Tv30.cpp.o] Error 1
*** [.pio/build/megaatmega2560/lib2c4/EspSoftwareSerial_ID168/SoftwareSerial.cpp.o] Error 1
================================= [FAILED] Took 1.33 seconds =================================`

Hardserial on bluepill doesn't work

Hi everyone!

I just got the pzem v3 module and found this library (I use hardserial examples, because like in pzem v2 to use bluepill, we can only use hardserial libraries). I use Bluepill as MCU, and use serial 1 on PA9 & PA10 pins, but Sketch can't be uploaded and error messages like this appear:

Arduino: 1.8.5 (Windows 10), Board: "Generic STM32F103C series, STM32F103C8 (20k RAM. 64k Flash), STLink, 72Mhz (Normal), Smallest (default)"
C: \ Users \ Windows 10 \ Documents \ Arduino \ libraries \ PZEM-004T-v30-master \ PZEM004Tv30.cpp: 32: 23: error: conflicting declaration 'HardwareSerial Serial'
 extern Hardware Serial Serial;
                       ^
In file included from C: \ Users \ Windows 10 \ Documents \ Arduino \ hardware \ Arduino_STM32-master \ STM32F1 \ cores \ maple / wirish.h: 71: 0,
                 from C: \ Users \ Windows 10 \ Documents \ Arduino \ hardware \ Arduino_STM32-master \ STM32F1 \ cores \ maple / Arduino.h: 30,
                 from C: \ Users \ Windows 10 \ Documents \ Arduino \ libraries \ PZEM-004T-v30-master \ PZEM004Tv30.h: 19,
                 from C: \ Users \ Windows 10 \ Documents \ Arduino \ libraries \ PZEM-004T-v30-master \ PZEM004Tv30.cpp: 1:
C: \ Users \ Windows 10 \ Documents \ Arduino \ hardware \ Arduino_STM32-master \ STM32F1 \ cores \ maple / usb_serial.h: 96: 22: error: 'Serial' has a previous declaration as 'USBSerial Serial'
     extern USB Serial Serial;
                      ^
C: \ Users \ Windows 10 \ Documents \ Arduino \ libraries \ PZEM-004T-v30-master \ PZEM004Tv30.cpp: In constructor 'PZEM004Tv30 :: PZEM004Tv30 (uint8_t, uint8_t, uint8_t)':
C: \ Users \ Windows 10 \ Documents \ Arduino \ libraries \ PZEM-004T-v30-master \ PZEM004Tv30.cpp: 62: 5: error: 'Software Serial' was not declared in this scope
     Software Serial * port = new Software Serial (receivePin, transmitPin);
     ^
C: \ Users \ Windows 10 \ Documents \ Arduino \ libraries \ PZEM-004T-v30-master \ PZEM004Tv30.cpp: 62: 21: error: 'port' was not declared in this scope
     Software Serial * port = new Software Serial (receivePin, transmitPin);
                     ^
C: \ Users \ Windows 10 \ Documents \ Arduino \ libraries \ PZEM-004T-v30-master \ PZEM004Tv30.cpp: 62: 32: error: expected type-specifier before 'SoftwareSerial'
     Software Serial * port = new Software Serial (receivePin, transmitPin);
                                ^
C: \ Users \ Windows 10 \ Documents \ Arduino \ libraries \ PZEM-004T-v30-master \ PZEM004Tv30.cpp: 62: 32: error: expected ';' before 'Software Serial'
exit status 1
Error compiling for Generic STM32F103C series board.

how is the solution to solve this problem?
I'm not good at programming for now

by the way, thank you for making this library for the v3 pzem module, hopefully it will get better in the future
Thank you!

Compatibility problem with Arduino Due

Hi,
I was able to test your library on an Arduino Mega. It works very well and thank you for your update. Unfortunately, only the Arduino Due is able to run my home automation programs and I have a compatibility problem when I wear it on this platform.

Thanks in advance,
cordially

Need example code (Arduino) to 'set' and 'read' getPowerAlarm(); and setPowerAlarm(uint16_t watts);

Hello
I can't seem to get the 'getPowerAlarm()' function to output a usable response. Does the returned value (boolean) in this case represent that the power alarm is 'triggered'? Or does it only signify that a value has been added to the 'setPowerAlarm' register?
If you could point me in the direction of an example of working code for the 'get and set' Power alarm functions, it would be very much appreciated.

**forgot to mention that I am using a Chinese Arduino nano clone, all other functions work perfectly for my application so the only issue seems to be the configuration of the power alarm.

Thanks in advance.
mjd

ESP32Support

I'm not able to use this in an ESP32 System, can you please check it and make the necessary changes or provide with an example of use specifically for an ESP32 Device. Thanks.

Measuring speed

Hello,

dont know if its an issue but is there some limitation to measuring only once a second? And if so is there a way to make the process faster. It looks like the measuring is happening faster but data get "updated" only once a second. What should i do if i want to measure faster?

I apologize, english is not my first language and Thank you all for your answers.

Reading Multiple PZEM-004t in one SoftwareSerial

Screen Shot 2020-01-24 at 4 02 10 PM

I follow the same initialization, as you said. But it only returns the last PZEM connected.

here's my code.
'#include <PZEM004Tv30.h>

/* Use software serial for the PZEM
Pin 11 Rx (Connects to the Tx pin on the PZEM)
Pin 12 Tx (Connects to the Rx pin on the PZEM)
*/
PZEM004Tv30 pzem1(D5, D6, 0x01);
PZEM004Tv30 pzem2(D5, D6, 0x02);
PZEM004Tv30 pzem3(D5, D6, 0x03);
void setup() {
Serial.begin(115200);
}

void loop() {
float voltage1 = pzem1.voltage();
if( !isnan(voltage1) ){
Serial.print("voltage1: "); Serial.print(voltage1); Serial.println("V");
} else {
Serial.println("Error reading voltage");
}

float current1 = pzem1.current();
if( !isnan(current1) ){
    Serial.print("Current1: "); Serial.print(current1); Serial.println("A");
} else {
    Serial.println("Error reading current");
}

float power1 = pzem1.power();
if( !isnan(power1) ){
    Serial.print("Power: "); Serial.print(power1); Serial.println("W");
} else {
    Serial.println("Error reading power");
}

float energy1 = pzem1.energy();
if( !isnan(energy1) ){
    Serial.print("Energy1: "); Serial.print(energy1,3); Serial.println("kWh");
} else {
    Serial.println("Error reading energy");
}

float frequency1 = pzem1.frequency();
if( !isnan(frequency1) ){
    Serial.print("Frequency1: "); Serial.print(frequency1, 1); Serial.println("Hz");
} else {
    Serial.println("Error reading frequency");
}

float pf1 = pzem1.pf();
if( !isnan(pf1) ){
    Serial.print("PF1: "); Serial.println(pf1);
} else {
    Serial.println("Error reading power factor");
}

float voltage2 = pzem2.voltage();
if( !isnan(voltage2) ){
Serial.print("voltage2: "); Serial.print(voltage2); Serial.println("V");
} else {
Serial.println("Error reading voltage");
}

float current2 = pzem2.current();
if( !isnan(current2) ){
    Serial.print("Current2: "); Serial.print(current2); Serial.println("A");
} else {
    Serial.println("Error reading current");
}

float power2 = pzem2.power();
if( !isnan(power2) ){
    Serial.print("Power: "); Serial.print(power2); Serial.println("W");
} else {
    Serial.println("Error reading power");
}

float energy2 = pzem2.energy();
if( !isnan(energy2) ){
    Serial.print("Energy2: "); Serial.print(energy2,3); Serial.println("kWh");
} else {
    Serial.println("Error reading energy");
}

float frequency2 = pzem2.frequency();
if( !isnan(frequency2) ){
    Serial.print("Frequency2: "); Serial.print(frequency2, 2); Serial.println("Hz");
} else {
    Serial.println("Error reading frequency");
}

float pf2 = pzem2.pf();
if( !isnan(pf2) ){
    Serial.print("PF2: "); Serial.println(pf2);
} else {
    Serial.println("Error reading power factor");
}

 float voltage3 = pzem3.voltage();
if( !isnan(voltage3) ){
    Serial.print("voltage3: "); Serial.print(voltage3); Serial.println("V");
} else {
    Serial.println("Error reading voltage");
}

float current3 = pzem3.current();
if( !isnan(current3) ){
    Serial.print("Current3: "); Serial.print(current3); Serial.println("A");
} else {
    Serial.println("Error reading current");
}

float power3 = pzem3.power();
if( !isnan(power3) ){
    Serial.print("Power: "); Serial.print(power3); Serial.println("W");
} else {
    Serial.println("Error reading power");
}

float energy3 = pzem3.energy();
if( !isnan(energy3) ){
    Serial.print("Energy3: "); Serial.print(energy3,3); Serial.println("kWh");
} else {
    Serial.println("Error reading energy");
}

float frequency3 = pzem3.frequency();
if( !isnan(frequency3) ){
    Serial.print("Frequency3: "); Serial.print(frequency3, 3); Serial.println("Hz");
} else {
    Serial.println("Error reading frequency");
}

float pf3 = pzem3.pf();
if( !isnan(pf3) ){
    Serial.print("PF3: "); Serial.println(pf3);
} else {
    Serial.println("Error reading power factor");
}

}`

Add debugging capability to the library

Wee need a way to easily set the debug level of the library in order to print out useful statistics for debugging purposes.

For start I imagine a simple debug macro setting a verbosity level which allows to print information to the debug console when receiving or sending commands to the PZEM module:

// For setting debug level verbosity
#define PZEM004TV30_DEBUG 0

// For configuring custom serial debug interface
#define PZEM004TV30_DEBUG_SERIAL Serial

The debug code should be conditioned by the DEBUG verbosity level and only compiled if required.

HardSerial connect issue

Hey there, first of all thanx for the great work you doing. I am using 4x pzem 004t v3 on d1 mini via softserial for months without issue. I want to attach more devices but run our of usable gpio ports. I was trying to run hardserial, connected multiple pzem to one rx/rx but no success. Whatever i do i always get nan, and the leds on pzem not blink. Even the changeaddress from examples i watsnt able to use i had to use windows tool downloaded from inovatorsguru.com website and so change the address. Please tell me what i doing wrong i am desperate. thank you very much

Multiple PZEMS

Hello friends, tell me how to fix the library to read in a loop.
I don't like the case option.
PZEM004Tv30 pzem1 (D1, D2);
PZEM004Tv30 pzem2 (D3, D4);
PZEM004Tv30 pzem3 (D5, D6);

v [0] = pzem1.voltage ();
c [0] = pzem1.current ();
p [0] = pzem1.power ();
e [0] = pzem1.energy ();
f [0] = pzem1.frequency ();

v [1] = pzem2.voltage ();
c [1] = pzem2.current ();
p [1] = pzem2.power ();
e [1] = pzem2.energy ();
f [1] = pzem2.frequency ();

v [2] = pzem3.voltage ();
c [2] = pzem3.current ();
p [2] = pzem3.power ();
e [2] = pzem3.energy ();
f [2] = pzem3.frequency ();

Is it possible to somehow bring to the form:
for (size_t i = 0; i < 3; i++){
v [i] = pzem[i].voltage ();
c [i] = pzem[i].current ();
p [i] = pzem[i].power ();
e [i] = pzem[i].energy ();
f [i] = pzem[i].frequency ();
}

PZEM-004T v3.0 Power and Energy meter" To save data to SD CARD

"PZEM-004T v3.0 Power and Energy meter" is used very well.

But there is one thing that is not good.

It wants to store the data value in SD CARD.
SD CARD stores data by SPI communication.

It works well if only one SD card is connected to Arduino.
Or "PZEM-004T v3.0 Power and Energy meter".

The problem is that if both are connected, it will not work properly.
Is there any way?

===============================code ==============================

// SD card attached MOSI - pin 11, MISO - pin 12, CLK - pin 13, CS - pin 10
#include <PZEM004Tv30.h>
PZEM004Tv30 pzem(7, 8);
#include <SD.h>
const int chipSelect = 10;
String inputString;
boolean stringComplete = false;
boolean doFlag = false;
boolean closeFlag = false;
boolean recFlag = false;
long idx = 0;
File myFile;

void setup() {

pinMode(SS, OUTPUT);
Serial.begin(57600);
// see if the card is present and can be initialized:

if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present"); // don't do anything more:
while (1) ;
}
Serial.println("I'm Ready");
}

void loop() {

while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();

if (inChar != '\r' && inChar != '\n') {
  inputString += inChar;
  stringComplete = true;
} else {
  if (stringComplete) {
    Serial.println(inputString);

    if (inputString.equals("on")) {
      // Serial.println("on_ok");
      doFlag = true;
    } else if (inputString.equals("off")) {
      //  Serial.println("off_ok");
      doFlag = false;
      closeFlag = true;
    }
    inputString = "";
    stringComplete = false;
  }
}

}

if (doFlag) {

if ( recFlag == false) {
  Serial.println("card initialized.");
  char filename[] = "LOGGER00.TXT";
  for (uint8_t i = 0; i < 1000; i++) {
    filename[6] = i / 10 + '0';
    filename[7] = i % 10 + '0';
    if (! SD.exists(filename)) {
      Serial.println(filename);
      myFile = SD.open(filename, FILE_WRITE);  // only open a new file if it doesn't exist
      break;  // leave the loop!
    }
  }
  if (myFile) {
    recFlag = true;
  }
  if (! myFile) {
    Serial.println("couldnt create file");
  }
}

    float voltage = pzem.voltage();

    if (voltage != NAN) {
      Serial.print("Voltage: "); Serial.print(voltage); Serial.println("V");
    } else {
      Serial.println("Error reading voltage");
    }

Serial.println(voltage);
myFile.println(voltage);
myFile.flush();
delay(2000);

} else if (closeFlag) {
Serial.println("gps recording stop");
recFlag = false;
doFlag = false;
closeFlag = false;
myFile.flush();
myFile.close();
}
}

Arduino 32U4 problem

Hello,
sorry for disturbing you.
Is it possible that there is a problem when using 32U4 processors?

I compile the Soft Serial example with the target Arduino Nano, everything is perfect.
If I now switch to 32U4 based Arduino boards like Leonardo or Micro, then I get the following error:


C:\Program Files\Arduino\hardware\arduino\avr\cores\arduino/USBAPI.h:154:16: note: previous declaration as 'Serial_ Serial'

extern Serial_ Serial;

^~~~~~

exit status 1

A similar behavior could be observed if I use the HW Serial example.

Thanks for your support.

Use programmable slave addresses

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
To monitor my solar panels, I need 5 PZEM as slaves. With the old library from [@olehs] it war possible. Why I can set the slaveAdress, if I can't use it?

Describe alternatives you've considered
I can use 5 Arduinos with SD-Card for ever Panel. Or I use the old PZEM004T. With this I have implemented three phase monitoring.
Additional context
Add any other context or screenshots about the feature request here.

Test the actual capabilities of the PZEM module

Though amazing, the manufacturer's specifications are sometimes slightly too optimistic. As was the case in this issue #47, the true Energy accumulation gets imprecise after about 60kWh.

It would be great to test the true specifications of the units with verified instruments so that we can get a better understanding of the real expectations we can have from the modules.

  • Voltage range and accuracy
  • Current range and accuracy
  • PF range and accuracy
  • Frequency range and accuracy
  • Energy range and accuracy
  • Power range and accuracy

I have an oscilloscope capable of doing the measurements, but in case anyone has professional instruments, it would be great to get more precise measurements.

Problem with integrating your lib example

Hey, i'am using a ESP32 and coding in Visual Studio Code.

I copied your example SoftwareSerial but getting a compiling errors

no instance of constructor "PZEM004Tv30::PZEM004Tv30" matches the argument list -- argument types are: (int, int)

and

invalid conversion from 'int' to 'HardwareSerial*' [-fpermissive]

It's happend at the line PZEM004Tv30 pzem(11, 12);

/* Use software serial for the PZEM

  • Pin 11 Rx (Connects to the Tx pin on the PZEM)
  • Pin 12 Tx (Connects to the Rx pin on the PZEM)
    */
    PZEM004Tv30 pzem(11, 12); <======================

and giving the next statement;

D:_Dev_MyLib\PZEM-004T-v30/PZEM004Tv30.h:65:5: note: initializing argument 1 of 'PZEM004Tv30::PZEM004Tv30(HardwareSerial*, uint8_t)'
PZEM004Tv30(HardwareSerial* port, uint8_t addr=PZEM_DEFAULT_ADDR);

Can't use SoftwareSerial example

Hi, you should rename SoftwareSerial.ino to PZEMSoftwareSerail.ino, otherwise it won't be shown in the Arduino IDE examples list.

Software Serial WemosD1Mini

I use WeMos D1 Mini and use 2 Pzem which I connect to pin D5-D8 and some other sensors on pin D0-D3
when starting boot must disconnect the pzem from the pin, otherwise the system will not work

compile errors with MKR 1010

hi, i've been using the library very well on an arduino uno, but today i decided to compile it for an arduino MKR1010, without sucess.
is this board compatible? i tried to use both hardware and software serial.
the errors are the following:

`In file included from C:\Users\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.8.8\cores\arduino/delay.h:23:0,
from C:\Users\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.8.8\cores\arduino/Arduino.h:81,
from C:\Users\MEOCloud\Arduino\libraries\PZEM-004T-v30-master\PZEM004Tv30.h:41,
from C:\Users\MEOCloud\Arduino\libraries\PZEM-004T-v30-master\PZEM004Tv30.cpp:23:
C:\Users\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.8.8\variants\mkrwifi1010/variant.h:222:37:

error: conflicting declaration 'HardwareSerial SerialUSB'
#define Serial SerialUSB

                                 ^

C:\Users\\Arduino\libraries\PZEM-004T-v30-master\PZEM004Tv30.cpp:54:23: note: in expansion of macro 'Serial'
extern HardwareSerial Serial;
^~~~~~
In file included from C:\Users\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.8.8\cores\arduino/Arduino.h:139:0,
from C:\Users\MEOCloud\Arduino\libraries\PZEM-004T-v30-master\PZEM004Tv30.h:41,
from C:\Users\MEOCloud\Arduino\libraries\PZEM-004T-v30-master\PZEM004Tv30.cpp:23:
C:\Users\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.8.8\cores\arduino/USB/CDC.h:158:16: note: previous declaration as 'Serial_ SerialUSB'
extern Serial_ SerialUSB;
^~~~~~~~~
C:\Users\\Arduino\libraries\PZEM-004T-v30-master\PZEM004Tv30.cpp: In destructor 'PZEM004Tv30::~PZEM004Tv30()':
C:\Users\MEOCloud\Arduino\libraries\PZEM-004T-v30-master\PZEM004Tv30.cpp:119:22: warning: deleting object of abstract class type 'Stream' which has non-virtual destructor will cause undefined behavior [-Wdelete-non-virtual-dtor]
delete this->_serial;
^~~~~~~
exit status 1
Erro ao compilar para a placa Arduino MKR WiFi 1010.
`

Refresh rate

Hi,
First i would like to thank you for the work done on library.
do you know how to speed up the refresh rate of measurements?
i did some testing with a n Arduino Mega and a 2x16 display to find out that the rate is around 1 sec or more.
it did not matther if i disable serial print statements.

do you have an idea?

Regards, Alrik

Reduce RAM usage by storing crcTable in PROGMEM

Hi, thanks for the module!

You could reduce the RAM usage of the module by declaring crcTable as:
static PROGMEM const uint16_t crcTable[]

In this case reading from the crcTable should be updated to:
crc ^= (uint16_t)pgm_read_word(&crcTable[nTemp]);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.