Setting up an array

Status
Not open for further replies.

SteveSFX

Well-known member
Hi all.

I have this following sub-routine that checks for data from a PZEM mains voltage monitor. It all works fine.

But, I have five of these modules on the serial bus and for the life of me, I cannot work out how to set up the required arrays so that I can simply use a single routine as I have below, but just change the pzem number (e.g pzem1, pzem2).
Rather than what I currently have, which is this routine repeated 5 times.

Code:
void ReadPZEM1() {

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

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

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

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

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

  Pf = pzem1.pf();
  if (!isnan(Pf)) {
    Serial.print(F("PZEM1 PF: "));
    Serial.println(Pf);
  } else {
    Serial.println(F("Error reading PZEM1 power factor"));
  }

  Serial.println();

}

Any guidance would be great. I have spent several evenings trying to work it out, but to no avail. Arrays are not my friends
 
...how to set up the required arrays so that I can simply use a single routine as I have below, but just change the pzem number (e.g pzem1, pzem2).

SteveSFX:

This is all extemporaneous, so you may have to make some adjustments for it to compile & run.

Maybe setup the array so that it contains a pointer to (which is essentially the address of) each PZEM. Then, just pass an index number (integer) into your ReadPZEM() function & use "->" in place of "." when calling the functions associated with each PZEM.

Definition & initialization of the array (assuming the type of each entry is PZEM . . . without full source of your skectch, it's hard to guess the type, so adjust accordingly . . . also note that the entries in the array are referenced by an index that goes from 0 to 4, not 1 to 5):

Code:
#define NUM_PZEM 5
PZEM *pzem_array[NUM_PZEM] = { &pzem1, &pzem2, &pzem3, &pzem4, &pzem5 };

And the updated/generalized function:

Code:
// pass an index = 1 to 5 into this function
void ReadPZEM(int index) {

  Voltage = pzem_array[index - 1]->voltage();
  if (!isnan(Voltage)) {
    Serial.print(F("PZEM"));
    Serial.print(index);
    Serial.print(F(" Voltage: "));
    Serial.print(Voltage);
    Serial.println(F("V"));
  } else {
    Serial.print(F("Error reading PZEM"));
    Serial.print(index);
    Serial.println(F(" voltage"));
  }

  Current = pzem_array[index - 1]->current();
  if (!isnan(Current)) {
    Serial.print(F("PZEM"));
    Serial.print(index);
    Serial.print(F(" Current: "));
    Serial.print(Current);
    Serial.println(F("A"));
  } else {
    Serial.print(F("Error reading PZEM"));
    Serial.print(index);
    Serial.print(F( current"));
  }

  Power = pzem_array[index - 1]->power();
  if (!isnan(Power)) {
    Serial.print(F("PZEM"));
    Serial.print(index);
    Serial.print(F(" Power: "));
    Serial.print(Power);
    Serial.println(F("W"));
  } else {
    Serial.print(F("Error reading PZEM"));
    Serial.print(index);
    Serial.print(F( power"));
  }

  Energy = pzem_array[index - 1]->energy();
  if (!isnan(Energy)) {
    Serial.print(F("PZEM"));
    Serial.print(index);
    Serial.print(F(" Energy: "));
    Serial.print(Energy);
    Serial.println(F("kWh"));
  } else {
    Serial.print(F("Error reading PZEM"));
    Serial.print(index);
    Serial.print(F( energy"));
  }

  Frequency = pzem_array[index - 1]->frequency();
  if (!isnan(Frequency)) {
    Serial.print(F("PZEM"));
    Serial.print(index);
    Serial.print(F(" Frequency: "));
    Serial.print(Frequency);
    Serial.println(F("Hz"));
  } else {
    Serial.print(F("Error reading PZEM"));
    Serial.print(index);
    Serial.print(F( frequency"));
  }

  Pf = pzem_array[index - 1]->pf();
  if (!isnan(Pf)) {
    Serial.print(F("PZEM"));
    Serial.print(index);
    Serial.print(F(" PF: "));
    Serial.println(Pf);
  } else {
    Serial.print(F("Error reading PZEM"));
    Serial.print(index);
    Serial.print(F( power factor"));
  }

}

Hopefully, that gets the main idea across. If I've made any errors, I apologize in advance for any additional confusion that I may cause !!

Mark J Culross
KD5RXT
 
Thank you Mark, I will have a go with that.

It's similar to my attempts, but I have failed so far. Google did not come to the rescue.

Code:
#define NUM_PZEM 5
PZEM *pzem_array[NUM_PZEM] = { &pzem1, &pzem2, &pzem3, &pzem4, &pzem5 };

This throws up:

C:\Users\steve\Documents\Arduino\10 Way controller\10_way_controller_v15_Pin_allocation_Teensy_3.2\10_way_controller_v15_Pin_allocation_Teensy_3.2.ino:172:1: error: 'PZEM' does not name a type

PZEM *pzem_array[NUM_PZEM] = { &pzem1, &pzem2, &pzem3, &pzem4, &pzem5 };

^


Thanks for the assistance
 
Thank you Mark, I will have a go with that.

It's similar to my attempts, but I have failed so far. Google did not come to the rescue.

Code:
#define NUM_PZEM 5
PZEM *pzem_array[NUM_PZEM] = { &pzem1, &pzem2, &pzem3, &pzem4, &pzem5 };

This throws up:

C:\Users\steve\Documents\Arduino\10 Way controller\10_way_controller_v15_Pin_allocation_Teensy_3.2\10_way_controller_v15_Pin_allocation_Teensy_3.2.ino:172:1: error: 'PZEM' does not name a type

PZEM *pzem_array[NUM_PZEM] = { &pzem1, &pzem2, &pzem3, &pzem4, &pzem5 };

^


Thanks for the assistance

SteveSFX:

The "PZEM" was just a placeholder. For your definition of the pzem array, you'll need to define the array using the same type as pzem1-pzem5. As I tried to indicate, without a full sketch, it's not possible to guess what that type may be (quoting from my earlier message: "...assuming the type of each entry is PZEM . . . without full source of your sketch, it's hard to guess the type, so adjust accordingly...").

Good luck & have fun !!

Mark J Culross
KD5RXT
 
So:

I have this at the start of my routine:

#include <PZEM004Tv30.h> // Mains AC monitoring library

PZEM004Tv30 pzem0(&Serial3, 0x00); // Declare the 5x monitors on the Serial bus. THESE ADDRESSES NEED PROGRAMMING INTO THE MODULES BEFORE USE
PZEM004Tv30 pzem1(&Serial3, 0x01); // Address 00x0 is the factory default (or possibly 0xF8)
PZEM004Tv30 pzem2(&Serial3, 0x02);
PZEM004Tv30 pzem3(&Serial3, 0x03);
PZEM004Tv30 pzem4(&Serial3, 0x04);
PZEM004Tv30 pzem5(&Serial3, 0x05);


and this seems to compile. I'll give it a go..

#define NUM_PZEM 5 // Set up the PZEM data array
PZEM004Tv30 *pzem_array[NUM_PZEM] = { &pzem1, &pzem2, &pzem3, &pzem4, &pzem5 };
 
Status
Not open for further replies.
Back
Top