mandulaj / PZEM-004T-v30

Arduino library for the Updated PZEM-004T v3.0 Power and Energy meter
MIT License
256 stars 108 forks source link

Multiple PZEMS cannot be used using same library #29

Closed alihassan2289 closed 3 years ago

alihassan2289 commented 4 years ago

Dear good day,

Appreciate your efforts, can you please update the library to use ip function to add multiple pzem v3 devices in the same code.

Thanks

Renato-REDS commented 3 years ago

Hello, thank you very much for sharing this library with us. It would be very important if we were able to create a library and be able to use multiple PZEM on the same network. thank you.

efakostya commented 3 years ago

PZEM004Tv30* pzem[] = { new PZEM004Tv30(D1, D2), new PZEM004Tv30(D3, D4), new PZEM004Tv30(D5, D6) };

for (size_t i = 0; i < 3; i++){ v[i] = pzem[i]->voltage(); ... }

or add uint8_t addr PZEM004Tv30::PZEM004Tv30(uint8_t receivePin, uint8_t transmitPin, uint8_t addr) PZEM004Tv30 pzem[] = { new PZEM004Tv30(D1, D2, uint8_t addr), ... }; or &Serial1 PZEM004Tv30::PZEM004Tv30(HardwareSerial port, uint8_t addr) PZEM004Tv30* pzem[] = { new PZEM004Tv30(&Serial1, uint8_t addr), ... };

Renato-REDS commented 3 years ago

Hi @Efakostya, Many thanks for the reply.

In my case I already have the hardware ready, and the communication of the PZEM's are in parallel, I cannot change the pins.

morganflint commented 3 years ago

I managed to read several sensors connected in parallel to the same software serial port, following the instructions here. The approach is to create two instances with different names, same port, and different address (of course, you have to program different addresses in each sensor, using the Windows software provided by the manufacturer, as I did, or the appropriate functions in this library, as explained here):

#include <PZEM004Tv30.h>

/* Use software serial for the PZEM
 * Pin 11 Rx (Connects to the Tx pin on both PZEMs)
 * Pin 12 Tx (Connects to the Rx pin on both PZEMs)
 *Two instances, one for each address
*/
PZEM004Tv30 pzem1(11,12, 0x01);
PZEM004Tv30 pzem2(11,12, 0x02);

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

void loop() {
    // 1st sensor
    Serial.println("==================================================");
    Serial.println("Sensor 1");
    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();
    delay(1000);

    // 2nd sensor
    Serial.println("==================================================");
    Serial.println("Sensor 2");
    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(1000);
}

The output is like this:

==================================================
Sensor 1
Voltage: 235.40V
Current: 0.04A
Power: 0.40W
Energy: 0.026kWh
Frequency: 49.9Hz
PF: 0.05

==================================================
Sensor 2
Voltage: 235.30V
Current: 0.07A
Power: 0.90W
Energy: 0.184kWh
Frequency: 49.9Hz
PF: 0.05

As you can see, this way of doing it has a problem if the number of sensors is higher, as you have to repeat a lot of code for each one. To avoid it, a possibility would be a modification in the library so the address could be passed as an argument (see here), but that's beyond my capabilities...

So I tried a second approach where the different instances of PZEM004Tv30 are created as an array. I wasn't sure this was going to work but, fortunately, it did!

Now the code is shorter and easy to escalate to more sensors:

#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 sensor[3] = {
  PZEM004Tv30(11,12, 0x01),
  PZEM004Tv30(11,12, 0x02),
  PZEM004Tv30(11,12, 0x03)
};

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

void loop() {
  for (int i=0; i<3; i++){  
    Serial.print("SENSOR No. "); Serial.println(i+1);
    float voltage = sensor[i].voltage();
    if( !isnan(voltage) ){
        Serial.print("Voltage: "); Serial.print(voltage); Serial.println("V");
    } else {
        Serial.println("Error reading voltage");
    }

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

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

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

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

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

    Serial.println();
    delay(2000);
  }
}

And it's output:

SENSOR No. 1
Voltage: 237.10V
Current: 0.04A
Power: 0.50W
Energy: 0.026kWh
Frequency: 50.0Hz
PF: 0.06

SENSOR No. 2
Voltage: 236.90V
Current: 0.07A
Power: 0.90W
Energy: 0.184kWh
Frequency: 50.0Hz
PF: 0.05

SENSOR No. 3
Error reading voltage
Error reading current
Error reading power
Error reading energy
Error reading frequency
Error reading power factor

The errors for sensor No 3 are due to the fact I haven't connected it yet ;-)

Hope it helps!

Renato-REDS commented 3 years ago

Hi @morganflint,

Thank you! Do me a lot! Congratulations !!!

mandulaj commented 3 years ago

Thanks @morganflint. Do you guys think the instructions should be placed somewhere more visible since this is a recurring issue people are coming across. If anyone has time and strength to describe this in the wiki or something, feel free to do so!