Closed Wachenanggo closed 4 years ago
You did .setaddress before, as Mandulaj wrote?
Yeah you have to use a separate sketch in order to set the address for each individual PZEM. Then you can address them on one Serial bus.
Yeah you have to use a separate sketch in order to set the address for each individual PZEM. Then you can address them on one Serial bus.
I already use the change address sketch and set each device address one by one. But only the last one is returning a value.or do i need a delay every tx of data and rx of data?
Are all of them connected to the mains voltage?
They are all connected to mains
I found out that you need to call PZEM004Tv30 pzem1(D5, D6, 0x01);
in void loop every time you query.
Wait a moment @Wachenaggo,following the necessity to reconstruct every time the object I went deep into and get this warning :
lib/PZEM-004T-v30/PZEM004Tv30.cpp: In destructor 'PZEM004Tv30::~PZEM004Tv30()': lib/PZEM-004T-v30/PZEM004Tv30.cpp:94:20: warning: deleting object of abstract class type 'Stream' which has non-virtual destructor will cause undefined behaviour [-Wdelete-non-virtual-dtor] delete this->_serial;
so I found https://stackoverflow.com/questions/47702776/how-to-properly-delete-pointers-when-using-abstract-classes it's needed a "virtual" destructor , thanks for your feedback.
@Wachenanggo could you explain what you mean with :
call PZEM004Tv30 pzem1(D5, D6, 0x01); in void loop every time you query.
Maybe send me the section of code you are talking about. You should not have to call the constructor multiple times....
I just threw together a simple sketch according to your original code and connected two of the PZEMs on one bus. They are both connected to the same AC voltage potential and don't measure current but my point is to read the data from them on one bus. And it appears to work no problem. I call the initialization functions only once at the beginning of the sketch. In the main loop, I only call the getter functions, such as pzem1.voltage()
:
#include <PZEM004Tv30.h>
/* You must use the pzem.setAddress() as shown in the example sketch
* in order to set up the individual addresses for each AC module
*/
PZEM004Tv30 pzem1(D5, D6, 0x01); // Only called once over here
PZEM004Tv30 pzem2(D5, D6, 0x02);
void setup() {
Serial.begin(115200);
}
void loop() {
Serial.println("PZEM1=====================");
float voltage = pzem1.voltage();
if(!isnan(voltage)){
Serial.print("Voltage: "); Serial.print(voltage); Serial.println("V");
} else {
Serial.println("Error reading voltage");
}
float current = pzem1.current();
if(!isnan(current)){
Serial.print("Current: "); Serial.print(current); Serial.println("A");
} else {
Serial.println("Error reading current");
}
float power = pzem1.power();
if(!isnan(power)){
Serial.print("Power: "); Serial.print(power); Serial.println("W");
} else {
Serial.println("Error reading power");
}
float energy = pzem1.energy();
if(!isnan(energy)){
Serial.print("Energy: "); Serial.print(energy,3); Serial.println("kWh");
} else {
Serial.println("Error reading energy");
}
float frequency = pzem1.frequency();
if(!isnan(frequency)){
Serial.print("Frequency: "); Serial.print(frequency, 1); Serial.println("Hz");
} else {
Serial.println("Error reading frequency");
}
float pf = pzem1.pf();
if(!isnan(pf)){
Serial.print("PF: "); Serial.println(pf);
} else {
Serial.println("Error reading power factor");
}
Serial.println();
Serial.println("PZEM2=====================");
voltage = pzem2.voltage();
if(!isnan(voltage)){
Serial.print("Voltage: "); Serial.print(voltage); Serial.println("V");
} else {
Serial.println("Error reading voltage");
}
current = pzem2.current();
if(!isnan(current)){
Serial.print("Current: "); Serial.print(current); Serial.println("A");
} else {
Serial.println("Error reading current");
}
power = pzem2.power();
if(!isnan(power)){
Serial.print("Power: "); Serial.print(power); Serial.println("W");
} else {
Serial.println("Error reading power");
}
energy = pzem2.energy();
if(!isnan(energy)){
Serial.print("Energy: "); Serial.print(energy,3); Serial.println("kWh");
} else {
Serial.println("Error reading energy");
}
frequency = pzem2.frequency();
if(!isnan(frequency)){
Serial.print("Frequency: "); Serial.print(frequency, 1); Serial.println("Hz");
} else {
Serial.println("Error reading frequency");
}
pf = pzem2.pf();
if(!isnan(pf)){
Serial.print("PF: "); Serial.println(pf);
} else {
Serial.println("Error reading power factor");
}
Serial.println();
delay(2000);
}
Of course I initially used the setAddress sketch for each of the modules individually to give them their respective addresses.
The output is as follows:
PZEM1=====================
Voltage: 239.00V
Current: 0.00A
Power: 0.00W
Energy: 0.000kWh
Frequency: 50.0Hz
PF: 0.00
PZEM2=====================
Voltage: 239.10V
Current: 0.00A
Power: 0.00W
Energy: 0.002kWh
Frequency: 50.0Hz
PF: 0.00
You can see that for example the Cumulative Energy quantity differs for the two modules, so I am definitely reading from the two different sensors on one bus.
Here is a picture of my setup. Please excuse the wire mess, I had little time and space :smile:
It might not be very clear but on the white breadboard I am connecting the RX
pins of both modules together to the one TX
pin on the Arduino and both module's TX
pins to the one Arduino RX
pin... Also both modules are supplied with 5V and GND.
Wouldnt it be a good idea if you could send the address as a parameter, instead of creating different instances for each PZEM? I mean, instead of reading PZEM with address X this way:
PZEM004Tv30 pzemX(D5, D6, 0xXX);
....
....
power = pzemX.power();
Would be better if you could do:
PZEM004Tv30 pzem(D5, D6);
....
....
power = pzem.power(0xXX);
This would allow, for example, to use a loop if you have to do the same thing with several PZEMs:
for (int sensor=1; sensor<4; sensor++){
power = pzem.power(sensor);
if(!isnan(power)){
Serial.print("Sensor "); Serial.print(sensor); Serial.print(" Power: "); Serial.print(power); Serial.println("W");
} else {
Serial.print("Error reading power for sensor "); Serialprintln(sensor);
}
}
To avoid incompatibility with "classic" mode I imagine it could be possible to make the library behave the same as now if you don't pass any parameter.
Would it be very difficult to implement?
[EDIT] I found a workaround for this using an array of PZEM004Tv30 instances and posted it here. Anyway, I still think the possibility to add PZEM's address as an argument in the function is also a good alternative...
Hello,
I have an issue while changing pzem address.
PZEM004Tv30 pzem(&Serial3); uint8_t addr=0x0001;
void setup() { Serial.begin(9800); pzem.setAddress(addr); }
void loop() { Serial.print("Current address:"); Serial.println(pzem.getAddress()); Serial.println(); delay(1000); }
When I restart de pzem, the address is back to 248.
Any idea what is wrong? Thanks,
How to reset pzem2 = 0x02 ?? Exemplo:
PZEM004Tv30 pzem1(D5, D6, 0x01); PZEM004Tv30 pzem2(D5, D6, 0x02);
For 0x01 = [0x01, 0x42, 0x80, 0x11]
for 0x02 = ???
help
How to reset pzem2 = 0x02 ?? Exemplo:
PZEM004Tv30 pzem1(D5, D6, 0x01); PZEM004Tv30 pzem2(D5, D6, 0x02);
For 0x01 = [0x01, 0x42, 0x80, 0x11]
for 0x02 = ???
help
Two ways. First, you could run the PZEM querying program on your PC and use it to change your PZEM's address to whatever you want. Second, you could connect your second PZEM ALONE to your Arduino and run the address changing "sketch" without any other PZEM devices attached to the Arduino. After changing its address, you can connect your other PZEMs back to the Arduino and they should have different addresses.
I follow the same initialization, as you said. But it only returns the last PZEM connected.
here's my code. '#include
/ 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 voltage2 = pzem2.voltage(); if( !isnan(voltage2) ){ Serial.print("voltage2: "); Serial.print(voltage2); Serial.println("V"); } else { Serial.println("Error reading voltage"); }
}`