Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple PZEM example - Single Variable Compile Error #7

Closed
Petros144 opened this issue Dec 3, 2023 · 4 comments · Fixed by #8
Closed

Multiple PZEM example - Single Variable Compile Error #7

Petros144 opened this issue Dec 3, 2023 · 4 comments · Fixed by #8
Labels
help wanted Extra attention is needed

Comments

@Petros144
Copy link

Petros144 commented Dec 3, 2023

Hi @vortigont, thanks for the nice Lib!

Im not a specialist in Programming, so I need to aks some silly questions.

I Use 3x PZEM and they work great with your example code.

pz004::rx_msg_prettyp(m); Gives me the Whole list of Values of the Boards wich is great!

What I need to do is only get Voltages / Currents / Power etc. and write them in custom variables.

I tried this from the main.cpp to get the current from one Sensor:

void mycallback(uint8_t id, const RX_msg* m){

auto *m = (const pz004::metrics*)meters->getMetrics(PZEM_ID_2)
Serial.printf("PZEM '%s' current as float: %.3f (Amps)\n", meters->getDescr(PZEM_ID_2), m->asFloat(meter_t::cur));

But it wont compile and gives me errors.

I also dont need floats, so raw Integer values would be enough for me.

how do I access the single values within the callback (Raw values & Floats)?

Thanks in advance!

@vortigont
Copy link
Owner

vortigont commented Dec 3, 2023

Hi @Petros144, what kind of compile error do you get?
For callback function library pass the pointer to the struct, so you do not need to request it.

As for getting integer values you can do like this

unsigned u, i, p;

void mycallback(uint8_t id, const RX_msg* m){
  if (meters->getState()->dataStale())
    return;   // something is wrong, message is bad or data stale

   const auto *metrics =(const pz004::metrics*)meters->getMetrics(id);

    u = metrics->voltage;
    i = metrics->current;
    p = metrics->power;

    Serial.printf("PZEM voltage: %d (decivolts)\n", u);
    Serial.printf("PZEM current: %u (mA)\n", i);
    Serial.printf("PZEM power: %u (dW)\n", p);
}

mind that integer values are given in the way that PZEM sends it, i.e. voltage is in decivolts, not volts, current is in mA.

@vortigont
Copy link
Owner

I will update example with more detailed code like the one above.
Thanks for the tip.

@Petros144
Copy link
Author

Petros144 commented Dec 3, 2023

unsigned u, i, p;

void mycallback(uint8_t id, const RX_msg* m){
if (meters->getState()->dataStale())
return; // something is wrong, message is bad or data stale

const auto metrics =(const pz004::metrics)meters->getMetrics(id);

u = metrics->voltage;
i = metrics->current;
p = metrics->power;

Serial.printf("PZEM voltage: %d (decivolts)\n", u);
Serial.printf("PZEM current: %u (mA)\n", i);
Serial.printf("PZEM power: %u (dW)\n", p);

}

Thank you for the fast reply! this will help me a lot! I will test this tomorrow.

so to get my values of interesst I have to change the getMetrics(id); (id ist not the adress, but the custom ID for one of my PZEMs), correct?

So for every Phase I need to implement :

const auto metrics =(const pz004::metrics)meters->getMetrics(41) ; // Phase 1

u1 = metrics->voltage;

const auto metrics =(const pz004::metrics)meters->getMetrics(42) ; // Phase 2

u2 = metrics->voltage;

const auto metrics =(const pz004::metrics)meters->getMetrics(42) ; // Phase 3

u3 = metrics->voltage;

@vortigont
Copy link
Owner

so to get my values of interesst I have to change the getMetrics(id); (id ist not the adress, but the custom ID for one of my PZEMs), correct?

that is possible but would be incorrect. What callback does it just says "Hey, pzem with this 'id' just updated with fresh data".
So iterating through all your devices in callback is useless because only one of those has been updated. You will receive three different callbacks - each for one of your devices, other two are unchanged.

Also you do not really need to have separate variables u1, u2, u3 and copy metrics values there. Actually it would be wise to use values directly from your pzem objects. Like in my example if you need to print the data (or i.e. send it to some mqtt topic)
you should do it like this

void mycallback(uint8_t id, const RX_msg* m){
  const auto *metrics =(const pz004::metrics*)meters->getMetrics(id);
  Serial.printf("PZEM ID: %u, name: %s, voltage:%u, current:%u, etc...\n", id,  meters->getDescr(id), metrics->voltage, metrics->current);

  someSendToMQTTFunction("topic\voltage", metrics->voltage);
  someSendToMQTTFunction("topic\current", metrics->current);
}

but just in case if you do really want to keep your own copy of the data, you'd better use pzem struct for this.

// somewhere in main.cpp
pz004::metrics phase1data;
pz004::metrics phase2data;
pz004::metrics phase3data;


void mycallback(uint8_t id, const RX_msg* m){
  // copy data to your strucs
  if (id == YOUR_PHASE1_ID){
    phase1data = meters->getMetrics(id)
    return;
  }

  if (id == YOUR_PHASE2_ID){
    phase2data = meters->getMetrics(id)
    return;
  }

  if (id == YOUR_PHASE3_ID){
    phase3data = meters->getMetrics(id)
    return;
  }
}

// in some other function you can get to your copy of the data
void some_other_function(){
  // print your data
  Serial.printf("Phase 1 device name: %s, voltage:%u, current:%u, etc...\n",  meters->getDescr(id), phase1data->voltage, phase1data->current);

  Serial.printf("Phase 2 device name: %s, voltage:%u, current:%u, etc...\n",  meters->getDescr(id), phase2data->voltage, phase2data->current);

  Serial.printf("Phase 3 device name: %s, voltage:%u, current:%u, etc...\n",  meters->getDescr(id), phase3data->voltage, phase3data->current);

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants